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