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