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