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