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