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