1 /* $OpenBSD: mpi.c,v 1.110 2009/03/06 01:28:44 krw 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, struct scsi_link *sl); 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 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 #if NBIO > 0 290 if (sc->sc_flags & MPI_F_RAID) { 291 if (bio_register(&sc->sc_dev, mpi_ioctl) != 0) 292 panic("%s: controller registration failed", 293 DEVNAME(sc)); 294 else { 295 if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_IOC, 296 2, 0, &sc->sc_cfg_hdr) != 0) { 297 printf("%s: can't get IOC page 2 hdr, bio " 298 "disabled\n", DEVNAME(sc)); 299 goto done; 300 } 301 sc->sc_vol_page = malloc(sc->sc_cfg_hdr.page_length * 4, 302 M_TEMP, 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 } 314 #ifndef SMALL_KERNEL 315 mpi_create_sensors(sc); 316 #endif /* SMALL_KERNEL */ 317 done: 318 #endif /* NBIO > 0 */ 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 return (NO_CCB); 1129 1130 DNPRINTF(MPI_D_CMD, "%s: ccb_id: %d xs->flags: 0x%x\n", 1131 DEVNAME(sc), ccb->ccb_id, xs->flags); 1132 1133 ccb->ccb_xs = xs; 1134 ccb->ccb_done = mpi_scsi_cmd_done; 1135 1136 mcb = ccb->ccb_cmd; 1137 io = &mcb->mcb_io; 1138 1139 io->function = MPI_FUNCTION_SCSI_IO_REQUEST; 1140 /* 1141 * bus is always 0 1142 * io->bus = htole16(sc->sc_bus); 1143 */ 1144 io->target_id = link->target; 1145 1146 io->cdb_length = xs->cmdlen; 1147 io->sense_buf_len = sizeof(xs->sense); 1148 io->msg_flags = MPI_SCSIIO_SENSE_BUF_ADDR_WIDTH_64; 1149 1150 io->msg_context = htole32(ccb->ccb_id); 1151 1152 io->lun[0] = htobe16(link->lun); 1153 1154 switch (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) { 1155 case SCSI_DATA_IN: 1156 io->direction = MPI_SCSIIO_DIR_READ; 1157 break; 1158 case SCSI_DATA_OUT: 1159 io->direction = MPI_SCSIIO_DIR_WRITE; 1160 break; 1161 default: 1162 io->direction = MPI_SCSIIO_DIR_NONE; 1163 break; 1164 } 1165 1166 if (sc->sc_porttype != MPI_PORTFACTS_PORTTYPE_SCSI && 1167 (link->quirks & SDEV_NOTAGS)) 1168 io->tagging = MPI_SCSIIO_ATTR_UNTAGGED; 1169 else 1170 io->tagging = MPI_SCSIIO_ATTR_SIMPLE_Q; 1171 1172 bcopy(xs->cmd, io->cdb, xs->cmdlen); 1173 1174 io->data_length = htole32(xs->datalen); 1175 1176 io->sense_buf_low_addr = htole32(ccb->ccb_cmd_dva + 1177 ((u_int8_t *)&mcb->mcb_sense - (u_int8_t *)mcb)); 1178 1179 if (mpi_load_xs(ccb) != 0) { 1180 xs->error = XS_DRIVER_STUFFUP; 1181 s = splbio(); 1182 mpi_put_ccb(sc, ccb); 1183 scsi_done(xs); 1184 splx(s); 1185 return (COMPLETE); 1186 } 1187 1188 timeout_set(&xs->stimeout, mpi_timeout_xs, ccb); 1189 1190 if (xs->flags & SCSI_POLL) { 1191 if (mpi_poll(sc, ccb, xs->timeout) != 0) 1192 xs->error = XS_DRIVER_STUFFUP; 1193 return (COMPLETE); 1194 } 1195 1196 s = splbio(); 1197 mpi_start(sc, ccb); 1198 splx(s); 1199 return (SUCCESSFULLY_QUEUED); 1200 } 1201 1202 void 1203 mpi_scsi_cmd_done(struct mpi_ccb *ccb) 1204 { 1205 struct mpi_softc *sc = ccb->ccb_sc; 1206 struct scsi_xfer *xs = ccb->ccb_xs; 1207 struct mpi_ccb_bundle *mcb = ccb->ccb_cmd; 1208 bus_dmamap_t dmap = ccb->ccb_dmamap; 1209 struct mpi_msg_scsi_io_error *sie; 1210 1211 if (xs->datalen != 0) { 1212 bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize, 1213 (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD : 1214 BUS_DMASYNC_POSTWRITE); 1215 1216 bus_dmamap_unload(sc->sc_dmat, dmap); 1217 } 1218 1219 /* timeout_del */ 1220 xs->error = XS_NOERROR; 1221 xs->resid = 0; 1222 xs->flags |= ITSDONE; 1223 1224 if (ccb->ccb_rcb == NULL) { 1225 /* no scsi error, we're ok so drop out early */ 1226 xs->status = SCSI_OK; 1227 mpi_put_ccb(sc, ccb); 1228 scsi_done(xs); 1229 return; 1230 } 1231 1232 sie = ccb->ccb_rcb->rcb_reply; 1233 1234 DNPRINTF(MPI_D_CMD, "%s: mpi_scsi_cmd_done xs cmd: 0x%02x len: %d " 1235 "flags 0x%x\n", DEVNAME(sc), xs->cmd->opcode, xs->datalen, 1236 xs->flags); 1237 DNPRINTF(MPI_D_CMD, "%s: target_id: %d bus: %d msg_length: %d " 1238 "function: 0x%02x\n", DEVNAME(sc), sie->target_id, sie->bus, 1239 sie->msg_length, sie->function); 1240 DNPRINTF(MPI_D_CMD, "%s: cdb_length: %d sense_buf_length: %d " 1241 "msg_flags: 0x%02x\n", DEVNAME(sc), sie->cdb_length, 1242 sie->sense_buf_len, sie->msg_flags); 1243 DNPRINTF(MPI_D_CMD, "%s: msg_context: 0x%08x\n", DEVNAME(sc), 1244 letoh32(sie->msg_context)); 1245 DNPRINTF(MPI_D_CMD, "%s: scsi_status: 0x%02x scsi_state: 0x%02x " 1246 "ioc_status: 0x%04x\n", DEVNAME(sc), sie->scsi_status, 1247 sie->scsi_state, letoh16(sie->ioc_status)); 1248 DNPRINTF(MPI_D_CMD, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc), 1249 letoh32(sie->ioc_loginfo)); 1250 DNPRINTF(MPI_D_CMD, "%s: transfer_count: %d\n", DEVNAME(sc), 1251 letoh32(sie->transfer_count)); 1252 DNPRINTF(MPI_D_CMD, "%s: sense_count: %d\n", DEVNAME(sc), 1253 letoh32(sie->sense_count)); 1254 DNPRINTF(MPI_D_CMD, "%s: response_info: 0x%08x\n", DEVNAME(sc), 1255 letoh32(sie->response_info)); 1256 DNPRINTF(MPI_D_CMD, "%s: tag: 0x%04x\n", DEVNAME(sc), 1257 letoh16(sie->tag)); 1258 1259 xs->status = sie->scsi_status; 1260 switch (letoh16(sie->ioc_status)) { 1261 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: 1262 xs->resid = xs->datalen - letoh32(sie->transfer_count); 1263 if (sie->scsi_state & MPI_SCSIIO_ERR_STATE_NO_SCSI_STATUS) { 1264 xs->error = XS_DRIVER_STUFFUP; 1265 break; 1266 } 1267 /* FALLTHROUGH */ 1268 case MPI_IOCSTATUS_SUCCESS: 1269 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: 1270 switch (xs->status) { 1271 case SCSI_OK: 1272 xs->resid = 0; 1273 break; 1274 1275 case SCSI_CHECK: 1276 xs->error = XS_SENSE; 1277 break; 1278 1279 case SCSI_BUSY: 1280 case SCSI_QUEUE_FULL: 1281 xs->error = XS_BUSY; 1282 break; 1283 1284 default: 1285 xs->error = XS_DRIVER_STUFFUP; 1286 break; 1287 } 1288 break; 1289 1290 case MPI_IOCSTATUS_BUSY: 1291 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: 1292 xs->error = XS_BUSY; 1293 break; 1294 1295 case MPI_IOCSTATUS_SCSI_INVALID_BUS: 1296 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: 1297 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: 1298 xs->error = XS_SELTIMEOUT; 1299 break; 1300 1301 default: 1302 xs->error = XS_DRIVER_STUFFUP; 1303 break; 1304 } 1305 1306 if (sie->scsi_state & MPI_SCSIIO_ERR_STATE_AUTOSENSE_VALID) 1307 bcopy(&mcb->mcb_sense, &xs->sense, sizeof(xs->sense)); 1308 1309 DNPRINTF(MPI_D_CMD, "%s: xs err: 0x%02x status: %d\n", DEVNAME(sc), 1310 xs->error, xs->status); 1311 1312 mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva); 1313 mpi_put_ccb(sc, ccb); 1314 scsi_done(xs); 1315 } 1316 1317 void 1318 mpi_timeout_xs(void *arg) 1319 { 1320 /* XXX */ 1321 } 1322 1323 int 1324 mpi_load_xs(struct mpi_ccb *ccb) 1325 { 1326 struct mpi_softc *sc = ccb->ccb_sc; 1327 struct scsi_xfer *xs = ccb->ccb_xs; 1328 struct mpi_ccb_bundle *mcb = ccb->ccb_cmd; 1329 struct mpi_msg_scsi_io *io = &mcb->mcb_io; 1330 struct mpi_sge *sge, *nsge = &mcb->mcb_sgl[0]; 1331 struct mpi_sge *ce = NULL, *nce; 1332 u_int64_t ce_dva; 1333 bus_dmamap_t dmap = ccb->ccb_dmamap; 1334 u_int32_t addr, flags; 1335 int i, error; 1336 1337 if (xs->datalen == 0) { 1338 nsge->sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE | 1339 MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | MPI_SGE_FL_EOL); 1340 return (0); 1341 } 1342 1343 error = bus_dmamap_load(sc->sc_dmat, dmap, 1344 xs->data, xs->datalen, NULL, 1345 (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK); 1346 if (error) { 1347 printf("%s: error %d loading dmamap\n", DEVNAME(sc), error); 1348 return (1); 1349 } 1350 1351 flags = MPI_SGE_FL_TYPE_SIMPLE | MPI_SGE_FL_SIZE_64; 1352 if (xs->flags & SCSI_DATA_OUT) 1353 flags |= MPI_SGE_FL_DIR_OUT; 1354 1355 if (dmap->dm_nsegs > sc->sc_first_sgl_len) { 1356 ce = &mcb->mcb_sgl[sc->sc_first_sgl_len - 1]; 1357 io->chain_offset = ((u_int8_t *)ce - (u_int8_t *)io) / 4; 1358 } 1359 1360 for (i = 0; i < dmap->dm_nsegs; i++) { 1361 1362 if (nsge == ce) { 1363 nsge++; 1364 sge->sg_hdr |= htole32(MPI_SGE_FL_LAST); 1365 1366 DNPRINTF(MPI_D_DMA, "%s: - 0x%08x 0x%08x 0x%08x\n", 1367 DEVNAME(sc), sge->sg_hdr, 1368 sge->sg_hi_addr, sge->sg_lo_addr); 1369 1370 if ((dmap->dm_nsegs - i) > sc->sc_chain_len) { 1371 nce = &nsge[sc->sc_chain_len - 1]; 1372 addr = ((u_int8_t *)nce - (u_int8_t *)nsge) / 4; 1373 addr = addr << 16 | 1374 sizeof(struct mpi_sge) * sc->sc_chain_len; 1375 } else { 1376 nce = NULL; 1377 addr = sizeof(struct mpi_sge) * 1378 (dmap->dm_nsegs - i); 1379 } 1380 1381 ce->sg_hdr = htole32(MPI_SGE_FL_TYPE_CHAIN | 1382 MPI_SGE_FL_SIZE_64 | addr); 1383 1384 ce_dva = ccb->ccb_cmd_dva + 1385 ((u_int8_t *)nsge - (u_int8_t *)mcb); 1386 1387 addr = (u_int32_t)(ce_dva >> 32); 1388 ce->sg_hi_addr = htole32(addr); 1389 addr = (u_int32_t)ce_dva; 1390 ce->sg_lo_addr = htole32(addr); 1391 1392 DNPRINTF(MPI_D_DMA, "%s: ce: 0x%08x 0x%08x 0x%08x\n", 1393 DEVNAME(sc), ce->sg_hdr, ce->sg_hi_addr, 1394 ce->sg_lo_addr); 1395 1396 ce = nce; 1397 } 1398 1399 DNPRINTF(MPI_D_DMA, "%s: %d: %d 0x%016llx\n", DEVNAME(sc), 1400 i, dmap->dm_segs[i].ds_len, 1401 (u_int64_t)dmap->dm_segs[i].ds_addr); 1402 1403 sge = nsge; 1404 1405 sge->sg_hdr = htole32(flags | dmap->dm_segs[i].ds_len); 1406 addr = (u_int32_t)((u_int64_t)dmap->dm_segs[i].ds_addr >> 32); 1407 sge->sg_hi_addr = htole32(addr); 1408 addr = (u_int32_t)dmap->dm_segs[i].ds_addr; 1409 sge->sg_lo_addr = htole32(addr); 1410 1411 DNPRINTF(MPI_D_DMA, "%s: %d: 0x%08x 0x%08x 0x%08x\n", 1412 DEVNAME(sc), i, sge->sg_hdr, sge->sg_hi_addr, 1413 sge->sg_lo_addr); 1414 1415 nsge = sge + 1; 1416 } 1417 1418 /* terminate list */ 1419 sge->sg_hdr |= htole32(MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | 1420 MPI_SGE_FL_EOL); 1421 1422 bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize, 1423 (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD : 1424 BUS_DMASYNC_PREWRITE); 1425 1426 return (0); 1427 } 1428 1429 void 1430 mpi_minphys(struct buf *bp, struct scsi_link *sl) 1431 { 1432 /* XXX */ 1433 if (bp->b_bcount > MAXPHYS) 1434 bp->b_bcount = MAXPHYS; 1435 minphys(bp); 1436 } 1437 1438 int 1439 mpi_scsi_probe(struct scsi_link *link) 1440 { 1441 struct mpi_softc *sc = link->adapter_softc; 1442 struct mpi_ecfg_hdr ehdr; 1443 struct mpi_cfg_sas_dev_pg0 pg0; 1444 u_int32_t address; 1445 1446 if (sc->sc_porttype != MPI_PORTFACTS_PORTTYPE_SAS) 1447 return (0); 1448 1449 address = MPI_CFG_SAS_DEV_ADDR_BUS | link->target; 1450 1451 if (mpi_ecfg_header(sc, MPI_CONFIG_REQ_EXTPAGE_TYPE_SAS_DEVICE, 0, 1452 address, &ehdr) != 0) 1453 return (EIO); 1454 1455 if (mpi_ecfg_page(sc, address, &ehdr, 1, &pg0, sizeof(pg0)) != 0) 1456 return (0); 1457 1458 DNPRINTF(MPI_D_MISC, "%s: mpi_scsi_probe sas dev pg 0 for target %d:\n", 1459 DEVNAME(sc), link->target); 1460 DNPRINTF(MPI_D_MISC, "%s: slot: 0x%04x enc_handle: 0x%04x\n", 1461 DEVNAME(sc), letoh16(pg0.slot), letoh16(pg0.enc_handle)); 1462 DNPRINTF(MPI_D_MISC, "%s: sas_addr: 0x%016llx\n", DEVNAME(sc), 1463 letoh64(pg0.sas_addr)); 1464 DNPRINTF(MPI_D_MISC, "%s: parent_dev_handle: 0x%04x phy_num: 0x%02x " 1465 "access_status: 0x%02x\n", DEVNAME(sc), 1466 letoh16(pg0.parent_dev_handle), pg0.phy_num, pg0.access_status); 1467 DNPRINTF(MPI_D_MISC, "%s: dev_handle: 0x%04x " 1468 "bus: 0x%02x target: 0x%02x\n", DEVNAME(sc), 1469 letoh16(pg0.dev_handle), pg0.bus, pg0.target); 1470 DNPRINTF(MPI_D_MISC, "%s: device_info: 0x%08x\n", DEVNAME(sc), 1471 letoh32(pg0.device_info)); 1472 DNPRINTF(MPI_D_MISC, "%s: flags: 0x%04x physical_port: 0x%02x\n", 1473 DEVNAME(sc), letoh16(pg0.flags), pg0.physical_port); 1474 1475 if (ISSET(letoh32(pg0.device_info), 1476 MPI_CFG_SAS_DEV_0_DEVINFO_ATAPI_DEVICE)) { 1477 DNPRINTF(MPI_D_MISC, "%s: target %d is an ATAPI device\n", 1478 DEVNAME(sc), link->target); 1479 link->flags |= SDEV_ATAPI; 1480 link->quirks |= SDEV_ONLYBIG; 1481 } 1482 1483 return (0); 1484 } 1485 1486 u_int32_t 1487 mpi_read(struct mpi_softc *sc, bus_size_t r) 1488 { 1489 u_int32_t rv; 1490 1491 bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4, 1492 BUS_SPACE_BARRIER_READ); 1493 rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, r); 1494 1495 DNPRINTF(MPI_D_RW, "%s: mpi_read %#x %#x\n", DEVNAME(sc), r, rv); 1496 1497 return (rv); 1498 } 1499 1500 void 1501 mpi_write(struct mpi_softc *sc, bus_size_t r, u_int32_t v) 1502 { 1503 DNPRINTF(MPI_D_RW, "%s: mpi_write %#x %#x\n", DEVNAME(sc), r, v); 1504 1505 bus_space_write_4(sc->sc_iot, sc->sc_ioh, r, v); 1506 bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4, 1507 BUS_SPACE_BARRIER_WRITE); 1508 } 1509 1510 int 1511 mpi_wait_eq(struct mpi_softc *sc, bus_size_t r, u_int32_t mask, 1512 u_int32_t target) 1513 { 1514 int i; 1515 1516 DNPRINTF(MPI_D_RW, "%s: mpi_wait_eq %#x %#x %#x\n", DEVNAME(sc), r, 1517 mask, target); 1518 1519 for (i = 0; i < 10000; i++) { 1520 if ((mpi_read(sc, r) & mask) == target) 1521 return (0); 1522 delay(1000); 1523 } 1524 1525 return (1); 1526 } 1527 1528 int 1529 mpi_wait_ne(struct mpi_softc *sc, bus_size_t r, u_int32_t mask, 1530 u_int32_t target) 1531 { 1532 int i; 1533 1534 DNPRINTF(MPI_D_RW, "%s: mpi_wait_ne %#x %#x %#x\n", DEVNAME(sc), r, 1535 mask, target); 1536 1537 for (i = 0; i < 10000; i++) { 1538 if ((mpi_read(sc, r) & mask) != target) 1539 return (0); 1540 delay(1000); 1541 } 1542 1543 return (1); 1544 } 1545 1546 int 1547 mpi_init(struct mpi_softc *sc) 1548 { 1549 u_int32_t db; 1550 int i; 1551 1552 /* spin until the IOC leaves the RESET state */ 1553 if (mpi_wait_ne(sc, MPI_DOORBELL, MPI_DOORBELL_STATE, 1554 MPI_DOORBELL_STATE_RESET) != 0) { 1555 DNPRINTF(MPI_D_MISC, "%s: mpi_init timeout waiting to leave " 1556 "reset state\n", DEVNAME(sc)); 1557 return (1); 1558 } 1559 1560 /* check current ownership */ 1561 db = mpi_read_db(sc); 1562 if ((db & MPI_DOORBELL_WHOINIT) == MPI_DOORBELL_WHOINIT_PCIPEER) { 1563 DNPRINTF(MPI_D_MISC, "%s: mpi_init initialised by pci peer\n", 1564 DEVNAME(sc)); 1565 return (0); 1566 } 1567 1568 for (i = 0; i < 5; i++) { 1569 switch (db & MPI_DOORBELL_STATE) { 1570 case MPI_DOORBELL_STATE_READY: 1571 DNPRINTF(MPI_D_MISC, "%s: mpi_init ioc is ready\n", 1572 DEVNAME(sc)); 1573 return (0); 1574 1575 case MPI_DOORBELL_STATE_OPER: 1576 case MPI_DOORBELL_STATE_FAULT: 1577 DNPRINTF(MPI_D_MISC, "%s: mpi_init ioc is being " 1578 "reset\n" , DEVNAME(sc)); 1579 if (mpi_reset_soft(sc) != 0) 1580 mpi_reset_hard(sc); 1581 break; 1582 1583 case MPI_DOORBELL_STATE_RESET: 1584 DNPRINTF(MPI_D_MISC, "%s: mpi_init waiting to come " 1585 "out of reset\n", DEVNAME(sc)); 1586 if (mpi_wait_ne(sc, MPI_DOORBELL, MPI_DOORBELL_STATE, 1587 MPI_DOORBELL_STATE_RESET) != 0) 1588 return (1); 1589 break; 1590 } 1591 db = mpi_read_db(sc); 1592 } 1593 1594 return (1); 1595 } 1596 1597 int 1598 mpi_reset_soft(struct mpi_softc *sc) 1599 { 1600 DNPRINTF(MPI_D_MISC, "%s: mpi_reset_soft\n", DEVNAME(sc)); 1601 1602 if (mpi_read_db(sc) & MPI_DOORBELL_INUSE) 1603 return (1); 1604 1605 mpi_write_db(sc, 1606 MPI_DOORBELL_FUNCTION(MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET)); 1607 if (mpi_wait_eq(sc, MPI_INTR_STATUS, 1608 MPI_INTR_STATUS_IOCDOORBELL, 0) != 0) 1609 return (1); 1610 1611 if (mpi_wait_eq(sc, MPI_DOORBELL, MPI_DOORBELL_STATE, 1612 MPI_DOORBELL_STATE_READY) != 0) 1613 return (1); 1614 1615 return (0); 1616 } 1617 1618 int 1619 mpi_reset_hard(struct mpi_softc *sc) 1620 { 1621 DNPRINTF(MPI_D_MISC, "%s: mpi_reset_hard\n", DEVNAME(sc)); 1622 1623 /* enable diagnostic register */ 1624 mpi_write(sc, MPI_WRITESEQ, 0xff); 1625 mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_1); 1626 mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_2); 1627 mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_3); 1628 mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_4); 1629 mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_5); 1630 1631 /* reset ioc */ 1632 mpi_write(sc, MPI_HOSTDIAG, MPI_HOSTDIAG_RESET_ADAPTER); 1633 1634 delay(10000); 1635 1636 /* disable diagnostic register */ 1637 mpi_write(sc, MPI_WRITESEQ, 0xff); 1638 1639 /* restore pci bits? */ 1640 1641 /* firmware bits? */ 1642 return (0); 1643 } 1644 1645 int 1646 mpi_handshake_send(struct mpi_softc *sc, void *buf, size_t dwords) 1647 { 1648 u_int32_t *query = buf; 1649 int i; 1650 1651 /* make sure the doorbell is not in use. */ 1652 if (mpi_read_db(sc) & MPI_DOORBELL_INUSE) 1653 return (1); 1654 1655 /* clear pending doorbell interrupts */ 1656 if (mpi_read_intr(sc) & MPI_INTR_STATUS_DOORBELL) 1657 mpi_write_intr(sc, 0); 1658 1659 /* 1660 * first write the doorbell with the handshake function and the 1661 * dword count. 1662 */ 1663 mpi_write_db(sc, MPI_DOORBELL_FUNCTION(MPI_FUNCTION_HANDSHAKE) | 1664 MPI_DOORBELL_DWORDS(dwords)); 1665 1666 /* 1667 * the doorbell used bit will be set because a doorbell function has 1668 * started. Wait for the interrupt and then ack it. 1669 */ 1670 if (mpi_wait_db_int(sc) != 0) 1671 return (1); 1672 mpi_write_intr(sc, 0); 1673 1674 /* poll for the acknowledgement. */ 1675 if (mpi_wait_db_ack(sc) != 0) 1676 return (1); 1677 1678 /* write the query through the doorbell. */ 1679 for (i = 0; i < dwords; i++) { 1680 mpi_write_db(sc, htole32(query[i])); 1681 if (mpi_wait_db_ack(sc) != 0) 1682 return (1); 1683 } 1684 1685 return (0); 1686 } 1687 1688 int 1689 mpi_handshake_recv_dword(struct mpi_softc *sc, u_int32_t *dword) 1690 { 1691 u_int16_t *words = (u_int16_t *)dword; 1692 int i; 1693 1694 for (i = 0; i < 2; i++) { 1695 if (mpi_wait_db_int(sc) != 0) 1696 return (1); 1697 words[i] = letoh16(mpi_read_db(sc) & MPI_DOORBELL_DATA_MASK); 1698 mpi_write_intr(sc, 0); 1699 } 1700 1701 return (0); 1702 } 1703 1704 int 1705 mpi_handshake_recv(struct mpi_softc *sc, void *buf, size_t dwords) 1706 { 1707 struct mpi_msg_reply *reply = buf; 1708 u_int32_t *dbuf = buf, dummy; 1709 int i; 1710 1711 /* get the first dword so we can read the length out of the header. */ 1712 if (mpi_handshake_recv_dword(sc, &dbuf[0]) != 0) 1713 return (1); 1714 1715 DNPRINTF(MPI_D_CMD, "%s: mpi_handshake_recv dwords: %d reply: %d\n", 1716 DEVNAME(sc), dwords, reply->msg_length); 1717 1718 /* 1719 * the total length, in dwords, is in the message length field of the 1720 * reply header. 1721 */ 1722 for (i = 1; i < MIN(dwords, reply->msg_length); i++) { 1723 if (mpi_handshake_recv_dword(sc, &dbuf[i]) != 0) 1724 return (1); 1725 } 1726 1727 /* if there's extra stuff to come off the ioc, discard it */ 1728 while (i++ < reply->msg_length) { 1729 if (mpi_handshake_recv_dword(sc, &dummy) != 0) 1730 return (1); 1731 DNPRINTF(MPI_D_CMD, "%s: mpi_handshake_recv dummy read: " 1732 "0x%08x\n", DEVNAME(sc), dummy); 1733 } 1734 1735 /* wait for the doorbell used bit to be reset and clear the intr */ 1736 if (mpi_wait_db_int(sc) != 0) 1737 return (1); 1738 mpi_write_intr(sc, 0); 1739 1740 return (0); 1741 } 1742 1743 void 1744 mpi_empty_done(struct mpi_ccb *ccb) 1745 { 1746 /* nothing to do */ 1747 } 1748 1749 int 1750 mpi_iocfacts(struct mpi_softc *sc) 1751 { 1752 struct mpi_msg_iocfacts_request ifq; 1753 struct mpi_msg_iocfacts_reply ifp; 1754 1755 DNPRINTF(MPI_D_MISC, "%s: mpi_iocfacts\n", DEVNAME(sc)); 1756 1757 bzero(&ifq, sizeof(ifq)); 1758 bzero(&ifp, sizeof(ifp)); 1759 1760 ifq.function = MPI_FUNCTION_IOC_FACTS; 1761 ifq.chain_offset = 0; 1762 ifq.msg_flags = 0; 1763 ifq.msg_context = htole32(0xdeadbeef); 1764 1765 if (mpi_handshake_send(sc, &ifq, dwordsof(ifq)) != 0) { 1766 DNPRINTF(MPI_D_MISC, "%s: mpi_iocfacts send failed\n", 1767 DEVNAME(sc)); 1768 return (1); 1769 } 1770 1771 if (mpi_handshake_recv(sc, &ifp, dwordsof(ifp)) != 0) { 1772 DNPRINTF(MPI_D_MISC, "%s: mpi_iocfacts recv failed\n", 1773 DEVNAME(sc)); 1774 return (1); 1775 } 1776 1777 DNPRINTF(MPI_D_MISC, "%s: func: 0x%02x len: %d msgver: %d.%d\n", 1778 DEVNAME(sc), ifp.function, ifp.msg_length, 1779 ifp.msg_version_maj, ifp.msg_version_min); 1780 DNPRINTF(MPI_D_MISC, "%s: msgflags: 0x%02x iocnumber: 0x%02x " 1781 "hdrver: %d.%d\n", DEVNAME(sc), ifp.msg_flags, 1782 ifp.ioc_number, ifp.header_version_maj, 1783 ifp.header_version_min); 1784 DNPRINTF(MPI_D_MISC, "%s: message context: 0x%08x\n", DEVNAME(sc), 1785 letoh32(ifp.msg_context)); 1786 DNPRINTF(MPI_D_MISC, "%s: iocstatus: 0x%04x ioexcept: 0x%04x\n", 1787 DEVNAME(sc), letoh16(ifp.ioc_status), 1788 letoh16(ifp.ioc_exceptions)); 1789 DNPRINTF(MPI_D_MISC, "%s: iocloginfo: 0x%08x\n", DEVNAME(sc), 1790 letoh32(ifp.ioc_loginfo)); 1791 DNPRINTF(MPI_D_MISC, "%s: flags: 0x%02x blocksize: %d whoinit: 0x%02x " 1792 "maxchdepth: %d\n", DEVNAME(sc), ifp.flags, 1793 ifp.block_size, ifp.whoinit, ifp.max_chain_depth); 1794 DNPRINTF(MPI_D_MISC, "%s: reqfrsize: %d replyqdepth: %d\n", 1795 DEVNAME(sc), letoh16(ifp.request_frame_size), 1796 letoh16(ifp.reply_queue_depth)); 1797 DNPRINTF(MPI_D_MISC, "%s: productid: 0x%04x\n", DEVNAME(sc), 1798 letoh16(ifp.product_id)); 1799 DNPRINTF(MPI_D_MISC, "%s: hostmfahiaddr: 0x%08x\n", DEVNAME(sc), 1800 letoh32(ifp.current_host_mfa_hi_addr)); 1801 DNPRINTF(MPI_D_MISC, "%s: event_state: 0x%02x number_of_ports: %d " 1802 "global_credits: %d\n", 1803 DEVNAME(sc), ifp.event_state, ifp.number_of_ports, 1804 letoh16(ifp.global_credits)); 1805 DNPRINTF(MPI_D_MISC, "%s: sensebufhiaddr: 0x%08x\n", DEVNAME(sc), 1806 letoh32(ifp.current_sense_buffer_hi_addr)); 1807 DNPRINTF(MPI_D_MISC, "%s: maxbus: %d maxdev: %d replyfrsize: %d\n", 1808 DEVNAME(sc), ifp.max_buses, ifp.max_devices, 1809 letoh16(ifp.current_reply_frame_size)); 1810 DNPRINTF(MPI_D_MISC, "%s: fw_image_size: %d\n", DEVNAME(sc), 1811 letoh32(ifp.fw_image_size)); 1812 DNPRINTF(MPI_D_MISC, "%s: ioc_capabilities: 0x%08x\n", DEVNAME(sc), 1813 letoh32(ifp.ioc_capabilities)); 1814 DNPRINTF(MPI_D_MISC, "%s: fw_version: %d.%d fw_version_unit: 0x%02x " 1815 "fw_version_dev: 0x%02x\n", DEVNAME(sc), 1816 ifp.fw_version_maj, ifp.fw_version_min, 1817 ifp.fw_version_unit, ifp.fw_version_dev); 1818 DNPRINTF(MPI_D_MISC, "%s: hi_priority_queue_depth: 0x%04x\n", 1819 DEVNAME(sc), letoh16(ifp.hi_priority_queue_depth)); 1820 DNPRINTF(MPI_D_MISC, "%s: host_page_buffer_sge: hdr: 0x%08x " 1821 "addr 0x%08x %08x\n", DEVNAME(sc), 1822 letoh32(ifp.host_page_buffer_sge.sg_hdr), 1823 letoh32(ifp.host_page_buffer_sge.sg_hi_addr), 1824 letoh32(ifp.host_page_buffer_sge.sg_lo_addr)); 1825 1826 sc->sc_maxcmds = letoh16(ifp.global_credits); 1827 sc->sc_maxchdepth = ifp.max_chain_depth; 1828 sc->sc_ioc_number = ifp.ioc_number; 1829 if (sc->sc_flags & MPI_F_SPI) 1830 sc->sc_buswidth = 16; 1831 else 1832 sc->sc_buswidth = 1833 (ifp.max_devices == 0) ? 256 : ifp.max_devices; 1834 if (ifp.flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) 1835 sc->sc_fw_len = letoh32(ifp.fw_image_size); 1836 1837 /* 1838 * you can fit sg elements on the end of the io cmd if they fit in the 1839 * request frame size. 1840 */ 1841 sc->sc_first_sgl_len = ((letoh16(ifp.request_frame_size) * 4) - 1842 sizeof(struct mpi_msg_scsi_io)) / sizeof(struct mpi_sge); 1843 DNPRINTF(MPI_D_MISC, "%s: first sgl len: %d\n", DEVNAME(sc), 1844 sc->sc_first_sgl_len); 1845 1846 sc->sc_chain_len = (letoh16(ifp.request_frame_size) * 4) / 1847 sizeof(struct mpi_sge); 1848 DNPRINTF(MPI_D_MISC, "%s: chain len: %d\n", DEVNAME(sc), 1849 sc->sc_chain_len); 1850 1851 /* the sgl tailing the io cmd loses an entry to the chain element. */ 1852 sc->sc_max_sgl_len = MPI_MAX_SGL - 1; 1853 /* the sgl chains lose an entry for each chain element */ 1854 sc->sc_max_sgl_len -= (MPI_MAX_SGL - sc->sc_first_sgl_len) / 1855 sc->sc_chain_len; 1856 DNPRINTF(MPI_D_MISC, "%s: max sgl len: %d\n", DEVNAME(sc), 1857 sc->sc_max_sgl_len); 1858 1859 /* XXX we're ignoring the max chain depth */ 1860 1861 return (0); 1862 } 1863 1864 int 1865 mpi_iocinit(struct mpi_softc *sc) 1866 { 1867 struct mpi_msg_iocinit_request iiq; 1868 struct mpi_msg_iocinit_reply iip; 1869 u_int32_t hi_addr; 1870 1871 DNPRINTF(MPI_D_MISC, "%s: mpi_iocinit\n", DEVNAME(sc)); 1872 1873 bzero(&iiq, sizeof(iiq)); 1874 bzero(&iip, sizeof(iip)); 1875 1876 iiq.function = MPI_FUNCTION_IOC_INIT; 1877 iiq.whoinit = MPI_WHOINIT_HOST_DRIVER; 1878 1879 iiq.max_devices = (sc->sc_buswidth == 256) ? 0 : sc->sc_buswidth; 1880 iiq.max_buses = 1; 1881 1882 iiq.msg_context = htole32(0xd00fd00f); 1883 1884 iiq.reply_frame_size = htole16(MPI_REPLY_SIZE); 1885 1886 hi_addr = (u_int32_t)((u_int64_t)MPI_DMA_DVA(sc->sc_requests) >> 32); 1887 iiq.host_mfa_hi_addr = htole32(hi_addr); 1888 iiq.sense_buffer_hi_addr = htole32(hi_addr); 1889 1890 hi_addr = (u_int32_t)((u_int64_t)MPI_DMA_DVA(sc->sc_replies) >> 32); 1891 iiq.reply_fifo_host_signalling_addr = htole32(hi_addr); 1892 1893 iiq.msg_version_maj = 0x01; 1894 iiq.msg_version_min = 0x02; 1895 1896 iiq.hdr_version_unit = 0x0d; 1897 iiq.hdr_version_dev = 0x00; 1898 1899 if (mpi_handshake_send(sc, &iiq, dwordsof(iiq)) != 0) { 1900 DNPRINTF(MPI_D_MISC, "%s: mpi_iocinit send failed\n", 1901 DEVNAME(sc)); 1902 return (1); 1903 } 1904 1905 if (mpi_handshake_recv(sc, &iip, dwordsof(iip)) != 0) { 1906 DNPRINTF(MPI_D_MISC, "%s: mpi_iocinit recv failed\n", 1907 DEVNAME(sc)); 1908 return (1); 1909 } 1910 1911 DNPRINTF(MPI_D_MISC, "%s: function: 0x%02x msg_length: %d " 1912 "whoinit: 0x%02x\n", DEVNAME(sc), iip.function, 1913 iip.msg_length, iip.whoinit); 1914 DNPRINTF(MPI_D_MISC, "%s: msg_flags: 0x%02x max_buses: %d " 1915 "max_devices: %d flags: 0x%02x\n", DEVNAME(sc), iip.msg_flags, 1916 iip.max_buses, iip.max_devices, iip.flags); 1917 DNPRINTF(MPI_D_MISC, "%s: msg_context: 0x%08x\n", DEVNAME(sc), 1918 letoh32(iip.msg_context)); 1919 DNPRINTF(MPI_D_MISC, "%s: ioc_status: 0x%04x\n", DEVNAME(sc), 1920 letoh16(iip.ioc_status)); 1921 DNPRINTF(MPI_D_MISC, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc), 1922 letoh32(iip.ioc_loginfo)); 1923 1924 return (0); 1925 } 1926 1927 int 1928 mpi_portfacts(struct mpi_softc *sc) 1929 { 1930 struct mpi_ccb *ccb; 1931 struct mpi_msg_portfacts_request *pfq; 1932 volatile struct mpi_msg_portfacts_reply *pfp; 1933 int s, rv = 1; 1934 1935 DNPRINTF(MPI_D_MISC, "%s: mpi_portfacts\n", DEVNAME(sc)); 1936 1937 s = splbio(); 1938 ccb = mpi_get_ccb(sc); 1939 splx(s); 1940 if (ccb == NULL) { 1941 DNPRINTF(MPI_D_MISC, "%s: mpi_portfacts ccb_get\n", 1942 DEVNAME(sc)); 1943 return (rv); 1944 } 1945 1946 ccb->ccb_done = mpi_empty_done; 1947 pfq = ccb->ccb_cmd; 1948 1949 pfq->function = MPI_FUNCTION_PORT_FACTS; 1950 pfq->chain_offset = 0; 1951 pfq->msg_flags = 0; 1952 pfq->port_number = 0; 1953 pfq->msg_context = htole32(ccb->ccb_id); 1954 1955 if (mpi_poll(sc, ccb, 50000) != 0) { 1956 DNPRINTF(MPI_D_MISC, "%s: mpi_portfacts poll\n", DEVNAME(sc)); 1957 goto err; 1958 } 1959 1960 if (ccb->ccb_rcb == NULL) { 1961 DNPRINTF(MPI_D_MISC, "%s: empty portfacts reply\n", 1962 DEVNAME(sc)); 1963 goto err; 1964 } 1965 pfp = ccb->ccb_rcb->rcb_reply; 1966 1967 DNPRINTF(MPI_D_MISC, "%s: function: 0x%02x msg_length: %d\n", 1968 DEVNAME(sc), pfp->function, pfp->msg_length); 1969 DNPRINTF(MPI_D_MISC, "%s: msg_flags: 0x%02x port_number: %d\n", 1970 DEVNAME(sc), pfp->msg_flags, pfp->port_number); 1971 DNPRINTF(MPI_D_MISC, "%s: msg_context: 0x%08x\n", DEVNAME(sc), 1972 letoh32(pfp->msg_context)); 1973 DNPRINTF(MPI_D_MISC, "%s: ioc_status: 0x%04x\n", DEVNAME(sc), 1974 letoh16(pfp->ioc_status)); 1975 DNPRINTF(MPI_D_MISC, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc), 1976 letoh32(pfp->ioc_loginfo)); 1977 DNPRINTF(MPI_D_MISC, "%s: max_devices: %d port_type: 0x%02x\n", 1978 DEVNAME(sc), letoh16(pfp->max_devices), pfp->port_type); 1979 DNPRINTF(MPI_D_MISC, "%s: protocol_flags: 0x%04x port_scsi_id: %d\n", 1980 DEVNAME(sc), letoh16(pfp->protocol_flags), 1981 letoh16(pfp->port_scsi_id)); 1982 DNPRINTF(MPI_D_MISC, "%s: max_persistent_ids: %d " 1983 "max_posted_cmd_buffers: %d\n", DEVNAME(sc), 1984 letoh16(pfp->max_persistent_ids), 1985 letoh16(pfp->max_posted_cmd_buffers)); 1986 DNPRINTF(MPI_D_MISC, "%s: max_lan_buckets: %d\n", DEVNAME(sc), 1987 letoh16(pfp->max_lan_buckets)); 1988 1989 sc->sc_porttype = pfp->port_type; 1990 if (sc->sc_target == -1) 1991 sc->sc_target = letoh16(pfp->port_scsi_id); 1992 1993 mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva); 1994 rv = 0; 1995 err: 1996 mpi_put_ccb(sc, ccb); 1997 1998 return (rv); 1999 } 2000 2001 int 2002 mpi_eventnotify(struct mpi_softc *sc) 2003 { 2004 struct mpi_ccb *ccb; 2005 struct mpi_msg_event_request *enq; 2006 int s; 2007 2008 s = splbio(); 2009 ccb = mpi_get_ccb(sc); 2010 splx(s); 2011 if (ccb == NULL) { 2012 DNPRINTF(MPI_D_MISC, "%s: mpi_eventnotify ccb_get\n", 2013 DEVNAME(sc)); 2014 return (1); 2015 } 2016 2017 ccb->ccb_done = mpi_eventnotify_done; 2018 enq = ccb->ccb_cmd; 2019 2020 enq->function = MPI_FUNCTION_EVENT_NOTIFICATION; 2021 enq->chain_offset = 0; 2022 enq->event_switch = MPI_EVENT_SWITCH_ON; 2023 enq->msg_context = htole32(ccb->ccb_id); 2024 2025 mpi_start(sc, ccb); 2026 return (0); 2027 } 2028 2029 void 2030 mpi_eventnotify_done(struct mpi_ccb *ccb) 2031 { 2032 struct mpi_softc *sc = ccb->ccb_sc; 2033 struct mpi_msg_event_reply *enp = ccb->ccb_rcb->rcb_reply; 2034 int deferred = 0; 2035 2036 DNPRINTF(MPI_D_EVT, "%s: mpi_eventnotify_done\n", DEVNAME(sc)); 2037 2038 DNPRINTF(MPI_D_EVT, "%s: function: 0x%02x msg_length: %d " 2039 "data_length: %d\n", DEVNAME(sc), enp->function, enp->msg_length, 2040 letoh16(enp->data_length)); 2041 DNPRINTF(MPI_D_EVT, "%s: ack_required: %d msg_flags 0x%02x\n", 2042 DEVNAME(sc), enp->ack_required, enp->msg_flags); 2043 DNPRINTF(MPI_D_EVT, "%s: msg_context: 0x%08x\n", DEVNAME(sc), 2044 letoh32(enp->msg_context)); 2045 DNPRINTF(MPI_D_EVT, "%s: ioc_status: 0x%04x\n", DEVNAME(sc), 2046 letoh16(enp->ioc_status)); 2047 DNPRINTF(MPI_D_EVT, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc), 2048 letoh32(enp->ioc_loginfo)); 2049 DNPRINTF(MPI_D_EVT, "%s: event: 0x%08x\n", DEVNAME(sc), 2050 letoh32(enp->event)); 2051 DNPRINTF(MPI_D_EVT, "%s: event_context: 0x%08x\n", DEVNAME(sc), 2052 letoh32(enp->event_context)); 2053 2054 switch (letoh32(enp->event)) { 2055 /* ignore these */ 2056 case MPI_EVENT_EVENT_CHANGE: 2057 case MPI_EVENT_SAS_PHY_LINK_STATUS: 2058 break; 2059 2060 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: 2061 if (sc->sc_scsibus == NULL) 2062 break; 2063 2064 if (scsi_task(mpi_evt_sas, sc, ccb->ccb_rcb, 0) != 0) { 2065 printf("%s: unable to run SAS device status change\n", 2066 DEVNAME(sc)); 2067 break; 2068 } 2069 deferred = 1; 2070 break; 2071 2072 default: 2073 printf("%s: unhandled event 0x%02x\n", DEVNAME(sc), 2074 letoh32(enp->event)); 2075 break; 2076 } 2077 2078 if (!deferred) { 2079 if (enp->ack_required) 2080 mpi_eventack(sc, enp); 2081 mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva); 2082 } 2083 2084 if ((enp->msg_flags & MPI_EVENT_FLAGS_REPLY_KEPT) == 0) { 2085 /* XXX this shouldnt happen till shutdown */ 2086 mpi_put_ccb(sc, ccb); 2087 } 2088 } 2089 2090 void 2091 mpi_evt_sas(void *xsc, void *arg) 2092 { 2093 struct mpi_softc *sc = xsc; 2094 struct mpi_rcb *rcb = arg; 2095 struct mpi_msg_event_reply *enp = rcb->rcb_reply; 2096 struct mpi_evt_sas_change *ch; 2097 u_int8_t *data; 2098 int s; 2099 2100 data = rcb->rcb_reply; 2101 data += sizeof(struct mpi_msg_event_reply); 2102 ch = (struct mpi_evt_sas_change *)data; 2103 2104 if (ch->bus != 0) 2105 return; 2106 2107 switch (ch->reason) { 2108 case MPI_EVT_SASCH_REASON_ADDED: 2109 case MPI_EVT_SASCH_REASON_NO_PERSIST_ADDED: 2110 scsi_probe_target(sc->sc_scsibus, ch->target); 2111 break; 2112 2113 case MPI_EVT_SASCH_REASON_NOT_RESPONDING: 2114 scsi_detach_target(sc->sc_scsibus, ch->target, DETACH_FORCE); 2115 break; 2116 2117 case MPI_EVT_SASCH_REASON_SMART_DATA: 2118 case MPI_EVT_SASCH_REASON_UNSUPPORTED: 2119 case MPI_EVT_SASCH_REASON_INTERNAL_RESET: 2120 break; 2121 default: 2122 printf("%s: unknown reason for SAS device status change: " 2123 "0x%02x\n", DEVNAME(sc), ch->reason); 2124 break; 2125 } 2126 2127 s = splbio(); 2128 mpi_push_reply(sc, rcb->rcb_reply_dva); 2129 if (enp->ack_required) 2130 mpi_eventack(sc, enp); 2131 splx(s); 2132 } 2133 2134 void 2135 mpi_eventack(struct mpi_softc *sc, struct mpi_msg_event_reply *enp) 2136 { 2137 struct mpi_ccb *ccb; 2138 struct mpi_msg_eventack_request *eaq; 2139 2140 ccb = mpi_get_ccb(sc); 2141 if (ccb == NULL) { 2142 DNPRINTF(MPI_D_EVT, "%s: mpi_eventack ccb_get\n", DEVNAME(sc)); 2143 return; 2144 } 2145 2146 ccb->ccb_done = mpi_eventack_done; 2147 eaq = ccb->ccb_cmd; 2148 2149 eaq->function = MPI_FUNCTION_EVENT_ACK; 2150 eaq->msg_context = htole32(ccb->ccb_id); 2151 2152 eaq->event = enp->event; 2153 eaq->event_context = enp->event_context; 2154 2155 mpi_start(sc, ccb); 2156 return; 2157 } 2158 2159 void 2160 mpi_eventack_done(struct mpi_ccb *ccb) 2161 { 2162 struct mpi_softc *sc = ccb->ccb_sc; 2163 2164 DNPRINTF(MPI_D_EVT, "%s: event ack done\n", DEVNAME(sc)); 2165 2166 mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva); 2167 mpi_put_ccb(sc, ccb); 2168 } 2169 2170 int 2171 mpi_portenable(struct mpi_softc *sc) 2172 { 2173 struct mpi_ccb *ccb; 2174 struct mpi_msg_portenable_request *peq; 2175 struct mpi_msg_portenable_repy *pep; 2176 int s; 2177 2178 DNPRINTF(MPI_D_MISC, "%s: mpi_portenable\n", DEVNAME(sc)); 2179 2180 s = splbio(); 2181 ccb = mpi_get_ccb(sc); 2182 splx(s); 2183 if (ccb == NULL) { 2184 DNPRINTF(MPI_D_MISC, "%s: mpi_portenable ccb_get\n", 2185 DEVNAME(sc)); 2186 return (1); 2187 } 2188 2189 ccb->ccb_done = mpi_empty_done; 2190 peq = ccb->ccb_cmd; 2191 2192 peq->function = MPI_FUNCTION_PORT_ENABLE; 2193 peq->port_number = 0; 2194 peq->msg_context = htole32(ccb->ccb_id); 2195 2196 if (mpi_poll(sc, ccb, 50000) != 0) { 2197 DNPRINTF(MPI_D_MISC, "%s: mpi_portenable poll\n", DEVNAME(sc)); 2198 return (1); 2199 } 2200 2201 if (ccb->ccb_rcb == NULL) { 2202 DNPRINTF(MPI_D_MISC, "%s: empty portenable reply\n", 2203 DEVNAME(sc)); 2204 return (1); 2205 } 2206 pep = ccb->ccb_rcb->rcb_reply; 2207 2208 mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva); 2209 mpi_put_ccb(sc, ccb); 2210 2211 return (0); 2212 } 2213 2214 int 2215 mpi_fwupload(struct mpi_softc *sc) 2216 { 2217 struct mpi_ccb *ccb; 2218 struct { 2219 struct mpi_msg_fwupload_request req; 2220 struct mpi_sge sge; 2221 } __packed *bundle; 2222 struct mpi_msg_fwupload_reply *upp; 2223 u_int64_t addr; 2224 int s; 2225 int rv = 0; 2226 2227 if (sc->sc_fw_len == 0) 2228 return (0); 2229 2230 DNPRINTF(MPI_D_MISC, "%s: mpi_fwupload\n", DEVNAME(sc)); 2231 2232 sc->sc_fw = mpi_dmamem_alloc(sc, sc->sc_fw_len); 2233 if (sc->sc_fw == NULL) { 2234 DNPRINTF(MPI_D_MISC, "%s: mpi_fwupload unable to allocate %d\n", 2235 DEVNAME(sc), sc->sc_fw_len); 2236 return (1); 2237 } 2238 2239 s = splbio(); 2240 ccb = mpi_get_ccb(sc); 2241 splx(s); 2242 if (ccb == NULL) { 2243 DNPRINTF(MPI_D_MISC, "%s: mpi_fwupload ccb_get\n", 2244 DEVNAME(sc)); 2245 goto err; 2246 } 2247 2248 ccb->ccb_done = mpi_empty_done; 2249 bundle = ccb->ccb_cmd; 2250 2251 bundle->req.function = MPI_FUNCTION_FW_UPLOAD; 2252 bundle->req.msg_context = htole32(ccb->ccb_id); 2253 2254 bundle->req.image_type = MPI_FWUPLOAD_IMAGETYPE_IOC_FW; 2255 2256 bundle->req.tce.details_length = 12; 2257 bundle->req.tce.image_size = htole32(sc->sc_fw_len); 2258 2259 bundle->sge.sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE | 2260 MPI_SGE_FL_SIZE_64 | MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | 2261 MPI_SGE_FL_EOL | (u_int32_t)sc->sc_fw_len); 2262 addr = MPI_DMA_DVA(sc->sc_fw); 2263 bundle->sge.sg_hi_addr = htole32((u_int32_t)(addr >> 32)); 2264 bundle->sge.sg_lo_addr = htole32((u_int32_t)addr); 2265 2266 if (mpi_poll(sc, ccb, 50000) != 0) { 2267 DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_header poll\n", DEVNAME(sc)); 2268 goto err; 2269 } 2270 2271 if (ccb->ccb_rcb == NULL) 2272 panic("%s: unable to do fw upload\n", DEVNAME(sc)); 2273 upp = ccb->ccb_rcb->rcb_reply; 2274 2275 if (letoh16(upp->ioc_status) != MPI_IOCSTATUS_SUCCESS) 2276 rv = 1; 2277 2278 mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva); 2279 mpi_put_ccb(sc, ccb); 2280 2281 return (rv); 2282 2283 err: 2284 mpi_dmamem_free(sc, sc->sc_fw); 2285 return (1); 2286 } 2287 2288 void 2289 mpi_get_raid(struct mpi_softc *sc) 2290 { 2291 struct mpi_cfg_hdr hdr; 2292 struct mpi_cfg_ioc_pg2 *vol_page; 2293 struct mpi_cfg_raid_vol *vol_list, *vol; 2294 size_t pagelen; 2295 u_int32_t capabilities; 2296 struct scsi_link *link; 2297 int i; 2298 2299 DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid\n", DEVNAME(sc)); 2300 2301 if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_IOC, 2, 0, &hdr) != 0) { 2302 DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid unable to fetch header" 2303 "for IOC page 2\n", DEVNAME(sc)); 2304 return; 2305 } 2306 2307 pagelen = hdr.page_length * 4; /* dwords to bytes */ 2308 vol_page = malloc(pagelen, M_TEMP, M_WAITOK|M_CANFAIL); 2309 if (vol_page == NULL) { 2310 DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid unable to allocate " 2311 "space for ioc config page 2\n", DEVNAME(sc)); 2312 return; 2313 } 2314 vol_list = (struct mpi_cfg_raid_vol *)(vol_page + 1); 2315 2316 if (mpi_cfg_page(sc, 0, &hdr, 1, vol_page, pagelen) != 0) { 2317 DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid unable to fetch IOC " 2318 "page 2\n", DEVNAME(sc)); 2319 goto out; 2320 } 2321 2322 capabilities = letoh32(vol_page->capabilities); 2323 2324 DNPRINTF(MPI_D_RAID, "%s: capabilities: 0x08%x\n", DEVNAME(sc), 2325 letoh32(vol_page->capabilities)); 2326 DNPRINTF(MPI_D_RAID, "%s: active_vols: %d max_vols: %d " 2327 "active_physdisks: %d max_physdisks: %d\n", DEVNAME(sc), 2328 vol_page->active_vols, vol_page->max_vols, 2329 vol_page->active_physdisks, vol_page->max_physdisks); 2330 2331 /* don't walk list if there are no RAID capability */ 2332 if (capabilities == 0xdeadbeef) { 2333 printf("%s: deadbeef in raid configuration\n", DEVNAME(sc)); 2334 goto out; 2335 } 2336 2337 if ((capabilities & MPI_CFG_IOC_2_CAPABILITIES_RAID) == 0 || 2338 (vol_page->active_vols == 0)) 2339 goto out; 2340 2341 sc->sc_flags |= MPI_F_RAID; 2342 2343 for (i = 0; i < vol_page->active_vols; i++) { 2344 vol = &vol_list[i]; 2345 2346 DNPRINTF(MPI_D_RAID, "%s: id: %d bus: %d ioc: %d pg: %d\n", 2347 DEVNAME(sc), vol->vol_id, vol->vol_bus, vol->vol_ioc, 2348 vol->vol_page); 2349 DNPRINTF(MPI_D_RAID, "%s: type: 0x%02x flags: 0x%02x\n", 2350 DEVNAME(sc), vol->vol_type, vol->flags); 2351 2352 if (vol->vol_ioc != sc->sc_ioc_number || vol->vol_bus != 0) 2353 continue; 2354 2355 link = sc->sc_scsibus->sc_link[vol->vol_id][0]; 2356 if (link == NULL) 2357 continue; 2358 2359 link->flags |= SDEV_VIRTUAL; 2360 } 2361 2362 out: 2363 free(vol_page, M_TEMP); 2364 } 2365 2366 int 2367 mpi_req_cfg_header(struct mpi_softc *sc, u_int8_t type, u_int8_t number, 2368 u_int32_t address, int extended, void *p) 2369 { 2370 struct mpi_ccb *ccb; 2371 struct mpi_msg_config_request *cq; 2372 struct mpi_msg_config_reply *cp; 2373 struct mpi_cfg_hdr *hdr = p; 2374 struct mpi_ecfg_hdr *ehdr = p; 2375 int etype = 0; 2376 int rv = 0; 2377 int s; 2378 2379 DNPRINTF(MPI_D_MISC, "%s: mpi_req_cfg_header type: %#x number: %x " 2380 "address: 0x%08x extended: %d\n", DEVNAME(sc), type, number, 2381 address, extended); 2382 2383 s = splbio(); 2384 ccb = mpi_get_ccb(sc); 2385 splx(s); 2386 if (ccb == NULL) { 2387 DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_header ccb_get\n", 2388 DEVNAME(sc)); 2389 return (1); 2390 } 2391 2392 if (extended) { 2393 etype = type; 2394 type = MPI_CONFIG_REQ_PAGE_TYPE_EXTENDED; 2395 } 2396 2397 ccb->ccb_done = mpi_empty_done; 2398 cq = ccb->ccb_cmd; 2399 2400 cq->function = MPI_FUNCTION_CONFIG; 2401 cq->msg_context = htole32(ccb->ccb_id); 2402 2403 cq->action = MPI_CONFIG_REQ_ACTION_PAGE_HEADER; 2404 2405 cq->config_header.page_number = number; 2406 cq->config_header.page_type = type; 2407 cq->ext_page_type = etype; 2408 cq->page_address = htole32(address); 2409 cq->page_buffer.sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE | 2410 MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | MPI_SGE_FL_EOL); 2411 2412 if (mpi_poll(sc, ccb, 50000) != 0) { 2413 DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_header poll\n", DEVNAME(sc)); 2414 return (1); 2415 } 2416 2417 if (ccb->ccb_rcb == NULL) 2418 panic("%s: unable to fetch config header\n", DEVNAME(sc)); 2419 cp = ccb->ccb_rcb->rcb_reply; 2420 2421 DNPRINTF(MPI_D_MISC, "%s: action: 0x%02x msg_length: %d function: " 2422 "0x%02x\n", DEVNAME(sc), cp->action, cp->msg_length, cp->function); 2423 DNPRINTF(MPI_D_MISC, "%s: ext_page_length: %d ext_page_type: 0x%02x " 2424 "msg_flags: 0x%02x\n", DEVNAME(sc), 2425 letoh16(cp->ext_page_length), cp->ext_page_type, 2426 cp->msg_flags); 2427 DNPRINTF(MPI_D_MISC, "%s: msg_context: 0x%08x\n", DEVNAME(sc), 2428 letoh32(cp->msg_context)); 2429 DNPRINTF(MPI_D_MISC, "%s: ioc_status: 0x%04x\n", DEVNAME(sc), 2430 letoh16(cp->ioc_status)); 2431 DNPRINTF(MPI_D_MISC, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc), 2432 letoh32(cp->ioc_loginfo)); 2433 DNPRINTF(MPI_D_MISC, "%s: page_version: 0x%02x page_length: %d " 2434 "page_number: 0x%02x page_type: 0x%02x\n", DEVNAME(sc), 2435 cp->config_header.page_version, 2436 cp->config_header.page_length, 2437 cp->config_header.page_number, 2438 cp->config_header.page_type); 2439 2440 if (letoh16(cp->ioc_status) != MPI_IOCSTATUS_SUCCESS) 2441 rv = 1; 2442 else if (extended) { 2443 bzero(ehdr, sizeof(*ehdr)); 2444 ehdr->page_version = cp->config_header.page_version; 2445 ehdr->page_number = cp->config_header.page_number; 2446 ehdr->page_type = cp->config_header.page_type; 2447 ehdr->ext_page_length = cp->ext_page_length; 2448 ehdr->ext_page_type = cp->ext_page_type; 2449 } else 2450 *hdr = cp->config_header; 2451 2452 mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva); 2453 mpi_put_ccb(sc, ccb); 2454 2455 return (rv); 2456 } 2457 2458 int 2459 mpi_req_cfg_page(struct mpi_softc *sc, u_int32_t address, int extended, 2460 void *p, int read, void *page, size_t len) 2461 { 2462 struct mpi_ccb *ccb; 2463 struct mpi_msg_config_request *cq; 2464 struct mpi_msg_config_reply *cp; 2465 struct mpi_cfg_hdr *hdr = p; 2466 struct mpi_ecfg_hdr *ehdr = p; 2467 u_int64_t dva; 2468 char *kva; 2469 int page_length; 2470 int rv = 0; 2471 int s; 2472 2473 DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_page address: %d read: %d type: %x\n", 2474 DEVNAME(sc), address, read, hdr->page_type); 2475 2476 page_length = extended ? 2477 letoh16(ehdr->ext_page_length) : hdr->page_length; 2478 2479 if (len > MPI_REQUEST_SIZE - sizeof(struct mpi_msg_config_request) || 2480 len < page_length * 4) 2481 return (1); 2482 2483 s = splbio(); 2484 ccb = mpi_get_ccb(sc); 2485 splx(s); 2486 if (ccb == NULL) { 2487 DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_page ccb_get\n", DEVNAME(sc)); 2488 return (1); 2489 } 2490 2491 ccb->ccb_done = mpi_empty_done; 2492 cq = ccb->ccb_cmd; 2493 2494 cq->function = MPI_FUNCTION_CONFIG; 2495 cq->msg_context = htole32(ccb->ccb_id); 2496 2497 cq->action = (read ? MPI_CONFIG_REQ_ACTION_PAGE_READ_CURRENT : 2498 MPI_CONFIG_REQ_ACTION_PAGE_WRITE_CURRENT); 2499 2500 if (extended) { 2501 cq->config_header.page_version = ehdr->page_version; 2502 cq->config_header.page_number = ehdr->page_number; 2503 cq->config_header.page_type = ehdr->page_type; 2504 cq->ext_page_len = ehdr->ext_page_length; 2505 cq->ext_page_type = ehdr->ext_page_type; 2506 } else 2507 cq->config_header = *hdr; 2508 cq->config_header.page_type &= MPI_CONFIG_REQ_PAGE_TYPE_MASK; 2509 cq->page_address = htole32(address); 2510 cq->page_buffer.sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE | 2511 MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | MPI_SGE_FL_EOL | 2512 (page_length * 4) | 2513 (read ? MPI_SGE_FL_DIR_IN : MPI_SGE_FL_DIR_OUT)); 2514 2515 /* bounce the page via the request space to avoid more bus_dma games */ 2516 dva = ccb->ccb_cmd_dva + sizeof(struct mpi_msg_config_request); 2517 2518 cq->page_buffer.sg_hi_addr = htole32((u_int32_t)(dva >> 32)); 2519 cq->page_buffer.sg_lo_addr = htole32((u_int32_t)dva); 2520 2521 kva = ccb->ccb_cmd; 2522 kva += sizeof(struct mpi_msg_config_request); 2523 if (!read) 2524 bcopy(page, kva, len); 2525 2526 if (mpi_poll(sc, ccb, 50000) != 0) { 2527 DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_page poll\n", DEVNAME(sc)); 2528 return (1); 2529 } 2530 2531 if (ccb->ccb_rcb == NULL) { 2532 mpi_put_ccb(sc, ccb); 2533 return (1); 2534 } 2535 cp = ccb->ccb_rcb->rcb_reply; 2536 2537 DNPRINTF(MPI_D_MISC, "%s: action: 0x%02x msg_length: %d function: " 2538 "0x%02x\n", DEVNAME(sc), cp->action, cp->msg_length, cp->function); 2539 DNPRINTF(MPI_D_MISC, "%s: ext_page_length: %d ext_page_type: 0x%02x " 2540 "msg_flags: 0x%02x\n", DEVNAME(sc), 2541 letoh16(cp->ext_page_length), cp->ext_page_type, 2542 cp->msg_flags); 2543 DNPRINTF(MPI_D_MISC, "%s: msg_context: 0x%08x\n", DEVNAME(sc), 2544 letoh32(cp->msg_context)); 2545 DNPRINTF(MPI_D_MISC, "%s: ioc_status: 0x%04x\n", DEVNAME(sc), 2546 letoh16(cp->ioc_status)); 2547 DNPRINTF(MPI_D_MISC, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc), 2548 letoh32(cp->ioc_loginfo)); 2549 DNPRINTF(MPI_D_MISC, "%s: page_version: 0x%02x page_length: %d " 2550 "page_number: 0x%02x page_type: 0x%02x\n", DEVNAME(sc), 2551 cp->config_header.page_version, 2552 cp->config_header.page_length, 2553 cp->config_header.page_number, 2554 cp->config_header.page_type); 2555 2556 if (letoh16(cp->ioc_status) != MPI_IOCSTATUS_SUCCESS) 2557 rv = 1; 2558 else if (read) 2559 bcopy(kva, page, len); 2560 2561 mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva); 2562 mpi_put_ccb(sc, ccb); 2563 2564 return (rv); 2565 } 2566 2567 int 2568 mpi_scsi_ioctl(struct scsi_link *link, u_long cmd, caddr_t addr, int flag, 2569 struct proc *p) 2570 { 2571 struct mpi_softc *sc = (struct mpi_softc *)link->adapter_softc; 2572 2573 DNPRINTF(MPI_D_IOCTL, "%s: mpi_scsi_ioctl\n", DEVNAME(sc)); 2574 2575 if (sc->sc_ioctl) 2576 return (sc->sc_ioctl(link->adapter_softc, cmd, addr)); 2577 else 2578 return (ENOTTY); 2579 } 2580 2581 #if NBIO > 0 2582 int 2583 mpi_bio_get_pg0_raid(struct mpi_softc *sc, int id) 2584 { 2585 int len, rv = EINVAL; 2586 u_int32_t address; 2587 struct mpi_cfg_hdr hdr; 2588 struct mpi_cfg_raid_vol_pg0 *rpg0; 2589 2590 /* get IOC page 2 */ 2591 if (mpi_cfg_page(sc, 0, &sc->sc_cfg_hdr, 1, sc->sc_vol_page, 2592 sc->sc_cfg_hdr.page_length * 4) != 0) { 2593 DNPRINTF(MPI_D_IOCTL, "%s: mpi_bio_get_pg0_raid unable to " 2594 "fetch IOC page 2\n", DEVNAME(sc)); 2595 goto done; 2596 } 2597 2598 /* XXX return something else than EINVAL to indicate within hs range */ 2599 if (id > sc->sc_vol_page->active_vols) { 2600 DNPRINTF(MPI_D_IOCTL, "%s: mpi_bio_get_pg0_raid invalid vol " 2601 "id: %d\n", DEVNAME(sc), id); 2602 goto done; 2603 } 2604 2605 /* replace current buffer with new one */ 2606 len = sizeof *rpg0 + sc->sc_vol_page->max_physdisks * 2607 sizeof(struct mpi_cfg_raid_vol_pg0_physdisk); 2608 rpg0 = malloc(len, M_TEMP, M_WAITOK | M_CANFAIL); 2609 if (rpg0 == NULL) { 2610 printf("%s: can't get memory for RAID page 0, " 2611 "bio disabled\n", DEVNAME(sc)); 2612 goto done; 2613 } 2614 if (sc->sc_rpg0) 2615 free(sc->sc_rpg0, M_DEVBUF); 2616 sc->sc_rpg0 = rpg0; 2617 2618 /* get raid vol page 0 */ 2619 address = sc->sc_vol_list[id].vol_id | 2620 (sc->sc_vol_list[id].vol_bus << 8); 2621 if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0, 2622 address, &hdr) != 0) 2623 goto done; 2624 if (mpi_cfg_page(sc, address, &hdr, 1, rpg0, len)) { 2625 printf("%s: can't get RAID vol cfg page 0\n", DEVNAME(sc)); 2626 goto done; 2627 } 2628 2629 rv = 0; 2630 done: 2631 return (rv); 2632 } 2633 2634 int 2635 mpi_ioctl(struct device *dev, u_long cmd, caddr_t addr) 2636 { 2637 struct mpi_softc *sc = (struct mpi_softc *)dev; 2638 int error = 0; 2639 2640 DNPRINTF(MPI_D_IOCTL, "%s: mpi_ioctl ", DEVNAME(sc)); 2641 2642 /* make sure we have bio enabled */ 2643 if (sc->sc_ioctl != mpi_ioctl) 2644 return (EINVAL); 2645 2646 rw_enter_write(&sc->sc_lock); 2647 2648 switch (cmd) { 2649 case BIOCINQ: 2650 DNPRINTF(MPI_D_IOCTL, "inq\n"); 2651 error = mpi_ioctl_inq(sc, (struct bioc_inq *)addr); 2652 break; 2653 2654 case BIOCVOL: 2655 DNPRINTF(MPI_D_IOCTL, "vol\n"); 2656 error = mpi_ioctl_vol(sc, (struct bioc_vol *)addr); 2657 break; 2658 2659 case BIOCDISK: 2660 DNPRINTF(MPI_D_IOCTL, "disk\n"); 2661 error = mpi_ioctl_disk(sc, (struct bioc_disk *)addr); 2662 break; 2663 2664 case BIOCALARM: 2665 DNPRINTF(MPI_D_IOCTL, "alarm\n"); 2666 break; 2667 2668 case BIOCBLINK: 2669 DNPRINTF(MPI_D_IOCTL, "blink\n"); 2670 break; 2671 2672 case BIOCSETSTATE: 2673 DNPRINTF(MPI_D_IOCTL, "setstate\n"); 2674 error = mpi_ioctl_setstate(sc, (struct bioc_setstate *)addr); 2675 break; 2676 2677 default: 2678 DNPRINTF(MPI_D_IOCTL, " invalid ioctl\n"); 2679 error = EINVAL; 2680 } 2681 2682 rw_exit_write(&sc->sc_lock); 2683 2684 return (error); 2685 } 2686 2687 int 2688 mpi_ioctl_inq(struct mpi_softc *sc, struct bioc_inq *bi) 2689 { 2690 if (!(sc->sc_flags & MPI_F_RAID)) { 2691 bi->bi_novol = 0; 2692 bi->bi_nodisk = 0; 2693 } 2694 2695 if (mpi_cfg_page(sc, 0, &sc->sc_cfg_hdr, 1, sc->sc_vol_page, 2696 sc->sc_cfg_hdr.page_length * 4) != 0) { 2697 DNPRINTF(MPI_D_IOCTL, "%s: mpi_get_raid unable to fetch IOC " 2698 "page 2\n", DEVNAME(sc)); 2699 return (EINVAL); 2700 } 2701 2702 DNPRINTF(MPI_D_IOCTL, "%s: active_vols: %d max_vols: %d " 2703 "active_physdisks: %d max_physdisks: %d\n", DEVNAME(sc), 2704 sc->sc_vol_page->active_vols, sc->sc_vol_page->max_vols, 2705 sc->sc_vol_page->active_physdisks, sc->sc_vol_page->max_physdisks); 2706 2707 bi->bi_novol = sc->sc_vol_page->active_vols; 2708 bi->bi_nodisk = sc->sc_vol_page->active_physdisks; 2709 strlcpy(bi->bi_dev, DEVNAME(sc), sizeof(bi->bi_dev)); 2710 2711 return (0); 2712 } 2713 2714 int 2715 mpi_ioctl_vol(struct mpi_softc *sc, struct bioc_vol *bv) 2716 { 2717 int i, vol, id, rv = EINVAL; 2718 struct device *dev; 2719 struct scsi_link *link; 2720 struct mpi_cfg_raid_vol_pg0 *rpg0; 2721 2722 id = bv->bv_volid; 2723 if (mpi_bio_get_pg0_raid(sc, id)) 2724 goto done; 2725 2726 if (id > sc->sc_vol_page->active_vols) 2727 return (EINVAL); /* XXX deal with hot spares */ 2728 2729 rpg0 = sc->sc_rpg0; 2730 if (rpg0 == NULL) 2731 goto done; 2732 2733 /* determine status */ 2734 switch (rpg0->volume_state) { 2735 case MPI_CFG_RAID_VOL_0_STATE_OPTIMAL: 2736 bv->bv_status = BIOC_SVONLINE; 2737 break; 2738 case MPI_CFG_RAID_VOL_0_STATE_DEGRADED: 2739 bv->bv_status = BIOC_SVDEGRADED; 2740 break; 2741 case MPI_CFG_RAID_VOL_0_STATE_FAILED: 2742 case MPI_CFG_RAID_VOL_0_STATE_MISSING: 2743 bv->bv_status = BIOC_SVOFFLINE; 2744 break; 2745 default: 2746 bv->bv_status = BIOC_SVINVALID; 2747 } 2748 2749 /* override status if scrubbing or something */ 2750 if (rpg0->volume_status & MPI_CFG_RAID_VOL_0_STATUS_RESYNCING) 2751 bv->bv_status = BIOC_SVREBUILD; 2752 2753 bv->bv_size = (u_quad_t)letoh32(rpg0->max_lba) * 512; 2754 2755 switch (sc->sc_vol_list[id].vol_type) { 2756 case MPI_CFG_RAID_TYPE_RAID_IS: 2757 bv->bv_level = 0; 2758 break; 2759 case MPI_CFG_RAID_TYPE_RAID_IME: 2760 case MPI_CFG_RAID_TYPE_RAID_IM: 2761 bv->bv_level = 1; 2762 break; 2763 case MPI_CFG_RAID_TYPE_RAID_5: 2764 bv->bv_level = 5; 2765 break; 2766 case MPI_CFG_RAID_TYPE_RAID_6: 2767 bv->bv_level = 6; 2768 break; 2769 case MPI_CFG_RAID_TYPE_RAID_10: 2770 bv->bv_level = 10; 2771 break; 2772 case MPI_CFG_RAID_TYPE_RAID_50: 2773 bv->bv_level = 50; 2774 break; 2775 default: 2776 bv->bv_level = -1; 2777 } 2778 2779 bv->bv_nodisk = rpg0->num_phys_disks; 2780 2781 for (i = 0, vol = -1; i < sc->sc_buswidth; i++) { 2782 link = sc->sc_scsibus->sc_link[i][0]; 2783 if (link == NULL) 2784 continue; 2785 2786 /* skip if not a virtual disk */ 2787 if (!(link->flags & SDEV_VIRTUAL)) 2788 continue; 2789 2790 vol++; 2791 /* are we it? */ 2792 if (vol == bv->bv_volid) { 2793 dev = link->device_softc; 2794 memcpy(bv->bv_vendor, link->inqdata.vendor, 2795 sizeof bv->bv_vendor); 2796 bv->bv_vendor[sizeof(bv->bv_vendor) - 1] = '\0'; 2797 strlcpy(bv->bv_dev, dev->dv_xname, sizeof bv->bv_dev); 2798 break; 2799 } 2800 } 2801 rv = 0; 2802 done: 2803 return (rv); 2804 } 2805 2806 int 2807 mpi_ioctl_disk(struct mpi_softc *sc, struct bioc_disk *bd) 2808 { 2809 int pdid, id, rv = EINVAL; 2810 u_int32_t address; 2811 struct mpi_cfg_hdr hdr; 2812 struct mpi_cfg_raid_vol_pg0 *rpg0; 2813 struct mpi_cfg_raid_vol_pg0_physdisk *physdisk; 2814 struct mpi_cfg_raid_physdisk_pg0 pdpg0; 2815 2816 id = bd->bd_volid; 2817 if (mpi_bio_get_pg0_raid(sc, id)) 2818 goto done; 2819 2820 if (id > sc->sc_vol_page->active_vols) 2821 return (EINVAL); /* XXX deal with hot spares */ 2822 2823 rpg0 = sc->sc_rpg0; 2824 if (rpg0 == NULL) 2825 goto done; 2826 2827 pdid = bd->bd_diskid; 2828 if (pdid > rpg0->num_phys_disks) 2829 goto done; 2830 physdisk = (struct mpi_cfg_raid_vol_pg0_physdisk *)(rpg0 + 1); 2831 physdisk += pdid; 2832 2833 /* get raid phys disk page 0 */ 2834 address = physdisk->phys_disk_num; 2835 if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_RAID_PD, 0, address, 2836 &hdr) != 0) 2837 goto done; 2838 if (mpi_cfg_page(sc, address, &hdr, 1, &pdpg0, sizeof pdpg0)) { 2839 bd->bd_status = BIOC_SDFAILED; 2840 return (0); 2841 } 2842 bd->bd_channel = pdpg0.phys_disk_bus; 2843 bd->bd_target = pdpg0.phys_disk_id; 2844 bd->bd_lun = 0; 2845 bd->bd_size = (u_quad_t)pdpg0.max_lba * 512; 2846 strlcpy(bd->bd_vendor, pdpg0.vendor_id, sizeof(bd->bd_vendor)); 2847 2848 switch (pdpg0.phys_disk_state) { 2849 case MPI_CFG_RAID_PHYDISK_0_STATE_ONLINE: 2850 bd->bd_status = BIOC_SDONLINE; 2851 break; 2852 case MPI_CFG_RAID_PHYDISK_0_STATE_MISSING: 2853 case MPI_CFG_RAID_PHYDISK_0_STATE_FAILED: 2854 bd->bd_status = BIOC_SDFAILED; 2855 break; 2856 case MPI_CFG_RAID_PHYDISK_0_STATE_HOSTFAIL: 2857 case MPI_CFG_RAID_PHYDISK_0_STATE_OTHER: 2858 case MPI_CFG_RAID_PHYDISK_0_STATE_OFFLINE: 2859 bd->bd_status = BIOC_SDOFFLINE; 2860 break; 2861 case MPI_CFG_RAID_PHYDISK_0_STATE_INIT: 2862 bd->bd_status = BIOC_SDSCRUB; 2863 break; 2864 case MPI_CFG_RAID_PHYDISK_0_STATE_INCOMPAT: 2865 default: 2866 bd->bd_status = BIOC_SDINVALID; 2867 break; 2868 } 2869 2870 /* XXX figure this out */ 2871 /* bd_serial[32]; */ 2872 /* bd_procdev[16]; */ 2873 2874 rv = 0; 2875 done: 2876 return (rv); 2877 } 2878 2879 int 2880 mpi_ioctl_setstate(struct mpi_softc *sc, struct bioc_setstate *bs) 2881 { 2882 return (ENOTTY); 2883 } 2884 2885 #ifndef SMALL_KERNEL 2886 int 2887 mpi_create_sensors(struct mpi_softc *sc) 2888 { 2889 struct device *dev; 2890 struct scsi_link *link; 2891 int i, vol; 2892 2893 /* count volumes */ 2894 for (i = 0, vol = 0; i < sc->sc_buswidth; i++) { 2895 link = sc->sc_scsibus->sc_link[i][0]; 2896 if (link == NULL) 2897 continue; 2898 /* skip if not a virtual disk */ 2899 if (!(link->flags & SDEV_VIRTUAL)) 2900 continue; 2901 2902 vol++; 2903 } 2904 2905 sc->sc_sensors = malloc(sizeof(struct ksensor) * vol, 2906 M_DEVBUF, M_WAITOK|M_ZERO); 2907 if (sc->sc_sensors == NULL) 2908 return (1); 2909 2910 strlcpy(sc->sc_sensordev.xname, DEVNAME(sc), 2911 sizeof(sc->sc_sensordev.xname)); 2912 2913 for (i = 0, vol= 0; i < sc->sc_buswidth; i++) { 2914 link = sc->sc_scsibus->sc_link[i][0]; 2915 if (link == NULL) 2916 continue; 2917 /* skip if not a virtual disk */ 2918 if (!(link->flags & SDEV_VIRTUAL)) 2919 continue; 2920 2921 dev = link->device_softc; 2922 strlcpy(sc->sc_sensors[vol].desc, dev->dv_xname, 2923 sizeof(sc->sc_sensors[vol].desc)); 2924 sc->sc_sensors[vol].type = SENSOR_DRIVE; 2925 sc->sc_sensors[vol].status = SENSOR_S_UNKNOWN; 2926 sensor_attach(&sc->sc_sensordev, &sc->sc_sensors[vol]); 2927 2928 vol++; 2929 } 2930 2931 if (sensor_task_register(sc, mpi_refresh_sensors, 10) == NULL) 2932 goto bad; 2933 2934 sensordev_install(&sc->sc_sensordev); 2935 2936 return (0); 2937 2938 bad: 2939 free(sc->sc_sensors, M_DEVBUF); 2940 return (1); 2941 } 2942 2943 void 2944 mpi_refresh_sensors(void *arg) 2945 { 2946 int i, vol; 2947 struct scsi_link *link; 2948 struct mpi_softc *sc = arg; 2949 struct mpi_cfg_raid_vol_pg0 *rpg0; 2950 2951 rw_enter_write(&sc->sc_lock); 2952 2953 for (i = 0, vol = 0; i < sc->sc_buswidth; i++) { 2954 link = sc->sc_scsibus->sc_link[i][0]; 2955 if (link == NULL) 2956 continue; 2957 /* skip if not a virtual disk */ 2958 if (!(link->flags & SDEV_VIRTUAL)) 2959 continue; 2960 2961 if (mpi_bio_get_pg0_raid(sc, vol)) 2962 continue; 2963 2964 rpg0 = sc->sc_rpg0; 2965 if (rpg0 == NULL) 2966 goto done; 2967 2968 /* determine status */ 2969 switch (rpg0->volume_state) { 2970 case MPI_CFG_RAID_VOL_0_STATE_OPTIMAL: 2971 sc->sc_sensors[vol].value = SENSOR_DRIVE_ONLINE; 2972 sc->sc_sensors[vol].status = SENSOR_S_OK; 2973 break; 2974 case MPI_CFG_RAID_VOL_0_STATE_DEGRADED: 2975 sc->sc_sensors[vol].value = SENSOR_DRIVE_PFAIL; 2976 sc->sc_sensors[vol].status = SENSOR_S_WARN; 2977 break; 2978 case MPI_CFG_RAID_VOL_0_STATE_FAILED: 2979 case MPI_CFG_RAID_VOL_0_STATE_MISSING: 2980 sc->sc_sensors[vol].value = SENSOR_DRIVE_FAIL; 2981 sc->sc_sensors[vol].status = SENSOR_S_CRIT; 2982 break; 2983 default: 2984 sc->sc_sensors[vol].value = 0; /* unknown */ 2985 sc->sc_sensors[vol].status = SENSOR_S_UNKNOWN; 2986 } 2987 2988 /* override status if scrubbing or something */ 2989 if (rpg0->volume_status & MPI_CFG_RAID_VOL_0_STATUS_RESYNCING) { 2990 sc->sc_sensors[vol].value = SENSOR_DRIVE_REBUILD; 2991 sc->sc_sensors[vol].status = SENSOR_S_WARN; 2992 } 2993 2994 vol++; 2995 } 2996 done: 2997 rw_exit_write(&sc->sc_lock); 2998 } 2999 #endif /* SMALL_KERNEL */ 3000 #endif /* NBIO > 0 */ 3001