1 /* $OpenBSD: mfi.c,v 1.94 2009/04/29 00:48:24 marco Exp $ */ 2 /* 3 * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include "bio.h" 19 20 #include <sys/param.h> 21 #include <sys/systm.h> 22 #include <sys/buf.h> 23 #include <sys/ioctl.h> 24 #include <sys/device.h> 25 #include <sys/kernel.h> 26 #include <sys/malloc.h> 27 #include <sys/proc.h> 28 #include <sys/rwlock.h> 29 #include <sys/sensors.h> 30 31 #include <machine/bus.h> 32 33 #include <scsi/scsi_all.h> 34 #include <scsi/scsi_disk.h> 35 #include <scsi/scsiconf.h> 36 37 #include <dev/biovar.h> 38 #include <dev/ic/mfireg.h> 39 #include <dev/ic/mfivar.h> 40 41 #ifdef MFI_DEBUG 42 uint32_t mfi_debug = 0 43 /* | MFI_D_CMD */ 44 /* | MFI_D_INTR */ 45 /* | MFI_D_MISC */ 46 /* | MFI_D_DMA */ 47 /* | MFI_D_IOCTL */ 48 /* | MFI_D_RW */ 49 /* | MFI_D_MEM */ 50 /* | MFI_D_CCB */ 51 ; 52 #endif 53 54 struct cfdriver mfi_cd = { 55 NULL, "mfi", DV_DULL 56 }; 57 58 int mfi_scsi_cmd(struct scsi_xfer *); 59 int mfi_scsi_ioctl(struct scsi_link *, u_long, caddr_t, int, struct proc *); 60 void mfiminphys(struct buf *bp, struct scsi_link *sl); 61 62 struct scsi_adapter mfi_switch = { 63 mfi_scsi_cmd, mfiminphys, 0, 0, mfi_scsi_ioctl 64 }; 65 66 struct scsi_device mfi_dev = { 67 NULL, NULL, NULL, NULL 68 }; 69 70 struct mfi_ccb *mfi_get_ccb(struct mfi_softc *); 71 void mfi_put_ccb(struct mfi_ccb *); 72 int mfi_init_ccb(struct mfi_softc *); 73 74 struct mfi_mem *mfi_allocmem(struct mfi_softc *, size_t); 75 void mfi_freemem(struct mfi_softc *, struct mfi_mem *); 76 77 int mfi_transition_firmware(struct mfi_softc *); 78 int mfi_initialize_firmware(struct mfi_softc *); 79 int mfi_get_info(struct mfi_softc *); 80 uint32_t mfi_read(struct mfi_softc *, bus_size_t); 81 void mfi_write(struct mfi_softc *, bus_size_t, uint32_t); 82 int mfi_poll(struct mfi_ccb *); 83 int mfi_create_sgl(struct mfi_ccb *, int); 84 85 /* commands */ 86 int mfi_scsi_ld(struct mfi_ccb *, struct scsi_xfer *); 87 int mfi_scsi_io(struct mfi_ccb *, struct scsi_xfer *, uint32_t, 88 uint32_t); 89 void mfi_scsi_xs_done(struct mfi_ccb *); 90 int mfi_mgmt(struct mfi_softc *, uint32_t, uint32_t, uint32_t, 91 void *, uint8_t *); 92 void mfi_mgmt_done(struct mfi_ccb *); 93 94 #if NBIO > 0 95 int mfi_ioctl(struct device *, u_long, caddr_t); 96 int mfi_bio_getitall(struct mfi_softc *); 97 int mfi_ioctl_inq(struct mfi_softc *, struct bioc_inq *); 98 int mfi_ioctl_vol(struct mfi_softc *, struct bioc_vol *); 99 int mfi_ioctl_disk(struct mfi_softc *, struct bioc_disk *); 100 int mfi_ioctl_alarm(struct mfi_softc *, struct bioc_alarm *); 101 int mfi_ioctl_blink(struct mfi_softc *sc, struct bioc_blink *); 102 int mfi_ioctl_setstate(struct mfi_softc *, struct bioc_setstate *); 103 int mfi_bio_hs(struct mfi_softc *, int, int, void *); 104 #ifndef SMALL_KERNEL 105 int mfi_create_sensors(struct mfi_softc *); 106 void mfi_refresh_sensors(void *); 107 #endif /* SMALL_KERNEL */ 108 #endif /* NBIO > 0 */ 109 110 u_int32_t mfi_xscale_fw_state(struct mfi_softc *sc); 111 void mfi_xscale_intr_ena(struct mfi_softc *sc); 112 int mfi_xscale_intr(struct mfi_softc *sc); 113 void mfi_xscale_post(struct mfi_softc *sc, struct mfi_ccb *ccb); 114 115 static const struct mfi_iop_ops mfi_iop_xscale = { 116 mfi_xscale_fw_state, 117 mfi_xscale_intr_ena, 118 mfi_xscale_intr, 119 mfi_xscale_post 120 }; 121 122 u_int32_t mfi_ppc_fw_state(struct mfi_softc *sc); 123 void mfi_ppc_intr_ena(struct mfi_softc *sc); 124 int mfi_ppc_intr(struct mfi_softc *sc); 125 void mfi_ppc_post(struct mfi_softc *sc, struct mfi_ccb *ccb); 126 127 static const struct mfi_iop_ops mfi_iop_ppc = { 128 mfi_ppc_fw_state, 129 mfi_ppc_intr_ena, 130 mfi_ppc_intr, 131 mfi_ppc_post 132 }; 133 134 u_int32_t mfi_gen2_fw_state(struct mfi_softc *sc); 135 void mfi_gen2_intr_ena(struct mfi_softc *sc); 136 int mfi_gen2_intr(struct mfi_softc *sc); 137 void mfi_gen2_post(struct mfi_softc *sc, struct mfi_ccb *ccb); 138 139 static const struct mfi_iop_ops mfi_iop_gen2 = { 140 mfi_gen2_fw_state, 141 mfi_gen2_intr_ena, 142 mfi_gen2_intr, 143 mfi_gen2_post 144 }; 145 146 #define mfi_fw_state(_s) ((_s)->sc_iop->mio_fw_state(_s)) 147 #define mfi_intr_enable(_s) ((_s)->sc_iop->mio_intr_ena(_s)) 148 #define mfi_my_intr(_s) ((_s)->sc_iop->mio_intr(_s)) 149 #define mfi_post(_s, _c) ((_s)->sc_iop->mio_post((_s), (_c))) 150 151 struct mfi_ccb * 152 mfi_get_ccb(struct mfi_softc *sc) 153 { 154 struct mfi_ccb *ccb; 155 int s; 156 157 s = splbio(); 158 ccb = TAILQ_FIRST(&sc->sc_ccb_freeq); 159 if (ccb) { 160 TAILQ_REMOVE(&sc->sc_ccb_freeq, ccb, ccb_link); 161 ccb->ccb_state = MFI_CCB_READY; 162 } 163 splx(s); 164 165 DNPRINTF(MFI_D_CCB, "%s: mfi_get_ccb: %p\n", DEVNAME(sc), ccb); 166 167 return (ccb); 168 } 169 170 void 171 mfi_put_ccb(struct mfi_ccb *ccb) 172 { 173 struct mfi_softc *sc = ccb->ccb_sc; 174 struct mfi_frame_header *hdr = &ccb->ccb_frame->mfr_header; 175 int s; 176 177 DNPRINTF(MFI_D_CCB, "%s: mfi_put_ccb: %p\n", DEVNAME(sc), ccb); 178 179 hdr->mfh_cmd_status = 0x0; 180 hdr->mfh_flags = 0x0; 181 ccb->ccb_state = MFI_CCB_FREE; 182 ccb->ccb_xs = NULL; 183 ccb->ccb_flags = 0; 184 ccb->ccb_done = NULL; 185 ccb->ccb_direction = 0; 186 ccb->ccb_frame_size = 0; 187 ccb->ccb_extra_frames = 0; 188 ccb->ccb_sgl = NULL; 189 ccb->ccb_data = NULL; 190 ccb->ccb_len = 0; 191 192 s = splbio(); 193 TAILQ_INSERT_TAIL(&sc->sc_ccb_freeq, ccb, ccb_link); 194 splx(s); 195 } 196 197 int 198 mfi_init_ccb(struct mfi_softc *sc) 199 { 200 struct mfi_ccb *ccb; 201 uint32_t i; 202 int error; 203 204 DNPRINTF(MFI_D_CCB, "%s: mfi_init_ccb\n", DEVNAME(sc)); 205 206 sc->sc_ccb = malloc(sizeof(struct mfi_ccb) * sc->sc_max_cmds, 207 M_DEVBUF, M_WAITOK|M_ZERO); 208 209 for (i = 0; i < sc->sc_max_cmds; i++) { 210 ccb = &sc->sc_ccb[i]; 211 212 ccb->ccb_sc = sc; 213 214 /* select i'th frame */ 215 ccb->ccb_frame = (union mfi_frame *) 216 (MFIMEM_KVA(sc->sc_frames) + sc->sc_frames_size * i); 217 ccb->ccb_pframe = 218 MFIMEM_DVA(sc->sc_frames) + sc->sc_frames_size * i; 219 ccb->ccb_frame->mfr_header.mfh_context = i; 220 221 /* select i'th sense */ 222 ccb->ccb_sense = (struct mfi_sense *) 223 (MFIMEM_KVA(sc->sc_sense) + MFI_SENSE_SIZE * i); 224 ccb->ccb_psense = 225 (MFIMEM_DVA(sc->sc_sense) + MFI_SENSE_SIZE * i); 226 227 /* create a dma map for transfer */ 228 error = bus_dmamap_create(sc->sc_dmat, 229 MAXPHYS, sc->sc_max_sgl, MAXPHYS, 0, 230 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->ccb_dmamap); 231 if (error) { 232 printf("%s: cannot create ccb dmamap (%d)\n", 233 DEVNAME(sc), error); 234 goto destroy; 235 } 236 237 DNPRINTF(MFI_D_CCB, 238 "ccb(%d): %p frame: %#x (%#x) sense: %#x (%#x) map: %#x\n", 239 ccb->ccb_frame->mfr_header.mfh_context, ccb, 240 ccb->ccb_frame, ccb->ccb_pframe, 241 ccb->ccb_sense, ccb->ccb_psense, 242 ccb->ccb_dmamap); 243 244 /* add ccb to queue */ 245 mfi_put_ccb(ccb); 246 } 247 248 return (0); 249 destroy: 250 /* free dma maps and ccb memory */ 251 while (i) { 252 ccb = &sc->sc_ccb[i]; 253 bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap); 254 i--; 255 } 256 257 free(sc->sc_ccb, M_DEVBUF); 258 259 return (1); 260 } 261 262 uint32_t 263 mfi_read(struct mfi_softc *sc, bus_size_t r) 264 { 265 uint32_t rv; 266 267 bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4, 268 BUS_SPACE_BARRIER_READ); 269 rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, r); 270 271 DNPRINTF(MFI_D_RW, "%s: mr 0x%x 0x08%x ", DEVNAME(sc), r, rv); 272 return (rv); 273 } 274 275 void 276 mfi_write(struct mfi_softc *sc, bus_size_t r, uint32_t v) 277 { 278 DNPRINTF(MFI_D_RW, "%s: mw 0x%x 0x%08x", DEVNAME(sc), r, v); 279 280 bus_space_write_4(sc->sc_iot, sc->sc_ioh, r, v); 281 bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4, 282 BUS_SPACE_BARRIER_WRITE); 283 } 284 285 struct mfi_mem * 286 mfi_allocmem(struct mfi_softc *sc, size_t size) 287 { 288 struct mfi_mem *mm; 289 int nsegs; 290 291 DNPRINTF(MFI_D_MEM, "%s: mfi_allocmem: %d\n", DEVNAME(sc), 292 size); 293 294 mm = malloc(sizeof(struct mfi_mem), M_DEVBUF, M_NOWAIT|M_ZERO); 295 if (mm == NULL) 296 return (NULL); 297 298 mm->am_size = size; 299 300 if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, 301 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mm->am_map) != 0) 302 goto amfree; 303 304 if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &mm->am_seg, 1, 305 &nsegs, BUS_DMA_NOWAIT) != 0) 306 goto destroy; 307 308 if (bus_dmamem_map(sc->sc_dmat, &mm->am_seg, nsegs, size, &mm->am_kva, 309 BUS_DMA_NOWAIT) != 0) 310 goto free; 311 312 if (bus_dmamap_load(sc->sc_dmat, mm->am_map, mm->am_kva, size, NULL, 313 BUS_DMA_NOWAIT) != 0) 314 goto unmap; 315 316 DNPRINTF(MFI_D_MEM, " kva: %p dva: %p map: %p\n", 317 mm->am_kva, mm->am_map->dm_segs[0].ds_addr, mm->am_map); 318 319 memset(mm->am_kva, 0, size); 320 return (mm); 321 322 unmap: 323 bus_dmamem_unmap(sc->sc_dmat, mm->am_kva, size); 324 free: 325 bus_dmamem_free(sc->sc_dmat, &mm->am_seg, 1); 326 destroy: 327 bus_dmamap_destroy(sc->sc_dmat, mm->am_map); 328 amfree: 329 free(mm, M_DEVBUF); 330 331 return (NULL); 332 } 333 334 void 335 mfi_freemem(struct mfi_softc *sc, struct mfi_mem *mm) 336 { 337 DNPRINTF(MFI_D_MEM, "%s: mfi_freemem: %p\n", DEVNAME(sc), mm); 338 339 bus_dmamap_unload(sc->sc_dmat, mm->am_map); 340 bus_dmamem_unmap(sc->sc_dmat, mm->am_kva, mm->am_size); 341 bus_dmamem_free(sc->sc_dmat, &mm->am_seg, 1); 342 bus_dmamap_destroy(sc->sc_dmat, mm->am_map); 343 free(mm, M_DEVBUF); 344 } 345 346 int 347 mfi_transition_firmware(struct mfi_softc *sc) 348 { 349 int32_t fw_state, cur_state; 350 int max_wait, i; 351 352 fw_state = mfi_fw_state(sc) & MFI_STATE_MASK; 353 354 DNPRINTF(MFI_D_CMD, "%s: mfi_transition_firmware: %#x\n", DEVNAME(sc), 355 fw_state); 356 357 while (fw_state != MFI_STATE_READY) { 358 DNPRINTF(MFI_D_MISC, 359 "%s: waiting for firmware to become ready\n", 360 DEVNAME(sc)); 361 cur_state = fw_state; 362 switch (fw_state) { 363 case MFI_STATE_FAULT: 364 printf("%s: firmware fault\n", DEVNAME(sc)); 365 return (1); 366 case MFI_STATE_WAIT_HANDSHAKE: 367 mfi_write(sc, MFI_IDB, MFI_INIT_CLEAR_HANDSHAKE); 368 max_wait = 2; 369 break; 370 case MFI_STATE_OPERATIONAL: 371 mfi_write(sc, MFI_IDB, MFI_INIT_READY); 372 max_wait = 10; 373 break; 374 case MFI_STATE_UNDEFINED: 375 case MFI_STATE_BB_INIT: 376 max_wait = 2; 377 break; 378 case MFI_STATE_FW_INIT: 379 case MFI_STATE_DEVICE_SCAN: 380 case MFI_STATE_FLUSH_CACHE: 381 max_wait = 20; 382 break; 383 default: 384 printf("%s: unknown firmware state %d\n", 385 DEVNAME(sc), fw_state); 386 return (1); 387 } 388 for (i = 0; i < (max_wait * 10); i++) { 389 fw_state = mfi_fw_state(sc) & MFI_STATE_MASK; 390 if (fw_state == cur_state) 391 DELAY(100000); 392 else 393 break; 394 } 395 if (fw_state == cur_state) { 396 printf("%s: firmware stuck in state %#x\n", 397 DEVNAME(sc), fw_state); 398 return (1); 399 } 400 } 401 402 return (0); 403 } 404 405 int 406 mfi_initialize_firmware(struct mfi_softc *sc) 407 { 408 struct mfi_ccb *ccb; 409 struct mfi_init_frame *init; 410 struct mfi_init_qinfo *qinfo; 411 412 DNPRINTF(MFI_D_MISC, "%s: mfi_initialize_firmware\n", DEVNAME(sc)); 413 414 if ((ccb = mfi_get_ccb(sc)) == NULL) 415 return (1); 416 417 init = &ccb->ccb_frame->mfr_init; 418 qinfo = (struct mfi_init_qinfo *)((uint8_t *)init + MFI_FRAME_SIZE); 419 420 memset(qinfo, 0, sizeof *qinfo); 421 qinfo->miq_rq_entries = sc->sc_max_cmds + 1; 422 qinfo->miq_rq_addr_lo = htole32(MFIMEM_DVA(sc->sc_pcq) + 423 offsetof(struct mfi_prod_cons, mpc_reply_q)); 424 qinfo->miq_pi_addr_lo = htole32(MFIMEM_DVA(sc->sc_pcq) + 425 offsetof(struct mfi_prod_cons, mpc_producer)); 426 qinfo->miq_ci_addr_lo = htole32(MFIMEM_DVA(sc->sc_pcq) + 427 offsetof(struct mfi_prod_cons, mpc_consumer)); 428 429 init->mif_header.mfh_cmd = MFI_CMD_INIT; 430 init->mif_header.mfh_data_len = sizeof *qinfo; 431 init->mif_qinfo_new_addr_lo = htole32(ccb->ccb_pframe + MFI_FRAME_SIZE); 432 433 DNPRINTF(MFI_D_MISC, "%s: entries: %#x rq: %#x pi: %#x ci: %#x\n", 434 DEVNAME(sc), 435 qinfo->miq_rq_entries, qinfo->miq_rq_addr_lo, 436 qinfo->miq_pi_addr_lo, qinfo->miq_ci_addr_lo); 437 438 if (mfi_poll(ccb)) { 439 printf("%s: mfi_initialize_firmware failed\n", DEVNAME(sc)); 440 return (1); 441 } 442 443 mfi_put_ccb(ccb); 444 445 return (0); 446 } 447 448 int 449 mfi_get_info(struct mfi_softc *sc) 450 { 451 #ifdef MFI_DEBUG 452 int i; 453 #endif 454 DNPRINTF(MFI_D_MISC, "%s: mfi_get_info\n", DEVNAME(sc)); 455 456 if (mfi_mgmt(sc, MR_DCMD_CTRL_GET_INFO, MFI_DATA_IN, 457 sizeof(sc->sc_info), &sc->sc_info, NULL)) 458 return (1); 459 460 #ifdef MFI_DEBUG 461 for (i = 0; i < sc->sc_info.mci_image_component_count; i++) { 462 printf("%s: active FW %s Version %s date %s time %s\n", 463 DEVNAME(sc), 464 sc->sc_info.mci_image_component[i].mic_name, 465 sc->sc_info.mci_image_component[i].mic_version, 466 sc->sc_info.mci_image_component[i].mic_build_date, 467 sc->sc_info.mci_image_component[i].mic_build_time); 468 } 469 470 for (i = 0; i < sc->sc_info.mci_pending_image_component_count; i++) { 471 printf("%s: pending FW %s Version %s date %s time %s\n", 472 DEVNAME(sc), 473 sc->sc_info.mci_pending_image_component[i].mic_name, 474 sc->sc_info.mci_pending_image_component[i].mic_version, 475 sc->sc_info.mci_pending_image_component[i].mic_build_date, 476 sc->sc_info.mci_pending_image_component[i].mic_build_time); 477 } 478 479 printf("%s: max_arms %d max_spans %d max_arrs %d max_lds %d name %s\n", 480 DEVNAME(sc), 481 sc->sc_info.mci_max_arms, 482 sc->sc_info.mci_max_spans, 483 sc->sc_info.mci_max_arrays, 484 sc->sc_info.mci_max_lds, 485 sc->sc_info.mci_product_name); 486 487 printf("%s: serial %s present %#x fw time %d max_cmds %d max_sg %d\n", 488 DEVNAME(sc), 489 sc->sc_info.mci_serial_number, 490 sc->sc_info.mci_hw_present, 491 sc->sc_info.mci_current_fw_time, 492 sc->sc_info.mci_max_cmds, 493 sc->sc_info.mci_max_sg_elements); 494 495 printf("%s: max_rq %d lds_pres %d lds_deg %d lds_off %d pd_pres %d\n", 496 DEVNAME(sc), 497 sc->sc_info.mci_max_request_size, 498 sc->sc_info.mci_lds_present, 499 sc->sc_info.mci_lds_degraded, 500 sc->sc_info.mci_lds_offline, 501 sc->sc_info.mci_pd_present); 502 503 printf("%s: pd_dsk_prs %d pd_dsk_pred_fail %d pd_dsk_fail %d\n", 504 DEVNAME(sc), 505 sc->sc_info.mci_pd_disks_present, 506 sc->sc_info.mci_pd_disks_pred_failure, 507 sc->sc_info.mci_pd_disks_failed); 508 509 printf("%s: nvram %d mem %d flash %d\n", 510 DEVNAME(sc), 511 sc->sc_info.mci_nvram_size, 512 sc->sc_info.mci_memory_size, 513 sc->sc_info.mci_flash_size); 514 515 printf("%s: ram_cor %d ram_uncor %d clus_all %d clus_act %d\n", 516 DEVNAME(sc), 517 sc->sc_info.mci_ram_correctable_errors, 518 sc->sc_info.mci_ram_uncorrectable_errors, 519 sc->sc_info.mci_cluster_allowed, 520 sc->sc_info.mci_cluster_active); 521 522 printf("%s: max_strps_io %d raid_lvl %#x adapt_ops %#x ld_ops %#x\n", 523 DEVNAME(sc), 524 sc->sc_info.mci_max_strips_per_io, 525 sc->sc_info.mci_raid_levels, 526 sc->sc_info.mci_adapter_ops, 527 sc->sc_info.mci_ld_ops); 528 529 printf("%s: strp_sz_min %d strp_sz_max %d pd_ops %#x pd_mix %#x\n", 530 DEVNAME(sc), 531 sc->sc_info.mci_stripe_sz_ops.min, 532 sc->sc_info.mci_stripe_sz_ops.max, 533 sc->sc_info.mci_pd_ops, 534 sc->sc_info.mci_pd_mix_support); 535 536 printf("%s: ecc_bucket %d pckg_prop %s\n", 537 DEVNAME(sc), 538 sc->sc_info.mci_ecc_bucket_count, 539 sc->sc_info.mci_package_version); 540 541 printf("%s: sq_nm %d prd_fail_poll %d intr_thrtl %d intr_thrtl_to %d\n", 542 DEVNAME(sc), 543 sc->sc_info.mci_properties.mcp_seq_num, 544 sc->sc_info.mci_properties.mcp_pred_fail_poll_interval, 545 sc->sc_info.mci_properties.mcp_intr_throttle_cnt, 546 sc->sc_info.mci_properties.mcp_intr_throttle_timeout); 547 548 printf("%s: rbld_rate %d patr_rd_rate %d bgi_rate %d cc_rate %d\n", 549 DEVNAME(sc), 550 sc->sc_info.mci_properties.mcp_rebuild_rate, 551 sc->sc_info.mci_properties.mcp_patrol_read_rate, 552 sc->sc_info.mci_properties.mcp_bgi_rate, 553 sc->sc_info.mci_properties.mcp_cc_rate); 554 555 printf("%s: rc_rate %d ch_flsh %d spin_cnt %d spin_dly %d clus_en %d\n", 556 DEVNAME(sc), 557 sc->sc_info.mci_properties.mcp_recon_rate, 558 sc->sc_info.mci_properties.mcp_cache_flush_interval, 559 sc->sc_info.mci_properties.mcp_spinup_drv_cnt, 560 sc->sc_info.mci_properties.mcp_spinup_delay, 561 sc->sc_info.mci_properties.mcp_cluster_enable); 562 563 printf("%s: coerc %d alarm %d dis_auto_rbld %d dis_bat_wrn %d ecc %d\n", 564 DEVNAME(sc), 565 sc->sc_info.mci_properties.mcp_coercion_mode, 566 sc->sc_info.mci_properties.mcp_alarm_enable, 567 sc->sc_info.mci_properties.mcp_disable_auto_rebuild, 568 sc->sc_info.mci_properties.mcp_disable_battery_warn, 569 sc->sc_info.mci_properties.mcp_ecc_bucket_size); 570 571 printf("%s: ecc_leak %d rest_hs %d exp_encl_dev %d\n", 572 DEVNAME(sc), 573 sc->sc_info.mci_properties.mcp_ecc_bucket_leak_rate, 574 sc->sc_info.mci_properties.mcp_restore_hotspare_on_insertion, 575 sc->sc_info.mci_properties.mcp_expose_encl_devices); 576 577 printf("%s: vendor %#x device %#x subvendor %#x subdevice %#x\n", 578 DEVNAME(sc), 579 sc->sc_info.mci_pci.mip_vendor, 580 sc->sc_info.mci_pci.mip_device, 581 sc->sc_info.mci_pci.mip_subvendor, 582 sc->sc_info.mci_pci.mip_subdevice); 583 584 printf("%s: type %#x port_count %d port_addr ", 585 DEVNAME(sc), 586 sc->sc_info.mci_host.mih_type, 587 sc->sc_info.mci_host.mih_port_count); 588 589 for (i = 0; i < 8; i++) 590 printf("%.0llx ", sc->sc_info.mci_host.mih_port_addr[i]); 591 printf("\n"); 592 593 printf("%s: type %.x port_count %d port_addr ", 594 DEVNAME(sc), 595 sc->sc_info.mci_device.mid_type, 596 sc->sc_info.mci_device.mid_port_count); 597 598 for (i = 0; i < 8; i++) 599 printf("%.0llx ", sc->sc_info.mci_device.mid_port_addr[i]); 600 printf("\n"); 601 #endif /* MFI_DEBUG */ 602 603 return (0); 604 } 605 606 void 607 mfiminphys(struct buf *bp, struct scsi_link *sl) 608 { 609 DNPRINTF(MFI_D_MISC, "mfiminphys: %d\n", bp->b_bcount); 610 611 /* XXX currently using MFI_MAXFER = MAXPHYS */ 612 if (bp->b_bcount > MFI_MAXFER) 613 bp->b_bcount = MFI_MAXFER; 614 minphys(bp); 615 } 616 617 int 618 mfi_attach(struct mfi_softc *sc, enum mfi_iop iop) 619 { 620 struct scsibus_attach_args saa; 621 uint32_t status, frames; 622 int i; 623 624 switch (iop) { 625 case MFI_IOP_XSCALE: 626 sc->sc_iop = &mfi_iop_xscale; 627 break; 628 case MFI_IOP_PPC: 629 sc->sc_iop = &mfi_iop_ppc; 630 break; 631 case MFI_IOP_GEN2: 632 sc->sc_iop = &mfi_iop_gen2; 633 break; 634 default: 635 panic("%s: unknown iop %d", DEVNAME(sc), iop); 636 } 637 638 DNPRINTF(MFI_D_MISC, "%s: mfi_attach\n", DEVNAME(sc)); 639 640 if (mfi_transition_firmware(sc)) 641 return (1); 642 643 TAILQ_INIT(&sc->sc_ccb_freeq); 644 645 rw_init(&sc->sc_lock, "mfi_lock"); 646 647 status = mfi_fw_state(sc); 648 sc->sc_max_cmds = status & MFI_STATE_MAXCMD_MASK; 649 sc->sc_max_sgl = (status & MFI_STATE_MAXSGL_MASK) >> 16; 650 DNPRINTF(MFI_D_MISC, "%s: max commands: %u, max sgl: %u\n", 651 DEVNAME(sc), sc->sc_max_cmds, sc->sc_max_sgl); 652 653 /* consumer/producer and reply queue memory */ 654 sc->sc_pcq = mfi_allocmem(sc, (sizeof(uint32_t) * sc->sc_max_cmds) + 655 sizeof(struct mfi_prod_cons)); 656 if (sc->sc_pcq == NULL) { 657 printf("%s: unable to allocate reply queue memory\n", 658 DEVNAME(sc)); 659 goto nopcq; 660 } 661 662 /* frame memory */ 663 /* we are not doing 64 bit IO so only calculate # of 32 bit frames */ 664 frames = (sizeof(struct mfi_sg32) * sc->sc_max_sgl + 665 MFI_FRAME_SIZE - 1) / MFI_FRAME_SIZE + 1; 666 sc->sc_frames_size = frames * MFI_FRAME_SIZE; 667 sc->sc_frames = mfi_allocmem(sc, sc->sc_frames_size * sc->sc_max_cmds); 668 if (sc->sc_frames == NULL) { 669 printf("%s: unable to allocate frame memory\n", DEVNAME(sc)); 670 goto noframe; 671 } 672 /* XXX hack, fix this */ 673 if (MFIMEM_DVA(sc->sc_frames) & 0x3f) { 674 printf("%s: improper frame alignment (%#x) FIXME\n", 675 DEVNAME(sc), MFIMEM_DVA(sc->sc_frames)); 676 goto noframe; 677 } 678 679 /* sense memory */ 680 sc->sc_sense = mfi_allocmem(sc, sc->sc_max_cmds * MFI_SENSE_SIZE); 681 if (sc->sc_sense == NULL) { 682 printf("%s: unable to allocate sense memory\n", DEVNAME(sc)); 683 goto nosense; 684 } 685 686 /* now that we have all memory bits go initialize ccbs */ 687 if (mfi_init_ccb(sc)) { 688 printf("%s: could not init ccb list\n", DEVNAME(sc)); 689 goto noinit; 690 } 691 692 /* kickstart firmware with all addresses and pointers */ 693 if (mfi_initialize_firmware(sc)) { 694 printf("%s: could not initialize firmware\n", DEVNAME(sc)); 695 goto noinit; 696 } 697 698 if (mfi_get_info(sc)) { 699 printf("%s: could not retrieve controller information\n", 700 DEVNAME(sc)); 701 goto noinit; 702 } 703 704 printf("%s: logical drives %d, version %s, %dMB RAM\n", 705 DEVNAME(sc), 706 sc->sc_info.mci_lds_present, 707 sc->sc_info.mci_package_version, 708 sc->sc_info.mci_memory_size); 709 710 sc->sc_ld_cnt = sc->sc_info.mci_lds_present; 711 sc->sc_max_ld = sc->sc_ld_cnt; 712 for (i = 0; i < sc->sc_ld_cnt; i++) 713 sc->sc_ld[i].ld_present = 1; 714 715 if (sc->sc_ld_cnt) 716 sc->sc_link.openings = sc->sc_max_cmds / sc->sc_ld_cnt; 717 else 718 sc->sc_link.openings = sc->sc_max_cmds; 719 720 sc->sc_link.device = &mfi_dev; 721 sc->sc_link.adapter_softc = sc; 722 sc->sc_link.adapter = &mfi_switch; 723 sc->sc_link.adapter_target = MFI_MAX_LD; 724 sc->sc_link.adapter_buswidth = sc->sc_max_ld; 725 726 bzero(&saa, sizeof(saa)); 727 saa.saa_sc_link = &sc->sc_link; 728 729 config_found(&sc->sc_dev, &saa, scsiprint); 730 731 /* enable interrupts */ 732 mfi_intr_enable(sc); 733 734 #if NBIO > 0 735 if (bio_register(&sc->sc_dev, mfi_ioctl) != 0) 736 panic("%s: controller registration failed", DEVNAME(sc)); 737 else 738 sc->sc_ioctl = mfi_ioctl; 739 740 #ifndef SMALL_KERNEL 741 if (mfi_create_sensors(sc) != 0) 742 printf("%s: unable to create sensors\n", DEVNAME(sc)); 743 #endif 744 #endif /* NBIO > 0 */ 745 746 return (0); 747 noinit: 748 mfi_freemem(sc, sc->sc_sense); 749 nosense: 750 mfi_freemem(sc, sc->sc_frames); 751 noframe: 752 mfi_freemem(sc, sc->sc_pcq); 753 nopcq: 754 return (1); 755 } 756 757 int 758 mfi_poll(struct mfi_ccb *ccb) 759 { 760 struct mfi_softc *sc = ccb->ccb_sc; 761 struct mfi_frame_header *hdr; 762 int to = 0, rv = 0; 763 764 DNPRINTF(MFI_D_CMD, "%s: mfi_poll\n", DEVNAME(sc)); 765 766 hdr = &ccb->ccb_frame->mfr_header; 767 hdr->mfh_cmd_status = 0xff; 768 hdr->mfh_flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE; 769 770 mfi_post(sc, ccb); 771 772 while (hdr->mfh_cmd_status == 0xff) { 773 delay(1000); 774 if (to++ > 5000) /* XXX 5 seconds busywait sucks */ 775 break; 776 } 777 if (hdr->mfh_cmd_status == 0xff) { 778 printf("%s: timeout on ccb %d\n", DEVNAME(sc), 779 hdr->mfh_context); 780 ccb->ccb_flags |= MFI_CCB_F_ERR; 781 rv = 1; 782 } 783 784 if (ccb->ccb_direction != MFI_DATA_NONE) { 785 bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap, 0, 786 ccb->ccb_dmamap->dm_mapsize, 787 (ccb->ccb_direction & MFI_DATA_IN) ? 788 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 789 790 bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap); 791 } 792 793 return (rv); 794 } 795 796 int 797 mfi_intr(void *arg) 798 { 799 struct mfi_softc *sc = arg; 800 struct mfi_prod_cons *pcq; 801 struct mfi_ccb *ccb; 802 uint32_t producer, consumer, ctx; 803 int claimed = 0; 804 805 if (!mfi_my_intr(sc)) 806 return (0); 807 808 pcq = MFIMEM_KVA(sc->sc_pcq); 809 producer = pcq->mpc_producer; 810 consumer = pcq->mpc_consumer; 811 812 DNPRINTF(MFI_D_INTR, "%s: mfi_intr %#x %#x\n", DEVNAME(sc), sc, pcq); 813 814 while (consumer != producer) { 815 DNPRINTF(MFI_D_INTR, "%s: mfi_intr pi %#x ci %#x\n", 816 DEVNAME(sc), producer, consumer); 817 818 ctx = pcq->mpc_reply_q[consumer]; 819 pcq->mpc_reply_q[consumer] = MFI_INVALID_CTX; 820 if (ctx == MFI_INVALID_CTX) 821 printf("%s: invalid context, p: %d c: %d\n", 822 DEVNAME(sc), producer, consumer); 823 else { 824 /* XXX remove from queue and call scsi_done */ 825 ccb = &sc->sc_ccb[ctx]; 826 DNPRINTF(MFI_D_INTR, "%s: mfi_intr context %#x\n", 827 DEVNAME(sc), ctx); 828 ccb->ccb_done(ccb); 829 830 claimed = 1; 831 } 832 consumer++; 833 if (consumer == (sc->sc_max_cmds + 1)) 834 consumer = 0; 835 } 836 837 pcq->mpc_consumer = consumer; 838 839 return (claimed); 840 } 841 842 int 843 mfi_scsi_io(struct mfi_ccb *ccb, struct scsi_xfer *xs, uint32_t blockno, 844 uint32_t blockcnt) 845 { 846 struct scsi_link *link = xs->sc_link; 847 struct mfi_io_frame *io; 848 849 DNPRINTF(MFI_D_CMD, "%s: mfi_scsi_io: %d\n", 850 DEVNAME((struct mfi_softc *)link->adapter_softc), link->target); 851 852 if (!xs->data) 853 return (1); 854 855 io = &ccb->ccb_frame->mfr_io; 856 if (xs->flags & SCSI_DATA_IN) { 857 io->mif_header.mfh_cmd = MFI_CMD_LD_READ; 858 ccb->ccb_direction = MFI_DATA_IN; 859 } else { 860 io->mif_header.mfh_cmd = MFI_CMD_LD_WRITE; 861 ccb->ccb_direction = MFI_DATA_OUT; 862 } 863 io->mif_header.mfh_target_id = link->target; 864 io->mif_header.mfh_timeout = 0; 865 io->mif_header.mfh_flags = 0; 866 io->mif_header.mfh_sense_len = MFI_SENSE_SIZE; 867 io->mif_header.mfh_data_len= blockcnt; 868 io->mif_lba_hi = 0; 869 io->mif_lba_lo = blockno; 870 io->mif_sense_addr_lo = htole32(ccb->ccb_psense); 871 io->mif_sense_addr_hi = 0; 872 873 ccb->ccb_done = mfi_scsi_xs_done; 874 ccb->ccb_xs = xs; 875 ccb->ccb_frame_size = MFI_IO_FRAME_SIZE; 876 ccb->ccb_sgl = &io->mif_sgl; 877 ccb->ccb_data = xs->data; 878 ccb->ccb_len = xs->datalen; 879 880 if (mfi_create_sgl(ccb, (xs->flags & SCSI_NOSLEEP) ? 881 BUS_DMA_NOWAIT : BUS_DMA_WAITOK)) 882 return (1); 883 884 return (0); 885 } 886 887 void 888 mfi_scsi_xs_done(struct mfi_ccb *ccb) 889 { 890 struct scsi_xfer *xs = ccb->ccb_xs; 891 struct mfi_softc *sc = ccb->ccb_sc; 892 struct mfi_frame_header *hdr = &ccb->ccb_frame->mfr_header; 893 894 DNPRINTF(MFI_D_INTR, "%s: mfi_scsi_xs_done %#x %#x\n", 895 DEVNAME(sc), ccb, ccb->ccb_frame); 896 897 if (xs->data != NULL) { 898 DNPRINTF(MFI_D_INTR, "%s: mfi_scsi_xs_done sync\n", 899 DEVNAME(sc)); 900 bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap, 0, 901 ccb->ccb_dmamap->dm_mapsize, 902 (xs->flags & SCSI_DATA_IN) ? 903 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 904 905 bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap); 906 } 907 908 if (hdr->mfh_cmd_status != MFI_STAT_OK) { 909 xs->error = XS_DRIVER_STUFFUP; 910 DNPRINTF(MFI_D_INTR, "%s: mfi_scsi_xs_done stuffup %#x\n", 911 DEVNAME(sc), hdr->mfh_cmd_status); 912 913 if (hdr->mfh_scsi_status != 0) { 914 DNPRINTF(MFI_D_INTR, 915 "%s: mfi_scsi_xs_done sense %#x %x %x\n", 916 DEVNAME(sc), hdr->mfh_scsi_status, 917 &xs->sense, ccb->ccb_sense); 918 memset(&xs->sense, 0, sizeof(xs->sense)); 919 memcpy(&xs->sense, ccb->ccb_sense, 920 sizeof(struct scsi_sense_data)); 921 xs->error = XS_SENSE; 922 } 923 } 924 925 xs->resid = 0; 926 xs->flags |= ITSDONE; 927 928 mfi_put_ccb(ccb); 929 scsi_done(xs); 930 } 931 932 int 933 mfi_scsi_ld(struct mfi_ccb *ccb, struct scsi_xfer *xs) 934 { 935 struct scsi_link *link = xs->sc_link; 936 struct mfi_pass_frame *pf; 937 938 DNPRINTF(MFI_D_CMD, "%s: mfi_scsi_ld: %d\n", 939 DEVNAME((struct mfi_softc *)link->adapter_softc), link->target); 940 941 pf = &ccb->ccb_frame->mfr_pass; 942 pf->mpf_header.mfh_cmd = MFI_CMD_LD_SCSI_IO; 943 pf->mpf_header.mfh_target_id = link->target; 944 pf->mpf_header.mfh_lun_id = 0; 945 pf->mpf_header.mfh_cdb_len = xs->cmdlen; 946 pf->mpf_header.mfh_timeout = 0; 947 pf->mpf_header.mfh_data_len= xs->datalen; /* XXX */ 948 pf->mpf_header.mfh_sense_len = MFI_SENSE_SIZE; 949 950 pf->mpf_sense_addr_hi = 0; 951 pf->mpf_sense_addr_lo = htole32(ccb->ccb_psense); 952 953 memset(pf->mpf_cdb, 0, 16); 954 memcpy(pf->mpf_cdb, &xs->cmdstore, xs->cmdlen); 955 956 ccb->ccb_done = mfi_scsi_xs_done; 957 ccb->ccb_xs = xs; 958 ccb->ccb_frame_size = MFI_PASS_FRAME_SIZE; 959 ccb->ccb_sgl = &pf->mpf_sgl; 960 961 if (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) 962 ccb->ccb_direction = xs->flags & SCSI_DATA_IN ? 963 MFI_DATA_IN : MFI_DATA_OUT; 964 else 965 ccb->ccb_direction = MFI_DATA_NONE; 966 967 if (xs->data) { 968 ccb->ccb_data = xs->data; 969 ccb->ccb_len = xs->datalen; 970 971 if (mfi_create_sgl(ccb, (xs->flags & SCSI_NOSLEEP) ? 972 BUS_DMA_NOWAIT : BUS_DMA_WAITOK)) 973 return (1); 974 } 975 976 return (0); 977 } 978 979 int 980 mfi_scsi_cmd(struct scsi_xfer *xs) 981 { 982 struct scsi_link *link = xs->sc_link; 983 struct mfi_softc *sc = link->adapter_softc; 984 struct device *dev = link->device_softc; 985 struct mfi_ccb *ccb; 986 struct scsi_rw *rw; 987 struct scsi_rw_big *rwb; 988 uint32_t blockno, blockcnt; 989 uint8_t target = link->target; 990 uint8_t mbox[MFI_MBOX_SIZE]; 991 int s; 992 993 DNPRINTF(MFI_D_CMD, "%s: mfi_scsi_cmd opcode: %#x\n", 994 DEVNAME(sc), xs->cmd->opcode); 995 996 if (target >= MFI_MAX_LD || !sc->sc_ld[target].ld_present || 997 link->lun != 0) { 998 DNPRINTF(MFI_D_CMD, "%s: invalid target %d\n", 999 DEVNAME(sc), target); 1000 goto stuffup; 1001 } 1002 1003 if ((ccb = mfi_get_ccb(sc)) == NULL) { 1004 DNPRINTF(MFI_D_CMD, "%s: mfi_scsi_cmd no ccb\n", DEVNAME(sc)); 1005 return (NO_CCB); 1006 } 1007 1008 xs->error = XS_NOERROR; 1009 1010 switch (xs->cmd->opcode) { 1011 /* IO path */ 1012 case READ_BIG: 1013 case WRITE_BIG: 1014 rwb = (struct scsi_rw_big *)xs->cmd; 1015 blockno = _4btol(rwb->addr); 1016 blockcnt = _2btol(rwb->length); 1017 if (mfi_scsi_io(ccb, xs, blockno, blockcnt)) { 1018 mfi_put_ccb(ccb); 1019 goto stuffup; 1020 } 1021 break; 1022 1023 case READ_COMMAND: 1024 case WRITE_COMMAND: 1025 rw = (struct scsi_rw *)xs->cmd; 1026 blockno = _3btol(rw->addr) & (SRW_TOPADDR << 16 | 0xffff); 1027 blockcnt = rw->length ? rw->length : 0x100; 1028 if (mfi_scsi_io(ccb, xs, blockno, blockcnt)) { 1029 mfi_put_ccb(ccb); 1030 goto stuffup; 1031 } 1032 break; 1033 1034 case SYNCHRONIZE_CACHE: 1035 mfi_put_ccb(ccb); /* we don't need this */ 1036 1037 mbox[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE; 1038 if (mfi_mgmt(sc, MR_DCMD_CTRL_CACHE_FLUSH, MFI_DATA_NONE, 1039 0, NULL, mbox)) 1040 goto stuffup; 1041 1042 goto complete; 1043 /* NOTREACHED */ 1044 1045 /* hand it of to the firmware and let it deal with it */ 1046 case TEST_UNIT_READY: 1047 /* save off sd? after autoconf */ 1048 if (!cold) /* XXX bogus */ 1049 strlcpy(sc->sc_ld[target].ld_dev, dev->dv_xname, 1050 sizeof(sc->sc_ld[target].ld_dev)); 1051 /* FALLTHROUGH */ 1052 1053 default: 1054 if (mfi_scsi_ld(ccb, xs)) { 1055 mfi_put_ccb(ccb); 1056 goto stuffup; 1057 } 1058 break; 1059 } 1060 1061 DNPRINTF(MFI_D_CMD, "%s: start io %d\n", DEVNAME(sc), target); 1062 1063 if (xs->flags & SCSI_POLL) { 1064 if (mfi_poll(ccb)) { 1065 /* XXX check for sense in ccb->ccb_sense? */ 1066 printf("%s: mfi_scsi_cmd poll failed\n", 1067 DEVNAME(sc)); 1068 bzero(&xs->sense, sizeof(xs->sense)); 1069 xs->sense.error_code = SSD_ERRCODE_VALID | 0x70; 1070 xs->sense.flags = SKEY_ILLEGAL_REQUEST; 1071 xs->sense.add_sense_code = 0x20; /* invalid opcode */ 1072 xs->error = XS_SENSE; 1073 } 1074 1075 mfi_put_ccb(ccb); 1076 xs->flags |= ITSDONE; 1077 s = splbio(); 1078 scsi_done(xs); 1079 splx(s); 1080 return (COMPLETE); 1081 } 1082 1083 mfi_post(sc, ccb); 1084 1085 DNPRINTF(MFI_D_DMA, "%s: mfi_scsi_cmd queued %d\n", DEVNAME(sc), 1086 ccb->ccb_dmamap->dm_nsegs); 1087 1088 return (SUCCESSFULLY_QUEUED); 1089 1090 stuffup: 1091 xs->error = XS_DRIVER_STUFFUP; 1092 complete: 1093 xs->flags |= ITSDONE; 1094 s = splbio(); 1095 scsi_done(xs); 1096 splx(s); 1097 return (COMPLETE); 1098 } 1099 1100 int 1101 mfi_create_sgl(struct mfi_ccb *ccb, int flags) 1102 { 1103 struct mfi_softc *sc = ccb->ccb_sc; 1104 struct mfi_frame_header *hdr; 1105 bus_dma_segment_t *sgd; 1106 union mfi_sgl *sgl; 1107 int error, i; 1108 1109 DNPRINTF(MFI_D_DMA, "%s: mfi_create_sgl %#x\n", DEVNAME(sc), 1110 ccb->ccb_data); 1111 1112 if (!ccb->ccb_data) 1113 return (1); 1114 1115 error = bus_dmamap_load(sc->sc_dmat, ccb->ccb_dmamap, 1116 ccb->ccb_data, ccb->ccb_len, NULL, flags); 1117 if (error) { 1118 if (error == EFBIG) 1119 printf("more than %d dma segs\n", 1120 sc->sc_max_sgl); 1121 else 1122 printf("error %d loading dma map\n", error); 1123 return (1); 1124 } 1125 1126 hdr = &ccb->ccb_frame->mfr_header; 1127 sgl = ccb->ccb_sgl; 1128 sgd = ccb->ccb_dmamap->dm_segs; 1129 for (i = 0; i < ccb->ccb_dmamap->dm_nsegs; i++) { 1130 sgl->sg32[i].addr = htole32(sgd[i].ds_addr); 1131 sgl->sg32[i].len = htole32(sgd[i].ds_len); 1132 DNPRINTF(MFI_D_DMA, "%s: addr: %#x len: %#x\n", 1133 DEVNAME(sc), sgl->sg32[i].addr, sgl->sg32[i].len); 1134 } 1135 1136 if (ccb->ccb_direction == MFI_DATA_IN) { 1137 hdr->mfh_flags |= MFI_FRAME_DIR_READ; 1138 bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap, 0, 1139 ccb->ccb_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD); 1140 } else { 1141 hdr->mfh_flags |= MFI_FRAME_DIR_WRITE; 1142 bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap, 0, 1143 ccb->ccb_dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE); 1144 } 1145 1146 hdr->mfh_sg_count = ccb->ccb_dmamap->dm_nsegs; 1147 /* for 64 bit io make the sizeof a variable to hold whatever sg size */ 1148 ccb->ccb_frame_size += sizeof(struct mfi_sg32) * 1149 ccb->ccb_dmamap->dm_nsegs; 1150 ccb->ccb_extra_frames = (ccb->ccb_frame_size - 1) / MFI_FRAME_SIZE; 1151 1152 DNPRINTF(MFI_D_DMA, "%s: sg_count: %d frame_size: %d frames_size: %d" 1153 " dm_nsegs: %d extra_frames: %d\n", 1154 DEVNAME(sc), 1155 hdr->mfh_sg_count, 1156 ccb->ccb_frame_size, 1157 sc->sc_frames_size, 1158 ccb->ccb_dmamap->dm_nsegs, 1159 ccb->ccb_extra_frames); 1160 1161 return (0); 1162 } 1163 1164 int 1165 mfi_mgmt(struct mfi_softc *sc, uint32_t opc, uint32_t dir, uint32_t len, 1166 void *buf, uint8_t *mbox) 1167 { 1168 struct mfi_ccb *ccb; 1169 struct mfi_dcmd_frame *dcmd; 1170 int rv = 1; 1171 int s; 1172 1173 DNPRINTF(MFI_D_MISC, "%s: mfi_mgmt %#x\n", DEVNAME(sc), opc); 1174 1175 if ((ccb = mfi_get_ccb(sc)) == NULL) 1176 return (rv); 1177 1178 dcmd = &ccb->ccb_frame->mfr_dcmd; 1179 memset(dcmd->mdf_mbox, 0, MFI_MBOX_SIZE); 1180 dcmd->mdf_header.mfh_cmd = MFI_CMD_DCMD; 1181 dcmd->mdf_header.mfh_timeout = 0; 1182 1183 dcmd->mdf_opcode = opc; 1184 dcmd->mdf_header.mfh_data_len = 0; 1185 ccb->ccb_direction = dir; 1186 ccb->ccb_done = mfi_mgmt_done; 1187 1188 ccb->ccb_frame_size = MFI_DCMD_FRAME_SIZE; 1189 1190 /* handle special opcodes */ 1191 if (mbox) 1192 memcpy(dcmd->mdf_mbox, mbox, MFI_MBOX_SIZE); 1193 1194 if (dir != MFI_DATA_NONE) { 1195 dcmd->mdf_header.mfh_data_len = len; 1196 ccb->ccb_data = buf; 1197 ccb->ccb_len = len; 1198 ccb->ccb_sgl = &dcmd->mdf_sgl; 1199 1200 if (mfi_create_sgl(ccb, BUS_DMA_WAITOK)) 1201 goto done; 1202 } 1203 1204 if (cold) { 1205 if (mfi_poll(ccb)) 1206 goto done; 1207 } else { 1208 s = splbio(); 1209 mfi_post(sc, ccb); 1210 1211 DNPRINTF(MFI_D_MISC, "%s: mfi_mgmt sleeping\n", DEVNAME(sc)); 1212 while (ccb->ccb_state != MFI_CCB_DONE) 1213 tsleep(ccb, PRIBIO, "mfi_mgmt", 0); 1214 splx(s); 1215 1216 if (ccb->ccb_flags & MFI_CCB_F_ERR) 1217 goto done; 1218 } 1219 1220 rv = 0; 1221 1222 done: 1223 mfi_put_ccb(ccb); 1224 return (rv); 1225 } 1226 1227 void 1228 mfi_mgmt_done(struct mfi_ccb *ccb) 1229 { 1230 struct mfi_softc *sc = ccb->ccb_sc; 1231 struct mfi_frame_header *hdr = &ccb->ccb_frame->mfr_header; 1232 1233 DNPRINTF(MFI_D_INTR, "%s: mfi_mgmt_done %#x %#x\n", 1234 DEVNAME(sc), ccb, ccb->ccb_frame); 1235 1236 if (ccb->ccb_data != NULL) { 1237 DNPRINTF(MFI_D_INTR, "%s: mfi_mgmt_done sync\n", 1238 DEVNAME(sc)); 1239 bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap, 0, 1240 ccb->ccb_dmamap->dm_mapsize, 1241 (ccb->ccb_direction & MFI_DATA_IN) ? 1242 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 1243 1244 bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap); 1245 } 1246 1247 if (hdr->mfh_cmd_status != MFI_STAT_OK) 1248 ccb->ccb_flags |= MFI_CCB_F_ERR; 1249 1250 ccb->ccb_state = MFI_CCB_DONE; 1251 1252 wakeup(ccb); 1253 } 1254 1255 int 1256 mfi_scsi_ioctl(struct scsi_link *link, u_long cmd, caddr_t addr, int flag, 1257 struct proc *p) 1258 { 1259 struct mfi_softc *sc = (struct mfi_softc *)link->adapter_softc; 1260 1261 DNPRINTF(MFI_D_IOCTL, "%s: mfi_scsi_ioctl\n", DEVNAME(sc)); 1262 1263 if (sc->sc_ioctl) 1264 return (sc->sc_ioctl(link->adapter_softc, cmd, addr)); 1265 else 1266 return (ENOTTY); 1267 } 1268 1269 #if NBIO > 0 1270 int 1271 mfi_ioctl(struct device *dev, u_long cmd, caddr_t addr) 1272 { 1273 struct mfi_softc *sc = (struct mfi_softc *)dev; 1274 int error = 0; 1275 1276 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl ", DEVNAME(sc)); 1277 1278 rw_enter_write(&sc->sc_lock); 1279 1280 switch (cmd) { 1281 case BIOCINQ: 1282 DNPRINTF(MFI_D_IOCTL, "inq\n"); 1283 error = mfi_ioctl_inq(sc, (struct bioc_inq *)addr); 1284 break; 1285 1286 case BIOCVOL: 1287 DNPRINTF(MFI_D_IOCTL, "vol\n"); 1288 error = mfi_ioctl_vol(sc, (struct bioc_vol *)addr); 1289 break; 1290 1291 case BIOCDISK: 1292 DNPRINTF(MFI_D_IOCTL, "disk\n"); 1293 error = mfi_ioctl_disk(sc, (struct bioc_disk *)addr); 1294 break; 1295 1296 case BIOCALARM: 1297 DNPRINTF(MFI_D_IOCTL, "alarm\n"); 1298 error = mfi_ioctl_alarm(sc, (struct bioc_alarm *)addr); 1299 break; 1300 1301 case BIOCBLINK: 1302 DNPRINTF(MFI_D_IOCTL, "blink\n"); 1303 error = mfi_ioctl_blink(sc, (struct bioc_blink *)addr); 1304 break; 1305 1306 case BIOCSETSTATE: 1307 DNPRINTF(MFI_D_IOCTL, "setstate\n"); 1308 error = mfi_ioctl_setstate(sc, (struct bioc_setstate *)addr); 1309 break; 1310 1311 default: 1312 DNPRINTF(MFI_D_IOCTL, " invalid ioctl\n"); 1313 error = EINVAL; 1314 } 1315 1316 rw_exit_write(&sc->sc_lock); 1317 1318 return (error); 1319 } 1320 1321 int 1322 mfi_bio_getitall(struct mfi_softc *sc) 1323 { 1324 int i, d, size, rv = EINVAL; 1325 uint8_t mbox[MFI_MBOX_SIZE]; 1326 struct mfi_conf *cfg = NULL; 1327 struct mfi_ld_details *ld_det = NULL; 1328 1329 /* get info */ 1330 if (mfi_get_info(sc)) { 1331 DNPRINTF(MFI_D_IOCTL, "%s: mfi_get_info failed\n", 1332 DEVNAME(sc)); 1333 goto done; 1334 } 1335 1336 /* send single element command to retrieve size for full structure */ 1337 cfg = malloc(sizeof *cfg, M_DEVBUF, M_NOWAIT | M_ZERO); 1338 if (cfg == NULL) 1339 goto done; 1340 if (mfi_mgmt(sc, MD_DCMD_CONF_GET, MFI_DATA_IN, sizeof *cfg, cfg, NULL)) 1341 goto done; 1342 1343 size = cfg->mfc_size; 1344 free(cfg, M_DEVBUF); 1345 1346 /* memory for read config */ 1347 cfg = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO); 1348 if (cfg == NULL) 1349 goto done; 1350 if (mfi_mgmt(sc, MD_DCMD_CONF_GET, MFI_DATA_IN, size, cfg, NULL)) 1351 goto done; 1352 1353 /* replace current pointer with enw one */ 1354 if (sc->sc_cfg) 1355 free(sc->sc_cfg, M_DEVBUF); 1356 sc->sc_cfg = cfg; 1357 1358 /* get all ld info */ 1359 if (mfi_mgmt(sc, MR_DCMD_LD_GET_LIST, MFI_DATA_IN, 1360 sizeof(sc->sc_ld_list), &sc->sc_ld_list, NULL)) 1361 goto done; 1362 1363 /* get memory for all ld structures */ 1364 size = cfg->mfc_no_ld * sizeof(struct mfi_ld_details); 1365 if (sc->sc_ld_sz != size) { 1366 if (sc->sc_ld_details) 1367 free(sc->sc_ld_details, M_DEVBUF); 1368 1369 ld_det = malloc( size, M_DEVBUF, M_NOWAIT | M_ZERO); 1370 if (ld_det == NULL) 1371 goto done; 1372 sc->sc_ld_sz = size; 1373 sc->sc_ld_details = ld_det; 1374 } 1375 1376 /* find used physical disks */ 1377 size = sizeof(struct mfi_ld_details); 1378 for (i = 0, d = 0; i < cfg->mfc_no_ld; i++) { 1379 mbox[0] = sc->sc_ld_list.mll_list[i].mll_ld.mld_target; 1380 if (mfi_mgmt(sc, MR_DCMD_LD_GET_INFO, MFI_DATA_IN, size, 1381 &sc->sc_ld_details[i], mbox)) 1382 goto done; 1383 1384 d += sc->sc_ld_details[i].mld_cfg.mlc_parm.mpa_no_drv_per_span * 1385 sc->sc_ld_details[i].mld_cfg.mlc_parm.mpa_span_depth; 1386 } 1387 sc->sc_no_pd = d; 1388 1389 rv = 0; 1390 done: 1391 return (rv); 1392 } 1393 1394 int 1395 mfi_ioctl_inq(struct mfi_softc *sc, struct bioc_inq *bi) 1396 { 1397 int rv = EINVAL; 1398 struct mfi_conf *cfg = NULL; 1399 1400 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_inq\n", DEVNAME(sc)); 1401 1402 if (mfi_bio_getitall(sc)) { 1403 DNPRINTF(MFI_D_IOCTL, "%s: mfi_bio_getitall failed\n", 1404 DEVNAME(sc)); 1405 goto done; 1406 } 1407 1408 /* count unused disks as volumes */ 1409 if (sc->sc_cfg == NULL) 1410 goto done; 1411 cfg = sc->sc_cfg; 1412 1413 bi->bi_nodisk = sc->sc_info.mci_pd_disks_present; 1414 bi->bi_novol = cfg->mfc_no_ld + cfg->mfc_no_hs; 1415 #if notyet 1416 bi->bi_novol = cfg->mfc_no_ld + cfg->mfc_no_hs + 1417 (bi->bi_nodisk - sc->sc_no_pd); 1418 #endif 1419 /* tell bio who we are */ 1420 strlcpy(bi->bi_dev, DEVNAME(sc), sizeof(bi->bi_dev)); 1421 1422 rv = 0; 1423 done: 1424 return (rv); 1425 } 1426 1427 int 1428 mfi_ioctl_vol(struct mfi_softc *sc, struct bioc_vol *bv) 1429 { 1430 int i, per, rv = EINVAL; 1431 1432 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_vol %#x\n", 1433 DEVNAME(sc), bv->bv_volid); 1434 1435 /* we really could skip and expect that inq took care of it */ 1436 if (mfi_bio_getitall(sc)) { 1437 DNPRINTF(MFI_D_IOCTL, "%s: mfi_bio_getitall failed\n", 1438 DEVNAME(sc)); 1439 goto done; 1440 } 1441 1442 if (bv->bv_volid >= sc->sc_ld_list.mll_no_ld) { 1443 /* go do hotspares & unused disks */ 1444 rv = mfi_bio_hs(sc, bv->bv_volid, MFI_MGMT_VD, bv); 1445 goto done; 1446 } 1447 1448 i = bv->bv_volid; 1449 strlcpy(bv->bv_dev, sc->sc_ld[i].ld_dev, sizeof(bv->bv_dev)); 1450 1451 switch(sc->sc_ld_list.mll_list[i].mll_state) { 1452 case MFI_LD_OFFLINE: 1453 bv->bv_status = BIOC_SVOFFLINE; 1454 break; 1455 1456 case MFI_LD_PART_DEGRADED: 1457 case MFI_LD_DEGRADED: 1458 bv->bv_status = BIOC_SVDEGRADED; 1459 break; 1460 1461 case MFI_LD_ONLINE: 1462 bv->bv_status = BIOC_SVONLINE; 1463 break; 1464 1465 default: 1466 bv->bv_status = BIOC_SVINVALID; 1467 DNPRINTF(MFI_D_IOCTL, "%s: invalid logical disk state %#x\n", 1468 DEVNAME(sc), 1469 sc->sc_ld_list.mll_list[i].mll_state); 1470 } 1471 1472 /* additional status can modify MFI status */ 1473 switch (sc->sc_ld_details[i].mld_progress.mlp_in_prog) { 1474 case MFI_LD_PROG_CC: 1475 case MFI_LD_PROG_BGI: 1476 bv->bv_status = BIOC_SVSCRUB; 1477 per = (int)sc->sc_ld_details[i].mld_progress.mlp_cc.mp_progress; 1478 bv->bv_percent = (per * 100) / 0xffff; 1479 bv->bv_seconds = 1480 sc->sc_ld_details[i].mld_progress.mlp_cc.mp_elapsed_seconds; 1481 break; 1482 1483 case MFI_LD_PROG_FGI: 1484 case MFI_LD_PROG_RECONSTRUCT: 1485 /* nothing yet */ 1486 break; 1487 } 1488 1489 /* 1490 * The RAID levels are determined per the SNIA DDF spec, this is only 1491 * a subset that is valid for the MFI controller. 1492 */ 1493 bv->bv_level = sc->sc_ld_details[i].mld_cfg.mlc_parm.mpa_pri_raid; 1494 if (sc->sc_ld_details[i].mld_cfg.mlc_parm.mpa_sec_raid == 1495 MFI_DDF_SRL_SPANNED) 1496 bv->bv_level *= 10; 1497 1498 bv->bv_nodisk = sc->sc_ld_details[i].mld_cfg.mlc_parm.mpa_no_drv_per_span * 1499 sc->sc_ld_details[i].mld_cfg.mlc_parm.mpa_span_depth; 1500 1501 bv->bv_size = sc->sc_ld_details[i].mld_size * 512; /* bytes per block */ 1502 1503 rv = 0; 1504 done: 1505 return (rv); 1506 } 1507 1508 int 1509 mfi_ioctl_disk(struct mfi_softc *sc, struct bioc_disk *bd) 1510 { 1511 struct mfi_conf *cfg; 1512 struct mfi_array *ar; 1513 struct mfi_ld_cfg *ld; 1514 struct mfi_pd_details *pd; 1515 struct scsi_inquiry_data *inqbuf; 1516 char vend[8+16+4+1]; 1517 int rv = EINVAL; 1518 int arr, vol, disk, span; 1519 uint8_t mbox[MFI_MBOX_SIZE]; 1520 1521 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_disk %#x\n", 1522 DEVNAME(sc), bd->bd_diskid); 1523 1524 /* we really could skip and expect that inq took care of it */ 1525 if (mfi_bio_getitall(sc)) { 1526 DNPRINTF(MFI_D_IOCTL, "%s: mfi_bio_getitall failed\n", 1527 DEVNAME(sc)); 1528 return (rv); 1529 } 1530 cfg = sc->sc_cfg; 1531 1532 pd = malloc(sizeof *pd, M_DEVBUF, M_WAITOK); 1533 1534 ar = cfg->mfc_array; 1535 vol = bd->bd_volid; 1536 if (vol >= cfg->mfc_no_ld) { 1537 /* do hotspares */ 1538 rv = mfi_bio_hs(sc, bd->bd_volid, MFI_MGMT_SD, bd); 1539 goto freeme; 1540 } 1541 1542 /* calculate offset to ld structure */ 1543 ld = (struct mfi_ld_cfg *)( 1544 ((uint8_t *)cfg) + offsetof(struct mfi_conf, mfc_array) + 1545 cfg->mfc_array_size * cfg->mfc_no_array); 1546 1547 /* use span 0 only when raid group is not spanned */ 1548 if (ld[vol].mlc_parm.mpa_span_depth > 1) 1549 span = bd->bd_diskid / ld[vol].mlc_parm.mpa_no_drv_per_span; 1550 else 1551 span = 0; 1552 arr = ld[vol].mlc_span[span].mls_index; 1553 1554 /* offset disk into pd list */ 1555 disk = bd->bd_diskid % ld[vol].mlc_parm.mpa_no_drv_per_span; 1556 bd->bd_target = ar[arr].pd[disk].mar_enc_slot; 1557 1558 /* get status */ 1559 switch (ar[arr].pd[disk].mar_pd_state){ 1560 case MFI_PD_UNCONFIG_GOOD: 1561 case MFI_PD_FAILED: 1562 bd->bd_status = BIOC_SDFAILED; 1563 break; 1564 1565 case MFI_PD_HOTSPARE: /* XXX dedicated hotspare part of array? */ 1566 bd->bd_status = BIOC_SDHOTSPARE; 1567 break; 1568 1569 case MFI_PD_OFFLINE: 1570 bd->bd_status = BIOC_SDOFFLINE; 1571 break; 1572 1573 case MFI_PD_REBUILD: 1574 bd->bd_status = BIOC_SDREBUILD; 1575 break; 1576 1577 case MFI_PD_ONLINE: 1578 bd->bd_status = BIOC_SDONLINE; 1579 break; 1580 1581 case MFI_PD_UNCONFIG_BAD: /* XXX define new state in bio */ 1582 default: 1583 bd->bd_status = BIOC_SDINVALID; 1584 break; 1585 } 1586 1587 /* get the remaining fields */ 1588 *((uint16_t *)&mbox) = ar[arr].pd[disk].mar_pd.mfp_id; 1589 if (mfi_mgmt(sc, MR_DCMD_PD_GET_INFO, MFI_DATA_IN, 1590 sizeof *pd, pd, mbox)) { 1591 /* disk is missing but succeed command */ 1592 rv = 0; 1593 goto freeme; 1594 } 1595 1596 bd->bd_size = pd->mpd_size * 512; /* bytes per block */ 1597 1598 /* if pd->mpd_enc_idx is 0 then it is not in an enclosure */ 1599 bd->bd_channel = pd->mpd_enc_idx; 1600 1601 inqbuf = (struct scsi_inquiry_data *)&pd->mpd_inq_data; 1602 memcpy(vend, inqbuf->vendor, sizeof vend - 1); 1603 vend[sizeof vend - 1] = '\0'; 1604 strlcpy(bd->bd_vendor, vend, sizeof(bd->bd_vendor)); 1605 1606 /* XXX find a way to retrieve serial nr from drive */ 1607 /* XXX find a way to get bd_procdev */ 1608 1609 rv = 0; 1610 freeme: 1611 free(pd, M_DEVBUF); 1612 1613 return (rv); 1614 } 1615 1616 int 1617 mfi_ioctl_alarm(struct mfi_softc *sc, struct bioc_alarm *ba) 1618 { 1619 uint32_t opc, dir = MFI_DATA_NONE; 1620 int rv = 0; 1621 int8_t ret; 1622 1623 switch(ba->ba_opcode) { 1624 case BIOC_SADISABLE: 1625 opc = MR_DCMD_SPEAKER_DISABLE; 1626 break; 1627 1628 case BIOC_SAENABLE: 1629 opc = MR_DCMD_SPEAKER_ENABLE; 1630 break; 1631 1632 case BIOC_SASILENCE: 1633 opc = MR_DCMD_SPEAKER_SILENCE; 1634 break; 1635 1636 case BIOC_GASTATUS: 1637 opc = MR_DCMD_SPEAKER_GET; 1638 dir = MFI_DATA_IN; 1639 break; 1640 1641 case BIOC_SATEST: 1642 opc = MR_DCMD_SPEAKER_TEST; 1643 break; 1644 1645 default: 1646 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_alarm biocalarm invalid " 1647 "opcode %x\n", DEVNAME(sc), ba->ba_opcode); 1648 return (EINVAL); 1649 } 1650 1651 if (mfi_mgmt(sc, opc, dir, sizeof(ret), &ret, NULL)) 1652 rv = EINVAL; 1653 else 1654 if (ba->ba_opcode == BIOC_GASTATUS) 1655 ba->ba_status = ret; 1656 else 1657 ba->ba_status = 0; 1658 1659 return (rv); 1660 } 1661 1662 int 1663 mfi_ioctl_blink(struct mfi_softc *sc, struct bioc_blink *bb) 1664 { 1665 int i, found, rv = EINVAL; 1666 uint8_t mbox[MFI_MBOX_SIZE]; 1667 uint32_t cmd; 1668 struct mfi_pd_list *pd; 1669 1670 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_blink %x\n", DEVNAME(sc), 1671 bb->bb_status); 1672 1673 /* channel 0 means not in an enclosure so can't be blinked */ 1674 if (bb->bb_channel == 0) 1675 return (EINVAL); 1676 1677 pd = malloc(MFI_PD_LIST_SIZE, M_DEVBUF, M_WAITOK); 1678 1679 if (mfi_mgmt(sc, MR_DCMD_PD_GET_LIST, MFI_DATA_IN, 1680 MFI_PD_LIST_SIZE, pd, NULL)) 1681 goto done; 1682 1683 for (i = 0, found = 0; i < pd->mpl_no_pd; i++) 1684 if (bb->bb_channel == pd->mpl_address[i].mpa_enc_index && 1685 bb->bb_target == pd->mpl_address[i].mpa_enc_slot) { 1686 found = 1; 1687 break; 1688 } 1689 1690 if (!found) 1691 goto done; 1692 1693 memset(mbox, 0, sizeof mbox); 1694 1695 *((uint16_t *)&mbox) = pd->mpl_address[i].mpa_pd_id; 1696 1697 switch (bb->bb_status) { 1698 case BIOC_SBUNBLINK: 1699 cmd = MR_DCMD_PD_UNBLINK; 1700 break; 1701 1702 case BIOC_SBBLINK: 1703 cmd = MR_DCMD_PD_BLINK; 1704 break; 1705 1706 case BIOC_SBALARM: 1707 default: 1708 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_blink biocblink invalid " 1709 "opcode %x\n", DEVNAME(sc), bb->bb_status); 1710 goto done; 1711 } 1712 1713 1714 if (mfi_mgmt(sc, cmd, MFI_DATA_NONE, 0, NULL, mbox)) 1715 goto done; 1716 1717 rv = 0; 1718 done: 1719 free(pd, M_DEVBUF); 1720 return (rv); 1721 } 1722 1723 int 1724 mfi_ioctl_setstate(struct mfi_softc *sc, struct bioc_setstate *bs) 1725 { 1726 struct mfi_pd_list *pd; 1727 int i, found, rv = EINVAL; 1728 uint8_t mbox[MFI_MBOX_SIZE]; 1729 uint32_t cmd; 1730 1731 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_setstate %x\n", DEVNAME(sc), 1732 bs->bs_status); 1733 1734 pd = malloc(MFI_PD_LIST_SIZE, M_DEVBUF, M_WAITOK); 1735 1736 if (mfi_mgmt(sc, MR_DCMD_PD_GET_LIST, MFI_DATA_IN, 1737 MFI_PD_LIST_SIZE, pd, NULL)) 1738 goto done; 1739 1740 for (i = 0, found = 0; i < pd->mpl_no_pd; i++) 1741 if (bs->bs_channel == pd->mpl_address[i].mpa_enc_index && 1742 bs->bs_target == pd->mpl_address[i].mpa_enc_slot) { 1743 found = 1; 1744 break; 1745 } 1746 1747 if (!found) 1748 goto done; 1749 1750 memset(mbox, 0, sizeof mbox); 1751 1752 *((uint16_t *)&mbox) = pd->mpl_address[i].mpa_pd_id; 1753 1754 switch (bs->bs_status) { 1755 case BIOC_SSONLINE: 1756 mbox[2] = MFI_PD_ONLINE; 1757 cmd = MD_DCMD_PD_SET_STATE; 1758 break; 1759 1760 case BIOC_SSOFFLINE: 1761 mbox[2] = MFI_PD_OFFLINE; 1762 cmd = MD_DCMD_PD_SET_STATE; 1763 break; 1764 1765 case BIOC_SSHOTSPARE: 1766 mbox[2] = MFI_PD_HOTSPARE; 1767 cmd = MD_DCMD_PD_SET_STATE; 1768 break; 1769 /* 1770 case BIOC_SSREBUILD: 1771 cmd = MD_DCMD_PD_REBUILD; 1772 break; 1773 */ 1774 default: 1775 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_setstate invalid " 1776 "opcode %x\n", DEVNAME(sc), bs->bs_status); 1777 goto done; 1778 } 1779 1780 1781 if (mfi_mgmt(sc, MD_DCMD_PD_SET_STATE, MFI_DATA_NONE, 0, NULL, mbox)) 1782 goto done; 1783 1784 rv = 0; 1785 done: 1786 free(pd, M_DEVBUF); 1787 return (rv); 1788 } 1789 1790 int 1791 mfi_bio_hs(struct mfi_softc *sc, int volid, int type, void *bio_hs) 1792 { 1793 struct mfi_conf *cfg; 1794 struct mfi_hotspare *hs; 1795 struct mfi_pd_details *pd; 1796 struct bioc_disk *sdhs; 1797 struct bioc_vol *vdhs; 1798 struct scsi_inquiry_data *inqbuf; 1799 char vend[8+16+4+1]; 1800 int i, rv = EINVAL; 1801 uint32_t size; 1802 uint8_t mbox[MFI_MBOX_SIZE]; 1803 1804 DNPRINTF(MFI_D_IOCTL, "%s: mfi_vol_hs %d\n", DEVNAME(sc), volid); 1805 1806 if (!bio_hs) 1807 return (EINVAL); 1808 1809 pd = malloc(sizeof *pd, M_DEVBUF, M_WAITOK); 1810 1811 /* send single element command to retrieve size for full structure */ 1812 cfg = malloc(sizeof *cfg, M_DEVBUF, M_WAITOK); 1813 if (mfi_mgmt(sc, MD_DCMD_CONF_GET, MFI_DATA_IN, sizeof *cfg, cfg, NULL)) 1814 goto freeme; 1815 1816 size = cfg->mfc_size; 1817 free(cfg, M_DEVBUF); 1818 1819 /* memory for read config */ 1820 cfg = malloc(size, M_DEVBUF, M_WAITOK|M_ZERO); 1821 if (mfi_mgmt(sc, MD_DCMD_CONF_GET, MFI_DATA_IN, size, cfg, NULL)) 1822 goto freeme; 1823 1824 /* calculate offset to hs structure */ 1825 hs = (struct mfi_hotspare *)( 1826 ((uint8_t *)cfg) + offsetof(struct mfi_conf, mfc_array) + 1827 cfg->mfc_array_size * cfg->mfc_no_array + 1828 cfg->mfc_ld_size * cfg->mfc_no_ld); 1829 1830 if (volid < cfg->mfc_no_ld) 1831 goto freeme; /* not a hotspare */ 1832 1833 if (volid > (cfg->mfc_no_ld + cfg->mfc_no_hs)) 1834 goto freeme; /* not a hotspare */ 1835 1836 /* offset into hotspare structure */ 1837 i = volid - cfg->mfc_no_ld; 1838 1839 DNPRINTF(MFI_D_IOCTL, "%s: mfi_vol_hs i %d volid %d no_ld %d no_hs %d " 1840 "hs %p cfg %p id %02x\n", DEVNAME(sc), i, volid, cfg->mfc_no_ld, 1841 cfg->mfc_no_hs, hs, cfg, hs[i].mhs_pd.mfp_id); 1842 1843 /* get pd fields */ 1844 memset(mbox, 0, sizeof mbox); 1845 *((uint16_t *)&mbox) = hs[i].mhs_pd.mfp_id; 1846 if (mfi_mgmt(sc, MR_DCMD_PD_GET_INFO, MFI_DATA_IN, 1847 sizeof *pd, pd, mbox)) { 1848 DNPRINTF(MFI_D_IOCTL, "%s: mfi_vol_hs illegal PD\n", 1849 DEVNAME(sc)); 1850 goto freeme; 1851 } 1852 1853 switch (type) { 1854 case MFI_MGMT_VD: 1855 vdhs = bio_hs; 1856 vdhs->bv_status = BIOC_SVONLINE; 1857 vdhs->bv_size = pd->mpd_size / 2 * 1024; /* XXX why? */ 1858 vdhs->bv_level = -1; /* hotspare */ 1859 vdhs->bv_nodisk = 1; 1860 break; 1861 1862 case MFI_MGMT_SD: 1863 sdhs = bio_hs; 1864 sdhs->bd_status = BIOC_SDHOTSPARE; 1865 sdhs->bd_size = pd->mpd_size / 2 * 1024; /* XXX why? */ 1866 sdhs->bd_channel = pd->mpd_enc_idx; 1867 sdhs->bd_target = pd->mpd_enc_slot; 1868 inqbuf = (struct scsi_inquiry_data *)&pd->mpd_inq_data; 1869 memcpy(vend, inqbuf->vendor, sizeof vend - 1); 1870 vend[sizeof vend - 1] = '\0'; 1871 strlcpy(sdhs->bd_vendor, vend, sizeof(sdhs->bd_vendor)); 1872 break; 1873 1874 default: 1875 goto freeme; 1876 } 1877 1878 DNPRINTF(MFI_D_IOCTL, "%s: mfi_vol_hs 6\n", DEVNAME(sc)); 1879 rv = 0; 1880 freeme: 1881 free(pd, M_DEVBUF); 1882 free(cfg, M_DEVBUF); 1883 1884 return (rv); 1885 } 1886 1887 #ifndef SMALL_KERNEL 1888 int 1889 mfi_create_sensors(struct mfi_softc *sc) 1890 { 1891 struct device *dev; 1892 struct scsibus_softc *ssc = NULL; 1893 int i; 1894 1895 TAILQ_FOREACH(dev, &alldevs, dv_list) { 1896 if (dev->dv_parent != &sc->sc_dev) 1897 continue; 1898 1899 /* check if this is the scsibus for the logical disks */ 1900 ssc = (struct scsibus_softc *)dev; 1901 if (ssc->adapter_link == &sc->sc_link) 1902 break; 1903 } 1904 1905 if (ssc == NULL) 1906 return (1); 1907 1908 sc->sc_sensors = malloc(sizeof(struct ksensor) * sc->sc_ld_cnt, 1909 M_DEVBUF, M_WAITOK|M_ZERO); 1910 if (sc->sc_sensors == NULL) 1911 return (1); 1912 1913 strlcpy(sc->sc_sensordev.xname, DEVNAME(sc), 1914 sizeof(sc->sc_sensordev.xname)); 1915 1916 for (i = 0; i < sc->sc_ld_cnt; i++) { 1917 if (ssc->sc_link[i][0] == NULL) 1918 goto bad; 1919 1920 dev = ssc->sc_link[i][0]->device_softc; 1921 1922 sc->sc_sensors[i].type = SENSOR_DRIVE; 1923 sc->sc_sensors[i].status = SENSOR_S_UNKNOWN; 1924 1925 strlcpy(sc->sc_sensors[i].desc, dev->dv_xname, 1926 sizeof(sc->sc_sensors[i].desc)); 1927 1928 sensor_attach(&sc->sc_sensordev, &sc->sc_sensors[i]); 1929 } 1930 1931 if (sensor_task_register(sc, mfi_refresh_sensors, 10) == NULL) 1932 goto bad; 1933 1934 sensordev_install(&sc->sc_sensordev); 1935 1936 return (0); 1937 1938 bad: 1939 free(sc->sc_sensors, M_DEVBUF); 1940 1941 return (1); 1942 } 1943 1944 void 1945 mfi_refresh_sensors(void *arg) 1946 { 1947 struct mfi_softc *sc = arg; 1948 int i; 1949 struct bioc_vol bv; 1950 1951 1952 for (i = 0; i < sc->sc_ld_cnt; i++) { 1953 bzero(&bv, sizeof(bv)); 1954 bv.bv_volid = i; 1955 if (mfi_ioctl_vol(sc, &bv)) 1956 return; 1957 1958 switch(bv.bv_status) { 1959 case BIOC_SVOFFLINE: 1960 sc->sc_sensors[i].value = SENSOR_DRIVE_FAIL; 1961 sc->sc_sensors[i].status = SENSOR_S_CRIT; 1962 break; 1963 1964 case BIOC_SVDEGRADED: 1965 sc->sc_sensors[i].value = SENSOR_DRIVE_PFAIL; 1966 sc->sc_sensors[i].status = SENSOR_S_WARN; 1967 break; 1968 1969 case BIOC_SVSCRUB: 1970 case BIOC_SVONLINE: 1971 sc->sc_sensors[i].value = SENSOR_DRIVE_ONLINE; 1972 sc->sc_sensors[i].status = SENSOR_S_OK; 1973 break; 1974 1975 case BIOC_SVINVALID: 1976 /* FALLTRHOUGH */ 1977 default: 1978 sc->sc_sensors[i].value = 0; /* unknown */ 1979 sc->sc_sensors[i].status = SENSOR_S_UNKNOWN; 1980 } 1981 1982 } 1983 } 1984 #endif /* SMALL_KERNEL */ 1985 #endif /* NBIO > 0 */ 1986 1987 u_int32_t 1988 mfi_xscale_fw_state(struct mfi_softc *sc) 1989 { 1990 return (mfi_read(sc, MFI_OMSG0)); 1991 } 1992 1993 void 1994 mfi_xscale_intr_ena(struct mfi_softc *sc) 1995 { 1996 mfi_write(sc, MFI_OMSK, MFI_ENABLE_INTR); 1997 } 1998 1999 int 2000 mfi_xscale_intr(struct mfi_softc *sc) 2001 { 2002 u_int32_t status; 2003 2004 status = mfi_read(sc, MFI_OSTS); 2005 if (!ISSET(status, MFI_OSTS_INTR_VALID)) 2006 return (0); 2007 2008 /* write status back to acknowledge interrupt */ 2009 mfi_write(sc, MFI_OSTS, status); 2010 2011 return (1); 2012 } 2013 2014 void 2015 mfi_xscale_post(struct mfi_softc *sc, struct mfi_ccb *ccb) 2016 { 2017 mfi_write(sc, MFI_IQP, (ccb->ccb_pframe >> 3) | 2018 ccb->ccb_extra_frames); 2019 } 2020 2021 u_int32_t 2022 mfi_ppc_fw_state(struct mfi_softc *sc) 2023 { 2024 return (mfi_read(sc, MFI_OSP)); 2025 } 2026 2027 void 2028 mfi_ppc_intr_ena(struct mfi_softc *sc) 2029 { 2030 mfi_write(sc, MFI_ODC, 0xffffffff); 2031 mfi_write(sc, MFI_OMSK, ~0x80000004); 2032 } 2033 2034 int 2035 mfi_ppc_intr(struct mfi_softc *sc) 2036 { 2037 u_int32_t status; 2038 2039 status = mfi_read(sc, MFI_OSTS); 2040 if (!ISSET(status, MFI_OSTS_PPC_INTR_VALID)) 2041 return (0); 2042 2043 /* write status back to acknowledge interrupt */ 2044 mfi_write(sc, MFI_ODC, status); 2045 2046 return (1); 2047 } 2048 2049 void 2050 mfi_ppc_post(struct mfi_softc *sc, struct mfi_ccb *ccb) 2051 { 2052 mfi_write(sc, MFI_IQP, 0x1 | ccb->ccb_pframe | 2053 (ccb->ccb_extra_frames << 1)); 2054 } 2055 2056 u_int32_t 2057 mfi_gen2_fw_state(struct mfi_softc *sc) 2058 { 2059 return (mfi_read(sc, MFI_OSP)); 2060 } 2061 2062 void 2063 mfi_gen2_intr_ena(struct mfi_softc *sc) 2064 { 2065 mfi_write(sc, MFI_ODC, 0xffffffff); 2066 mfi_write(sc, MFI_OMSK, ~MFI_OSTS_GEN2_INTR_VALID); 2067 } 2068 2069 int 2070 mfi_gen2_intr(struct mfi_softc *sc) 2071 { 2072 u_int32_t status; 2073 2074 status = mfi_read(sc, MFI_OSTS); 2075 if (!ISSET(status, MFI_OSTS_GEN2_INTR_VALID)) 2076 return (0); 2077 2078 /* write status back to acknowledge interrupt */ 2079 mfi_write(sc, MFI_ODC, status); 2080 2081 return (1); 2082 } 2083 2084 void 2085 mfi_gen2_post(struct mfi_softc *sc, struct mfi_ccb *ccb) 2086 { 2087 mfi_write(sc, MFI_IQP, 0x1 | ccb->ccb_pframe | 2088 (ccb->ccb_extra_frames << 1)); 2089 } 2090