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