1 /* $OpenBSD: mpi.c,v 1.63 2006/07/15 04:09:57 dlg Exp $ */ 2 3 /* 4 * Copyright (c) 2005, 2006 David Gwynne <dlg@openbsd.org> 5 * Copyright (c) 2005 Marco Peereboom <marco@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <sys/param.h> 21 #include <sys/systm.h> 22 #include <sys/buf.h> 23 #include <sys/device.h> 24 #include <sys/proc.h> 25 #include <sys/malloc.h> 26 #include <sys/kernel.h> 27 28 #include <machine/bus.h> 29 30 #include <scsi/scsi_all.h> 31 #include <scsi/scsiconf.h> 32 33 #include <dev/ic/mpireg.h> 34 #include <dev/ic/mpivar.h> 35 36 #ifdef MPI_DEBUG 37 uint32_t mpi_debug = 0 38 /* | MPI_D_CMD */ 39 /* | MPI_D_INTR */ 40 /* | MPI_D_MISC */ 41 /* | MPI_D_DMA */ 42 /* | MPI_D_IOCTL */ 43 /* | MPI_D_RW */ 44 /* | MPI_D_MEM */ 45 /* | MPI_D_CCB */ 46 /* | MPI_D_PPR */ 47 /* | MPI_D_RAID */ 48 ; 49 #endif 50 51 struct cfdriver mpi_cd = { 52 NULL, "mpi", DV_DULL 53 }; 54 55 int mpi_scsi_cmd(struct scsi_xfer *); 56 void mpi_scsi_cmd_done(struct mpi_ccb *); 57 void mpi_minphys(struct buf *bp); 58 int mpi_scsi_ioctl(struct scsi_link *, u_long, caddr_t, 59 int, struct proc *); 60 61 struct scsi_adapter mpi_switch = { 62 mpi_scsi_cmd, mpi_minphys, NULL, NULL, mpi_scsi_ioctl 63 }; 64 65 struct scsi_device mpi_dev = { 66 NULL, NULL, NULL, NULL 67 }; 68 69 struct mpi_dmamem *mpi_dmamem_alloc(struct mpi_softc *, size_t); 70 void mpi_dmamem_free(struct mpi_softc *, 71 struct mpi_dmamem *); 72 int mpi_alloc_ccbs(struct mpi_softc *); 73 struct mpi_ccb *mpi_get_ccb(struct mpi_softc *); 74 void mpi_put_ccb(struct mpi_softc *, struct mpi_ccb *); 75 int mpi_alloc_replies(struct mpi_softc *); 76 void mpi_push_replies(struct mpi_softc *); 77 78 void mpi_start(struct mpi_softc *, struct mpi_ccb *); 79 int mpi_complete(struct mpi_softc *, struct mpi_ccb *, int); 80 int mpi_poll(struct mpi_softc *, struct mpi_ccb *, int); 81 82 void mpi_fc_print(struct mpi_softc *); 83 void mpi_squash_ppr(struct mpi_softc *); 84 void mpi_run_ppr(struct mpi_softc *); 85 int mpi_ppr(struct mpi_softc *, struct scsi_link *, 86 struct mpi_cfg_raid_physdisk *, int, int, int); 87 int mpi_inq(struct mpi_softc *, u_int16_t, int); 88 89 void mpi_timeout_xs(void *); 90 int mpi_load_xs(struct mpi_ccb *); 91 92 u_int32_t mpi_read(struct mpi_softc *, bus_size_t); 93 void mpi_write(struct mpi_softc *, bus_size_t, u_int32_t); 94 int mpi_wait_eq(struct mpi_softc *, bus_size_t, u_int32_t, 95 u_int32_t); 96 int mpi_wait_ne(struct mpi_softc *, bus_size_t, u_int32_t, 97 u_int32_t); 98 99 int mpi_init(struct mpi_softc *); 100 int mpi_reset_soft(struct mpi_softc *); 101 int mpi_reset_hard(struct mpi_softc *); 102 103 int mpi_handshake_send(struct mpi_softc *, void *, size_t); 104 int mpi_handshake_recv_dword(struct mpi_softc *, 105 u_int32_t *); 106 int mpi_handshake_recv(struct mpi_softc *, void *, size_t); 107 108 void mpi_empty_done(struct mpi_ccb *); 109 110 int mpi_iocinit(struct mpi_softc *); 111 int mpi_iocfacts(struct mpi_softc *); 112 int mpi_portfacts(struct mpi_softc *); 113 int mpi_eventnotify(struct mpi_softc *); 114 void mpi_eventnotify_done(struct mpi_ccb *); 115 int mpi_portenable(struct mpi_softc *); 116 void mpi_get_raid(struct mpi_softc *); 117 int mpi_fwupload(struct mpi_softc *); 118 119 int mpi_cfg_header(struct mpi_softc *, u_int8_t, u_int8_t, 120 u_int32_t, struct mpi_cfg_hdr *); 121 int mpi_cfg_page(struct mpi_softc *, u_int32_t, 122 struct mpi_cfg_hdr *, int, void *, size_t); 123 124 #define DEVNAME(s) ((s)->sc_dev.dv_xname) 125 126 #define dwordsof(s) (sizeof(s) / sizeof(u_int32_t)) 127 #define sizeofa(s) (sizeof(s) / sizeof((s)[0])) 128 129 #define mpi_read_db(s) mpi_read((s), MPI_DOORBELL) 130 #define mpi_write_db(s, v) mpi_write((s), MPI_DOORBELL, (v)) 131 #define mpi_read_intr(s) mpi_read((s), MPI_INTR_STATUS) 132 #define mpi_write_intr(s, v) mpi_write((s), MPI_INTR_STATUS, (v)) 133 #define mpi_pop_reply(s) mpi_read((s), MPI_REPLY_QUEUE) 134 #define mpi_push_reply(s, v) mpi_write((s), MPI_REPLY_QUEUE, (v)) 135 136 #define mpi_wait_db_int(s) mpi_wait_ne((s), MPI_INTR_STATUS, \ 137 MPI_INTR_STATUS_DOORBELL, 0) 138 #define mpi_wait_db_ack(s) mpi_wait_eq((s), MPI_INTR_STATUS, \ 139 MPI_INTR_STATUS_IOCDOORBELL, 0) 140 141 int 142 mpi_attach(struct mpi_softc *sc) 143 { 144 struct device *dev; 145 struct mpi_ccb *ccb; 146 147 printf("\n"); 148 149 /* disable interrupts */ 150 mpi_write(sc, MPI_INTR_MASK, 151 MPI_INTR_MASK_REPLY | MPI_INTR_MASK_DOORBELL); 152 153 if (mpi_init(sc) != 0) { 154 printf("%s: unable to initialise\n", DEVNAME(sc)); 155 return (1); 156 } 157 158 if (mpi_iocfacts(sc) != 0) { 159 printf("%s: unable to get iocfacts\n", DEVNAME(sc)); 160 return (1); 161 } 162 163 if (mpi_alloc_ccbs(sc) != 0) { 164 /* error already printed */ 165 return (1); 166 } 167 168 if (mpi_alloc_replies(sc) != 0) { 169 printf("%s: unable to allocate reply space\n", DEVNAME(sc)); 170 goto free_ccbs; 171 } 172 173 if (mpi_iocinit(sc) != 0) { 174 printf("%s: unable to send iocinit\n", DEVNAME(sc)); 175 goto free_ccbs; 176 } 177 178 /* spin until we're operational */ 179 if (mpi_wait_eq(sc, MPI_DOORBELL, MPI_DOORBELL_STATE, 180 MPI_DOORBELL_STATE_OPER) != 0) { 181 printf("%s: state: 0x%08x\n", DEVNAME(sc), 182 mpi_read_db(sc) & MPI_DOORBELL_STATE); 183 printf("%s: operational state timeout\n", DEVNAME(sc)); 184 goto free_ccbs; 185 } 186 187 mpi_push_replies(sc); 188 189 if (mpi_portfacts(sc) != 0) { 190 printf("%s: unable to get portfacts\n", DEVNAME(sc)); 191 goto free_replies; 192 } 193 194 #if notyet 195 if (mpi_eventnotify(sc) != 0) { 196 printf("%s: unable to get portfacts\n", DEVNAME(sc)); 197 goto free_replies; 198 } 199 #endif 200 201 if (mpi_portenable(sc) != 0) { 202 printf("%s: unable to enable port\n", DEVNAME(sc)); 203 goto free_replies; 204 } 205 206 if (mpi_fwupload(sc) != 0) { 207 printf("%s: unable to upload firmware\n", DEVNAME(sc)); 208 goto free_replies; 209 } 210 211 if (sc->sc_porttype == MPI_PORTFACTS_PORTTYPE_SCSI) 212 mpi_squash_ppr(sc); 213 214 /* we should be good to go now, attach scsibus */ 215 sc->sc_link.device = &mpi_dev; 216 sc->sc_link.adapter = &mpi_switch; 217 sc->sc_link.adapter_softc = sc; 218 sc->sc_link.adapter_target = sc->sc_target; 219 sc->sc_link.adapter_buswidth = sc->sc_buswidth; 220 sc->sc_link.openings = sc->sc_maxcmds / sc->sc_buswidth; 221 222 config_found(&sc->sc_dev, &sc->sc_link, scsiprint); 223 224 /* find our scsibus */ 225 TAILQ_FOREACH(dev, &alldevs, dv_list) { 226 if (dev->dv_parent == &sc->sc_dev) 227 break; 228 } 229 sc->sc_scsibus = (struct scsibus_softc *)dev; 230 231 /* get raid pages */ 232 mpi_get_raid(sc); 233 234 /* do domain validation */ 235 if (sc->sc_porttype == MPI_PORTFACTS_PORTTYPE_SCSI) 236 mpi_run_ppr(sc); 237 if (sc->sc_porttype == MPI_PORTFACTS_PORTTYPE_FC) 238 mpi_fc_print(sc); 239 240 /* enable interrupts */ 241 mpi_write(sc, MPI_INTR_MASK, MPI_INTR_MASK_DOORBELL); 242 243 return (0); 244 245 free_replies: 246 bus_dmamap_sync(sc->sc_dmat, MPI_DMA_MAP(sc->sc_replies), 247 0, PAGE_SIZE, BUS_DMASYNC_POSTREAD); 248 mpi_dmamem_free(sc, sc->sc_replies); 249 free_ccbs: 250 while ((ccb = mpi_get_ccb(sc)) != NULL) 251 bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap); 252 mpi_dmamem_free(sc, sc->sc_requests); 253 free(sc->sc_ccbs, M_DEVBUF); 254 255 return(1); 256 } 257 258 void 259 mpi_fc_print(struct mpi_softc *sc) 260 { 261 struct mpi_cfg_hdr hdr; 262 struct mpi_cfg_fc_port_pg0 pg; 263 struct mpi_cfg_fc_device_pg0 dpg; 264 struct device *dev; 265 struct scsibus_softc *ssc; 266 struct scsi_link *link; 267 int i; 268 u_int32_t btid; 269 270 if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_FC_PORT, 0, 0, 271 &hdr) != 0) { 272 DNPRINTF(MPI_D_MISC, "%s: mpi_fc_print unable to fetch " 273 "FC port header 0\n", DEVNAME(sc)); 274 return; 275 } 276 277 if (mpi_cfg_page(sc, 0, &hdr, 1, &pg, sizeof(pg)) != 0) { 278 DNPRINTF(MPI_D_MISC, "%s: mpi_fc_print unable to fetch " 279 "FC port page 0\n", 280 DEVNAME(sc)); 281 return; 282 } 283 284 DNPRINTF(MPI_D_MISC, "%s: at: %dGHz WWNN: %016llx WWPN: %016llx\n", 285 DEVNAME(sc), letoh32(pg.current_speed), letoh64(pg.wwnn), 286 letoh64(pg.wwpn)); 287 288 TAILQ_FOREACH(dev, &alldevs, dv_list) { 289 if (dev->dv_parent == &sc->sc_dev) 290 break; 291 } 292 293 /* im too nice to punish idiots who don't configure scsibus */ 294 if (dev == NULL) 295 return; 296 297 ssc = (struct scsibus_softc *)dev; 298 for (i = 0; i < sc->sc_link.adapter_buswidth; i++) { 299 300 link = ssc->sc_link[i][0]; 301 302 if (link == NULL) 303 continue; 304 305 btid = i | MPI_PAGE_ADDRESS_FC_BTID; 306 if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_FC_DEV, 0, 307 btid, &hdr) != 0) { 308 DNPRINTF(MPI_D_MISC, "%s: mpi_fc_print unable to fetch " 309 "device header 0\n", DEVNAME(sc)); 310 return; 311 } 312 313 bzero(&dpg, sizeof(dpg)); 314 if (mpi_cfg_page(sc, btid, &hdr, 1, &dpg, sizeof(dpg)) != 0) { 315 DNPRINTF(MPI_D_MISC, "%s: mpi_fc_print unable to fetch " 316 "device page 0\n", DEVNAME(sc)); 317 continue; 318 } 319 320 link->port_wwn = letoh64(dpg.wwpn); 321 link->node_wwn = letoh64(dpg.wwnn); 322 323 DNPRINTF(MPI_D_MISC, "%s: target %d WWNN: %016llx " 324 "WWPN: %016llx\n", DEVNAME(sc), i, 325 letoh64(dpg.wwnn), letoh64(dpg.wwpn)); 326 } 327 } 328 329 void 330 mpi_squash_ppr(struct mpi_softc *sc) 331 { 332 struct mpi_cfg_hdr hdr; 333 struct mpi_cfg_spi_dev_pg1 page; 334 int i; 335 336 DNPRINTF(MPI_D_PPR, "%s: mpi_squash_ppr\n", DEVNAME(sc)); 337 338 for (i = 0; i < sc->sc_buswidth; i++) { 339 if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_SCSI_SPI_DEV, 340 1, i, &hdr) != 0) 341 return; 342 343 if (mpi_cfg_page(sc, i, &hdr, 1, &page, sizeof(page)) != 0) 344 return; 345 346 DNPRINTF(MPI_D_PPR, "%s: target: %d req_params1: 0x%02x " 347 "req_offset: 0x%02x req_period: 0x%02x " 348 "req_params2: 0x%02x conf: 0x%08x\n", DEVNAME(sc), i, 349 page.req_params1, page.req_offset, page.req_period, 350 page.req_params2, letoh32(page.configuration)); 351 352 page.req_params1 = 0x0; 353 page.req_offset = 0x0; 354 page.req_period = 0x0; 355 page.req_params2 = 0x0; 356 page.configuration = htole32(0x0); 357 358 if (mpi_cfg_page(sc, i, &hdr, 0, &page, sizeof(page)) != 0) 359 return; 360 } 361 } 362 363 void 364 mpi_run_ppr(struct mpi_softc *sc) 365 { 366 struct mpi_cfg_hdr hdr; 367 struct mpi_cfg_spi_port_pg0 port_pg; 368 struct mpi_cfg_ioc_pg3 *physdisk_pg; 369 struct mpi_cfg_raid_physdisk *physdisk_list, *physdisk; 370 size_t pagelen; 371 struct scsi_link *link; 372 int i, tries; 373 374 if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_SCSI_SPI_PORT, 0, 0x0, 375 &hdr) != 0) { 376 DNPRINTF(MPI_D_PPR, "%s: mpi_run_ppr unable to fetch header\n", 377 DEVNAME(sc)); 378 return; 379 } 380 381 if (mpi_cfg_page(sc, 0x0, &hdr, 1, &port_pg, sizeof(port_pg)) != 0) { 382 DNPRINTF(MPI_D_PPR, "%s: mpi_run_ppr unable to fetch page\n", 383 DEVNAME(sc)); 384 return; 385 } 386 387 for (i = 0; i < sc->sc_buswidth; i++) { 388 link = sc->sc_scsibus->sc_link[i][0]; 389 if (link == NULL) 390 continue; 391 392 /* do not ppr volumes */ 393 if (link->flags & SDEV_VIRTUAL) 394 continue; 395 396 tries = 0; 397 while (mpi_ppr(sc, link, NULL, port_pg.min_period, 398 port_pg.max_offset, tries) == EAGAIN) 399 tries++; 400 } 401 402 if ((sc->sc_flags & MPI_F_RAID) == 0) 403 return; 404 405 if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_IOC, 3, 0x0, 406 &hdr) != 0) { 407 DNPRINTF(MPI_D_RAID|MPI_D_PPR, "%s: mpi_run_ppr unable to " 408 "fetch ioc pg 3 header\n", DEVNAME(sc)); 409 return; 410 } 411 412 pagelen = hdr.page_length * 4; /* dwords to bytes */ 413 physdisk_pg = malloc(pagelen, M_TEMP, M_WAITOK); 414 if (physdisk_pg == NULL) { 415 DNPRINTF(MPI_D_RAID|MPI_D_PPR, "%s: mpi_run_ppr unable to " 416 "allocate ioc pg 3\n", DEVNAME(sc)); 417 return; 418 } 419 physdisk_list = (struct mpi_cfg_raid_physdisk *)(physdisk_pg + 1); 420 421 if (mpi_cfg_page(sc, 0, &hdr, 1, physdisk_pg, pagelen) != 0) { 422 DNPRINTF(MPI_D_PPR|MPI_D_PPR, "%s: mpi_run_ppr unable to " 423 "fetch ioc page 3\n", DEVNAME(sc)); 424 goto out; 425 } 426 427 DNPRINTF(MPI_D_PPR|MPI_D_PPR, "%s: no_phys_disks: %d\n", DEVNAME(sc), 428 physdisk_pg->no_phys_disks); 429 430 for (i = 0; i < physdisk_pg->no_phys_disks; i++) { 431 physdisk = &physdisk_list[i]; 432 433 DNPRINTF(MPI_D_PPR|MPI_D_PPR, "%s: id: %d bus: %d ioc: %d " 434 "num: %d\n", DEVNAME(sc), physdisk->phys_disk_id, 435 physdisk->phys_disk_bus, physdisk->phys_disk_ioc, 436 physdisk->phys_disk_num); 437 438 if (physdisk->phys_disk_ioc != sc->sc_ioc_number) 439 continue; 440 441 tries = 0; 442 while (mpi_ppr(sc, NULL, physdisk, port_pg.min_period, 443 port_pg.max_offset, tries) == EAGAIN) 444 tries++; 445 } 446 447 out: 448 free(physdisk_pg, M_TEMP); 449 } 450 451 int 452 mpi_ppr(struct mpi_softc *sc, struct scsi_link *link, 453 struct mpi_cfg_raid_physdisk *physdisk, int period, int offset, int try) 454 { 455 struct mpi_cfg_hdr hdr0, hdr1; 456 struct mpi_cfg_spi_dev_pg0 pg0; 457 struct mpi_cfg_spi_dev_pg1 pg1; 458 u_int32_t address; 459 int id; 460 int raid = 0; 461 462 DNPRINTF(MPI_D_PPR, "%s: mpi_ppr period: %d offset: %d try: %d " 463 "link quirks: 0x%x\n", DEVNAME(sc), period, offset, try, 464 link->quirks); 465 466 if (try >= 3) 467 return (EIO); 468 469 if (physdisk == NULL) { 470 if ((link->inqdata.device & SID_TYPE) == T_PROCESSOR) 471 return (EIO); 472 473 address = link->target; 474 id = link->target; 475 } else { 476 raid = 1; 477 address = (physdisk->phys_disk_bus << 8) | 478 (physdisk->phys_disk_id); 479 id = physdisk->phys_disk_num; 480 } 481 482 if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_SCSI_SPI_DEV, 0, 483 address, &hdr0) != 0) { 484 DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to fetch header 0\n", 485 DEVNAME(sc)); 486 return (EIO); 487 } 488 489 if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_SCSI_SPI_DEV, 1, 490 address, &hdr1) != 0) { 491 DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to fetch header 1\n", 492 DEVNAME(sc)); 493 return (EIO); 494 } 495 496 #ifdef MPI_DEBUG 497 if (mpi_cfg_page(sc, address, &hdr0, 1, &pg0, sizeof(pg0)) != 0) { 498 DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to fetch page 0\n", 499 DEVNAME(sc)); 500 return (EIO); 501 } 502 503 DNPRINTF(MPI_D_PPR, "%s: mpi_ppr dev pg 0 neg_params1: 0x%02x " 504 "neg_offset: %d neg_period: 0x%02x neg_params2: 0x%02x " 505 "info: 0x%08x\n", DEVNAME(sc), pg0.neg_params1, pg0.neg_offset, 506 pg0.neg_period, pg0.neg_params2, letoh32(pg0.information)); 507 #endif 508 509 if (mpi_cfg_page(sc, address, &hdr1, 1, &pg1, sizeof(pg1)) != 0) { 510 DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to fetch page 1\n", 511 DEVNAME(sc)); 512 return (EIO); 513 } 514 515 DNPRINTF(MPI_D_PPR, "%s: mpi_ppr dev pg 1 req_params1: 0x%02x " 516 "req_offset: 0x%02x req_period: 0x%02x req_params2: 0x%02x " 517 "conf: 0x%08x\n", DEVNAME(sc), pg1.req_params1, pg1.req_offset, 518 pg1.req_period, pg1.req_params2, letoh32(pg1.configuration)); 519 520 pg1.req_params1 = 0; 521 pg1.req_offset = offset; 522 pg1.req_period = period; 523 pg1.req_params2 &= ~MPI_CFG_SPI_DEV_1_REQPARAMS_WIDTH; 524 525 if (raid || !(link->quirks & SDEV_NOSYNC)) { 526 pg1.req_params2 |= MPI_CFG_SPI_DEV_1_REQPARAMS_WIDTH_WIDE; 527 528 switch (try) { 529 case 0: /* U320 */ 530 break; 531 case 1: /* U160 */ 532 pg1.req_period = 0x09; 533 break; 534 case 2: /* U80 */ 535 pg1.req_period = 0x0a; 536 break; 537 } 538 539 if (pg1.req_period < 0x09) { 540 /* Ultra320: enable QAS & PACKETIZED */ 541 pg1.req_params1 |= MPI_CFG_SPI_DEV_1_REQPARAMS_QAS | 542 MPI_CFG_SPI_DEV_1_REQPARAMS_PACKETIZED; 543 } 544 if (pg1.req_period < 0xa) { 545 /* >= Ultra160: enable dual xfers */ 546 pg1.req_params1 |= 547 MPI_CFG_SPI_DEV_1_REQPARAMS_DUALXFERS; 548 } 549 } 550 551 DNPRINTF(MPI_D_PPR, "%s: mpi_ppr dev pg 1 req_params1: 0x%02x " 552 "req_offset: 0x%02x req_period: 0x%02x req_params2: 0x%02x " 553 "conf: 0x%08x\n", DEVNAME(sc), pg1.req_params1, pg1.req_offset, 554 pg1.req_period, pg1.req_params2, letoh32(pg1.configuration)); 555 556 if (mpi_cfg_page(sc, address, &hdr1, 0, &pg1, sizeof(pg1)) != 0) { 557 DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to write page 1\n", 558 DEVNAME(sc)); 559 return (EIO); 560 } 561 562 if (mpi_cfg_page(sc, address, &hdr1, 1, &pg1, sizeof(pg1)) != 0) { 563 DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to read page 1\n", 564 DEVNAME(sc)); 565 return (EIO); 566 } 567 568 DNPRINTF(MPI_D_PPR, "%s: mpi_ppr dev pg 1 req_params1: 0x%02x " 569 "req_offset: 0x%02x req_period: 0x%02x req_params2: 0x%02x " 570 "conf: 0x%08x\n", DEVNAME(sc), pg1.req_params1, pg1.req_offset, 571 pg1.req_period, pg1.req_params2, letoh32(pg1.configuration)); 572 573 if (mpi_inq(sc, id, raid) != 0) { 574 DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to do inquiry against " 575 "target %d\n", DEVNAME(sc), link->target); 576 return (EIO); 577 } 578 579 if (mpi_cfg_page(sc, address, &hdr0, 1, &pg0, sizeof(pg0)) != 0) { 580 DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to read page 0 after " 581 "inquiry\n", DEVNAME(sc)); 582 return (EIO); 583 } 584 585 DNPRINTF(MPI_D_PPR, "%s: mpi_ppr dev pg 0 neg_params1: 0x%02x " 586 "neg_offset: %d neg_period: 0x%02x neg_params2: 0x%02x " 587 "info: 0x%08x\n", DEVNAME(sc), pg0.neg_params1, pg0.neg_offset, 588 pg0.neg_period, pg0.neg_params2, letoh32(pg0.information)); 589 590 if (!(letoh32(pg0.information) & 0x07) && (try == 0)) { 591 DNPRINTF(MPI_D_PPR, "%s: mpi_ppr U320 ppr rejected\n", 592 DEVNAME(sc)); 593 return (EAGAIN); 594 } 595 596 if ((((letoh32(pg0.information) >> 8) & 0xff) > 0x09) && (try == 1)) { 597 DNPRINTF(MPI_D_PPR, "%s: mpi_ppr U160 ppr rejected\n", 598 DEVNAME(sc)); 599 return (EAGAIN); 600 } 601 602 if (letoh32(pg0.information) & 0x0e) { 603 DNPRINTF(MPI_D_PPR, "%s: mpi_ppr ppr rejected: %0x\n", 604 DEVNAME(sc), letoh32(pg0.information)); 605 return (EAGAIN); 606 } 607 608 switch(pg0.neg_period) { 609 case 0x08: 610 period = 160; 611 break; 612 case 0x09: 613 period = 80; 614 break; 615 case 0x0a: 616 period = 40; 617 break; 618 case 0x0b: 619 period = 20; 620 break; 621 case 0x0c: 622 period = 10; 623 break; 624 default: 625 period = 0; 626 break; 627 } 628 629 printf("%s: %s %d %s at %dMHz width %dbit offset %d " 630 "QAS %d DT %d IU %d\n", DEVNAME(sc), raid ? "phys disk" : "target", 631 id, period ? "Sync" : "Async", period, 632 (pg0.neg_params2 & MPI_CFG_SPI_DEV_0_NEGPARAMS_WIDTH_WIDE) ? 16 : 8, 633 pg0.neg_offset, 634 (pg0.neg_params1 & MPI_CFG_SPI_DEV_0_NEGPARAMS_QAS) ? 1 : 0, 635 (pg0.neg_params1 & MPI_CFG_SPI_DEV_0_NEGPARAMS_DUALXFERS) ? 1 : 0, 636 (pg0.neg_params1 & MPI_CFG_SPI_DEV_0_NEGPARAMS_PACKETIZED) ? 1 : 0); 637 638 return (0); 639 } 640 641 int 642 mpi_inq(struct mpi_softc *sc, u_int16_t target, int physdisk) 643 { 644 struct mpi_ccb *ccb; 645 struct scsi_inquiry inq; 646 struct { 647 struct mpi_msg_scsi_io io; 648 struct mpi_sge sge; 649 struct scsi_inquiry_data inqbuf; 650 struct scsi_sense_data sense; 651 } __packed *bundle; 652 struct mpi_msg_scsi_io *io; 653 struct mpi_sge *sge; 654 u_int64_t addr; 655 656 DNPRINTF(MPI_D_PPR, "%s: mpi_inq\n", DEVNAME(sc)); 657 658 bzero(&inq, sizeof(inq)); 659 inq.opcode = INQUIRY; 660 661 ccb = mpi_get_ccb(sc); 662 if (ccb == NULL) 663 return (1); 664 665 ccb->ccb_done = mpi_empty_done; 666 667 bundle = ccb->ccb_cmd; 668 io = &bundle->io; 669 sge = &bundle->sge; 670 671 io->function = physdisk ? MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH : 672 MPI_FUNCTION_SCSI_IO_REQUEST; 673 /* 674 * bus is always 0 675 * io->bus = htole16(sc->sc_bus); 676 */ 677 io->target_id = target; 678 679 io->cdb_length = sizeof(inq); 680 io->sense_buf_len = sizeof(struct scsi_sense_data); 681 io->msg_flags = MPI_SCSIIO_SENSE_BUF_ADDR_WIDTH_64; 682 683 io->msg_context = htole32(ccb->ccb_id); 684 685 /* 686 * always lun 0 687 * io->lun[0] = htobe16(link->lun); 688 */ 689 690 io->direction = MPI_SCSIIO_DIR_READ; 691 io->tagging = MPI_SCSIIO_ATTR_NO_DISCONNECT; 692 693 bcopy(&inq, io->cdb, sizeof(inq)); 694 695 io->data_length = htole32(sizeof(struct scsi_inquiry_data)); 696 697 io->sense_buf_low_addr = htole32(ccb->ccb_cmd_dva + 698 ((u_int8_t *)&bundle->sense - (u_int8_t *)bundle)); 699 700 sge->sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE | MPI_SGE_FL_SIZE_64 | 701 MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | MPI_SGE_FL_EOL | 702 (u_int32_t)sizeof(inq)); 703 704 addr = ccb->ccb_cmd_dva + 705 ((u_int8_t *)&bundle->inqbuf - (u_int8_t *)bundle); 706 sge->sg_hi_addr = htole32((u_int32_t)(addr >> 32)); 707 sge->sg_lo_addr = htole32((u_int32_t)addr); 708 709 if (mpi_poll(sc, ccb, 5000) != 0) 710 return (1); 711 712 if (ccb->ccb_reply != NULL) 713 mpi_push_reply(sc, ccb->ccb_reply_dva); 714 715 mpi_put_ccb(sc, ccb); 716 717 return (0); 718 } 719 720 void 721 mpi_detach(struct mpi_softc *sc) 722 { 723 724 } 725 726 int 727 mpi_intr(void *arg) 728 { 729 struct mpi_softc *sc = arg; 730 struct mpi_ccb *ccb; 731 struct mpi_msg_reply *reply; 732 u_int32_t reply_dva; 733 char *reply_addr; 734 u_int32_t reg, id; 735 int rv = 0; 736 737 while ((reg = mpi_pop_reply(sc)) != 0xffffffff) { 738 739 DNPRINTF(MPI_D_INTR, "%s: mpi_intr reply_queue: 0x%08x\n", 740 DEVNAME(sc), reg); 741 742 if (reg & MPI_REPLY_QUEUE_ADDRESS) { 743 bus_dmamap_sync(sc->sc_dmat, 744 MPI_DMA_MAP(sc->sc_replies), 0, PAGE_SIZE, 745 BUS_DMASYNC_POSTREAD); 746 747 reply_dva = (reg & MPI_REPLY_QUEUE_ADDRESS_MASK) << 1; 748 749 reply_addr = MPI_DMA_KVA(sc->sc_replies); 750 reply_addr += reply_dva - 751 (u_int32_t)MPI_DMA_DVA(sc->sc_replies); 752 reply = (struct mpi_msg_reply *)reply_addr; 753 754 id = letoh32(reply->msg_context); 755 756 bus_dmamap_sync(sc->sc_dmat, 757 MPI_DMA_MAP(sc->sc_replies), 0, PAGE_SIZE, 758 BUS_DMASYNC_PREREAD); 759 } else { 760 switch (reg & MPI_REPLY_QUEUE_TYPE_MASK) { 761 case MPI_REPLY_QUEUE_TYPE_INIT: 762 id = reg & MPI_REPLY_QUEUE_CONTEXT; 763 break; 764 765 default: 766 panic("%s: unsupported context reply\n", 767 DEVNAME(sc)); 768 } 769 770 reply = NULL; 771 } 772 773 DNPRINTF(MPI_D_INTR, "%s: mpi_intr id: %d reply: %p\n", 774 DEVNAME(sc), id, reply); 775 776 ccb = &sc->sc_ccbs[id]; 777 778 bus_dmamap_sync(sc->sc_dmat, MPI_DMA_MAP(sc->sc_requests), 779 ccb->ccb_offset, MPI_REQUEST_SIZE, 780 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 781 ccb->ccb_state = MPI_CCB_READY; 782 ccb->ccb_reply = reply; 783 ccb->ccb_reply_dva = reply_dva; 784 785 ccb->ccb_done(ccb); 786 rv = 1; 787 } 788 789 return (rv); 790 } 791 792 struct mpi_dmamem * 793 mpi_dmamem_alloc(struct mpi_softc *sc, size_t size) 794 { 795 struct mpi_dmamem *mdm; 796 int nsegs; 797 798 mdm = malloc(sizeof(struct mpi_dmamem), M_DEVBUF, M_NOWAIT); 799 if (mdm == NULL) 800 return (NULL); 801 802 bzero(mdm, sizeof(struct mpi_dmamem)); 803 mdm->mdm_size = size; 804 805 if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, 806 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mdm->mdm_map) != 0) 807 goto mdmfree; 808 809 if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &mdm->mdm_seg, 810 1, &nsegs, BUS_DMA_NOWAIT) != 0) 811 goto destroy; 812 813 if (bus_dmamem_map(sc->sc_dmat, &mdm->mdm_seg, nsegs, size, 814 &mdm->mdm_kva, BUS_DMA_NOWAIT) != 0) 815 goto free; 816 817 if (bus_dmamap_load(sc->sc_dmat, mdm->mdm_map, mdm->mdm_kva, size, 818 NULL, BUS_DMA_NOWAIT) != 0) 819 goto unmap; 820 821 bzero(mdm->mdm_kva, size); 822 823 DNPRINTF(MPI_D_MEM, "%s: mpi_dmamem_alloc size: %d mdm: %#x " 824 "map: %#x nsegs: %d segs: %#x kva: %x\n", 825 DEVNAME(sc), size, mdm->mdm_map, nsegs, mdm->mdm_seg, mdm->mdm_kva); 826 827 return (mdm); 828 829 unmap: 830 bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, size); 831 free: 832 bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1); 833 destroy: 834 bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map); 835 mdmfree: 836 free(mdm, M_DEVBUF); 837 838 return (NULL); 839 } 840 841 void 842 mpi_dmamem_free(struct mpi_softc *sc, struct mpi_dmamem *mdm) 843 { 844 DNPRINTF(MPI_D_MEM, "%s: mpi_dmamem_free %#x\n", DEVNAME(sc), mdm); 845 846 bus_dmamap_unload(sc->sc_dmat, mdm->mdm_map); 847 bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, mdm->mdm_size); 848 bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1); 849 bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map); 850 free(mdm, M_DEVBUF); 851 } 852 853 int 854 mpi_alloc_ccbs(struct mpi_softc *sc) 855 { 856 struct mpi_ccb *ccb; 857 u_int8_t *cmd; 858 int i; 859 860 TAILQ_INIT(&sc->sc_ccb_free); 861 862 sc->sc_ccbs = malloc(sizeof(struct mpi_ccb) * sc->sc_maxcmds, 863 M_DEVBUF, M_WAITOK); 864 if (sc->sc_ccbs == NULL) { 865 printf("%s: unable to allocate ccbs\n", DEVNAME(sc)); 866 return (1); 867 } 868 bzero(sc->sc_ccbs, sizeof(struct mpi_ccb) * sc->sc_maxcmds); 869 870 sc->sc_requests = mpi_dmamem_alloc(sc, 871 MPI_REQUEST_SIZE * sc->sc_maxcmds); 872 if (sc->sc_requests == NULL) { 873 printf("%s: unable to allocate ccb dmamem\n", DEVNAME(sc)); 874 goto free_ccbs; 875 } 876 cmd = MPI_DMA_KVA(sc->sc_requests); 877 bzero(cmd, MPI_REQUEST_SIZE * sc->sc_maxcmds); 878 879 for (i = 0; i < sc->sc_maxcmds; i++) { 880 ccb = &sc->sc_ccbs[i]; 881 882 if (bus_dmamap_create(sc->sc_dmat, MAXPHYS, 883 sc->sc_max_sgl_len, MAXPHYS, 0, 0, 884 &ccb->ccb_dmamap) != 0) { 885 printf("%s: unable to create dma map\n", DEVNAME(sc)); 886 goto free_maps; 887 } 888 889 ccb->ccb_sc = sc; 890 ccb->ccb_id = i; 891 ccb->ccb_offset = MPI_REQUEST_SIZE * i; 892 893 ccb->ccb_cmd = &cmd[ccb->ccb_offset]; 894 ccb->ccb_cmd_dva = (u_int32_t)MPI_DMA_DVA(sc->sc_requests) + 895 ccb->ccb_offset; 896 897 DNPRINTF(MPI_D_CCB, "%s: mpi_alloc_ccbs(%d) ccb: %#x map: %#x " 898 "sc: %#x id: %#x offs: %#x cmd: %#x dva: %#x\n", 899 DEVNAME(sc), i, ccb, ccb->ccb_dmamap, ccb->ccb_sc, 900 ccb->ccb_id, ccb->ccb_offset, ccb->ccb_cmd, 901 ccb->ccb_cmd_dva); 902 903 mpi_put_ccb(sc, ccb); 904 } 905 906 return (0); 907 908 free_maps: 909 while ((ccb = mpi_get_ccb(sc)) != NULL) 910 bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap); 911 912 mpi_dmamem_free(sc, sc->sc_requests); 913 free_ccbs: 914 free(sc->sc_ccbs, M_DEVBUF); 915 916 return (1); 917 } 918 919 struct mpi_ccb * 920 mpi_get_ccb(struct mpi_softc *sc) 921 { 922 struct mpi_ccb *ccb; 923 924 ccb = TAILQ_FIRST(&sc->sc_ccb_free); 925 if (ccb == NULL) { 926 DNPRINTF(MPI_D_CCB, "%s: mpi_get_ccb == NULL\n", DEVNAME(sc)); 927 return (NULL); 928 } 929 930 TAILQ_REMOVE(&sc->sc_ccb_free, ccb, ccb_link); 931 932 ccb->ccb_state = MPI_CCB_READY; 933 934 DNPRINTF(MPI_D_CCB, "%s: mpi_get_ccb %#x\n", DEVNAME(sc), ccb); 935 936 return (ccb); 937 } 938 939 void 940 mpi_put_ccb(struct mpi_softc *sc, struct mpi_ccb *ccb) 941 { 942 DNPRINTF(MPI_D_CCB, "%s: mpi_put_ccb %#x\n", DEVNAME(sc), ccb); 943 944 ccb->ccb_state = MPI_CCB_FREE; 945 ccb->ccb_xs = NULL; 946 ccb->ccb_done = NULL; 947 bzero(ccb->ccb_cmd, MPI_REQUEST_SIZE); 948 TAILQ_INSERT_TAIL(&sc->sc_ccb_free, ccb, ccb_link); 949 } 950 951 int 952 mpi_alloc_replies(struct mpi_softc *sc) 953 { 954 DNPRINTF(MPI_D_MISC, "%s: mpi_alloc_replies\n", DEVNAME(sc)); 955 956 sc->sc_replies = mpi_dmamem_alloc(sc, PAGE_SIZE); 957 if (sc->sc_replies == NULL) 958 return (1); 959 960 return (0); 961 } 962 963 void 964 mpi_push_replies(struct mpi_softc *sc) 965 { 966 paddr_t reply; 967 int i; 968 969 bus_dmamap_sync(sc->sc_dmat, MPI_DMA_MAP(sc->sc_replies), 970 0, PAGE_SIZE, BUS_DMASYNC_PREREAD); 971 972 for (i = 0; i < PAGE_SIZE / MPI_REPLY_SIZE; i++) { 973 reply = (u_int32_t)MPI_DMA_DVA(sc->sc_replies) + 974 MPI_REPLY_SIZE * i; 975 DNPRINTF(MPI_D_MEM, "%s: mpi_push_replies %#x\n", DEVNAME(sc), 976 reply); 977 mpi_push_reply(sc, reply); 978 } 979 } 980 981 void 982 mpi_start(struct mpi_softc *sc, struct mpi_ccb *ccb) 983 { 984 DNPRINTF(MPI_D_RW, "%s: mpi_start %#x\n", DEVNAME(sc), 985 ccb->ccb_cmd_dva); 986 987 bus_dmamap_sync(sc->sc_dmat, MPI_DMA_MAP(sc->sc_requests), 988 ccb->ccb_offset, MPI_REQUEST_SIZE, 989 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 990 991 ccb->ccb_state = MPI_CCB_QUEUED; 992 mpi_write(sc, MPI_REQ_QUEUE, ccb->ccb_cmd_dva); 993 } 994 995 int 996 mpi_complete(struct mpi_softc *sc, struct mpi_ccb *nccb, int timeout) 997 { 998 struct mpi_ccb *ccb; 999 struct mpi_msg_reply *reply; 1000 u_int32_t reply_dva; 1001 char *reply_addr; 1002 u_int32_t reg, id = 0xffffffff; 1003 1004 DNPRINTF(MPI_D_INTR, "%s: mpi_complete timeout %d\n", DEVNAME(sc), 1005 timeout); 1006 1007 do { 1008 reg = mpi_pop_reply(sc); 1009 if (reg == 0xffffffff) { 1010 if (timeout-- == 0) 1011 return (1); 1012 1013 delay(1000); 1014 continue; 1015 } 1016 1017 DNPRINTF(MPI_D_INTR, "%s: mpi_complete reply_queue: 0x%08x\n", 1018 DEVNAME(sc), reg); 1019 1020 if (reg & MPI_REPLY_QUEUE_ADDRESS) { 1021 bus_dmamap_sync(sc->sc_dmat, 1022 MPI_DMA_MAP(sc->sc_replies), 0, PAGE_SIZE, 1023 BUS_DMASYNC_POSTREAD); 1024 1025 reply_dva = (reg & MPI_REPLY_QUEUE_ADDRESS_MASK) << 1; 1026 1027 reply_addr = MPI_DMA_KVA(sc->sc_replies); 1028 reply_addr += reply_dva - 1029 (u_int32_t)MPI_DMA_DVA(sc->sc_replies); 1030 reply = (struct mpi_msg_reply *)reply_addr; 1031 1032 id = letoh32(reply->msg_context); 1033 1034 bus_dmamap_sync(sc->sc_dmat, 1035 MPI_DMA_MAP(sc->sc_replies), 0, PAGE_SIZE, 1036 BUS_DMASYNC_PREREAD); 1037 } else { 1038 switch (reg & MPI_REPLY_QUEUE_TYPE_MASK) { 1039 case MPI_REPLY_QUEUE_TYPE_INIT: 1040 id = reg & MPI_REPLY_QUEUE_CONTEXT; 1041 break; 1042 1043 default: 1044 panic("%s: unsupported context reply\n", 1045 DEVNAME(sc)); 1046 } 1047 1048 reply = NULL; 1049 } 1050 1051 DNPRINTF(MPI_D_INTR, "%s: mpi_complete id: %d\n", 1052 DEVNAME(sc), id); 1053 1054 ccb = &sc->sc_ccbs[id]; 1055 1056 bus_dmamap_sync(sc->sc_dmat, MPI_DMA_MAP(sc->sc_requests), 1057 ccb->ccb_offset, MPI_REQUEST_SIZE, 1058 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1059 ccb->ccb_state = MPI_CCB_READY; 1060 ccb->ccb_reply = reply; 1061 ccb->ccb_reply_dva = reply_dva; 1062 1063 ccb->ccb_done(ccb); 1064 1065 } while (nccb->ccb_id != id); 1066 1067 return (0); 1068 } 1069 1070 int 1071 mpi_poll(struct mpi_softc *sc, struct mpi_ccb *ccb, int timeout) 1072 { 1073 int error; 1074 int s; 1075 1076 DNPRINTF(MPI_D_CMD, "%s: mpi_poll\n", DEVNAME(sc)); 1077 1078 s = splbio(); 1079 mpi_start(sc, ccb); 1080 error = mpi_complete(sc, ccb, timeout); 1081 splx(s); 1082 1083 return (error); 1084 } 1085 1086 int 1087 mpi_scsi_cmd(struct scsi_xfer *xs) 1088 { 1089 struct scsi_link *link = xs->sc_link; 1090 struct mpi_softc *sc = link->adapter_softc; 1091 struct mpi_ccb *ccb; 1092 struct mpi_ccb_bundle *mcb; 1093 struct mpi_msg_scsi_io *io; 1094 int s; 1095 1096 DNPRINTF(MPI_D_CMD, "%s: mpi_scsi_cmd\n", DEVNAME(sc)); 1097 1098 if (xs->cmdlen > MPI_CDB_LEN) { 1099 DNPRINTF(MPI_D_CMD, "%s: CBD too big %d\n", 1100 DEVNAME(sc), xs->cmdlen); 1101 bzero(&xs->sense, sizeof(xs->sense)); 1102 xs->sense.error_code = SSD_ERRCODE_VALID | 0x70; 1103 xs->sense.flags = SKEY_ILLEGAL_REQUEST; 1104 xs->sense.add_sense_code = 0x20; 1105 xs->error = XS_SENSE; 1106 scsi_done(xs); 1107 return (COMPLETE); 1108 } 1109 1110 s = splbio(); 1111 ccb = mpi_get_ccb(sc); 1112 splx(s); 1113 if (ccb == NULL) { 1114 xs->error = XS_DRIVER_STUFFUP; 1115 scsi_done(xs); 1116 return (COMPLETE); 1117 } 1118 DNPRINTF(MPI_D_CMD, "%s: ccb_id: %d xs->flags: 0x%x\n", 1119 DEVNAME(sc), ccb->ccb_id, xs->flags); 1120 1121 ccb->ccb_xs = xs; 1122 ccb->ccb_done = mpi_scsi_cmd_done; 1123 1124 mcb = ccb->ccb_cmd; 1125 io = &mcb->mcb_io; 1126 1127 io->function = MPI_FUNCTION_SCSI_IO_REQUEST; 1128 /* 1129 * bus is always 0 1130 * io->bus = htole16(sc->sc_bus); 1131 */ 1132 io->target_id = link->target; 1133 1134 io->cdb_length = xs->cmdlen; 1135 io->sense_buf_len = sizeof(xs->sense); 1136 io->msg_flags = MPI_SCSIIO_SENSE_BUF_ADDR_WIDTH_64; 1137 1138 io->msg_context = htole32(ccb->ccb_id); 1139 1140 io->lun[0] = htobe16(link->lun); 1141 1142 switch (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) { 1143 case SCSI_DATA_IN: 1144 io->direction = MPI_SCSIIO_DIR_READ; 1145 break; 1146 case SCSI_DATA_OUT: 1147 io->direction = MPI_SCSIIO_DIR_WRITE; 1148 break; 1149 default: 1150 io->direction = MPI_SCSIIO_DIR_NONE; 1151 break; 1152 } 1153 1154 if (link->quirks & SDEV_NOTAGS) 1155 io->tagging = MPI_SCSIIO_ATTR_UNTAGGED; 1156 else 1157 io->tagging = MPI_SCSIIO_ATTR_SIMPLE_Q; 1158 1159 bcopy(xs->cmd, io->cdb, xs->cmdlen); 1160 1161 io->data_length = htole32(xs->datalen); 1162 1163 io->sense_buf_low_addr = htole32(ccb->ccb_cmd_dva + 1164 ((u_int8_t *)&mcb->mcb_sense - (u_int8_t *)mcb)); 1165 1166 if (mpi_load_xs(ccb) != 0) { 1167 s = splbio(); 1168 mpi_put_ccb(sc, ccb); 1169 splx(s); 1170 xs->error = XS_DRIVER_STUFFUP; 1171 scsi_done(xs); 1172 return (COMPLETE); 1173 } 1174 1175 timeout_set(&xs->stimeout, mpi_timeout_xs, ccb); 1176 1177 if (xs->flags & SCSI_POLL) { 1178 if (mpi_poll(sc, ccb, xs->timeout) != 0) 1179 xs->error = XS_DRIVER_STUFFUP; 1180 return (COMPLETE); 1181 } 1182 1183 mpi_start(sc, ccb); 1184 return (SUCCESSFULLY_QUEUED); 1185 } 1186 1187 void 1188 mpi_scsi_cmd_done(struct mpi_ccb *ccb) 1189 { 1190 struct mpi_softc *sc = ccb->ccb_sc; 1191 struct scsi_xfer *xs = ccb->ccb_xs; 1192 struct mpi_ccb_bundle *mcb = ccb->ccb_cmd; 1193 bus_dmamap_t dmap = ccb->ccb_dmamap; 1194 struct mpi_msg_scsi_io_error *sie = ccb->ccb_reply; 1195 1196 if (xs->datalen != 0) { 1197 bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize, 1198 (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD : 1199 BUS_DMASYNC_POSTWRITE); 1200 1201 bus_dmamap_unload(sc->sc_dmat, dmap); 1202 } 1203 1204 /* timeout_del */ 1205 xs->error = XS_NOERROR; 1206 xs->resid = 0; 1207 xs->flags |= ITSDONE; 1208 1209 if (sie == NULL) { 1210 /* no scsi error, we're ok so drop out early */ 1211 xs->status = SCSI_OK; 1212 mpi_put_ccb(sc, ccb); 1213 scsi_done(xs); 1214 return; 1215 } 1216 1217 xs->status = sie->scsi_status; 1218 switch (letoh16(sie->ioc_status)) { 1219 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: 1220 xs->error = XS_DRIVER_STUFFUP; 1221 break; 1222 1223 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: 1224 /* 1225 * Yikes! Tagged queue full comes through this path! 1226 * 1227 * So we'll change it to a status error and anything 1228 * that returns status should probably be a status 1229 * error as well. 1230 */ 1231 xs->resid = xs->datalen - letoh32(sie->transfer_count); 1232 if (sie->scsi_state & MPI_SCSIIO_ERR_STATE_NO_SCSI_STATUS) { 1233 xs->error = XS_DRIVER_STUFFUP; 1234 break; 1235 } 1236 /* FALLTHROUGH */ 1237 case MPI_IOCSTATUS_SUCCESS: 1238 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: 1239 switch (xs->status) { 1240 case SCSI_OK: 1241 xs->resid = 0; 1242 break; 1243 1244 case SCSI_CHECK: 1245 xs->error = XS_SENSE; 1246 break; 1247 1248 case SCSI_BUSY: 1249 xs->error = XS_BUSY; 1250 break; 1251 1252 case SCSI_QUEUE_FULL: 1253 xs->error = XS_TIMEOUT; 1254 xs->retries++; 1255 break; 1256 default: 1257 printf("%s: invalid status code %d\n", 1258 DEVNAME(sc), xs->status); 1259 xs->error = XS_DRIVER_STUFFUP; 1260 break; 1261 } 1262 break; 1263 1264 case MPI_IOCSTATUS_BUSY: 1265 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: 1266 xs->error = XS_BUSY; 1267 break; 1268 1269 case MPI_IOCSTATUS_SCSI_INVALID_BUS: 1270 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: 1271 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: 1272 xs->error = XS_SELTIMEOUT; 1273 break; 1274 1275 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: 1276 xs->error = XS_DRIVER_STUFFUP; 1277 break; 1278 1279 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: 1280 xs->error = XS_DRIVER_STUFFUP; 1281 break; 1282 1283 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: 1284 /* XXX */ 1285 xs->error = XS_DRIVER_STUFFUP; 1286 break; 1287 1288 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: 1289 /* XXX */ 1290 xs->error = XS_DRIVER_STUFFUP; 1291 break; 1292 1293 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: 1294 /* XXX This is a bus-reset */ 1295 xs->error = XS_DRIVER_STUFFUP; 1296 break; 1297 1298 default: 1299 /* XXX unrecognized HBA error */ 1300 xs->error = XS_DRIVER_STUFFUP; 1301 break; 1302 } 1303 1304 if (sie->scsi_state & MPI_SCSIIO_ERR_STATE_AUTOSENSE_VALID) 1305 bcopy(&mcb->mcb_sense, &xs->sense, sizeof(xs->sense)); 1306 else if (sie->scsi_state & MPI_SCSIIO_ERR_STATE_AUTOSENSE_FAILED) { 1307 /* This will cause the scsi layer to issue a REQUEST SENSE */ 1308 if (xs->status == SCSI_CHECK) 1309 xs->error = XS_BUSY; 1310 } 1311 1312 if (xs->error != XS_NOERROR && !cold) { 1313 printf("%s: xs cmd: 0x%02x len: %d error: 0x%02x " 1314 "flags 0x%x\n", DEVNAME(sc), xs->cmd->opcode, xs->datalen, 1315 xs->error, xs->flags); 1316 printf("%s: target_id: %d bus: %d msg_length: %d " 1317 "function: 0x%02x\n", DEVNAME(sc), sie->target_id, 1318 sie->bus, sie->msg_length, sie->function); 1319 printf("%s: cdb_length: %d sense_buf_length: %d " 1320 "msg_flags: 0x%02x\n", DEVNAME(sc), sie->cdb_length, 1321 sie->bus, sie->msg_flags); 1322 printf("%s: msg_context: 0x%08x\n", DEVNAME(sc), 1323 letoh32(sie->msg_context)); 1324 printf("%s: scsi_status: 0x%02x scsi_state: 0x%02x " 1325 "ioc_status: 0x%04x\n", DEVNAME(sc), sie->scsi_status, 1326 sie->scsi_state, letoh16(sie->ioc_status)); 1327 printf("%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc), 1328 letoh32(sie->ioc_loginfo)); 1329 printf("%s: transfer_count: %d\n", DEVNAME(sc), 1330 letoh32(sie->transfer_count)); 1331 printf("%s: sense_count: %d\n", DEVNAME(sc), 1332 letoh32(sie->sense_count)); 1333 printf("%s: response_info: 0x%08x\n", DEVNAME(sc), 1334 letoh32(sie->response_info)); 1335 printf("%s: tag: 0x%04x\n", DEVNAME(sc), 1336 letoh16(sie->tag)); 1337 printf("%s: xs error: 0x%02x xs status: %d\n", DEVNAME(sc), 1338 xs->error, xs->status); 1339 } 1340 1341 mpi_push_reply(sc, ccb->ccb_reply_dva); 1342 mpi_put_ccb(sc, ccb); 1343 scsi_done(xs); 1344 } 1345 1346 void 1347 mpi_timeout_xs(void *arg) 1348 { 1349 /* XXX */ 1350 } 1351 1352 int 1353 mpi_load_xs(struct mpi_ccb *ccb) 1354 { 1355 struct mpi_softc *sc = ccb->ccb_sc; 1356 struct scsi_xfer *xs = ccb->ccb_xs; 1357 struct mpi_ccb_bundle *mcb = ccb->ccb_cmd; 1358 struct mpi_msg_scsi_io *io = &mcb->mcb_io; 1359 struct mpi_sge *sge, *nsge = &mcb->mcb_sgl[0]; 1360 struct mpi_sge *ce = NULL, *nce; 1361 u_int64_t ce_dva; 1362 bus_dmamap_t dmap = ccb->ccb_dmamap; 1363 u_int32_t addr, flags; 1364 int i, error; 1365 1366 if (xs->datalen == 0) { 1367 nsge->sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE | 1368 MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | MPI_SGE_FL_EOL); 1369 return (0); 1370 } 1371 1372 error = bus_dmamap_load(sc->sc_dmat, dmap, 1373 xs->data, xs->datalen, NULL, 1374 (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK); 1375 if (error) { 1376 printf("%s: error %d loading dmamap\n", DEVNAME(sc), error); 1377 return (1); 1378 } 1379 1380 flags = MPI_SGE_FL_TYPE_SIMPLE | MPI_SGE_FL_SIZE_64; 1381 if (xs->flags & SCSI_DATA_OUT) 1382 flags |= MPI_SGE_FL_DIR_OUT; 1383 1384 if (dmap->dm_nsegs > sc->sc_first_sgl_len) { 1385 ce = &mcb->mcb_sgl[sc->sc_first_sgl_len - 1]; 1386 io->chain_offset = ((u_int8_t *)ce - (u_int8_t *)io) / 4; 1387 } 1388 1389 for (i = 0; i < dmap->dm_nsegs; i++) { 1390 1391 if (nsge == ce) { 1392 nsge++; 1393 sge->sg_hdr |= htole32(MPI_SGE_FL_LAST); 1394 1395 DNPRINTF(MPI_D_DMA, "%s: - 0x%08x 0x%08x 0x%08x\n", 1396 DEVNAME(sc), sge->sg_hdr, 1397 sge->sg_hi_addr, sge->sg_lo_addr); 1398 1399 if ((dmap->dm_nsegs - i) > sc->sc_chain_len) { 1400 nce = &nsge[sc->sc_chain_len - 1]; 1401 addr = ((u_int8_t *)nce - (u_int8_t *)nsge) / 4; 1402 addr = addr << 16 | 1403 sizeof(struct mpi_sge) * sc->sc_chain_len; 1404 } else { 1405 nce = NULL; 1406 addr = sizeof(struct mpi_sge) * 1407 (dmap->dm_nsegs - i); 1408 } 1409 1410 ce->sg_hdr = htole32(MPI_SGE_FL_TYPE_CHAIN | 1411 MPI_SGE_FL_SIZE_64 | addr); 1412 1413 ce_dva = ccb->ccb_cmd_dva + 1414 ((u_int8_t *)nsge - (u_int8_t *)mcb); 1415 1416 addr = (u_int32_t)(ce_dva >> 32); 1417 ce->sg_hi_addr = htole32(addr); 1418 addr = (u_int32_t)ce_dva; 1419 ce->sg_lo_addr = htole32(addr); 1420 1421 DNPRINTF(MPI_D_DMA, "%s: ce: 0x%08x 0x%08x 0x%08x\n", 1422 DEVNAME(sc), ce->sg_hdr, ce->sg_hi_addr, 1423 ce->sg_lo_addr); 1424 1425 ce = nce; 1426 } 1427 1428 DNPRINTF(MPI_D_DMA, "%s: %d: %d 0x%016llx\n", DEVNAME(sc), 1429 i, dmap->dm_segs[i].ds_len, 1430 (u_int64_t)dmap->dm_segs[i].ds_addr); 1431 1432 sge = nsge; 1433 1434 sge->sg_hdr = htole32(flags | dmap->dm_segs[i].ds_len); 1435 addr = (u_int32_t)((u_int64_t)dmap->dm_segs[i].ds_addr >> 32); 1436 sge->sg_hi_addr = htole32(addr); 1437 addr = (u_int32_t)dmap->dm_segs[i].ds_addr; 1438 sge->sg_lo_addr = htole32(addr); 1439 1440 DNPRINTF(MPI_D_DMA, "%s: %d: 0x%08x 0x%08x 0x%08x\n", 1441 DEVNAME(sc), i, sge->sg_hdr, sge->sg_hi_addr, 1442 sge->sg_lo_addr); 1443 1444 nsge = sge + 1; 1445 } 1446 1447 /* terminate list */ 1448 sge->sg_hdr |= htole32(MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | 1449 MPI_SGE_FL_EOL); 1450 1451 bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize, 1452 (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD : 1453 BUS_DMASYNC_PREWRITE); 1454 1455 return (0); 1456 } 1457 1458 void 1459 mpi_minphys(struct buf *bp) 1460 { 1461 /* XXX */ 1462 if (bp->b_bcount > MAXPHYS) 1463 bp->b_bcount = MAXPHYS; 1464 minphys(bp); 1465 } 1466 1467 int 1468 mpi_scsi_ioctl(struct scsi_link *a, u_long b, caddr_t c, int d, struct proc *e) 1469 { 1470 return (0); 1471 } 1472 1473 u_int32_t 1474 mpi_read(struct mpi_softc *sc, bus_size_t r) 1475 { 1476 u_int32_t rv; 1477 1478 bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4, 1479 BUS_SPACE_BARRIER_READ); 1480 rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, r); 1481 1482 DNPRINTF(MPI_D_RW, "%s: mpi_read %#x %#x\n", DEVNAME(sc), r, rv); 1483 1484 return (rv); 1485 } 1486 1487 void 1488 mpi_write(struct mpi_softc *sc, bus_size_t r, u_int32_t v) 1489 { 1490 DNPRINTF(MPI_D_RW, "%s: mpi_write %#x %#x\n", DEVNAME(sc), r, v); 1491 1492 bus_space_write_4(sc->sc_iot, sc->sc_ioh, r, v); 1493 bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4, 1494 BUS_SPACE_BARRIER_WRITE); 1495 } 1496 1497 int 1498 mpi_wait_eq(struct mpi_softc *sc, bus_size_t r, u_int32_t mask, 1499 u_int32_t target) 1500 { 1501 int i; 1502 1503 DNPRINTF(MPI_D_RW, "%s: mpi_wait_eq %#x %#x %#x\n", DEVNAME(sc), r, 1504 mask, target); 1505 1506 for (i = 0; i < 10000; i++) { 1507 if ((mpi_read(sc, r) & mask) == target) 1508 return (0); 1509 delay(1000); 1510 } 1511 1512 return (1); 1513 } 1514 1515 int 1516 mpi_wait_ne(struct mpi_softc *sc, bus_size_t r, u_int32_t mask, 1517 u_int32_t target) 1518 { 1519 int i; 1520 1521 DNPRINTF(MPI_D_RW, "%s: mpi_wait_ne %#x %#x %#x\n", DEVNAME(sc), r, 1522 mask, target); 1523 1524 for (i = 0; i < 10000; i++) { 1525 if ((mpi_read(sc, r) & mask) != target) 1526 return (0); 1527 delay(1000); 1528 } 1529 1530 return (1); 1531 } 1532 1533 int 1534 mpi_init(struct mpi_softc *sc) 1535 { 1536 u_int32_t db; 1537 int i; 1538 1539 /* spin until the IOC leaves the RESET state */ 1540 if (mpi_wait_ne(sc, MPI_DOORBELL, MPI_DOORBELL_STATE, 1541 MPI_DOORBELL_STATE_RESET) != 0) { 1542 DNPRINTF(MPI_D_MISC, "%s: mpi_init timeout waiting to leave " 1543 "reset state\n", DEVNAME(sc)); 1544 return (1); 1545 } 1546 1547 /* check current ownership */ 1548 db = mpi_read_db(sc); 1549 if ((db & MPI_DOORBELL_WHOINIT) == MPI_DOORBELL_WHOINIT_PCIPEER) { 1550 DNPRINTF(MPI_D_MISC, "%s: mpi_init initialised by pci peer\n", 1551 DEVNAME(sc)); 1552 return (0); 1553 } 1554 1555 for (i = 0; i < 5; i++) { 1556 switch (db & MPI_DOORBELL_STATE) { 1557 case MPI_DOORBELL_STATE_READY: 1558 DNPRINTF(MPI_D_MISC, "%s: mpi_init ioc is ready\n", 1559 DEVNAME(sc)); 1560 return (0); 1561 1562 case MPI_DOORBELL_STATE_OPER: 1563 case MPI_DOORBELL_STATE_FAULT: 1564 DNPRINTF(MPI_D_MISC, "%s: mpi_init ioc is being " 1565 "reset\n" , DEVNAME(sc)); 1566 if (mpi_reset_soft(sc) != 0) 1567 mpi_reset_hard(sc); 1568 break; 1569 1570 case MPI_DOORBELL_STATE_RESET: 1571 DNPRINTF(MPI_D_MISC, "%s: mpi_init waiting to come " 1572 "out of reset\n", DEVNAME(sc)); 1573 if (mpi_wait_ne(sc, MPI_DOORBELL, MPI_DOORBELL_STATE, 1574 MPI_DOORBELL_STATE_RESET) != 0) 1575 return (1); 1576 break; 1577 } 1578 db = mpi_read_db(sc); 1579 } 1580 1581 return (1); 1582 } 1583 1584 int 1585 mpi_reset_soft(struct mpi_softc *sc) 1586 { 1587 DNPRINTF(MPI_D_MISC, "%s: mpi_reset_soft\n", DEVNAME(sc)); 1588 1589 if (mpi_read_db(sc) & MPI_DOORBELL_INUSE) 1590 return (1); 1591 1592 mpi_write_db(sc, 1593 MPI_DOORBELL_FUNCTION(MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET)); 1594 if (mpi_wait_eq(sc, MPI_INTR_STATUS, 1595 MPI_INTR_STATUS_IOCDOORBELL, 0) != 0) 1596 return (1); 1597 1598 if (mpi_wait_eq(sc, MPI_DOORBELL, MPI_DOORBELL_STATE, 1599 MPI_DOORBELL_STATE_READY) != 0) 1600 return (1); 1601 1602 return (0); 1603 } 1604 1605 int 1606 mpi_reset_hard(struct mpi_softc *sc) 1607 { 1608 DNPRINTF(MPI_D_MISC, "%s: mpi_reset_hard\n", DEVNAME(sc)); 1609 1610 /* enable diagnostic register */ 1611 mpi_write(sc, MPI_WRITESEQ, 0xff); 1612 mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_1); 1613 mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_2); 1614 mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_3); 1615 mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_4); 1616 mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_5); 1617 1618 /* reset ioc */ 1619 mpi_write(sc, MPI_HOSTDIAG, MPI_HOSTDIAG_RESET_ADAPTER); 1620 1621 delay(10000); 1622 1623 /* disable diagnostic register */ 1624 mpi_write(sc, MPI_WRITESEQ, 0xff); 1625 1626 /* restore pci bits? */ 1627 1628 /* firmware bits? */ 1629 return (0); 1630 } 1631 1632 int 1633 mpi_handshake_send(struct mpi_softc *sc, void *buf, size_t dwords) 1634 { 1635 u_int32_t *query = buf; 1636 int i; 1637 1638 /* make sure the doorbell is not in use. */ 1639 if (mpi_read_db(sc) & MPI_DOORBELL_INUSE) 1640 return (1); 1641 1642 /* clear pending doorbell interrupts */ 1643 if (mpi_read_intr(sc) & MPI_INTR_STATUS_DOORBELL) 1644 mpi_write_intr(sc, 0); 1645 1646 /* 1647 * first write the doorbell with the handshake function and the 1648 * dword count. 1649 */ 1650 mpi_write_db(sc, MPI_DOORBELL_FUNCTION(MPI_FUNCTION_HANDSHAKE) | 1651 MPI_DOORBELL_DWORDS(dwords)); 1652 1653 /* 1654 * the doorbell used bit will be set because a doorbell function has 1655 * started. Wait for the interrupt and then ack it. 1656 */ 1657 if (mpi_wait_db_int(sc) != 0) 1658 return (1); 1659 mpi_write_intr(sc, 0); 1660 1661 /* poll for the acknowledgement. */ 1662 if (mpi_wait_db_ack(sc) != 0) 1663 return (1); 1664 1665 /* write the query through the doorbell. */ 1666 for (i = 0; i < dwords; i++) { 1667 mpi_write_db(sc, htole32(query[i])); 1668 if (mpi_wait_db_ack(sc) != 0) 1669 return (1); 1670 } 1671 1672 return (0); 1673 } 1674 1675 int 1676 mpi_handshake_recv_dword(struct mpi_softc *sc, u_int32_t *dword) 1677 { 1678 u_int16_t *words = (u_int16_t *)dword; 1679 int i; 1680 1681 for (i = 0; i < 2; i++) { 1682 if (mpi_wait_db_int(sc) != 0) 1683 return (1); 1684 words[i] = letoh16(mpi_read_db(sc) & MPI_DOORBELL_DATA_MASK); 1685 mpi_write_intr(sc, 0); 1686 } 1687 1688 return (0); 1689 } 1690 1691 int 1692 mpi_handshake_recv(struct mpi_softc *sc, void *buf, size_t dwords) 1693 { 1694 struct mpi_msg_reply *reply = buf; 1695 u_int32_t *dbuf = buf, dummy; 1696 int i; 1697 1698 /* get the first dword so we can read the length out of the header. */ 1699 if (mpi_handshake_recv_dword(sc, &dbuf[0]) != 0) 1700 return (1); 1701 1702 DNPRINTF(MPI_D_CMD, "%s: mpi_handshake_recv dwords: %d reply: %d\n", 1703 DEVNAME(sc), dwords, reply->msg_length); 1704 1705 /* 1706 * the total length, in dwords, is in the message length field of the 1707 * reply header. 1708 */ 1709 for (i = 1; i < MIN(dwords, reply->msg_length); i++) { 1710 if (mpi_handshake_recv_dword(sc, &dbuf[i]) != 0) 1711 return (1); 1712 } 1713 1714 /* if there's extra stuff to come off the ioc, discard it */ 1715 while (i++ < reply->msg_length) { 1716 if (mpi_handshake_recv_dword(sc, &dummy) != 0) 1717 return (1); 1718 DNPRINTF(MPI_D_CMD, "%s: mpi_handshake_recv dummy read: " 1719 "0x%08x\n", DEVNAME(sc), dummy); 1720 } 1721 1722 /* wait for the doorbell used bit to be reset and clear the intr */ 1723 if (mpi_wait_db_int(sc) != 0) 1724 return (1); 1725 mpi_write_intr(sc, 0); 1726 1727 return (0); 1728 } 1729 1730 void 1731 mpi_empty_done(struct mpi_ccb *ccb) 1732 { 1733 /* nothing to do */ 1734 } 1735 1736 int 1737 mpi_iocfacts(struct mpi_softc *sc) 1738 { 1739 struct mpi_msg_iocfacts_request ifq; 1740 struct mpi_msg_iocfacts_reply ifp; 1741 1742 DNPRINTF(MPI_D_MISC, "%s: mpi_iocfacts\n", DEVNAME(sc)); 1743 1744 bzero(&ifq, sizeof(ifq)); 1745 bzero(&ifp, sizeof(ifp)); 1746 1747 ifq.function = MPI_FUNCTION_IOC_FACTS; 1748 ifq.chain_offset = 0; 1749 ifq.msg_flags = 0; 1750 ifq.msg_context = htole32(0xdeadbeef); 1751 1752 if (mpi_handshake_send(sc, &ifq, dwordsof(ifq)) != 0) { 1753 DNPRINTF(MPI_D_MISC, "%s: mpi_iocfacts send failed\n", 1754 DEVNAME(sc)); 1755 return (1); 1756 } 1757 1758 if (mpi_handshake_recv(sc, &ifp, dwordsof(ifp)) != 0) { 1759 DNPRINTF(MPI_D_MISC, "%s: mpi_iocfacts recv failed\n", 1760 DEVNAME(sc)); 1761 return (1); 1762 } 1763 1764 DNPRINTF(MPI_D_MISC, "%s: func: 0x%02x len: %d msgver: %d.%d\n", 1765 DEVNAME(sc), ifp.function, ifp.msg_length, 1766 ifp.msg_version_maj, ifp.msg_version_min); 1767 DNPRINTF(MPI_D_MISC, "%s: msgflags: 0x%02x iocnumber: 0x%02x " 1768 "hdrver: %d.%d\n", DEVNAME(sc), ifp.msg_flags, 1769 ifp.ioc_number, ifp.header_version_maj, 1770 ifp.header_version_min); 1771 DNPRINTF(MPI_D_MISC, "%s: message context: 0x%08x\n", DEVNAME(sc), 1772 letoh32(ifp.msg_context)); 1773 DNPRINTF(MPI_D_MISC, "%s: iocstatus: 0x%04x ioexcept: 0x%04x\n", 1774 DEVNAME(sc), letoh16(ifp.ioc_status), 1775 letoh16(ifp.ioc_exceptions)); 1776 DNPRINTF(MPI_D_MISC, "%s: iocloginfo: 0x%08x\n", DEVNAME(sc), 1777 letoh32(ifp.ioc_loginfo)); 1778 DNPRINTF(MPI_D_MISC, "%s: flags: 0x%02x blocksize: %d whoinit: 0x%02x " 1779 "maxchdepth: %d\n", DEVNAME(sc), ifp.flags, 1780 ifp.block_size, ifp.whoinit, ifp.max_chain_depth); 1781 DNPRINTF(MPI_D_MISC, "%s: reqfrsize: %d replyqdepth: %d\n", 1782 DEVNAME(sc), letoh16(ifp.request_frame_size), 1783 letoh16(ifp.reply_queue_depth)); 1784 DNPRINTF(MPI_D_MISC, "%s: productid: 0x%04x\n", DEVNAME(sc), 1785 letoh16(ifp.product_id)); 1786 DNPRINTF(MPI_D_MISC, "%s: hostmfahiaddr: 0x%08x\n", DEVNAME(sc), 1787 letoh32(ifp.current_host_mfa_hi_addr)); 1788 DNPRINTF(MPI_D_MISC, "%s: event_state: 0x%02x number_of_ports: %d " 1789 "global_credits: %d\n", 1790 DEVNAME(sc), ifp.event_state, ifp.number_of_ports, 1791 letoh16(ifp.global_credits)); 1792 DNPRINTF(MPI_D_MISC, "%s: sensebufhiaddr: 0x%08x\n", DEVNAME(sc), 1793 letoh32(ifp.current_sense_buffer_hi_addr)); 1794 DNPRINTF(MPI_D_MISC, "%s: maxbus: %d maxdev: %d replyfrsize: %d\n", 1795 DEVNAME(sc), ifp.max_buses, ifp.max_devices, 1796 letoh16(ifp.current_reply_frame_size)); 1797 DNPRINTF(MPI_D_MISC, "%s: fw_image_size: %d\n", DEVNAME(sc), 1798 letoh32(ifp.fw_image_size)); 1799 DNPRINTF(MPI_D_MISC, "%s: ioc_capabilities: 0x%08x\n", DEVNAME(sc), 1800 letoh32(ifp.ioc_capabilities)); 1801 DNPRINTF(MPI_D_MISC, "%s: fw_version: %d.%d fw_version_unit: 0x%02x " 1802 "fw_version_dev: 0x%02x\n", DEVNAME(sc), 1803 ifp.fw_version_maj, ifp.fw_version_min, 1804 ifp.fw_version_unit, ifp.fw_version_dev); 1805 DNPRINTF(MPI_D_MISC, "%s: hi_priority_queue_depth: 0x%04x\n", 1806 DEVNAME(sc), letoh16(ifp.hi_priority_queue_depth)); 1807 DNPRINTF(MPI_D_MISC, "%s: host_page_buffer_sge: hdr: 0x%08x " 1808 "addr 0x%08x %08x\n", DEVNAME(sc), 1809 letoh32(ifp.host_page_buffer_sge.sg_hdr), 1810 letoh32(ifp.host_page_buffer_sge.sg_hi_addr), 1811 letoh32(ifp.host_page_buffer_sge.sg_lo_addr)); 1812 1813 sc->sc_maxcmds = letoh16(ifp.global_credits); 1814 sc->sc_maxchdepth = ifp.max_chain_depth; 1815 sc->sc_ioc_number = ifp.ioc_number; 1816 if (sc->sc_flags & MPI_F_VMWARE) 1817 sc->sc_buswidth = 16; 1818 else 1819 sc->sc_buswidth = 1820 (ifp.max_devices == 0) ? 256 : ifp.max_devices; 1821 if (ifp.flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) 1822 sc->sc_fw_len = letoh32(ifp.fw_image_size); 1823 1824 /* 1825 * you can fit sg elements on the end of the io cmd if they fit in the 1826 * request frame size. 1827 */ 1828 sc->sc_first_sgl_len = ((letoh16(ifp.request_frame_size) * 4) - 1829 sizeof(struct mpi_msg_scsi_io)) / sizeof(struct mpi_sge); 1830 DNPRINTF(MPI_D_MISC, "%s: first sgl len: %d\n", DEVNAME(sc), 1831 sc->sc_first_sgl_len); 1832 1833 sc->sc_chain_len = (letoh16(ifp.request_frame_size) * 4) / 1834 sizeof(struct mpi_sge); 1835 DNPRINTF(MPI_D_MISC, "%s: chain len: %d\n", DEVNAME(sc), 1836 sc->sc_chain_len); 1837 1838 /* the sgl tailing the io cmd loses an entry to the chain element. */ 1839 sc->sc_max_sgl_len = MPI_MAX_SGL - 1; 1840 /* the sgl chains lose an entry for each chain element */ 1841 sc->sc_max_sgl_len -= (MPI_MAX_SGL - sc->sc_first_sgl_len) / 1842 sc->sc_chain_len; 1843 DNPRINTF(MPI_D_MISC, "%s: max sgl len: %d\n", DEVNAME(sc), 1844 sc->sc_max_sgl_len); 1845 1846 /* XXX we're ignoring the max chain depth */ 1847 1848 return (0); 1849 } 1850 1851 int 1852 mpi_iocinit(struct mpi_softc *sc) 1853 { 1854 struct mpi_msg_iocinit_request iiq; 1855 struct mpi_msg_iocinit_reply iip; 1856 u_int32_t hi_addr; 1857 1858 DNPRINTF(MPI_D_MISC, "%s: mpi_iocinit\n", DEVNAME(sc)); 1859 1860 bzero(&iiq, sizeof(iiq)); 1861 bzero(&iip, sizeof(iip)); 1862 1863 iiq.function = MPI_FUNCTION_IOC_INIT; 1864 iiq.whoinit = MPI_WHOINIT_HOST_DRIVER; 1865 1866 iiq.max_devices = (sc->sc_buswidth == 256) ? 0 : sc->sc_buswidth; 1867 iiq.max_buses = 1; 1868 1869 iiq.msg_context = htole32(0xd00fd00f); 1870 1871 iiq.reply_frame_size = htole16(MPI_REPLY_SIZE); 1872 1873 hi_addr = (u_int32_t)((u_int64_t)MPI_DMA_DVA(sc->sc_requests) >> 32); 1874 iiq.host_mfa_hi_addr = htole32(hi_addr); 1875 iiq.sense_buffer_hi_addr = htole32(hi_addr); 1876 1877 hi_addr = (u_int32_t)((u_int64_t)MPI_DMA_DVA(sc->sc_replies) >> 32); 1878 iiq.reply_fifo_host_signalling_addr = htole32(hi_addr); 1879 1880 iiq.msg_version_maj = 0x01; 1881 iiq.msg_version_min = 0x02; 1882 1883 iiq.hdr_version_unit = 0x0d; 1884 iiq.hdr_version_dev = 0x00; 1885 1886 if (mpi_handshake_send(sc, &iiq, dwordsof(iiq)) != 0) { 1887 DNPRINTF(MPI_D_MISC, "%s: mpi_iocinit send failed\n", 1888 DEVNAME(sc)); 1889 return (1); 1890 } 1891 1892 if (mpi_handshake_recv(sc, &iip, dwordsof(iip)) != 0) { 1893 DNPRINTF(MPI_D_MISC, "%s: mpi_iocinit recv failed\n", 1894 DEVNAME(sc)); 1895 return (1); 1896 } 1897 1898 DNPRINTF(MPI_D_MISC, "%s: function: 0x%02x msg_length: %d " 1899 "whoinit: 0x%02x\n", DEVNAME(sc), iip.function, 1900 iip.msg_length, iip.whoinit); 1901 DNPRINTF(MPI_D_MISC, "%s: msg_flags: 0x%02x max_buses: %d " 1902 "max_devices: %d flags: 0x%02x\n", DEVNAME(sc), iip.msg_flags, 1903 iip.max_buses, iip.max_devices, iip.flags); 1904 DNPRINTF(MPI_D_MISC, "%s: msg_context: 0x%08x\n", DEVNAME(sc), 1905 letoh32(iip.msg_context)); 1906 DNPRINTF(MPI_D_MISC, "%s: ioc_status: 0x%04x\n", DEVNAME(sc), 1907 letoh16(iip.ioc_status)); 1908 DNPRINTF(MPI_D_MISC, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc), 1909 letoh32(iip.ioc_loginfo)); 1910 1911 return (0); 1912 } 1913 1914 int 1915 mpi_portfacts(struct mpi_softc *sc) 1916 { 1917 struct mpi_ccb *ccb; 1918 struct mpi_msg_portfacts_request *pfq; 1919 volatile struct mpi_msg_portfacts_reply *pfp; 1920 int s, rv = 1; 1921 1922 DNPRINTF(MPI_D_MISC, "%s: mpi_portfacts\n", DEVNAME(sc)); 1923 1924 s = splbio(); 1925 ccb = mpi_get_ccb(sc); 1926 splx(s); 1927 if (ccb == NULL) { 1928 DNPRINTF(MPI_D_MISC, "%s: mpi_portfacts ccb_get\n", 1929 DEVNAME(sc)); 1930 return (rv); 1931 } 1932 1933 ccb->ccb_done = mpi_empty_done; 1934 pfq = ccb->ccb_cmd; 1935 1936 pfq->function = MPI_FUNCTION_PORT_FACTS; 1937 pfq->chain_offset = 0; 1938 pfq->msg_flags = 0; 1939 pfq->port_number = 0; 1940 pfq->msg_context = htole32(ccb->ccb_id); 1941 1942 if (mpi_poll(sc, ccb, 50000) != 0) { 1943 DNPRINTF(MPI_D_MISC, "%s: mpi_portfacts poll\n", DEVNAME(sc)); 1944 goto err; 1945 } 1946 1947 pfp = ccb->ccb_reply; 1948 if (pfp == NULL) { 1949 DNPRINTF(MPI_D_MISC, "%s: empty portfacts reply\n", 1950 DEVNAME(sc)); 1951 goto err; 1952 } 1953 1954 DNPRINTF(MPI_D_MISC, "%s: function: 0x%02x msg_length: %d\n", 1955 DEVNAME(sc), pfp->function, pfp->msg_length); 1956 DNPRINTF(MPI_D_MISC, "%s: msg_flags: 0x%02x port_number: %d\n", 1957 DEVNAME(sc), pfp->msg_flags, pfp->port_number); 1958 DNPRINTF(MPI_D_MISC, "%s: msg_context: 0x%08x\n", DEVNAME(sc), 1959 letoh32(pfp->msg_context)); 1960 DNPRINTF(MPI_D_MISC, "%s: ioc_status: 0x%04x\n", DEVNAME(sc), 1961 letoh16(pfp->ioc_status)); 1962 DNPRINTF(MPI_D_MISC, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc), 1963 letoh32(pfp->ioc_loginfo)); 1964 DNPRINTF(MPI_D_MISC, "%s: max_devices: %d port_type: 0x%02x\n", 1965 DEVNAME(sc), letoh16(pfp->max_devices), pfp->port_type); 1966 DNPRINTF(MPI_D_MISC, "%s: protocol_flags: 0x%04x port_scsi_id: %d\n", 1967 DEVNAME(sc), letoh16(pfp->protocol_flags), 1968 letoh16(pfp->port_scsi_id)); 1969 DNPRINTF(MPI_D_MISC, "%s: max_persistent_ids: %d " 1970 "max_posted_cmd_buffers: %d\n", DEVNAME(sc), 1971 letoh16(pfp->max_persistent_ids), 1972 letoh16(pfp->max_posted_cmd_buffers)); 1973 DNPRINTF(MPI_D_MISC, "%s: max_lan_buckets: %d\n", DEVNAME(sc), 1974 letoh16(pfp->max_lan_buckets)); 1975 1976 sc->sc_porttype = pfp->port_type; 1977 sc->sc_target = letoh16(pfp->port_scsi_id); 1978 1979 mpi_push_reply(sc, ccb->ccb_reply_dva); 1980 rv = 0; 1981 err: 1982 mpi_put_ccb(sc, ccb); 1983 1984 return (rv); 1985 } 1986 1987 int 1988 mpi_eventnotify(struct mpi_softc *sc) 1989 { 1990 struct mpi_ccb *ccb; 1991 struct mpi_msg_event_request *enq; 1992 int s; 1993 1994 s = splbio(); 1995 ccb = mpi_get_ccb(sc); 1996 splx(s); 1997 if (ccb == NULL) { 1998 DNPRINTF(MPI_D_MISC, "%s: mpi_eventnotify ccb_get\n", 1999 DEVNAME(sc)); 2000 return (1); 2001 } 2002 2003 ccb->ccb_done = mpi_eventnotify_done; 2004 enq = ccb->ccb_cmd; 2005 2006 enq->function = MPI_FUNCTION_EVENT_NOTIFICATION; 2007 enq->chain_offset = 0; 2008 enq->ev_switch = 1; 2009 enq->msg_context = htole32(ccb->ccb_id); 2010 2011 mpi_start(sc, ccb); 2012 2013 return (0); 2014 } 2015 2016 void 2017 mpi_eventnotify_done(struct mpi_ccb *ccb) 2018 { 2019 struct mpi_softc *sc = ccb->ccb_sc; 2020 struct mpi_msg_event_reply *enp = ccb->ccb_reply; 2021 u_int32_t *data; 2022 int i; 2023 2024 printf("%s: %s\n", DEVNAME(sc), __func__); 2025 2026 printf("%s: function: 0x%02x msg_length: %d data_length: %d\n", 2027 DEVNAME(sc), enp->function, enp->msg_length, 2028 letoh16(enp->data_length)); 2029 2030 printf("%s: ack_required: %d msg_flags 0x%02x\n", DEVNAME(sc), 2031 enp->msg_flags, enp->msg_flags); 2032 2033 printf("%s: msg_context: 0x%08x\n", DEVNAME(sc), 2034 letoh32(enp->msg_context)); 2035 2036 printf("%s: ioc_status: 0x%04x\n", DEVNAME(sc), 2037 letoh16(enp->ioc_status)); 2038 2039 printf("%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc), 2040 letoh32(enp->ioc_loginfo)); 2041 2042 data = ccb->ccb_reply; 2043 data += dwordsof(struct mpi_msg_event_reply); 2044 for (i = 0; i < letoh16(enp->data_length); i++) { 2045 printf("%s: data[%d]: 0x%08x\n", DEVNAME(sc), i, data[i]); 2046 } 2047 } 2048 2049 int 2050 mpi_portenable(struct mpi_softc *sc) 2051 { 2052 struct mpi_ccb *ccb; 2053 struct mpi_msg_portenable_request *peq; 2054 struct mpi_msg_portenable_repy *pep; 2055 int s; 2056 2057 DNPRINTF(MPI_D_MISC, "%s: mpi_portenable\n", DEVNAME(sc)); 2058 2059 s = splbio(); 2060 ccb = mpi_get_ccb(sc); 2061 splx(s); 2062 if (ccb == NULL) { 2063 DNPRINTF(MPI_D_MISC, "%s: mpi_portenable ccb_get\n", 2064 DEVNAME(sc)); 2065 return (1); 2066 } 2067 2068 ccb->ccb_done = mpi_empty_done; 2069 peq = ccb->ccb_cmd; 2070 2071 peq->function = MPI_FUNCTION_PORT_ENABLE; 2072 peq->port_number = 0; 2073 peq->msg_context = htole32(ccb->ccb_id); 2074 2075 if (mpi_poll(sc, ccb, 50000) != 0) { 2076 DNPRINTF(MPI_D_MISC, "%s: mpi_portenable poll\n", DEVNAME(sc)); 2077 return (1); 2078 } 2079 2080 pep = ccb->ccb_reply; 2081 if (pep == NULL) { 2082 DNPRINTF(MPI_D_MISC, "%s: empty portenable reply\n", 2083 DEVNAME(sc)); 2084 return (1); 2085 } 2086 2087 mpi_push_reply(sc, ccb->ccb_reply_dva); 2088 mpi_put_ccb(sc, ccb); 2089 2090 return (0); 2091 } 2092 2093 int 2094 mpi_fwupload(struct mpi_softc *sc) 2095 { 2096 struct mpi_ccb *ccb; 2097 struct { 2098 struct mpi_msg_fwupload_request req; 2099 struct mpi_sge sge; 2100 } __packed *bundle; 2101 struct mpi_msg_fwupload_reply *upp; 2102 u_int64_t addr; 2103 int s; 2104 int rv = 0; 2105 2106 if (sc->sc_fw_len == 0) 2107 return (0); 2108 2109 DNPRINTF(MPI_D_MISC, "%s: mpi_fwupload\n", DEVNAME(sc)); 2110 2111 sc->sc_fw = mpi_dmamem_alloc(sc, sc->sc_fw_len); 2112 if (sc->sc_fw == NULL) { 2113 DNPRINTF(MPI_D_MISC, "%s: mpi_fwupload unable to allocate %d\n", 2114 DEVNAME(sc), sc->sc_fw_len); 2115 return (1); 2116 } 2117 2118 s = splbio(); 2119 ccb = mpi_get_ccb(sc); 2120 splx(s); 2121 if (ccb == NULL) { 2122 DNPRINTF(MPI_D_MISC, "%s: mpi_fwupload ccb_get\n", 2123 DEVNAME(sc)); 2124 goto err; 2125 } 2126 2127 ccb->ccb_done = mpi_empty_done; 2128 bundle = ccb->ccb_cmd; 2129 2130 bundle->req.function = MPI_FUNCTION_FW_UPLOAD; 2131 bundle->req.msg_context = htole32(ccb->ccb_id); 2132 2133 bundle->req.image_type = MPI_FWUPLOAD_IMAGETYPE_IOC_FW; 2134 2135 bundle->req.tce.details_length = 12; 2136 bundle->req.tce.image_size = htole32(sc->sc_fw_len); 2137 2138 bundle->sge.sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE | 2139 MPI_SGE_FL_SIZE_64 | MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | 2140 MPI_SGE_FL_EOL | (u_int32_t)sc->sc_fw_len); 2141 addr = MPI_DMA_DVA(sc->sc_fw); 2142 bundle->sge.sg_hi_addr = htole32((u_int32_t)(addr >> 32)); 2143 bundle->sge.sg_lo_addr = htole32((u_int32_t)addr); 2144 2145 if (mpi_poll(sc, ccb, 50000) != 0) { 2146 DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_header poll\n", DEVNAME(sc)); 2147 goto err; 2148 } 2149 2150 upp = ccb->ccb_reply; 2151 if (upp == NULL) 2152 panic("%s: unable to do fw upload\n", DEVNAME(sc)); 2153 2154 if (letoh16(upp->ioc_status) != MPI_IOCSTATUS_SUCCESS) 2155 rv = 1; 2156 2157 mpi_push_reply(sc, ccb->ccb_reply_dva); 2158 mpi_put_ccb(sc, ccb); 2159 2160 return (rv); 2161 2162 err: 2163 mpi_dmamem_free(sc, sc->sc_fw); 2164 return (1); 2165 } 2166 2167 void 2168 mpi_get_raid(struct mpi_softc *sc) 2169 { 2170 struct mpi_cfg_hdr hdr; 2171 struct mpi_cfg_ioc_pg2 *vol_page; 2172 struct mpi_cfg_raid_vol *vol_list, *vol; 2173 size_t pagelen; 2174 u_int32_t capabilities; 2175 struct scsi_link *link; 2176 int i; 2177 2178 DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid\n", DEVNAME(sc)); 2179 2180 if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_IOC, 2, 0, &hdr) != 0) { 2181 DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid unable to fetch header" 2182 "for IOC page 2\n", DEVNAME(sc)); 2183 return; 2184 } 2185 2186 pagelen = hdr.page_length * 4; /* dwords to bytes */ 2187 vol_page = malloc(pagelen, M_TEMP, M_WAITOK); 2188 if (vol_page == NULL) { 2189 DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid unable to allocate " 2190 "space for ioc config page 2\n", DEVNAME(sc)); 2191 return; 2192 } 2193 vol_list = (struct mpi_cfg_raid_vol *)(vol_page + 1); 2194 2195 if (mpi_cfg_page(sc, 0, &hdr, 1, vol_page, pagelen) != 0) { 2196 DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid unable to fetch IOC " 2197 "page 2\n", DEVNAME(sc)); 2198 goto out; 2199 } 2200 2201 capabilities = letoh32(vol_page->capabilities); 2202 2203 DNPRINTF(MPI_D_RAID, "%s: capabilities: 0x08%x\n", DEVNAME(sc), 2204 letoh32(vol_page->capabilities)); 2205 DNPRINTF(MPI_D_RAID, "%s: active_vols: %d max_vols: %d " 2206 "active_physdisks: %d max_physdisks: %d\n", DEVNAME(sc), 2207 vol_page->active_vols, vol_page->max_vols, 2208 vol_page->active_physdisks, vol_page->max_physdisks); 2209 2210 /* don't walk list if there are no RAID capability */ 2211 if (capabilities == 0xdeadbeef) { 2212 printf("%s: deadbeef in raid configuration\n", DEVNAME(sc)); 2213 goto out; 2214 } 2215 2216 if ((capabilities & MPI_CFG_IOC_2_CAPABILITIES_RAID) == 0 || 2217 (vol_page->active_vols == 0)) 2218 goto out; 2219 2220 sc->sc_flags |= MPI_F_RAID; 2221 2222 for (i = 0; i < vol_page->active_vols; i++) { 2223 vol = &vol_list[i]; 2224 2225 DNPRINTF(MPI_D_RAID, "%s: id: %d bus: %d ioc: %d pg: %d\n", 2226 DEVNAME(sc), vol->vol_id, vol->vol_bus, vol->vol_ioc, 2227 vol->vol_page); 2228 DNPRINTF(MPI_D_RAID, "%s: type: 0x%02x flags: 0x%02x\n", 2229 DEVNAME(sc), vol->vol_type, vol->flags); 2230 2231 if (vol->vol_ioc != sc->sc_ioc_number || vol->vol_bus != 0) 2232 continue; 2233 2234 link = sc->sc_scsibus->sc_link[vol->vol_id][0]; 2235 if (link == NULL) 2236 continue; 2237 2238 link->flags |= SDEV_VIRTUAL; 2239 } 2240 2241 out: 2242 free(vol_page, M_TEMP); 2243 } 2244 2245 int 2246 mpi_cfg_header(struct mpi_softc *sc, u_int8_t type, u_int8_t number, 2247 u_int32_t address, struct mpi_cfg_hdr *hdr) 2248 { 2249 struct mpi_ccb *ccb; 2250 struct mpi_msg_config_request *cq; 2251 struct mpi_msg_config_reply *cp; 2252 int rv = 0; 2253 int s; 2254 2255 DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_header type: %#x number: %x " 2256 "address: %d\n", DEVNAME(sc), type, number, address); 2257 2258 s = splbio(); 2259 ccb = mpi_get_ccb(sc); 2260 splx(s); 2261 if (ccb == NULL) { 2262 DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_header ccb_get\n", 2263 DEVNAME(sc)); 2264 return (1); 2265 } 2266 2267 ccb->ccb_done = mpi_empty_done; 2268 cq = ccb->ccb_cmd; 2269 2270 cq->function = MPI_FUNCTION_CONFIG; 2271 cq->msg_context = htole32(ccb->ccb_id); 2272 2273 cq->action = MPI_CONFIG_REQ_ACTION_PAGE_HEADER; 2274 2275 cq->config_header.page_number = number; 2276 cq->config_header.page_type = type; 2277 cq->page_address = htole32(address); 2278 cq->page_buffer.sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE | 2279 MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | MPI_SGE_FL_EOL); 2280 2281 if (mpi_poll(sc, ccb, 50000) != 0) { 2282 DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_header poll\n", DEVNAME(sc)); 2283 return (1); 2284 } 2285 2286 cp = ccb->ccb_reply; 2287 if (cp == NULL) 2288 panic("%s: unable to fetch config header\n", DEVNAME(sc)); 2289 2290 DNPRINTF(MPI_D_MISC, "%s: action: 0x%02x msg_length: %d function: " 2291 "0x%02x\n", DEVNAME(sc), cp->action, cp->msg_length, cp->function); 2292 DNPRINTF(MPI_D_MISC, "%s: ext_page_length: %d ext_page_type: 0x%02x " 2293 "msg_flags: 0x%02x\n", DEVNAME(sc), 2294 letoh16(cp->ext_page_length), cp->ext_page_type, 2295 cp->msg_flags); 2296 DNPRINTF(MPI_D_MISC, "%s: msg_context: 0x%08x\n", DEVNAME(sc), 2297 letoh32(cp->msg_context)); 2298 DNPRINTF(MPI_D_MISC, "%s: ioc_status: 0x%04x\n", DEVNAME(sc), 2299 letoh16(cp->ioc_status)); 2300 DNPRINTF(MPI_D_MISC, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc), 2301 letoh32(cp->ioc_loginfo)); 2302 DNPRINTF(MPI_D_MISC, "%s: page_version: 0x%02x page_length: %d " 2303 "page_number: 0x%02x page_type: 0x%02x\n", DEVNAME(sc), 2304 cp->config_header.page_version, 2305 cp->config_header.page_length, 2306 cp->config_header.page_number, 2307 cp->config_header.page_type); 2308 2309 if (letoh16(cp->ioc_status) != MPI_IOCSTATUS_SUCCESS) 2310 rv = 1; 2311 else 2312 *hdr = cp->config_header; 2313 2314 mpi_push_reply(sc, ccb->ccb_reply_dva); 2315 mpi_put_ccb(sc, ccb); 2316 2317 return (rv); 2318 } 2319 2320 int 2321 mpi_cfg_page(struct mpi_softc *sc, u_int32_t address, struct mpi_cfg_hdr *hdr, 2322 int read, void *page, size_t len) 2323 { 2324 struct mpi_ccb *ccb; 2325 struct mpi_msg_config_request *cq; 2326 struct mpi_msg_config_reply *cp; 2327 u_int64_t dva; 2328 char *kva; 2329 int rv = 0; 2330 int s; 2331 2332 DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_page address: %d read: %d type: %x\n", 2333 DEVNAME(sc), address, read, hdr->page_type); 2334 2335 if (len > MPI_REQUEST_SIZE - sizeof(struct mpi_msg_config_request) || 2336 len < hdr->page_length * 4) 2337 return (1); 2338 2339 s = splbio(); 2340 ccb = mpi_get_ccb(sc); 2341 splx(s); 2342 if (ccb == NULL) { 2343 DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_page ccb_get\n", DEVNAME(sc)); 2344 return (1); 2345 } 2346 2347 ccb->ccb_done = mpi_empty_done; 2348 cq = ccb->ccb_cmd; 2349 2350 cq->function = MPI_FUNCTION_CONFIG; 2351 cq->msg_context = htole32(ccb->ccb_id); 2352 2353 cq->action = (read ? MPI_CONFIG_REQ_ACTION_PAGE_READ_CURRENT : 2354 MPI_CONFIG_REQ_ACTION_PAGE_WRITE_CURRENT); 2355 2356 cq->config_header = *hdr; 2357 cq->config_header.page_type &= MPI_CONFIG_REQ_PAGE_TYPE_MASK; 2358 cq->page_address = htole32(address); 2359 cq->page_buffer.sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE | 2360 MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | MPI_SGE_FL_EOL | 2361 (hdr->page_length * 4) | 2362 (read ? MPI_SGE_FL_DIR_IN : MPI_SGE_FL_DIR_OUT)); 2363 2364 /* bounce the page via the request space to avoid more bus_dma games */ 2365 dva = ccb->ccb_cmd_dva + sizeof(struct mpi_msg_config_request); 2366 2367 cq->page_buffer.sg_hi_addr = htole32((u_int32_t)(dva >> 32)); 2368 cq->page_buffer.sg_lo_addr = htole32((u_int32_t)dva); 2369 2370 kva = ccb->ccb_cmd; 2371 kva += sizeof(struct mpi_msg_config_request); 2372 if (!read) 2373 bcopy(page, kva, len); 2374 2375 if (mpi_poll(sc, ccb, 50000) != 0) { 2376 DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_page poll\n", DEVNAME(sc)); 2377 return (1); 2378 } 2379 2380 cp = ccb->ccb_reply; 2381 if (cp == NULL) { 2382 mpi_put_ccb(sc, ccb); 2383 return (1); 2384 } 2385 2386 DNPRINTF(MPI_D_MISC, "%s: action: 0x%02x msg_length: %d function: " 2387 "0x%02x\n", DEVNAME(sc), cp->action, cp->msg_length, cp->function); 2388 DNPRINTF(MPI_D_MISC, "%s: ext_page_length: %d ext_page_type: 0x%02x " 2389 "msg_flags: 0x%02x\n", DEVNAME(sc), 2390 letoh16(cp->ext_page_length), cp->ext_page_type, 2391 cp->msg_flags); 2392 DNPRINTF(MPI_D_MISC, "%s: msg_context: 0x%08x\n", DEVNAME(sc), 2393 letoh32(cp->msg_context)); 2394 DNPRINTF(MPI_D_MISC, "%s: ioc_status: 0x%04x\n", DEVNAME(sc), 2395 letoh16(cp->ioc_status)); 2396 DNPRINTF(MPI_D_MISC, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc), 2397 letoh32(cp->ioc_loginfo)); 2398 DNPRINTF(MPI_D_MISC, "%s: page_version: 0x%02x page_length: %d " 2399 "page_number: 0x%02x page_type: 0x%02x\n", DEVNAME(sc), 2400 cp->config_header.page_version, 2401 cp->config_header.page_length, 2402 cp->config_header.page_number, 2403 cp->config_header.page_type); 2404 2405 if (letoh16(cp->ioc_status) != MPI_IOCSTATUS_SUCCESS) 2406 rv = 1; 2407 else if (read) 2408 bcopy(kva, page, len); 2409 2410 mpi_push_reply(sc, ccb->ccb_reply_dva); 2411 mpi_put_ccb(sc, ccb); 2412 2413 return (rv); 2414 } 2415