1 /* $NetBSD: mfi.c,v 1.64 2021/04/24 23:36:55 thorpej Exp $ */ 2 /* $OpenBSD: mfi.c,v 1.66 2006/11/28 23:59:45 dlg Exp $ */ 3 4 /* 5 * Copyright (c) 2012 Manuel Bouyer. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 /* 29 * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us> 30 * 31 * Permission to use, copy, modify, and distribute this software for any 32 * purpose with or without fee is hereby granted, provided that the above 33 * copyright notice and this permission notice appear in all copies. 34 * 35 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 36 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 37 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 38 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 39 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 40 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 41 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 42 */ 43 44 /*- 45 * Redistribution and use in source and binary forms, with or without 46 * modification, are permitted provided that the following conditions 47 * are met: 48 * 49 * Copyright 1994-2009 The FreeBSD Project. 50 * All rights reserved. 51 * 52 * 1. Redistributions of source code must retain the above copyright 53 * notice, this list of conditions and the following disclaimer. 54 * 2. Redistributions in binary form must reproduce the above copyright 55 * notice, this list of conditions and the following disclaimer in the 56 * documentation and/or other materials provided with the distribution. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT``AS IS'' AND 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 60 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 61 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR 62 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 63 * EXEMPLARY,OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 64 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 65 * PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY THEORY 66 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 67 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 68 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 69 * 70 * The views and conclusions contained in the software and documentation 71 * are those of the authors and should not be interpreted as representing 72 * official policies,either expressed or implied, of the FreeBSD Project. 73 */ 74 75 #include <sys/cdefs.h> 76 __KERNEL_RCSID(0, "$NetBSD: mfi.c,v 1.64 2021/04/24 23:36:55 thorpej Exp $"); 77 78 #include "bio.h" 79 80 #include <sys/param.h> 81 #include <sys/systm.h> 82 #include <sys/buf.h> 83 #include <sys/ioctl.h> 84 #include <sys/device.h> 85 #include <sys/kernel.h> 86 #include <sys/malloc.h> 87 #include <sys/proc.h> 88 #include <sys/cpu.h> 89 #include <sys/conf.h> 90 #include <sys/kauth.h> 91 92 #include <uvm/uvm_param.h> 93 94 #include <sys/bus.h> 95 96 #include <dev/scsipi/scsipi_all.h> 97 #include <dev/scsipi/scsi_all.h> 98 #include <dev/scsipi/scsi_spc.h> 99 #include <dev/scsipi/scsipi_disk.h> 100 #include <dev/scsipi/scsi_disk.h> 101 #include <dev/scsipi/scsiconf.h> 102 103 #include <dev/ic/mfireg.h> 104 #include <dev/ic/mfivar.h> 105 #include <dev/ic/mfiio.h> 106 107 #if NBIO > 0 108 #include <dev/biovar.h> 109 #endif /* NBIO > 0 */ 110 111 #include "ioconf.h" 112 113 #ifdef MFI_DEBUG 114 uint32_t mfi_debug = 0 115 /* | MFI_D_CMD */ 116 /* | MFI_D_INTR */ 117 /* | MFI_D_MISC */ 118 /* | MFI_D_DMA */ 119 /* | MFI_D_IOCTL */ 120 /* | MFI_D_RW */ 121 /* | MFI_D_MEM */ 122 /* | MFI_D_CCB */ 123 /* | MFI_D_SYNC */ 124 ; 125 #endif 126 127 static void mfi_scsipi_request(struct scsipi_channel *, 128 scsipi_adapter_req_t, void *); 129 static void mfiminphys(struct buf *bp); 130 131 static struct mfi_ccb *mfi_get_ccb(struct mfi_softc *); 132 static void mfi_put_ccb(struct mfi_ccb *); 133 static int mfi_init_ccb(struct mfi_softc *); 134 135 static struct mfi_mem *mfi_allocmem(struct mfi_softc *, size_t); 136 static void mfi_freemem(struct mfi_softc *, struct mfi_mem **); 137 138 static int mfi_transition_firmware(struct mfi_softc *); 139 static int mfi_initialize_firmware(struct mfi_softc *); 140 static int mfi_get_info(struct mfi_softc *); 141 static int mfi_get_bbu(struct mfi_softc *, 142 struct mfi_bbu_status *); 143 /* return codes for mfi_get_bbu */ 144 #define MFI_BBU_GOOD 0 145 #define MFI_BBU_BAD 1 146 #define MFI_BBU_UNKNOWN 2 147 static uint32_t mfi_read(struct mfi_softc *, bus_size_t); 148 static void mfi_write(struct mfi_softc *, bus_size_t, uint32_t); 149 static int mfi_poll(struct mfi_ccb *); 150 static int mfi_create_sgl(struct mfi_ccb *, int); 151 152 /* commands */ 153 static int mfi_scsi_ld(struct mfi_ccb *, struct scsipi_xfer *); 154 static int mfi_scsi_ld_io(struct mfi_ccb *, struct scsipi_xfer *, 155 uint64_t, uint32_t); 156 static void mfi_scsi_ld_done(struct mfi_ccb *); 157 static void mfi_scsi_xs_done(struct mfi_ccb *, int, int); 158 static int mfi_mgmt_internal(struct mfi_softc *, uint32_t, 159 uint32_t, uint32_t, void *, uint8_t *, bool); 160 static int mfi_mgmt(struct mfi_ccb *,struct scsipi_xfer *, 161 uint32_t, uint32_t, uint32_t, void *, uint8_t *); 162 static void mfi_mgmt_done(struct mfi_ccb *); 163 164 #if NBIO > 0 165 static int mfi_ioctl(device_t, u_long, void *); 166 static int mfi_ioctl_inq(struct mfi_softc *, struct bioc_inq *); 167 static int mfi_ioctl_vol(struct mfi_softc *, struct bioc_vol *); 168 static int mfi_ioctl_disk(struct mfi_softc *, struct bioc_disk *); 169 static int mfi_ioctl_alarm(struct mfi_softc *, 170 struct bioc_alarm *); 171 static int mfi_ioctl_blink(struct mfi_softc *sc, 172 struct bioc_blink *); 173 static int mfi_ioctl_setstate(struct mfi_softc *, 174 struct bioc_setstate *); 175 static int mfi_bio_hs(struct mfi_softc *, int, int, void *); 176 static int mfi_create_sensors(struct mfi_softc *); 177 static int mfi_destroy_sensors(struct mfi_softc *); 178 static void mfi_sensor_refresh(struct sysmon_envsys *, 179 envsys_data_t *); 180 #endif /* NBIO > 0 */ 181 static bool mfi_shutdown(device_t, int); 182 static bool mfi_suspend(device_t, const pmf_qual_t *); 183 static bool mfi_resume(device_t, const pmf_qual_t *); 184 185 static dev_type_open(mfifopen); 186 static dev_type_close(mfifclose); 187 static dev_type_ioctl(mfifioctl); 188 const struct cdevsw mfi_cdevsw = { 189 .d_open = mfifopen, 190 .d_close = mfifclose, 191 .d_read = noread, 192 .d_write = nowrite, 193 .d_ioctl = mfifioctl, 194 .d_stop = nostop, 195 .d_tty = notty, 196 .d_poll = nopoll, 197 .d_mmap = nommap, 198 .d_kqfilter = nokqfilter, 199 .d_discard = nodiscard, 200 .d_flag = D_OTHER 201 }; 202 203 static uint32_t mfi_xscale_fw_state(struct mfi_softc *sc); 204 static void mfi_xscale_intr_ena(struct mfi_softc *sc); 205 static void mfi_xscale_intr_dis(struct mfi_softc *sc); 206 static int mfi_xscale_intr(struct mfi_softc *sc); 207 static void mfi_xscale_post(struct mfi_softc *sc, struct mfi_ccb *ccb); 208 209 static const struct mfi_iop_ops mfi_iop_xscale = { 210 mfi_xscale_fw_state, 211 mfi_xscale_intr_dis, 212 mfi_xscale_intr_ena, 213 mfi_xscale_intr, 214 mfi_xscale_post, 215 mfi_scsi_ld_io, 216 }; 217 218 static uint32_t mfi_ppc_fw_state(struct mfi_softc *sc); 219 static void mfi_ppc_intr_ena(struct mfi_softc *sc); 220 static void mfi_ppc_intr_dis(struct mfi_softc *sc); 221 static int mfi_ppc_intr(struct mfi_softc *sc); 222 static void mfi_ppc_post(struct mfi_softc *sc, struct mfi_ccb *ccb); 223 224 static const struct mfi_iop_ops mfi_iop_ppc = { 225 mfi_ppc_fw_state, 226 mfi_ppc_intr_dis, 227 mfi_ppc_intr_ena, 228 mfi_ppc_intr, 229 mfi_ppc_post, 230 mfi_scsi_ld_io, 231 }; 232 233 uint32_t mfi_gen2_fw_state(struct mfi_softc *sc); 234 void mfi_gen2_intr_ena(struct mfi_softc *sc); 235 void mfi_gen2_intr_dis(struct mfi_softc *sc); 236 int mfi_gen2_intr(struct mfi_softc *sc); 237 void mfi_gen2_post(struct mfi_softc *sc, struct mfi_ccb *ccb); 238 239 static const struct mfi_iop_ops mfi_iop_gen2 = { 240 mfi_gen2_fw_state, 241 mfi_gen2_intr_dis, 242 mfi_gen2_intr_ena, 243 mfi_gen2_intr, 244 mfi_gen2_post, 245 mfi_scsi_ld_io, 246 }; 247 248 u_int32_t mfi_skinny_fw_state(struct mfi_softc *); 249 void mfi_skinny_intr_dis(struct mfi_softc *); 250 void mfi_skinny_intr_ena(struct mfi_softc *); 251 int mfi_skinny_intr(struct mfi_softc *); 252 void mfi_skinny_post(struct mfi_softc *, struct mfi_ccb *); 253 254 static const struct mfi_iop_ops mfi_iop_skinny = { 255 mfi_skinny_fw_state, 256 mfi_skinny_intr_dis, 257 mfi_skinny_intr_ena, 258 mfi_skinny_intr, 259 mfi_skinny_post, 260 mfi_scsi_ld_io, 261 }; 262 263 static int mfi_tbolt_init_desc_pool(struct mfi_softc *); 264 static int mfi_tbolt_init_MFI_queue(struct mfi_softc *); 265 static void mfi_tbolt_build_mpt_ccb(struct mfi_ccb *); 266 int mfi_tbolt_scsi_ld_io(struct mfi_ccb *, struct scsipi_xfer *, 267 uint64_t, uint32_t); 268 static void mfi_tbolt_scsi_ld_done(struct mfi_ccb *); 269 static int mfi_tbolt_create_sgl(struct mfi_ccb *, int); 270 void mfi_tbolt_sync_map_info(struct work *, void *); 271 static void mfi_sync_map_complete(struct mfi_ccb *); 272 273 u_int32_t mfi_tbolt_fw_state(struct mfi_softc *); 274 void mfi_tbolt_intr_dis(struct mfi_softc *); 275 void mfi_tbolt_intr_ena(struct mfi_softc *); 276 int mfi_tbolt_intr(struct mfi_softc *sc); 277 void mfi_tbolt_post(struct mfi_softc *, struct mfi_ccb *); 278 279 static const struct mfi_iop_ops mfi_iop_tbolt = { 280 mfi_tbolt_fw_state, 281 mfi_tbolt_intr_dis, 282 mfi_tbolt_intr_ena, 283 mfi_tbolt_intr, 284 mfi_tbolt_post, 285 mfi_tbolt_scsi_ld_io, 286 }; 287 288 #define mfi_fw_state(_s) ((_s)->sc_iop->mio_fw_state(_s)) 289 #define mfi_intr_enable(_s) ((_s)->sc_iop->mio_intr_ena(_s)) 290 #define mfi_intr_disable(_s) ((_s)->sc_iop->mio_intr_dis(_s)) 291 #define mfi_my_intr(_s) ((_s)->sc_iop->mio_intr(_s)) 292 #define mfi_post(_s, _c) ((_s)->sc_iop->mio_post((_s), (_c))) 293 294 static struct mfi_ccb * 295 mfi_get_ccb(struct mfi_softc *sc) 296 { 297 struct mfi_ccb *ccb; 298 int s; 299 300 s = splbio(); 301 ccb = TAILQ_FIRST(&sc->sc_ccb_freeq); 302 if (ccb) { 303 TAILQ_REMOVE(&sc->sc_ccb_freeq, ccb, ccb_link); 304 ccb->ccb_state = MFI_CCB_READY; 305 } 306 splx(s); 307 308 DNPRINTF(MFI_D_CCB, "%s: mfi_get_ccb: %p\n", DEVNAME(sc), ccb); 309 if (__predict_false(ccb == NULL && sc->sc_running)) 310 aprint_error_dev(sc->sc_dev, "out of ccb\n"); 311 312 return ccb; 313 } 314 315 static void 316 mfi_put_ccb(struct mfi_ccb *ccb) 317 { 318 struct mfi_softc *sc = ccb->ccb_sc; 319 struct mfi_frame_header *hdr = &ccb->ccb_frame->mfr_header; 320 int s; 321 322 DNPRINTF(MFI_D_CCB, "%s: mfi_put_ccb: %p\n", DEVNAME(sc), ccb); 323 324 hdr->mfh_cmd_status = 0x0; 325 hdr->mfh_flags = 0x0; 326 ccb->ccb_state = MFI_CCB_FREE; 327 ccb->ccb_xs = NULL; 328 ccb->ccb_flags = 0; 329 ccb->ccb_done = NULL; 330 ccb->ccb_direction = 0; 331 ccb->ccb_frame_size = 0; 332 ccb->ccb_extra_frames = 0; 333 ccb->ccb_sgl = NULL; 334 ccb->ccb_data = NULL; 335 ccb->ccb_len = 0; 336 if (sc->sc_ioptype == MFI_IOP_TBOLT) { 337 /* erase tb_request_desc but preserve SMID */ 338 int index = ccb->ccb_tb_request_desc.header.SMID; 339 ccb->ccb_tb_request_desc.words = 0; 340 ccb->ccb_tb_request_desc.header.SMID = index; 341 } 342 s = splbio(); 343 TAILQ_INSERT_TAIL(&sc->sc_ccb_freeq, ccb, ccb_link); 344 splx(s); 345 } 346 347 static int 348 mfi_destroy_ccb(struct mfi_softc *sc) 349 { 350 struct mfi_ccb *ccb; 351 uint32_t i; 352 353 DNPRINTF(MFI_D_CCB, "%s: mfi_destroy_ccb\n", DEVNAME(sc)); 354 355 356 for (i = 0; (ccb = mfi_get_ccb(sc)) != NULL; i++) { 357 /* create a dma map for transfer */ 358 bus_dmamap_destroy(sc->sc_datadmat, ccb->ccb_dmamap); 359 } 360 361 if (i < sc->sc_max_cmds) 362 return EBUSY; 363 364 free(sc->sc_ccb, M_DEVBUF); 365 366 return 0; 367 } 368 369 static int 370 mfi_init_ccb(struct mfi_softc *sc) 371 { 372 struct mfi_ccb *ccb; 373 uint32_t i; 374 int error; 375 bus_addr_t io_req_base_phys; 376 uint8_t *io_req_base; 377 int offset; 378 379 DNPRINTF(MFI_D_CCB, "%s: mfi_init_ccb\n", DEVNAME(sc)); 380 381 sc->sc_ccb = malloc(sizeof(struct mfi_ccb) * sc->sc_max_cmds, 382 M_DEVBUF, M_WAITOK|M_ZERO); 383 if (sc->sc_ioptype == MFI_IOP_TBOLT) { 384 /* 385 * The first 256 bytes (SMID 0) is not used. 386 * Don't add to the cmd list. 387 */ 388 io_req_base = (uint8_t *)MFIMEM_KVA(sc->sc_tbolt_reqmsgpool) + 389 MEGASAS_THUNDERBOLT_NEW_MSG_SIZE; 390 io_req_base_phys = MFIMEM_DVA(sc->sc_tbolt_reqmsgpool) + 391 MEGASAS_THUNDERBOLT_NEW_MSG_SIZE; 392 } else { 393 io_req_base = NULL; /* XXX: gcc */ 394 io_req_base_phys = 0; /* XXX: gcc */ 395 } 396 397 for (i = 0; i < sc->sc_max_cmds; i++) { 398 ccb = &sc->sc_ccb[i]; 399 400 ccb->ccb_sc = sc; 401 402 /* select i'th frame */ 403 ccb->ccb_frame = (union mfi_frame *) 404 ((char*)MFIMEM_KVA(sc->sc_frames) + sc->sc_frames_size * i); 405 ccb->ccb_pframe = 406 MFIMEM_DVA(sc->sc_frames) + sc->sc_frames_size * i; 407 ccb->ccb_frame->mfr_header.mfh_context = i; 408 409 /* select i'th sense */ 410 ccb->ccb_sense = (struct mfi_sense *) 411 ((char*)MFIMEM_KVA(sc->sc_sense) + MFI_SENSE_SIZE * i); 412 ccb->ccb_psense = 413 (MFIMEM_DVA(sc->sc_sense) + MFI_SENSE_SIZE * i); 414 415 /* create a dma map for transfer */ 416 error = bus_dmamap_create(sc->sc_datadmat, 417 MAXPHYS, sc->sc_max_sgl, MAXPHYS, 0, 418 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->ccb_dmamap); 419 if (error) { 420 aprint_error_dev(sc->sc_dev, 421 "cannot create ccb dmamap (%d)\n", error); 422 goto destroy; 423 } 424 if (sc->sc_ioptype == MFI_IOP_TBOLT) { 425 offset = MEGASAS_THUNDERBOLT_NEW_MSG_SIZE * i; 426 ccb->ccb_tb_io_request = 427 (struct mfi_mpi2_request_raid_scsi_io *) 428 (io_req_base + offset); 429 ccb->ccb_tb_pio_request = 430 io_req_base_phys + offset; 431 offset = MEGASAS_MAX_SZ_CHAIN_FRAME * i; 432 ccb->ccb_tb_sg_frame = 433 (mpi2_sge_io_union *)(sc->sc_reply_pool_limit + 434 offset); 435 ccb->ccb_tb_psg_frame = sc->sc_sg_frame_busaddr + 436 offset; 437 /* SMID 0 is reserved. Set SMID/index from 1 */ 438 ccb->ccb_tb_request_desc.header.SMID = i + 1; 439 } 440 441 DNPRINTF(MFI_D_CCB, 442 "ccb(%d): %p frame: %#lx (%#lx) sense: %#lx (%#lx) map: %#lx\n", 443 ccb->ccb_frame->mfr_header.mfh_context, ccb, 444 (u_long)ccb->ccb_frame, (u_long)ccb->ccb_pframe, 445 (u_long)ccb->ccb_sense, (u_long)ccb->ccb_psense, 446 (u_long)ccb->ccb_dmamap); 447 448 /* add ccb to queue */ 449 mfi_put_ccb(ccb); 450 } 451 452 return 0; 453 destroy: 454 /* free dma maps and ccb memory */ 455 while (i) { 456 i--; 457 ccb = &sc->sc_ccb[i]; 458 bus_dmamap_destroy(sc->sc_datadmat, ccb->ccb_dmamap); 459 } 460 461 free(sc->sc_ccb, M_DEVBUF); 462 463 return 1; 464 } 465 466 static uint32_t 467 mfi_read(struct mfi_softc *sc, bus_size_t r) 468 { 469 uint32_t rv; 470 471 bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4, 472 BUS_SPACE_BARRIER_READ); 473 rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, r); 474 475 DNPRINTF(MFI_D_RW, "%s: mr 0x%lx 0x08%x ", DEVNAME(sc), (u_long)r, rv); 476 return rv; 477 } 478 479 static void 480 mfi_write(struct mfi_softc *sc, bus_size_t r, uint32_t v) 481 { 482 DNPRINTF(MFI_D_RW, "%s: mw 0x%lx 0x%08x", DEVNAME(sc), (u_long)r, v); 483 484 bus_space_write_4(sc->sc_iot, sc->sc_ioh, r, v); 485 bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4, 486 BUS_SPACE_BARRIER_WRITE); 487 } 488 489 static struct mfi_mem * 490 mfi_allocmem(struct mfi_softc *sc, size_t size) 491 { 492 struct mfi_mem *mm; 493 int nsegs; 494 495 DNPRINTF(MFI_D_MEM, "%s: mfi_allocmem: %ld\n", DEVNAME(sc), 496 (long)size); 497 498 mm = malloc(sizeof(struct mfi_mem), M_DEVBUF, M_WAITOK|M_ZERO); 499 mm->am_size = size; 500 501 if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, 502 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mm->am_map) != 0) 503 goto amfree; 504 505 if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &mm->am_seg, 1, 506 &nsegs, BUS_DMA_NOWAIT) != 0) 507 goto destroy; 508 509 if (bus_dmamem_map(sc->sc_dmat, &mm->am_seg, nsegs, size, &mm->am_kva, 510 BUS_DMA_NOWAIT) != 0) 511 goto free; 512 513 if (bus_dmamap_load(sc->sc_dmat, mm->am_map, mm->am_kva, size, NULL, 514 BUS_DMA_NOWAIT) != 0) 515 goto unmap; 516 517 DNPRINTF(MFI_D_MEM, " kva: %p dva: %p map: %p\n", 518 mm->am_kva, (void *)mm->am_map->dm_segs[0].ds_addr, mm->am_map); 519 520 memset(mm->am_kva, 0, size); 521 return mm; 522 523 unmap: 524 bus_dmamem_unmap(sc->sc_dmat, mm->am_kva, size); 525 free: 526 bus_dmamem_free(sc->sc_dmat, &mm->am_seg, 1); 527 destroy: 528 bus_dmamap_destroy(sc->sc_dmat, mm->am_map); 529 amfree: 530 free(mm, M_DEVBUF); 531 532 return NULL; 533 } 534 535 static void 536 mfi_freemem(struct mfi_softc *sc, struct mfi_mem **mmp) 537 { 538 struct mfi_mem *mm = *mmp; 539 540 if (mm == NULL) 541 return; 542 543 *mmp = NULL; 544 545 DNPRINTF(MFI_D_MEM, "%s: mfi_freemem: %p\n", DEVNAME(sc), mm); 546 547 bus_dmamap_unload(sc->sc_dmat, mm->am_map); 548 bus_dmamem_unmap(sc->sc_dmat, mm->am_kva, mm->am_size); 549 bus_dmamem_free(sc->sc_dmat, &mm->am_seg, 1); 550 bus_dmamap_destroy(sc->sc_dmat, mm->am_map); 551 free(mm, M_DEVBUF); 552 } 553 554 static int 555 mfi_transition_firmware(struct mfi_softc *sc) 556 { 557 uint32_t fw_state, cur_state; 558 int max_wait, i; 559 560 fw_state = mfi_fw_state(sc) & MFI_STATE_MASK; 561 562 DNPRINTF(MFI_D_CMD, "%s: mfi_transition_firmware: %#x\n", DEVNAME(sc), 563 fw_state); 564 565 while (fw_state != MFI_STATE_READY) { 566 DNPRINTF(MFI_D_MISC, 567 "%s: waiting for firmware to become ready\n", 568 DEVNAME(sc)); 569 cur_state = fw_state; 570 switch (fw_state) { 571 case MFI_STATE_FAULT: 572 aprint_error_dev(sc->sc_dev, "firmware fault\n"); 573 return 1; 574 case MFI_STATE_WAIT_HANDSHAKE: 575 if (sc->sc_ioptype == MFI_IOP_SKINNY || 576 sc->sc_ioptype == MFI_IOP_TBOLT) 577 mfi_write(sc, MFI_SKINNY_IDB, MFI_INIT_CLEAR_HANDSHAKE); 578 else 579 mfi_write(sc, MFI_IDB, MFI_INIT_CLEAR_HANDSHAKE); 580 max_wait = 2; 581 break; 582 case MFI_STATE_OPERATIONAL: 583 if (sc->sc_ioptype == MFI_IOP_SKINNY || 584 sc->sc_ioptype == MFI_IOP_TBOLT) 585 mfi_write(sc, MFI_SKINNY_IDB, MFI_INIT_READY); 586 else 587 mfi_write(sc, MFI_IDB, MFI_INIT_READY); 588 max_wait = 10; 589 break; 590 case MFI_STATE_UNDEFINED: 591 case MFI_STATE_BB_INIT: 592 max_wait = 2; 593 break; 594 case MFI_STATE_FW_INIT: 595 case MFI_STATE_DEVICE_SCAN: 596 case MFI_STATE_FLUSH_CACHE: 597 max_wait = 20; 598 break; 599 case MFI_STATE_BOOT_MESSAGE_PENDING: 600 if (sc->sc_ioptype == MFI_IOP_SKINNY || 601 sc->sc_ioptype == MFI_IOP_TBOLT) { 602 mfi_write(sc, MFI_SKINNY_IDB, MFI_INIT_HOTPLUG); 603 } else { 604 mfi_write(sc, MFI_IDB, MFI_INIT_HOTPLUG); 605 } 606 max_wait = 180; 607 break; 608 default: 609 aprint_error_dev(sc->sc_dev, 610 "unknown firmware state %d\n", fw_state); 611 return 1; 612 } 613 for (i = 0; i < (max_wait * 10); i++) { 614 fw_state = mfi_fw_state(sc) & MFI_STATE_MASK; 615 if (fw_state == cur_state) 616 DELAY(100000); 617 else 618 break; 619 } 620 if (fw_state == cur_state) { 621 aprint_error_dev(sc->sc_dev, 622 "firmware stuck in state %#x\n", fw_state); 623 return 1; 624 } 625 } 626 627 return 0; 628 } 629 630 static int 631 mfi_initialize_firmware(struct mfi_softc *sc) 632 { 633 struct mfi_ccb *ccb; 634 struct mfi_init_frame *init; 635 struct mfi_init_qinfo *qinfo; 636 637 DNPRINTF(MFI_D_MISC, "%s: mfi_initialize_firmware\n", DEVNAME(sc)); 638 639 if ((ccb = mfi_get_ccb(sc)) == NULL) 640 return 1; 641 642 init = &ccb->ccb_frame->mfr_init; 643 qinfo = (struct mfi_init_qinfo *)((uint8_t *)init + MFI_FRAME_SIZE); 644 645 memset(qinfo, 0, sizeof *qinfo); 646 qinfo->miq_rq_entries = sc->sc_max_cmds + 1; 647 qinfo->miq_rq_addr_lo = htole32(MFIMEM_DVA(sc->sc_pcq) + 648 offsetof(struct mfi_prod_cons, mpc_reply_q)); 649 qinfo->miq_pi_addr_lo = htole32(MFIMEM_DVA(sc->sc_pcq) + 650 offsetof(struct mfi_prod_cons, mpc_producer)); 651 qinfo->miq_ci_addr_lo = htole32(MFIMEM_DVA(sc->sc_pcq) + 652 offsetof(struct mfi_prod_cons, mpc_consumer)); 653 654 init->mif_header.mfh_cmd = MFI_CMD_INIT; 655 init->mif_header.mfh_data_len = sizeof *qinfo; 656 init->mif_qinfo_new_addr_lo = htole32(ccb->ccb_pframe + MFI_FRAME_SIZE); 657 658 DNPRINTF(MFI_D_MISC, "%s: entries: %#x rq: %#x pi: %#x ci: %#x\n", 659 DEVNAME(sc), 660 qinfo->miq_rq_entries, qinfo->miq_rq_addr_lo, 661 qinfo->miq_pi_addr_lo, qinfo->miq_ci_addr_lo); 662 663 if (mfi_poll(ccb)) { 664 aprint_error_dev(sc->sc_dev, 665 "mfi_initialize_firmware failed\n"); 666 return 1; 667 } 668 669 mfi_put_ccb(ccb); 670 671 return 0; 672 } 673 674 static int 675 mfi_get_info(struct mfi_softc *sc) 676 { 677 #ifdef MFI_DEBUG 678 int i; 679 #endif 680 DNPRINTF(MFI_D_MISC, "%s: mfi_get_info\n", DEVNAME(sc)); 681 682 if (mfi_mgmt_internal(sc, MR_DCMD_CTRL_GET_INFO, MFI_DATA_IN, 683 sizeof(sc->sc_info), &sc->sc_info, NULL, cold ? true : false)) 684 return 1; 685 686 #ifdef MFI_DEBUG 687 688 for (i = 0; i < sc->sc_info.mci_image_component_count; i++) { 689 printf("%s: active FW %s Version %s date %s time %s\n", 690 DEVNAME(sc), 691 sc->sc_info.mci_image_component[i].mic_name, 692 sc->sc_info.mci_image_component[i].mic_version, 693 sc->sc_info.mci_image_component[i].mic_build_date, 694 sc->sc_info.mci_image_component[i].mic_build_time); 695 } 696 697 for (i = 0; i < sc->sc_info.mci_pending_image_component_count; i++) { 698 printf("%s: pending FW %s Version %s date %s time %s\n", 699 DEVNAME(sc), 700 sc->sc_info.mci_pending_image_component[i].mic_name, 701 sc->sc_info.mci_pending_image_component[i].mic_version, 702 sc->sc_info.mci_pending_image_component[i].mic_build_date, 703 sc->sc_info.mci_pending_image_component[i].mic_build_time); 704 } 705 706 printf("%s: max_arms %d max_spans %d max_arrs %d max_lds %d name %s\n", 707 DEVNAME(sc), 708 sc->sc_info.mci_max_arms, 709 sc->sc_info.mci_max_spans, 710 sc->sc_info.mci_max_arrays, 711 sc->sc_info.mci_max_lds, 712 sc->sc_info.mci_product_name); 713 714 printf("%s: serial %s present %#x fw time %d max_cmds %d max_sg %d\n", 715 DEVNAME(sc), 716 sc->sc_info.mci_serial_number, 717 sc->sc_info.mci_hw_present, 718 sc->sc_info.mci_current_fw_time, 719 sc->sc_info.mci_max_cmds, 720 sc->sc_info.mci_max_sg_elements); 721 722 printf("%s: max_rq %d lds_pres %d lds_deg %d lds_off %d pd_pres %d\n", 723 DEVNAME(sc), 724 sc->sc_info.mci_max_request_size, 725 sc->sc_info.mci_lds_present, 726 sc->sc_info.mci_lds_degraded, 727 sc->sc_info.mci_lds_offline, 728 sc->sc_info.mci_pd_present); 729 730 printf("%s: pd_dsk_prs %d pd_dsk_pred_fail %d pd_dsk_fail %d\n", 731 DEVNAME(sc), 732 sc->sc_info.mci_pd_disks_present, 733 sc->sc_info.mci_pd_disks_pred_failure, 734 sc->sc_info.mci_pd_disks_failed); 735 736 printf("%s: nvram %d mem %d flash %d\n", 737 DEVNAME(sc), 738 sc->sc_info.mci_nvram_size, 739 sc->sc_info.mci_memory_size, 740 sc->sc_info.mci_flash_size); 741 742 printf("%s: ram_cor %d ram_uncor %d clus_all %d clus_act %d\n", 743 DEVNAME(sc), 744 sc->sc_info.mci_ram_correctable_errors, 745 sc->sc_info.mci_ram_uncorrectable_errors, 746 sc->sc_info.mci_cluster_allowed, 747 sc->sc_info.mci_cluster_active); 748 749 printf("%s: max_strps_io %d raid_lvl %#x adapt_ops %#x ld_ops %#x\n", 750 DEVNAME(sc), 751 sc->sc_info.mci_max_strips_per_io, 752 sc->sc_info.mci_raid_levels, 753 sc->sc_info.mci_adapter_ops, 754 sc->sc_info.mci_ld_ops); 755 756 printf("%s: strp_sz_min %d strp_sz_max %d pd_ops %#x pd_mix %#x\n", 757 DEVNAME(sc), 758 sc->sc_info.mci_stripe_sz_ops.min, 759 sc->sc_info.mci_stripe_sz_ops.max, 760 sc->sc_info.mci_pd_ops, 761 sc->sc_info.mci_pd_mix_support); 762 763 printf("%s: ecc_bucket %d pckg_prop %s\n", 764 DEVNAME(sc), 765 sc->sc_info.mci_ecc_bucket_count, 766 sc->sc_info.mci_package_version); 767 768 printf("%s: sq_nm %d prd_fail_poll %d intr_thrtl %d intr_thrtl_to %d\n", 769 DEVNAME(sc), 770 sc->sc_info.mci_properties.mcp_seq_num, 771 sc->sc_info.mci_properties.mcp_pred_fail_poll_interval, 772 sc->sc_info.mci_properties.mcp_intr_throttle_cnt, 773 sc->sc_info.mci_properties.mcp_intr_throttle_timeout); 774 775 printf("%s: rbld_rate %d patr_rd_rate %d bgi_rate %d cc_rate %d\n", 776 DEVNAME(sc), 777 sc->sc_info.mci_properties.mcp_rebuild_rate, 778 sc->sc_info.mci_properties.mcp_patrol_read_rate, 779 sc->sc_info.mci_properties.mcp_bgi_rate, 780 sc->sc_info.mci_properties.mcp_cc_rate); 781 782 printf("%s: rc_rate %d ch_flsh %d spin_cnt %d spin_dly %d clus_en %d\n", 783 DEVNAME(sc), 784 sc->sc_info.mci_properties.mcp_recon_rate, 785 sc->sc_info.mci_properties.mcp_cache_flush_interval, 786 sc->sc_info.mci_properties.mcp_spinup_drv_cnt, 787 sc->sc_info.mci_properties.mcp_spinup_delay, 788 sc->sc_info.mci_properties.mcp_cluster_enable); 789 790 printf("%s: coerc %d alarm %d dis_auto_rbld %d dis_bat_wrn %d ecc %d\n", 791 DEVNAME(sc), 792 sc->sc_info.mci_properties.mcp_coercion_mode, 793 sc->sc_info.mci_properties.mcp_alarm_enable, 794 sc->sc_info.mci_properties.mcp_disable_auto_rebuild, 795 sc->sc_info.mci_properties.mcp_disable_battery_warn, 796 sc->sc_info.mci_properties.mcp_ecc_bucket_size); 797 798 printf("%s: ecc_leak %d rest_hs %d exp_encl_dev %d\n", 799 DEVNAME(sc), 800 sc->sc_info.mci_properties.mcp_ecc_bucket_leak_rate, 801 sc->sc_info.mci_properties.mcp_restore_hotspare_on_insertion, 802 sc->sc_info.mci_properties.mcp_expose_encl_devices); 803 804 printf("%s: vendor %#x device %#x subvendor %#x subdevice %#x\n", 805 DEVNAME(sc), 806 sc->sc_info.mci_pci.mip_vendor, 807 sc->sc_info.mci_pci.mip_device, 808 sc->sc_info.mci_pci.mip_subvendor, 809 sc->sc_info.mci_pci.mip_subdevice); 810 811 printf("%s: type %#x port_count %d port_addr ", 812 DEVNAME(sc), 813 sc->sc_info.mci_host.mih_type, 814 sc->sc_info.mci_host.mih_port_count); 815 816 for (i = 0; i < 8; i++) 817 printf("%.0" PRIx64 " ", sc->sc_info.mci_host.mih_port_addr[i]); 818 printf("\n"); 819 820 printf("%s: type %.x port_count %d port_addr ", 821 DEVNAME(sc), 822 sc->sc_info.mci_device.mid_type, 823 sc->sc_info.mci_device.mid_port_count); 824 825 for (i = 0; i < 8; i++) { 826 printf("%.0" PRIx64 " ", 827 sc->sc_info.mci_device.mid_port_addr[i]); 828 } 829 printf("\n"); 830 #endif /* MFI_DEBUG */ 831 832 return 0; 833 } 834 835 static int 836 mfi_get_bbu(struct mfi_softc *sc, struct mfi_bbu_status *stat) 837 { 838 DNPRINTF(MFI_D_MISC, "%s: mfi_get_bbu\n", DEVNAME(sc)); 839 840 if (mfi_mgmt_internal(sc, MR_DCMD_BBU_GET_STATUS, MFI_DATA_IN, 841 sizeof(*stat), stat, NULL, cold ? true : false)) 842 return MFI_BBU_UNKNOWN; 843 #ifdef MFI_DEBUG 844 printf("bbu type %d, voltage %d, current %d, temperature %d, " 845 "status 0x%x\n", stat->battery_type, stat->voltage, stat->current, 846 stat->temperature, stat->fw_status); 847 printf("details: "); 848 switch(stat->battery_type) { 849 case MFI_BBU_TYPE_IBBU: 850 printf("guage %d relative charge %d charger state %d " 851 "charger ctrl %d\n", stat->detail.ibbu.gas_guage_status, 852 stat->detail.ibbu.relative_charge , 853 stat->detail.ibbu.charger_system_state , 854 stat->detail.ibbu.charger_system_ctrl); 855 printf("\tcurrent %d abs charge %d max error %d\n", 856 stat->detail.ibbu.charging_current , 857 stat->detail.ibbu.absolute_charge , 858 stat->detail.ibbu.max_error); 859 break; 860 case MFI_BBU_TYPE_BBU: 861 printf("guage %d relative charge %d charger state %d\n", 862 stat->detail.ibbu.gas_guage_status, 863 stat->detail.bbu.relative_charge , 864 stat->detail.bbu.charger_status ); 865 printf("\trem capacity %d fyll capacity %d SOH %d\n", 866 stat->detail.bbu.remaining_capacity , 867 stat->detail.bbu.full_charge_capacity , 868 stat->detail.bbu.is_SOH_good); 869 break; 870 default: 871 printf("\n"); 872 } 873 #endif 874 switch(stat->battery_type) { 875 case MFI_BBU_TYPE_BBU: 876 return (stat->detail.bbu.is_SOH_good ? 877 MFI_BBU_GOOD : MFI_BBU_BAD); 878 case MFI_BBU_TYPE_NONE: 879 return MFI_BBU_UNKNOWN; 880 default: 881 if (stat->fw_status & 882 (MFI_BBU_STATE_PACK_MISSING | 883 MFI_BBU_STATE_VOLTAGE_LOW | 884 MFI_BBU_STATE_TEMPERATURE_HIGH | 885 MFI_BBU_STATE_LEARN_CYC_FAIL | 886 MFI_BBU_STATE_LEARN_CYC_TIMEOUT | 887 MFI_BBU_STATE_I2C_ERR_DETECT)) 888 return MFI_BBU_BAD; 889 return MFI_BBU_GOOD; 890 } 891 } 892 893 static void 894 mfiminphys(struct buf *bp) 895 { 896 DNPRINTF(MFI_D_MISC, "mfiminphys: %d\n", bp->b_bcount); 897 898 /* XXX currently using MFI_MAXFER = MAXPHYS */ 899 if (bp->b_bcount > MFI_MAXFER) 900 bp->b_bcount = MFI_MAXFER; 901 minphys(bp); 902 } 903 904 int 905 mfi_rescan(device_t self, const char *ifattr, const int *locators) 906 { 907 struct mfi_softc *sc = device_private(self); 908 909 if (sc->sc_child != NULL) 910 return 0; 911 912 sc->sc_child = config_found(self, &sc->sc_chan, scsiprint, CFARG_EOL); 913 914 return 0; 915 } 916 917 void 918 mfi_childdetached(device_t self, device_t child) 919 { 920 struct mfi_softc *sc = device_private(self); 921 922 KASSERT(self == sc->sc_dev); 923 KASSERT(child == sc->sc_child); 924 925 if (child == sc->sc_child) 926 sc->sc_child = NULL; 927 } 928 929 int 930 mfi_detach(struct mfi_softc *sc, int flags) 931 { 932 int error; 933 934 DNPRINTF(MFI_D_MISC, "%s: mfi_detach\n", DEVNAME(sc)); 935 936 if ((error = config_detach_children(sc->sc_dev, flags)) != 0) 937 return error; 938 939 #if NBIO > 0 940 mfi_destroy_sensors(sc); 941 bio_unregister(sc->sc_dev); 942 #endif /* NBIO > 0 */ 943 944 mfi_intr_disable(sc); 945 mfi_shutdown(sc->sc_dev, 0); 946 947 if (sc->sc_ioptype == MFI_IOP_TBOLT) { 948 workqueue_destroy(sc->sc_ldsync_wq); 949 mfi_put_ccb(sc->sc_ldsync_ccb); 950 mfi_freemem(sc, &sc->sc_tbolt_reqmsgpool); 951 mfi_freemem(sc, &sc->sc_tbolt_ioc_init); 952 mfi_freemem(sc, &sc->sc_tbolt_verbuf); 953 } 954 955 if ((error = mfi_destroy_ccb(sc)) != 0) 956 return error; 957 958 mfi_freemem(sc, &sc->sc_sense); 959 960 mfi_freemem(sc, &sc->sc_frames); 961 962 mfi_freemem(sc, &sc->sc_pcq); 963 964 return 0; 965 } 966 967 static bool 968 mfi_shutdown(device_t dev, int how) 969 { 970 struct mfi_softc *sc = device_private(dev); 971 uint8_t mbox[MFI_MBOX_SIZE]; 972 int s = splbio(); 973 DNPRINTF(MFI_D_MISC, "%s: mfi_shutdown\n", DEVNAME(sc)); 974 if (sc->sc_running) { 975 mbox[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE; 976 if (mfi_mgmt_internal(sc, MR_DCMD_CTRL_CACHE_FLUSH, 977 MFI_DATA_NONE, 0, NULL, mbox, true)) { 978 aprint_error_dev(dev, "shutdown: cache flush failed\n"); 979 goto fail; 980 } 981 982 mbox[0] = 0; 983 if (mfi_mgmt_internal(sc, MR_DCMD_CTRL_SHUTDOWN, 984 MFI_DATA_NONE, 0, NULL, mbox, true)) { 985 aprint_error_dev(dev, "shutdown: " 986 "firmware shutdown failed\n"); 987 goto fail; 988 } 989 sc->sc_running = false; 990 } 991 splx(s); 992 return true; 993 fail: 994 splx(s); 995 return false; 996 } 997 998 static bool 999 mfi_suspend(device_t dev, const pmf_qual_t *q) 1000 { 1001 /* XXX to be implemented */ 1002 return false; 1003 } 1004 1005 static bool 1006 mfi_resume(device_t dev, const pmf_qual_t *q) 1007 { 1008 /* XXX to be implemented */ 1009 return false; 1010 } 1011 1012 int 1013 mfi_attach(struct mfi_softc *sc, enum mfi_iop iop) 1014 { 1015 struct scsipi_adapter *adapt = &sc->sc_adapt; 1016 struct scsipi_channel *chan = &sc->sc_chan; 1017 uint32_t status, frames, max_sgl; 1018 int i; 1019 1020 DNPRINTF(MFI_D_MISC, "%s: mfi_attach\n", DEVNAME(sc)); 1021 1022 sc->sc_ioptype = iop; 1023 1024 switch (iop) { 1025 case MFI_IOP_XSCALE: 1026 sc->sc_iop = &mfi_iop_xscale; 1027 break; 1028 case MFI_IOP_PPC: 1029 sc->sc_iop = &mfi_iop_ppc; 1030 break; 1031 case MFI_IOP_GEN2: 1032 sc->sc_iop = &mfi_iop_gen2; 1033 break; 1034 case MFI_IOP_SKINNY: 1035 sc->sc_iop = &mfi_iop_skinny; 1036 break; 1037 case MFI_IOP_TBOLT: 1038 sc->sc_iop = &mfi_iop_tbolt; 1039 break; 1040 default: 1041 panic("%s: unknown iop %d", DEVNAME(sc), iop); 1042 } 1043 1044 if (mfi_transition_firmware(sc)) 1045 return 1; 1046 1047 TAILQ_INIT(&sc->sc_ccb_freeq); 1048 1049 status = mfi_fw_state(sc); 1050 sc->sc_max_cmds = status & MFI_STATE_MAXCMD_MASK; 1051 max_sgl = (status & MFI_STATE_MAXSGL_MASK) >> 16; 1052 if (sc->sc_ioptype == MFI_IOP_TBOLT) { 1053 sc->sc_max_sgl = uimin(max_sgl, (128 * 1024) / PAGE_SIZE + 1); 1054 sc->sc_sgl_size = sizeof(struct mfi_sg_ieee); 1055 } else if (sc->sc_64bit_dma) { 1056 sc->sc_max_sgl = uimin(max_sgl, (128 * 1024) / PAGE_SIZE + 1); 1057 sc->sc_sgl_size = sizeof(struct mfi_sg64); 1058 } else { 1059 sc->sc_max_sgl = max_sgl; 1060 sc->sc_sgl_size = sizeof(struct mfi_sg32); 1061 } 1062 DNPRINTF(MFI_D_MISC, "%s: max commands: %u, max sgl: %u\n", 1063 DEVNAME(sc), sc->sc_max_cmds, sc->sc_max_sgl); 1064 1065 if (sc->sc_ioptype == MFI_IOP_TBOLT) { 1066 uint32_t tb_mem_size; 1067 /* for Alignment */ 1068 tb_mem_size = MEGASAS_THUNDERBOLT_MSG_ALLIGNMENT; 1069 1070 tb_mem_size += 1071 MEGASAS_THUNDERBOLT_NEW_MSG_SIZE * (sc->sc_max_cmds + 1); 1072 sc->sc_reply_pool_size = 1073 ((sc->sc_max_cmds + 1 + 15) / 16) * 16; 1074 tb_mem_size += 1075 MEGASAS_THUNDERBOLT_REPLY_SIZE * sc->sc_reply_pool_size; 1076 1077 /* this is for SGL's */ 1078 tb_mem_size += MEGASAS_MAX_SZ_CHAIN_FRAME * sc->sc_max_cmds; 1079 sc->sc_tbolt_reqmsgpool = mfi_allocmem(sc, tb_mem_size); 1080 if (sc->sc_tbolt_reqmsgpool == NULL) { 1081 aprint_error_dev(sc->sc_dev, 1082 "unable to allocate thunderbolt " 1083 "request message pool\n"); 1084 goto nopcq; 1085 } 1086 if (mfi_tbolt_init_desc_pool(sc)) { 1087 aprint_error_dev(sc->sc_dev, 1088 "Thunderbolt pool preparation error\n"); 1089 goto nopcq; 1090 } 1091 1092 /* 1093 * Allocate DMA memory mapping for MPI2 IOC Init descriptor, 1094 * we are taking it diffrent from what we have allocated for 1095 * Request and reply descriptors to avoid confusion later 1096 */ 1097 sc->sc_tbolt_ioc_init = mfi_allocmem(sc, 1098 sizeof(struct mpi2_ioc_init_request)); 1099 if (sc->sc_tbolt_ioc_init == NULL) { 1100 aprint_error_dev(sc->sc_dev, 1101 "unable to allocate thunderbolt IOC init memory"); 1102 goto nopcq; 1103 } 1104 1105 sc->sc_tbolt_verbuf = mfi_allocmem(sc, 1106 MEGASAS_MAX_NAME*sizeof(bus_addr_t)); 1107 if (sc->sc_tbolt_verbuf == NULL) { 1108 aprint_error_dev(sc->sc_dev, 1109 "unable to allocate thunderbolt version buffer\n"); 1110 goto nopcq; 1111 } 1112 1113 } 1114 /* consumer/producer and reply queue memory */ 1115 sc->sc_pcq = mfi_allocmem(sc, (sizeof(uint32_t) * sc->sc_max_cmds) + 1116 sizeof(struct mfi_prod_cons)); 1117 if (sc->sc_pcq == NULL) { 1118 aprint_error_dev(sc->sc_dev, 1119 "unable to allocate reply queue memory\n"); 1120 goto nopcq; 1121 } 1122 bus_dmamap_sync(sc->sc_dmat, MFIMEM_MAP(sc->sc_pcq), 0, 1123 sizeof(uint32_t) * sc->sc_max_cmds + sizeof(struct mfi_prod_cons), 1124 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1125 1126 /* frame memory */ 1127 frames = (sc->sc_sgl_size * sc->sc_max_sgl + MFI_FRAME_SIZE - 1) / 1128 MFI_FRAME_SIZE + 1; 1129 sc->sc_frames_size = frames * MFI_FRAME_SIZE; 1130 sc->sc_frames = mfi_allocmem(sc, sc->sc_frames_size * sc->sc_max_cmds); 1131 if (sc->sc_frames == NULL) { 1132 aprint_error_dev(sc->sc_dev, 1133 "unable to allocate frame memory\n"); 1134 goto noframe; 1135 } 1136 /* XXX hack, fix this */ 1137 if (MFIMEM_DVA(sc->sc_frames) & 0x3f) { 1138 aprint_error_dev(sc->sc_dev, 1139 "improper frame alignment (%#llx) FIXME\n", 1140 (long long int)MFIMEM_DVA(sc->sc_frames)); 1141 goto noframe; 1142 } 1143 1144 /* sense memory */ 1145 sc->sc_sense = mfi_allocmem(sc, sc->sc_max_cmds * MFI_SENSE_SIZE); 1146 if (sc->sc_sense == NULL) { 1147 aprint_error_dev(sc->sc_dev, 1148 "unable to allocate sense memory\n"); 1149 goto nosense; 1150 } 1151 1152 /* now that we have all memory bits go initialize ccbs */ 1153 if (mfi_init_ccb(sc)) { 1154 aprint_error_dev(sc->sc_dev, "could not init ccb list\n"); 1155 goto noinit; 1156 } 1157 1158 /* kickstart firmware with all addresses and pointers */ 1159 if (sc->sc_ioptype == MFI_IOP_TBOLT) { 1160 if (mfi_tbolt_init_MFI_queue(sc)) { 1161 aprint_error_dev(sc->sc_dev, 1162 "could not initialize firmware\n"); 1163 goto noinit; 1164 } 1165 } else { 1166 if (mfi_initialize_firmware(sc)) { 1167 aprint_error_dev(sc->sc_dev, 1168 "could not initialize firmware\n"); 1169 goto noinit; 1170 } 1171 } 1172 sc->sc_running = true; 1173 1174 if (mfi_get_info(sc)) { 1175 aprint_error_dev(sc->sc_dev, 1176 "could not retrieve controller information\n"); 1177 goto noinit; 1178 } 1179 aprint_normal_dev(sc->sc_dev, 1180 "%s version %s\n", 1181 sc->sc_info.mci_product_name, 1182 sc->sc_info.mci_package_version); 1183 1184 1185 aprint_normal_dev(sc->sc_dev, "logical drives %d, %dMB RAM, ", 1186 sc->sc_info.mci_lds_present, 1187 sc->sc_info.mci_memory_size); 1188 sc->sc_bbuok = false; 1189 if (sc->sc_info.mci_hw_present & MFI_INFO_HW_BBU) { 1190 struct mfi_bbu_status bbu_stat; 1191 int mfi_bbu_status = mfi_get_bbu(sc, &bbu_stat); 1192 aprint_normal("BBU type "); 1193 switch (bbu_stat.battery_type) { 1194 case MFI_BBU_TYPE_BBU: 1195 aprint_normal("BBU"); 1196 break; 1197 case MFI_BBU_TYPE_IBBU: 1198 aprint_normal("IBBU"); 1199 break; 1200 default: 1201 aprint_normal("unknown type %d", bbu_stat.battery_type); 1202 } 1203 aprint_normal(", status "); 1204 switch(mfi_bbu_status) { 1205 case MFI_BBU_GOOD: 1206 aprint_normal("good\n"); 1207 sc->sc_bbuok = true; 1208 break; 1209 case MFI_BBU_BAD: 1210 aprint_normal("bad\n"); 1211 break; 1212 case MFI_BBU_UNKNOWN: 1213 aprint_normal("unknown\n"); 1214 break; 1215 default: 1216 panic("mfi_bbu_status"); 1217 } 1218 } else { 1219 aprint_normal("BBU not present\n"); 1220 } 1221 1222 sc->sc_ld_cnt = sc->sc_info.mci_lds_present; 1223 sc->sc_max_ld = sc->sc_ld_cnt; 1224 for (i = 0; i < sc->sc_ld_cnt; i++) 1225 sc->sc_ld[i].ld_present = 1; 1226 1227 memset(adapt, 0, sizeof(*adapt)); 1228 adapt->adapt_dev = sc->sc_dev; 1229 adapt->adapt_nchannels = 1; 1230 /* keep a few commands for management */ 1231 if (sc->sc_max_cmds > 4) 1232 adapt->adapt_openings = sc->sc_max_cmds - 4; 1233 else 1234 adapt->adapt_openings = sc->sc_max_cmds; 1235 adapt->adapt_max_periph = adapt->adapt_openings; 1236 adapt->adapt_request = mfi_scsipi_request; 1237 adapt->adapt_minphys = mfiminphys; 1238 1239 memset(chan, 0, sizeof(*chan)); 1240 chan->chan_adapter = adapt; 1241 chan->chan_bustype = &scsi_sas_bustype; 1242 chan->chan_channel = 0; 1243 chan->chan_flags = 0; 1244 chan->chan_nluns = 8; 1245 chan->chan_ntargets = MFI_MAX_LD; 1246 chan->chan_id = MFI_MAX_LD; 1247 1248 mfi_rescan(sc->sc_dev, NULL, NULL); 1249 1250 /* enable interrupts */ 1251 mfi_intr_enable(sc); 1252 1253 #if NBIO > 0 1254 if (bio_register(sc->sc_dev, mfi_ioctl) != 0) 1255 panic("%s: controller registration failed", DEVNAME(sc)); 1256 if (mfi_create_sensors(sc) != 0) 1257 aprint_error_dev(sc->sc_dev, "unable to create sensors\n"); 1258 #endif /* NBIO > 0 */ 1259 if (!pmf_device_register1(sc->sc_dev, mfi_suspend, mfi_resume, 1260 mfi_shutdown)) { 1261 aprint_error_dev(sc->sc_dev, 1262 "couldn't establish power handler\n"); 1263 } 1264 1265 return 0; 1266 noinit: 1267 mfi_freemem(sc, &sc->sc_sense); 1268 nosense: 1269 mfi_freemem(sc, &sc->sc_frames); 1270 noframe: 1271 mfi_freemem(sc, &sc->sc_pcq); 1272 nopcq: 1273 if (sc->sc_ioptype == MFI_IOP_TBOLT) { 1274 if (sc->sc_tbolt_reqmsgpool) 1275 mfi_freemem(sc, &sc->sc_tbolt_reqmsgpool); 1276 if (sc->sc_tbolt_verbuf) 1277 mfi_freemem(sc, &sc->sc_tbolt_verbuf); 1278 } 1279 return 1; 1280 } 1281 1282 static int 1283 mfi_poll(struct mfi_ccb *ccb) 1284 { 1285 struct mfi_softc *sc = ccb->ccb_sc; 1286 struct mfi_frame_header *hdr; 1287 int to = 0; 1288 int rv = 0; 1289 1290 DNPRINTF(MFI_D_CMD, "%s: mfi_poll\n", DEVNAME(sc)); 1291 1292 hdr = &ccb->ccb_frame->mfr_header; 1293 hdr->mfh_cmd_status = 0xff; 1294 if (!sc->sc_MFA_enabled) 1295 hdr->mfh_flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE; 1296 1297 /* no callback, caller is supposed to do the cleanup */ 1298 ccb->ccb_done = NULL; 1299 1300 mfi_post(sc, ccb); 1301 if (sc->sc_MFA_enabled) { 1302 /* 1303 * depending on the command type, result may be posted 1304 * to *hdr, or not. In addition it seems there's 1305 * no way to avoid posting the SMID to the reply queue. 1306 * So pool using the interrupt routine. 1307 */ 1308 while (ccb->ccb_state != MFI_CCB_DONE) { 1309 delay(1000); 1310 if (to++ > 5000) { /* XXX 5 seconds busywait sucks */ 1311 rv = 1; 1312 break; 1313 } 1314 mfi_tbolt_intrh(sc); 1315 } 1316 } else { 1317 bus_dmamap_sync(sc->sc_dmat, MFIMEM_MAP(sc->sc_frames), 1318 ccb->ccb_pframe - MFIMEM_DVA(sc->sc_frames), 1319 sc->sc_frames_size, BUS_DMASYNC_POSTREAD); 1320 1321 while (hdr->mfh_cmd_status == 0xff) { 1322 delay(1000); 1323 if (to++ > 5000) { /* XXX 5 seconds busywait sucks */ 1324 rv = 1; 1325 break; 1326 } 1327 bus_dmamap_sync(sc->sc_dmat, MFIMEM_MAP(sc->sc_frames), 1328 ccb->ccb_pframe - MFIMEM_DVA(sc->sc_frames), 1329 sc->sc_frames_size, BUS_DMASYNC_POSTREAD); 1330 } 1331 } 1332 bus_dmamap_sync(sc->sc_dmat, MFIMEM_MAP(sc->sc_frames), 1333 ccb->ccb_pframe - MFIMEM_DVA(sc->sc_frames), 1334 sc->sc_frames_size, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1335 1336 if (ccb->ccb_data != NULL) { 1337 DNPRINTF(MFI_D_INTR, "%s: mfi_mgmt_done sync\n", 1338 DEVNAME(sc)); 1339 bus_dmamap_sync(sc->sc_datadmat, ccb->ccb_dmamap, 0, 1340 ccb->ccb_dmamap->dm_mapsize, 1341 (ccb->ccb_direction & MFI_DATA_IN) ? 1342 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 1343 1344 bus_dmamap_unload(sc->sc_datadmat, ccb->ccb_dmamap); 1345 } 1346 1347 if (rv != 0) { 1348 aprint_error_dev(sc->sc_dev, "timeout on ccb %d\n", 1349 hdr->mfh_context); 1350 ccb->ccb_flags |= MFI_CCB_F_ERR; 1351 return 1; 1352 } 1353 1354 return 0; 1355 } 1356 1357 int 1358 mfi_intr(void *arg) 1359 { 1360 struct mfi_softc *sc = arg; 1361 struct mfi_prod_cons *pcq; 1362 struct mfi_ccb *ccb; 1363 uint32_t producer, consumer, ctx; 1364 int claimed = 0; 1365 1366 if (!mfi_my_intr(sc)) 1367 return 0; 1368 1369 pcq = MFIMEM_KVA(sc->sc_pcq); 1370 1371 DNPRINTF(MFI_D_INTR, "%s: mfi_intr %#lx %#lx\n", DEVNAME(sc), 1372 (u_long)sc, (u_long)pcq); 1373 1374 bus_dmamap_sync(sc->sc_dmat, MFIMEM_MAP(sc->sc_pcq), 0, 1375 sizeof(uint32_t) * sc->sc_max_cmds + sizeof(struct mfi_prod_cons), 1376 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1377 1378 producer = pcq->mpc_producer; 1379 consumer = pcq->mpc_consumer; 1380 1381 while (consumer != producer) { 1382 DNPRINTF(MFI_D_INTR, "%s: mfi_intr pi %#x ci %#x\n", 1383 DEVNAME(sc), producer, consumer); 1384 1385 ctx = pcq->mpc_reply_q[consumer]; 1386 pcq->mpc_reply_q[consumer] = MFI_INVALID_CTX; 1387 if (ctx == MFI_INVALID_CTX) 1388 aprint_error_dev(sc->sc_dev, 1389 "invalid context, p: %d c: %d\n", 1390 producer, consumer); 1391 else { 1392 /* XXX remove from queue and call scsi_done */ 1393 ccb = &sc->sc_ccb[ctx]; 1394 DNPRINTF(MFI_D_INTR, "%s: mfi_intr context %#x\n", 1395 DEVNAME(sc), ctx); 1396 bus_dmamap_sync(sc->sc_dmat, MFIMEM_MAP(sc->sc_frames), 1397 ccb->ccb_pframe - MFIMEM_DVA(sc->sc_frames), 1398 sc->sc_frames_size, 1399 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1400 ccb->ccb_done(ccb); 1401 1402 claimed = 1; 1403 } 1404 consumer++; 1405 if (consumer == (sc->sc_max_cmds + 1)) 1406 consumer = 0; 1407 } 1408 1409 pcq->mpc_consumer = consumer; 1410 bus_dmamap_sync(sc->sc_dmat, MFIMEM_MAP(sc->sc_pcq), 0, 1411 sizeof(uint32_t) * sc->sc_max_cmds + sizeof(struct mfi_prod_cons), 1412 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1413 1414 return claimed; 1415 } 1416 1417 static int 1418 mfi_scsi_ld_io(struct mfi_ccb *ccb, struct scsipi_xfer *xs, uint64_t blockno, 1419 uint32_t blockcnt) 1420 { 1421 struct scsipi_periph *periph = xs->xs_periph; 1422 struct mfi_io_frame *io; 1423 1424 DNPRINTF(MFI_D_CMD, "%s: mfi_scsi_ld_io: %d\n", 1425 device_xname(periph->periph_channel->chan_adapter->adapt_dev), 1426 periph->periph_target); 1427 1428 if (!xs->data) 1429 return 1; 1430 1431 io = &ccb->ccb_frame->mfr_io; 1432 if (xs->xs_control & XS_CTL_DATA_IN) { 1433 io->mif_header.mfh_cmd = MFI_CMD_LD_READ; 1434 ccb->ccb_direction = MFI_DATA_IN; 1435 } else { 1436 io->mif_header.mfh_cmd = MFI_CMD_LD_WRITE; 1437 ccb->ccb_direction = MFI_DATA_OUT; 1438 } 1439 io->mif_header.mfh_target_id = periph->periph_target; 1440 io->mif_header.mfh_timeout = 0; 1441 io->mif_header.mfh_flags = 0; 1442 io->mif_header.mfh_sense_len = MFI_SENSE_SIZE; 1443 io->mif_header.mfh_data_len= blockcnt; 1444 io->mif_lba_hi = (blockno >> 32); 1445 io->mif_lba_lo = (blockno & 0xffffffff); 1446 io->mif_sense_addr_lo = htole32(ccb->ccb_psense); 1447 io->mif_sense_addr_hi = 0; 1448 1449 ccb->ccb_done = mfi_scsi_ld_done; 1450 ccb->ccb_xs = xs; 1451 ccb->ccb_frame_size = MFI_IO_FRAME_SIZE; 1452 ccb->ccb_sgl = &io->mif_sgl; 1453 ccb->ccb_data = xs->data; 1454 ccb->ccb_len = xs->datalen; 1455 1456 if (mfi_create_sgl(ccb, (xs->xs_control & XS_CTL_NOSLEEP) ? 1457 BUS_DMA_NOWAIT : BUS_DMA_WAITOK)) 1458 return 1; 1459 1460 return 0; 1461 } 1462 1463 static void 1464 mfi_scsi_ld_done(struct mfi_ccb *ccb) 1465 { 1466 struct mfi_frame_header *hdr = &ccb->ccb_frame->mfr_header; 1467 mfi_scsi_xs_done(ccb, hdr->mfh_cmd_status, hdr->mfh_scsi_status); 1468 } 1469 1470 static void 1471 mfi_scsi_xs_done(struct mfi_ccb *ccb, int status, int scsi_status) 1472 { 1473 struct scsipi_xfer *xs = ccb->ccb_xs; 1474 struct mfi_softc *sc = ccb->ccb_sc; 1475 1476 DNPRINTF(MFI_D_INTR, "%s: mfi_scsi_xs_done %#lx %#lx\n", 1477 DEVNAME(sc), (u_long)ccb, (u_long)ccb->ccb_frame); 1478 1479 if (xs->data != NULL) { 1480 DNPRINTF(MFI_D_INTR, "%s: mfi_scsi_xs_done sync\n", 1481 DEVNAME(sc)); 1482 bus_dmamap_sync(sc->sc_datadmat, ccb->ccb_dmamap, 0, 1483 ccb->ccb_dmamap->dm_mapsize, 1484 (xs->xs_control & XS_CTL_DATA_IN) ? 1485 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 1486 1487 bus_dmamap_unload(sc->sc_datadmat, ccb->ccb_dmamap); 1488 } 1489 1490 if (status != MFI_STAT_OK) { 1491 xs->error = XS_DRIVER_STUFFUP; 1492 DNPRINTF(MFI_D_INTR, "%s: mfi_scsi_xs_done stuffup %#x\n", 1493 DEVNAME(sc), status); 1494 1495 if (scsi_status != 0) { 1496 bus_dmamap_sync(sc->sc_dmat, MFIMEM_MAP(sc->sc_sense), 1497 ccb->ccb_psense - MFIMEM_DVA(sc->sc_sense), 1498 MFI_SENSE_SIZE, BUS_DMASYNC_POSTREAD); 1499 DNPRINTF(MFI_D_INTR, 1500 "%s: mfi_scsi_xs_done sense %#x %lx %lx\n", 1501 DEVNAME(sc), scsi_status, 1502 (u_long)&xs->sense, (u_long)ccb->ccb_sense); 1503 memset(&xs->sense, 0, sizeof(xs->sense)); 1504 memcpy(&xs->sense, ccb->ccb_sense, 1505 sizeof(struct scsi_sense_data)); 1506 xs->error = XS_SENSE; 1507 } 1508 } else { 1509 xs->error = XS_NOERROR; 1510 xs->status = SCSI_OK; 1511 xs->resid = 0; 1512 } 1513 1514 mfi_put_ccb(ccb); 1515 scsipi_done(xs); 1516 } 1517 1518 static int 1519 mfi_scsi_ld(struct mfi_ccb *ccb, struct scsipi_xfer *xs) 1520 { 1521 struct mfi_pass_frame *pf; 1522 struct scsipi_periph *periph = xs->xs_periph; 1523 1524 DNPRINTF(MFI_D_CMD, "%s: mfi_scsi_ld: %d\n", 1525 device_xname(periph->periph_channel->chan_adapter->adapt_dev), 1526 periph->periph_target); 1527 1528 pf = &ccb->ccb_frame->mfr_pass; 1529 pf->mpf_header.mfh_cmd = MFI_CMD_LD_SCSI_IO; 1530 pf->mpf_header.mfh_target_id = periph->periph_target; 1531 pf->mpf_header.mfh_lun_id = 0; 1532 pf->mpf_header.mfh_cdb_len = xs->cmdlen; 1533 pf->mpf_header.mfh_timeout = 0; 1534 pf->mpf_header.mfh_data_len= xs->datalen; /* XXX */ 1535 pf->mpf_header.mfh_sense_len = MFI_SENSE_SIZE; 1536 1537 pf->mpf_sense_addr_hi = 0; 1538 pf->mpf_sense_addr_lo = htole32(ccb->ccb_psense); 1539 1540 memset(pf->mpf_cdb, 0, 16); 1541 memcpy(pf->mpf_cdb, &xs->cmdstore, xs->cmdlen); 1542 1543 ccb->ccb_done = mfi_scsi_ld_done; 1544 ccb->ccb_xs = xs; 1545 ccb->ccb_frame_size = MFI_PASS_FRAME_SIZE; 1546 ccb->ccb_sgl = &pf->mpf_sgl; 1547 1548 if (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) 1549 ccb->ccb_direction = (xs->xs_control & XS_CTL_DATA_IN) ? 1550 MFI_DATA_IN : MFI_DATA_OUT; 1551 else 1552 ccb->ccb_direction = MFI_DATA_NONE; 1553 1554 if (xs->data) { 1555 ccb->ccb_data = xs->data; 1556 ccb->ccb_len = xs->datalen; 1557 1558 if (mfi_create_sgl(ccb, (xs->xs_control & XS_CTL_NOSLEEP) ? 1559 BUS_DMA_NOWAIT : BUS_DMA_WAITOK)) 1560 return 1; 1561 } 1562 1563 return 0; 1564 } 1565 1566 static void 1567 mfi_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, 1568 void *arg) 1569 { 1570 struct scsipi_periph *periph; 1571 struct scsipi_xfer *xs; 1572 struct scsipi_adapter *adapt = chan->chan_adapter; 1573 struct mfi_softc *sc = device_private(adapt->adapt_dev); 1574 struct mfi_ccb *ccb; 1575 struct scsi_rw_6 *rw; 1576 struct scsipi_rw_10 *rwb; 1577 struct scsipi_rw_12 *rw12; 1578 struct scsipi_rw_16 *rw16; 1579 uint64_t blockno; 1580 uint32_t blockcnt; 1581 uint8_t target; 1582 uint8_t mbox[MFI_MBOX_SIZE]; 1583 int s; 1584 1585 switch (req) { 1586 case ADAPTER_REQ_GROW_RESOURCES: 1587 /* Not supported. */ 1588 return; 1589 case ADAPTER_REQ_SET_XFER_MODE: 1590 { 1591 struct scsipi_xfer_mode *xm = arg; 1592 xm->xm_mode = PERIPH_CAP_TQING; 1593 xm->xm_period = 0; 1594 xm->xm_offset = 0; 1595 scsipi_async_event(&sc->sc_chan, ASYNC_EVENT_XFER_MODE, xm); 1596 return; 1597 } 1598 case ADAPTER_REQ_RUN_XFER: 1599 break; 1600 } 1601 1602 xs = arg; 1603 1604 periph = xs->xs_periph; 1605 target = periph->periph_target; 1606 1607 DNPRINTF(MFI_D_CMD, "%s: mfi_scsipi_request req %d opcode: %#x " 1608 "target %d lun %d\n", DEVNAME(sc), req, xs->cmd->opcode, 1609 periph->periph_target, periph->periph_lun); 1610 1611 s = splbio(); 1612 if (target >= MFI_MAX_LD || !sc->sc_ld[target].ld_present || 1613 periph->periph_lun != 0) { 1614 DNPRINTF(MFI_D_CMD, "%s: invalid target %d\n", 1615 DEVNAME(sc), target); 1616 xs->error = XS_SELTIMEOUT; 1617 scsipi_done(xs); 1618 splx(s); 1619 return; 1620 } 1621 if ((xs->cmd->opcode == SCSI_SYNCHRONIZE_CACHE_10 || 1622 xs->cmd->opcode == SCSI_SYNCHRONIZE_CACHE_16) && sc->sc_bbuok) { 1623 /* the cache is stable storage, don't flush */ 1624 xs->error = XS_NOERROR; 1625 xs->status = SCSI_OK; 1626 xs->resid = 0; 1627 scsipi_done(xs); 1628 splx(s); 1629 return; 1630 } 1631 1632 if ((ccb = mfi_get_ccb(sc)) == NULL) { 1633 DNPRINTF(MFI_D_CMD, "%s: mfi_scsipi_request no ccb\n", DEVNAME(sc)); 1634 xs->error = XS_RESOURCE_SHORTAGE; 1635 scsipi_done(xs); 1636 splx(s); 1637 return; 1638 } 1639 1640 switch (xs->cmd->opcode) { 1641 /* IO path */ 1642 case READ_16: 1643 case WRITE_16: 1644 rw16 = (struct scsipi_rw_16 *)xs->cmd; 1645 blockno = _8btol(rw16->addr); 1646 blockcnt = _4btol(rw16->length); 1647 if (sc->sc_iop->mio_ld_io(ccb, xs, blockno, blockcnt)) { 1648 goto stuffup; 1649 } 1650 break; 1651 1652 case READ_12: 1653 case WRITE_12: 1654 rw12 = (struct scsipi_rw_12 *)xs->cmd; 1655 blockno = _4btol(rw12->addr); 1656 blockcnt = _4btol(rw12->length); 1657 if (sc->sc_iop->mio_ld_io(ccb, xs, blockno, blockcnt)) { 1658 goto stuffup; 1659 } 1660 break; 1661 1662 case READ_10: 1663 case WRITE_10: 1664 rwb = (struct scsipi_rw_10 *)xs->cmd; 1665 blockno = _4btol(rwb->addr); 1666 blockcnt = _2btol(rwb->length); 1667 if (sc->sc_iop->mio_ld_io(ccb, xs, blockno, blockcnt)) { 1668 goto stuffup; 1669 } 1670 break; 1671 1672 case SCSI_READ_6_COMMAND: 1673 case SCSI_WRITE_6_COMMAND: 1674 rw = (struct scsi_rw_6 *)xs->cmd; 1675 blockno = _3btol(rw->addr) & (SRW_TOPADDR << 16 | 0xffff); 1676 blockcnt = rw->length ? rw->length : 0x100; 1677 if (sc->sc_iop->mio_ld_io(ccb, xs, blockno, blockcnt)) { 1678 goto stuffup; 1679 } 1680 break; 1681 1682 case SCSI_SYNCHRONIZE_CACHE_10: 1683 case SCSI_SYNCHRONIZE_CACHE_16: 1684 mbox[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE; 1685 if (mfi_mgmt(ccb, xs, 1686 MR_DCMD_CTRL_CACHE_FLUSH, MFI_DATA_NONE, 0, NULL, mbox)) { 1687 goto stuffup; 1688 } 1689 break; 1690 1691 /* hand it of to the firmware and let it deal with it */ 1692 case SCSI_TEST_UNIT_READY: 1693 /* save off sd? after autoconf */ 1694 if (!cold) /* XXX bogus */ 1695 strlcpy(sc->sc_ld[target].ld_dev, device_xname(sc->sc_dev), 1696 sizeof(sc->sc_ld[target].ld_dev)); 1697 /* FALLTHROUGH */ 1698 1699 default: 1700 if (mfi_scsi_ld(ccb, xs)) { 1701 goto stuffup; 1702 } 1703 break; 1704 } 1705 1706 DNPRINTF(MFI_D_CMD, "%s: start io %d\n", DEVNAME(sc), target); 1707 1708 if (xs->xs_control & XS_CTL_POLL) { 1709 if (mfi_poll(ccb)) { 1710 /* XXX check for sense in ccb->ccb_sense? */ 1711 aprint_error_dev(sc->sc_dev, 1712 "mfi_scsipi_request poll failed\n"); 1713 memset(&xs->sense, 0, sizeof(xs->sense)); 1714 xs->sense.scsi_sense.response_code = 1715 SSD_RCODE_VALID | SSD_RCODE_CURRENT; 1716 xs->sense.scsi_sense.flags = SKEY_ILLEGAL_REQUEST; 1717 xs->sense.scsi_sense.asc = 0x20; /* invalid opcode */ 1718 xs->error = XS_SENSE; 1719 xs->status = SCSI_CHECK; 1720 } else { 1721 DNPRINTF(MFI_D_DMA, 1722 "%s: mfi_scsipi_request poll complete %d\n", 1723 DEVNAME(sc), ccb->ccb_dmamap->dm_nsegs); 1724 xs->error = XS_NOERROR; 1725 xs->status = SCSI_OK; 1726 xs->resid = 0; 1727 } 1728 mfi_put_ccb(ccb); 1729 scsipi_done(xs); 1730 splx(s); 1731 return; 1732 } 1733 1734 mfi_post(sc, ccb); 1735 1736 DNPRINTF(MFI_D_DMA, "%s: mfi_scsipi_request queued %d\n", DEVNAME(sc), 1737 ccb->ccb_dmamap->dm_nsegs); 1738 1739 splx(s); 1740 return; 1741 1742 stuffup: 1743 mfi_put_ccb(ccb); 1744 xs->error = XS_DRIVER_STUFFUP; 1745 scsipi_done(xs); 1746 splx(s); 1747 } 1748 1749 static int 1750 mfi_create_sgl(struct mfi_ccb *ccb, int flags) 1751 { 1752 struct mfi_softc *sc = ccb->ccb_sc; 1753 struct mfi_frame_header *hdr; 1754 bus_dma_segment_t *sgd; 1755 union mfi_sgl *sgl; 1756 int error, i; 1757 1758 DNPRINTF(MFI_D_DMA, "%s: mfi_create_sgl %#lx\n", DEVNAME(sc), 1759 (u_long)ccb->ccb_data); 1760 1761 if (!ccb->ccb_data) 1762 return 1; 1763 1764 KASSERT(flags == BUS_DMA_NOWAIT || !cpu_intr_p()); 1765 error = bus_dmamap_load(sc->sc_datadmat, ccb->ccb_dmamap, 1766 ccb->ccb_data, ccb->ccb_len, NULL, flags); 1767 if (error) { 1768 if (error == EFBIG) { 1769 aprint_error_dev(sc->sc_dev, "more than %d dma segs\n", 1770 sc->sc_max_sgl); 1771 } else { 1772 aprint_error_dev(sc->sc_dev, 1773 "error %d loading dma map\n", error); 1774 } 1775 return 1; 1776 } 1777 1778 hdr = &ccb->ccb_frame->mfr_header; 1779 sgl = ccb->ccb_sgl; 1780 sgd = ccb->ccb_dmamap->dm_segs; 1781 for (i = 0; i < ccb->ccb_dmamap->dm_nsegs; i++) { 1782 if (sc->sc_ioptype == MFI_IOP_TBOLT && 1783 (hdr->mfh_cmd == MFI_CMD_PD_SCSI_IO || 1784 hdr->mfh_cmd == MFI_CMD_LD_READ || 1785 hdr->mfh_cmd == MFI_CMD_LD_WRITE)) { 1786 sgl->sg_ieee[i].addr = htole64(sgd[i].ds_addr); 1787 sgl->sg_ieee[i].len = htole32(sgd[i].ds_len); 1788 sgl->sg_ieee[i].flags = 0; 1789 DNPRINTF(MFI_D_DMA, "%s: addr: %#" PRIx64 " len: %#" 1790 PRIx32 "\n", 1791 DEVNAME(sc), sgl->sg64[i].addr, sgl->sg64[i].len); 1792 hdr->mfh_flags |= MFI_FRAME_IEEE_SGL | MFI_FRAME_SGL64; 1793 } else if (sc->sc_64bit_dma) { 1794 sgl->sg64[i].addr = htole64(sgd[i].ds_addr); 1795 sgl->sg64[i].len = htole32(sgd[i].ds_len); 1796 DNPRINTF(MFI_D_DMA, "%s: addr: %#" PRIx64 " len: %#" 1797 PRIx32 "\n", 1798 DEVNAME(sc), sgl->sg64[i].addr, sgl->sg64[i].len); 1799 hdr->mfh_flags |= MFI_FRAME_SGL64; 1800 } else { 1801 sgl->sg32[i].addr = htole32(sgd[i].ds_addr); 1802 sgl->sg32[i].len = htole32(sgd[i].ds_len); 1803 DNPRINTF(MFI_D_DMA, "%s: addr: %#x len: %#x\n", 1804 DEVNAME(sc), sgl->sg32[i].addr, sgl->sg32[i].len); 1805 hdr->mfh_flags |= MFI_FRAME_SGL32; 1806 } 1807 } 1808 1809 if (ccb->ccb_direction == MFI_DATA_IN) { 1810 hdr->mfh_flags |= MFI_FRAME_DIR_READ; 1811 bus_dmamap_sync(sc->sc_datadmat, ccb->ccb_dmamap, 0, 1812 ccb->ccb_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD); 1813 } else { 1814 hdr->mfh_flags |= MFI_FRAME_DIR_WRITE; 1815 bus_dmamap_sync(sc->sc_datadmat, ccb->ccb_dmamap, 0, 1816 ccb->ccb_dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE); 1817 } 1818 1819 hdr->mfh_sg_count = ccb->ccb_dmamap->dm_nsegs; 1820 ccb->ccb_frame_size += sc->sc_sgl_size * ccb->ccb_dmamap->dm_nsegs; 1821 ccb->ccb_extra_frames = (ccb->ccb_frame_size - 1) / MFI_FRAME_SIZE; 1822 1823 DNPRINTF(MFI_D_DMA, "%s: sg_count: %d frame_size: %d frames_size: %d" 1824 " dm_nsegs: %d extra_frames: %d\n", 1825 DEVNAME(sc), 1826 hdr->mfh_sg_count, 1827 ccb->ccb_frame_size, 1828 sc->sc_frames_size, 1829 ccb->ccb_dmamap->dm_nsegs, 1830 ccb->ccb_extra_frames); 1831 1832 return 0; 1833 } 1834 1835 static int 1836 mfi_mgmt_internal(struct mfi_softc *sc, uint32_t opc, uint32_t dir, 1837 uint32_t len, void *buf, uint8_t *mbox, bool poll) 1838 { 1839 struct mfi_ccb *ccb; 1840 int rv = 1; 1841 1842 if ((ccb = mfi_get_ccb(sc)) == NULL) 1843 return rv; 1844 rv = mfi_mgmt(ccb, NULL, opc, dir, len, buf, mbox); 1845 if (rv) 1846 return rv; 1847 1848 if (poll) { 1849 rv = 1; 1850 if (mfi_poll(ccb)) 1851 goto done; 1852 } else { 1853 mfi_post(sc, ccb); 1854 1855 DNPRINTF(MFI_D_MISC, "%s: mfi_mgmt_internal sleeping\n", 1856 DEVNAME(sc)); 1857 while (ccb->ccb_state != MFI_CCB_DONE) 1858 tsleep(ccb, PRIBIO, "mfi_mgmt", 0); 1859 1860 if (ccb->ccb_flags & MFI_CCB_F_ERR) 1861 goto done; 1862 } 1863 rv = 0; 1864 1865 done: 1866 mfi_put_ccb(ccb); 1867 return rv; 1868 } 1869 1870 static int 1871 mfi_mgmt(struct mfi_ccb *ccb, struct scsipi_xfer *xs, 1872 uint32_t opc, uint32_t dir, uint32_t len, void *buf, uint8_t *mbox) 1873 { 1874 struct mfi_dcmd_frame *dcmd; 1875 1876 DNPRINTF(MFI_D_MISC, "%s: mfi_mgmt %#x\n", DEVNAME(ccb->ccb_sc), opc); 1877 1878 dcmd = &ccb->ccb_frame->mfr_dcmd; 1879 memset(dcmd->mdf_mbox.b, 0, MFI_MBOX_SIZE); 1880 dcmd->mdf_header.mfh_cmd = MFI_CMD_DCMD; 1881 dcmd->mdf_header.mfh_timeout = 0; 1882 1883 dcmd->mdf_opcode = opc; 1884 dcmd->mdf_header.mfh_data_len = 0; 1885 ccb->ccb_direction = dir; 1886 ccb->ccb_xs = xs; 1887 ccb->ccb_done = mfi_mgmt_done; 1888 1889 ccb->ccb_frame_size = MFI_DCMD_FRAME_SIZE; 1890 1891 /* handle special opcodes */ 1892 if (mbox) 1893 memcpy(dcmd->mdf_mbox.b, mbox, MFI_MBOX_SIZE); 1894 1895 if (dir != MFI_DATA_NONE) { 1896 dcmd->mdf_header.mfh_data_len = len; 1897 ccb->ccb_data = buf; 1898 ccb->ccb_len = len; 1899 ccb->ccb_sgl = &dcmd->mdf_sgl; 1900 1901 if (mfi_create_sgl(ccb, BUS_DMA_WAITOK)) 1902 return 1; 1903 } 1904 return 0; 1905 } 1906 1907 static void 1908 mfi_mgmt_done(struct mfi_ccb *ccb) 1909 { 1910 struct scsipi_xfer *xs = ccb->ccb_xs; 1911 struct mfi_softc *sc = ccb->ccb_sc; 1912 struct mfi_frame_header *hdr = &ccb->ccb_frame->mfr_header; 1913 1914 DNPRINTF(MFI_D_INTR, "%s: mfi_mgmt_done %#lx %#lx\n", 1915 DEVNAME(sc), (u_long)ccb, (u_long)ccb->ccb_frame); 1916 1917 if (ccb->ccb_data != NULL) { 1918 DNPRINTF(MFI_D_INTR, "%s: mfi_mgmt_done sync\n", 1919 DEVNAME(sc)); 1920 bus_dmamap_sync(sc->sc_datadmat, ccb->ccb_dmamap, 0, 1921 ccb->ccb_dmamap->dm_mapsize, 1922 (ccb->ccb_direction & MFI_DATA_IN) ? 1923 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 1924 1925 bus_dmamap_unload(sc->sc_datadmat, ccb->ccb_dmamap); 1926 } 1927 1928 if (hdr->mfh_cmd_status != MFI_STAT_OK) 1929 ccb->ccb_flags |= MFI_CCB_F_ERR; 1930 1931 ccb->ccb_state = MFI_CCB_DONE; 1932 if (xs) { 1933 if (hdr->mfh_cmd_status != MFI_STAT_OK) { 1934 xs->error = XS_DRIVER_STUFFUP; 1935 } else { 1936 xs->error = XS_NOERROR; 1937 xs->status = SCSI_OK; 1938 xs->resid = 0; 1939 } 1940 mfi_put_ccb(ccb); 1941 scsipi_done(xs); 1942 } else 1943 wakeup(ccb); 1944 } 1945 1946 #if NBIO > 0 1947 int 1948 mfi_ioctl(device_t dev, u_long cmd, void *addr) 1949 { 1950 struct mfi_softc *sc = device_private(dev); 1951 int error = 0; 1952 int s; 1953 1954 KERNEL_LOCK(1, curlwp); 1955 s = splbio(); 1956 1957 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl ", DEVNAME(sc)); 1958 1959 switch (cmd) { 1960 case BIOCINQ: 1961 DNPRINTF(MFI_D_IOCTL, "inq\n"); 1962 error = mfi_ioctl_inq(sc, (struct bioc_inq *)addr); 1963 break; 1964 1965 case BIOCVOL: 1966 DNPRINTF(MFI_D_IOCTL, "vol\n"); 1967 error = mfi_ioctl_vol(sc, (struct bioc_vol *)addr); 1968 break; 1969 1970 case BIOCDISK: 1971 DNPRINTF(MFI_D_IOCTL, "disk\n"); 1972 error = mfi_ioctl_disk(sc, (struct bioc_disk *)addr); 1973 break; 1974 1975 case BIOCALARM: 1976 DNPRINTF(MFI_D_IOCTL, "alarm\n"); 1977 error = mfi_ioctl_alarm(sc, (struct bioc_alarm *)addr); 1978 break; 1979 1980 case BIOCBLINK: 1981 DNPRINTF(MFI_D_IOCTL, "blink\n"); 1982 error = mfi_ioctl_blink(sc, (struct bioc_blink *)addr); 1983 break; 1984 1985 case BIOCSETSTATE: 1986 DNPRINTF(MFI_D_IOCTL, "setstate\n"); 1987 error = mfi_ioctl_setstate(sc, (struct bioc_setstate *)addr); 1988 break; 1989 1990 default: 1991 DNPRINTF(MFI_D_IOCTL, " invalid ioctl\n"); 1992 error = EINVAL; 1993 } 1994 splx(s); 1995 KERNEL_UNLOCK_ONE(curlwp); 1996 1997 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl return %x\n", DEVNAME(sc), error); 1998 return error; 1999 } 2000 2001 static int 2002 mfi_ioctl_inq(struct mfi_softc *sc, struct bioc_inq *bi) 2003 { 2004 struct mfi_conf *cfg; 2005 int rv = EINVAL; 2006 2007 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_inq\n", DEVNAME(sc)); 2008 2009 if (mfi_get_info(sc)) { 2010 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_inq failed\n", 2011 DEVNAME(sc)); 2012 return EIO; 2013 } 2014 2015 /* get figures */ 2016 cfg = malloc(sizeof *cfg, M_DEVBUF, M_WAITOK); 2017 if (mfi_mgmt_internal(sc, MR_DCMD_CONF_GET, MFI_DATA_IN, 2018 sizeof *cfg, cfg, NULL, false)) 2019 goto freeme; 2020 2021 strlcpy(bi->bi_dev, DEVNAME(sc), sizeof(bi->bi_dev)); 2022 bi->bi_novol = cfg->mfc_no_ld + cfg->mfc_no_hs; 2023 bi->bi_nodisk = sc->sc_info.mci_pd_disks_present; 2024 2025 rv = 0; 2026 freeme: 2027 free(cfg, M_DEVBUF); 2028 return rv; 2029 } 2030 2031 static int 2032 mfi_ioctl_vol(struct mfi_softc *sc, struct bioc_vol *bv) 2033 { 2034 int i, per, rv = EINVAL; 2035 uint8_t mbox[MFI_MBOX_SIZE]; 2036 2037 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_vol %#x\n", 2038 DEVNAME(sc), bv->bv_volid); 2039 2040 if (mfi_mgmt_internal(sc, MR_DCMD_LD_GET_LIST, MFI_DATA_IN, 2041 sizeof(sc->sc_ld_list), &sc->sc_ld_list, NULL, false)) 2042 goto done; 2043 2044 i = bv->bv_volid; 2045 mbox[0] = sc->sc_ld_list.mll_list[i].mll_ld.mld_target; 2046 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_vol target %#x\n", 2047 DEVNAME(sc), mbox[0]); 2048 2049 if (mfi_mgmt_internal(sc, MR_DCMD_LD_GET_INFO, MFI_DATA_IN, 2050 sizeof(sc->sc_ld_details), &sc->sc_ld_details, mbox, false)) 2051 goto done; 2052 2053 if (bv->bv_volid >= sc->sc_ld_list.mll_no_ld) { 2054 /* go do hotspares */ 2055 rv = mfi_bio_hs(sc, bv->bv_volid, MFI_MGMT_VD, bv); 2056 goto done; 2057 } 2058 2059 strlcpy(bv->bv_dev, sc->sc_ld[i].ld_dev, sizeof(bv->bv_dev)); 2060 2061 switch(sc->sc_ld_list.mll_list[i].mll_state) { 2062 case MFI_LD_OFFLINE: 2063 bv->bv_status = BIOC_SVOFFLINE; 2064 break; 2065 2066 case MFI_LD_PART_DEGRADED: 2067 case MFI_LD_DEGRADED: 2068 bv->bv_status = BIOC_SVDEGRADED; 2069 break; 2070 2071 case MFI_LD_ONLINE: 2072 bv->bv_status = BIOC_SVONLINE; 2073 break; 2074 2075 default: 2076 bv->bv_status = BIOC_SVINVALID; 2077 DNPRINTF(MFI_D_IOCTL, "%s: invalid logical disk state %#x\n", 2078 DEVNAME(sc), 2079 sc->sc_ld_list.mll_list[i].mll_state); 2080 } 2081 2082 /* additional status can modify MFI status */ 2083 switch (sc->sc_ld_details.mld_progress.mlp_in_prog) { 2084 case MFI_LD_PROG_CC: 2085 case MFI_LD_PROG_BGI: 2086 bv->bv_status = BIOC_SVSCRUB; 2087 per = (int)sc->sc_ld_details.mld_progress.mlp_cc.mp_progress; 2088 bv->bv_percent = (per * 100) / 0xffff; 2089 bv->bv_seconds = 2090 sc->sc_ld_details.mld_progress.mlp_cc.mp_elapsed_seconds; 2091 break; 2092 2093 case MFI_LD_PROG_FGI: 2094 case MFI_LD_PROG_RECONSTRUCT: 2095 /* nothing yet */ 2096 break; 2097 } 2098 2099 /* 2100 * The RAID levels are determined per the SNIA DDF spec, this is only 2101 * a subset that is valid for the MFI contrller. 2102 */ 2103 bv->bv_level = sc->sc_ld_details.mld_cfg.mlc_parm.mpa_pri_raid; 2104 if (sc->sc_ld_details.mld_cfg.mlc_parm.mpa_sec_raid == 2105 MFI_DDF_SRL_SPANNED) 2106 bv->bv_level *= 10; 2107 2108 bv->bv_nodisk = sc->sc_ld_details.mld_cfg.mlc_parm.mpa_no_drv_per_span * 2109 sc->sc_ld_details.mld_cfg.mlc_parm.mpa_span_depth; 2110 2111 bv->bv_size = sc->sc_ld_details.mld_size * 512; /* bytes per block */ 2112 2113 rv = 0; 2114 done: 2115 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_vol done %x\n", 2116 DEVNAME(sc), rv); 2117 return rv; 2118 } 2119 2120 static int 2121 mfi_ioctl_disk(struct mfi_softc *sc, struct bioc_disk *bd) 2122 { 2123 struct mfi_conf *cfg; 2124 struct mfi_array *ar; 2125 struct mfi_ld_cfg *ld; 2126 struct mfi_pd_details *pd; 2127 struct scsipi_inquiry_data *inqbuf; 2128 char vend[8+16+4+1]; 2129 int i, rv = EINVAL; 2130 int arr, vol, disk; 2131 uint32_t size; 2132 uint8_t mbox[MFI_MBOX_SIZE]; 2133 2134 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_disk %#x\n", 2135 DEVNAME(sc), bd->bd_diskid); 2136 2137 pd = malloc(sizeof *pd, M_DEVBUF, M_WAITOK | M_ZERO); 2138 2139 /* send single element command to retrieve size for full structure */ 2140 cfg = malloc(sizeof *cfg, M_DEVBUF, M_WAITOK); 2141 if (mfi_mgmt_internal(sc, MR_DCMD_CONF_GET, MFI_DATA_IN, 2142 sizeof *cfg, cfg, NULL, false)) 2143 goto freeme; 2144 2145 size = cfg->mfc_size; 2146 free(cfg, M_DEVBUF); 2147 2148 /* memory for read config */ 2149 cfg = malloc(size, M_DEVBUF, M_WAITOK|M_ZERO); 2150 if (mfi_mgmt_internal(sc, MR_DCMD_CONF_GET, MFI_DATA_IN, 2151 size, cfg, NULL, false)) 2152 goto freeme; 2153 2154 ar = cfg->mfc_array; 2155 2156 /* calculate offset to ld structure */ 2157 ld = (struct mfi_ld_cfg *)( 2158 ((uint8_t *)cfg) + offsetof(struct mfi_conf, mfc_array) + 2159 cfg->mfc_array_size * cfg->mfc_no_array); 2160 2161 vol = bd->bd_volid; 2162 2163 if (vol >= cfg->mfc_no_ld) { 2164 /* do hotspares */ 2165 rv = mfi_bio_hs(sc, bd->bd_volid, MFI_MGMT_SD, bd); 2166 goto freeme; 2167 } 2168 2169 /* find corresponding array for ld */ 2170 for (i = 0, arr = 0; i < vol; i++) 2171 arr += ld[i].mlc_parm.mpa_span_depth; 2172 2173 /* offset disk into pd list */ 2174 disk = bd->bd_diskid % ld[vol].mlc_parm.mpa_no_drv_per_span; 2175 2176 /* offset array index into the next spans */ 2177 arr += bd->bd_diskid / ld[vol].mlc_parm.mpa_no_drv_per_span; 2178 2179 bd->bd_target = ar[arr].pd[disk].mar_enc_slot; 2180 switch (ar[arr].pd[disk].mar_pd_state){ 2181 case MFI_PD_UNCONFIG_GOOD: 2182 bd->bd_status = BIOC_SDUNUSED; 2183 break; 2184 2185 case MFI_PD_HOTSPARE: /* XXX dedicated hotspare part of array? */ 2186 bd->bd_status = BIOC_SDHOTSPARE; 2187 break; 2188 2189 case MFI_PD_OFFLINE: 2190 bd->bd_status = BIOC_SDOFFLINE; 2191 break; 2192 2193 case MFI_PD_FAILED: 2194 bd->bd_status = BIOC_SDFAILED; 2195 break; 2196 2197 case MFI_PD_REBUILD: 2198 bd->bd_status = BIOC_SDREBUILD; 2199 break; 2200 2201 case MFI_PD_ONLINE: 2202 bd->bd_status = BIOC_SDONLINE; 2203 break; 2204 2205 case MFI_PD_UNCONFIG_BAD: /* XXX define new state in bio */ 2206 default: 2207 bd->bd_status = BIOC_SDINVALID; 2208 break; 2209 2210 } 2211 2212 /* get the remaining fields */ 2213 *((uint16_t *)&mbox) = ar[arr].pd[disk].mar_pd.mfp_id; 2214 memset(pd, 0, sizeof(*pd)); 2215 if (mfi_mgmt_internal(sc, MR_DCMD_PD_GET_INFO, MFI_DATA_IN, 2216 sizeof *pd, pd, mbox, false)) 2217 goto freeme; 2218 2219 bd->bd_size = pd->mpd_size * 512; /* bytes per block */ 2220 2221 /* if pd->mpd_enc_idx is 0 then it is not in an enclosure */ 2222 bd->bd_channel = pd->mpd_enc_idx; 2223 2224 inqbuf = (struct scsipi_inquiry_data *)&pd->mpd_inq_data; 2225 memcpy(vend, inqbuf->vendor, sizeof vend - 1); 2226 vend[sizeof vend - 1] = '\0'; 2227 strlcpy(bd->bd_vendor, vend, sizeof(bd->bd_vendor)); 2228 2229 /* XXX find a way to retrieve serial nr from drive */ 2230 /* XXX find a way to get bd_procdev */ 2231 2232 rv = 0; 2233 freeme: 2234 free(pd, M_DEVBUF); 2235 free(cfg, M_DEVBUF); 2236 2237 return rv; 2238 } 2239 2240 static int 2241 mfi_ioctl_alarm(struct mfi_softc *sc, struct bioc_alarm *ba) 2242 { 2243 uint32_t opc, dir = MFI_DATA_NONE; 2244 int rv = 0; 2245 int8_t ret; 2246 2247 switch(ba->ba_opcode) { 2248 case BIOC_SADISABLE: 2249 opc = MR_DCMD_SPEAKER_DISABLE; 2250 break; 2251 2252 case BIOC_SAENABLE: 2253 opc = MR_DCMD_SPEAKER_ENABLE; 2254 break; 2255 2256 case BIOC_SASILENCE: 2257 opc = MR_DCMD_SPEAKER_SILENCE; 2258 break; 2259 2260 case BIOC_GASTATUS: 2261 opc = MR_DCMD_SPEAKER_GET; 2262 dir = MFI_DATA_IN; 2263 break; 2264 2265 case BIOC_SATEST: 2266 opc = MR_DCMD_SPEAKER_TEST; 2267 break; 2268 2269 default: 2270 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_alarm biocalarm invalid " 2271 "opcode %x\n", DEVNAME(sc), ba->ba_opcode); 2272 return EINVAL; 2273 } 2274 2275 if (mfi_mgmt_internal(sc, opc, dir, sizeof(ret), &ret, NULL, false)) 2276 rv = EINVAL; 2277 else 2278 if (ba->ba_opcode == BIOC_GASTATUS) 2279 ba->ba_status = ret; 2280 else 2281 ba->ba_status = 0; 2282 2283 return rv; 2284 } 2285 2286 static int 2287 mfi_ioctl_blink(struct mfi_softc *sc, struct bioc_blink *bb) 2288 { 2289 int i, found, rv = EINVAL; 2290 uint8_t mbox[MFI_MBOX_SIZE]; 2291 uint32_t cmd; 2292 struct mfi_pd_list *pd; 2293 2294 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_blink %x\n", DEVNAME(sc), 2295 bb->bb_status); 2296 2297 /* channel 0 means not in an enclosure so can't be blinked */ 2298 if (bb->bb_channel == 0) 2299 return EINVAL; 2300 2301 pd = malloc(MFI_PD_LIST_SIZE, M_DEVBUF, M_WAITOK); 2302 2303 if (mfi_mgmt_internal(sc, MR_DCMD_PD_GET_LIST, MFI_DATA_IN, 2304 MFI_PD_LIST_SIZE, pd, NULL, false)) 2305 goto done; 2306 2307 for (i = 0, found = 0; i < pd->mpl_no_pd; i++) 2308 if (bb->bb_channel == pd->mpl_address[i].mpa_enc_index && 2309 bb->bb_target == pd->mpl_address[i].mpa_enc_slot) { 2310 found = 1; 2311 break; 2312 } 2313 2314 if (!found) 2315 goto done; 2316 2317 memset(mbox, 0, sizeof mbox); 2318 2319 *((uint16_t *)&mbox) = pd->mpl_address[i].mpa_pd_id; 2320 2321 switch (bb->bb_status) { 2322 case BIOC_SBUNBLINK: 2323 cmd = MR_DCMD_PD_UNBLINK; 2324 break; 2325 2326 case BIOC_SBBLINK: 2327 cmd = MR_DCMD_PD_BLINK; 2328 break; 2329 2330 case BIOC_SBALARM: 2331 default: 2332 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_blink biocblink invalid " 2333 "opcode %x\n", DEVNAME(sc), bb->bb_status); 2334 goto done; 2335 } 2336 2337 2338 if (mfi_mgmt_internal(sc, cmd, MFI_DATA_NONE, 0, NULL, mbox, false)) 2339 goto done; 2340 2341 rv = 0; 2342 done: 2343 free(pd, M_DEVBUF); 2344 return rv; 2345 } 2346 2347 static int 2348 mfi_ioctl_setstate(struct mfi_softc *sc, struct bioc_setstate *bs) 2349 { 2350 struct mfi_pd_list *pd; 2351 int i, found, rv = EINVAL; 2352 uint8_t mbox[MFI_MBOX_SIZE]; 2353 2354 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_setstate %x\n", DEVNAME(sc), 2355 bs->bs_status); 2356 2357 pd = malloc(MFI_PD_LIST_SIZE, M_DEVBUF, M_WAITOK); 2358 2359 if (mfi_mgmt_internal(sc, MR_DCMD_PD_GET_LIST, MFI_DATA_IN, 2360 MFI_PD_LIST_SIZE, pd, NULL, false)) 2361 goto done; 2362 2363 for (i = 0, found = 0; i < pd->mpl_no_pd; i++) 2364 if (bs->bs_channel == pd->mpl_address[i].mpa_enc_index && 2365 bs->bs_target == pd->mpl_address[i].mpa_enc_slot) { 2366 found = 1; 2367 break; 2368 } 2369 2370 if (!found) 2371 goto done; 2372 2373 memset(mbox, 0, sizeof mbox); 2374 2375 *((uint16_t *)&mbox) = pd->mpl_address[i].mpa_pd_id; 2376 2377 switch (bs->bs_status) { 2378 case BIOC_SSONLINE: 2379 mbox[2] = MFI_PD_ONLINE; 2380 break; 2381 2382 case BIOC_SSOFFLINE: 2383 mbox[2] = MFI_PD_OFFLINE; 2384 break; 2385 2386 case BIOC_SSHOTSPARE: 2387 mbox[2] = MFI_PD_HOTSPARE; 2388 break; 2389 /* 2390 case BIOC_SSREBUILD: 2391 break; 2392 */ 2393 default: 2394 DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_setstate invalid " 2395 "opcode %x\n", DEVNAME(sc), bs->bs_status); 2396 goto done; 2397 } 2398 2399 2400 if (mfi_mgmt_internal(sc, MR_DCMD_PD_SET_STATE, MFI_DATA_NONE, 2401 0, NULL, mbox, false)) 2402 goto done; 2403 2404 rv = 0; 2405 done: 2406 free(pd, M_DEVBUF); 2407 return rv; 2408 } 2409 2410 static int 2411 mfi_bio_hs(struct mfi_softc *sc, int volid, int type, void *bio_hs) 2412 { 2413 struct mfi_conf *cfg; 2414 struct mfi_hotspare *hs; 2415 struct mfi_pd_details *pd; 2416 struct bioc_disk *sdhs; 2417 struct bioc_vol *vdhs; 2418 struct scsipi_inquiry_data *inqbuf; 2419 char vend[8+16+4+1]; 2420 int i, rv = EINVAL; 2421 uint32_t size; 2422 uint8_t mbox[MFI_MBOX_SIZE]; 2423 2424 DNPRINTF(MFI_D_IOCTL, "%s: mfi_vol_hs %d\n", DEVNAME(sc), volid); 2425 2426 if (!bio_hs) 2427 return EINVAL; 2428 2429 pd = malloc(sizeof *pd, M_DEVBUF, M_WAITOK | M_ZERO); 2430 2431 /* send single element command to retrieve size for full structure */ 2432 cfg = malloc(sizeof *cfg, M_DEVBUF, M_WAITOK); 2433 if (mfi_mgmt_internal(sc, MR_DCMD_CONF_GET, MFI_DATA_IN, 2434 sizeof *cfg, cfg, NULL, false)) 2435 goto freeme; 2436 2437 size = cfg->mfc_size; 2438 free(cfg, M_DEVBUF); 2439 2440 /* memory for read config */ 2441 cfg = malloc(size, M_DEVBUF, M_WAITOK|M_ZERO); 2442 if (mfi_mgmt_internal(sc, MR_DCMD_CONF_GET, MFI_DATA_IN, 2443 size, cfg, NULL, false)) 2444 goto freeme; 2445 2446 /* calculate offset to hs structure */ 2447 hs = (struct mfi_hotspare *)( 2448 ((uint8_t *)cfg) + offsetof(struct mfi_conf, mfc_array) + 2449 cfg->mfc_array_size * cfg->mfc_no_array + 2450 cfg->mfc_ld_size * cfg->mfc_no_ld); 2451 2452 if (volid < cfg->mfc_no_ld) 2453 goto freeme; /* not a hotspare */ 2454 2455 if (volid > (cfg->mfc_no_ld + cfg->mfc_no_hs)) 2456 goto freeme; /* not a hotspare */ 2457 2458 /* offset into hotspare structure */ 2459 i = volid - cfg->mfc_no_ld; 2460 2461 DNPRINTF(MFI_D_IOCTL, "%s: mfi_vol_hs i %d volid %d no_ld %d no_hs %d " 2462 "hs %p cfg %p id %02x\n", DEVNAME(sc), i, volid, cfg->mfc_no_ld, 2463 cfg->mfc_no_hs, hs, cfg, hs[i].mhs_pd.mfp_id); 2464 2465 /* get pd fields */ 2466 memset(mbox, 0, sizeof mbox); 2467 *((uint16_t *)&mbox) = hs[i].mhs_pd.mfp_id; 2468 if (mfi_mgmt_internal(sc, MR_DCMD_PD_GET_INFO, MFI_DATA_IN, 2469 sizeof *pd, pd, mbox, false)) { 2470 DNPRINTF(MFI_D_IOCTL, "%s: mfi_vol_hs illegal PD\n", 2471 DEVNAME(sc)); 2472 goto freeme; 2473 } 2474 2475 switch (type) { 2476 case MFI_MGMT_VD: 2477 vdhs = bio_hs; 2478 vdhs->bv_status = BIOC_SVONLINE; 2479 vdhs->bv_size = pd->mpd_size * 512; /* bytes per block */ 2480 vdhs->bv_level = -1; /* hotspare */ 2481 vdhs->bv_nodisk = 1; 2482 break; 2483 2484 case MFI_MGMT_SD: 2485 sdhs = bio_hs; 2486 sdhs->bd_status = BIOC_SDHOTSPARE; 2487 sdhs->bd_size = pd->mpd_size * 512; /* bytes per block */ 2488 sdhs->bd_channel = pd->mpd_enc_idx; 2489 sdhs->bd_target = pd->mpd_enc_slot; 2490 inqbuf = (struct scsipi_inquiry_data *)&pd->mpd_inq_data; 2491 memcpy(vend, inqbuf->vendor, sizeof(vend) - 1); 2492 vend[sizeof vend - 1] = '\0'; 2493 strlcpy(sdhs->bd_vendor, vend, sizeof(sdhs->bd_vendor)); 2494 break; 2495 2496 default: 2497 goto freeme; 2498 } 2499 2500 DNPRINTF(MFI_D_IOCTL, "%s: mfi_vol_hs 6\n", DEVNAME(sc)); 2501 rv = 0; 2502 freeme: 2503 free(pd, M_DEVBUF); 2504 free(cfg, M_DEVBUF); 2505 2506 return rv; 2507 } 2508 2509 static int 2510 mfi_destroy_sensors(struct mfi_softc *sc) 2511 { 2512 if (sc->sc_sme == NULL) 2513 return 0; 2514 sysmon_envsys_unregister(sc->sc_sme); 2515 sc->sc_sme = NULL; 2516 free(sc->sc_sensor, M_DEVBUF); 2517 return 0; 2518 } 2519 2520 static int 2521 mfi_create_sensors(struct mfi_softc *sc) 2522 { 2523 int i; 2524 int nsensors = sc->sc_ld_cnt + 1; 2525 int rv; 2526 2527 sc->sc_sme = sysmon_envsys_create(); 2528 sc->sc_sensor = malloc(sizeof(envsys_data_t) * nsensors, 2529 M_DEVBUF, M_WAITOK | M_ZERO); 2530 2531 /* BBU */ 2532 sc->sc_sensor[0].units = ENVSYS_INDICATOR; 2533 sc->sc_sensor[0].state = ENVSYS_SINVALID; 2534 sc->sc_sensor[0].value_cur = 0; 2535 /* Enable monitoring for BBU state changes, if present */ 2536 if (sc->sc_info.mci_hw_present & MFI_INFO_HW_BBU) 2537 sc->sc_sensor[0].flags |= ENVSYS_FMONCRITICAL; 2538 snprintf(sc->sc_sensor[0].desc, 2539 sizeof(sc->sc_sensor[0].desc), "%s BBU", DEVNAME(sc)); 2540 if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_sensor[0])) 2541 goto out; 2542 2543 for (i = 1; i < nsensors; i++) { 2544 sc->sc_sensor[i].units = ENVSYS_DRIVE; 2545 sc->sc_sensor[i].state = ENVSYS_SINVALID; 2546 sc->sc_sensor[i].value_cur = ENVSYS_DRIVE_EMPTY; 2547 /* Enable monitoring for drive state changes */ 2548 sc->sc_sensor[i].flags |= ENVSYS_FMONSTCHANGED; 2549 /* logical drives */ 2550 snprintf(sc->sc_sensor[i].desc, 2551 sizeof(sc->sc_sensor[i].desc), "%s:%d", 2552 DEVNAME(sc), i - 1); 2553 if (sysmon_envsys_sensor_attach(sc->sc_sme, 2554 &sc->sc_sensor[i])) 2555 goto out; 2556 } 2557 2558 sc->sc_sme->sme_name = DEVNAME(sc); 2559 sc->sc_sme->sme_cookie = sc; 2560 sc->sc_sme->sme_refresh = mfi_sensor_refresh; 2561 rv = sysmon_envsys_register(sc->sc_sme); 2562 if (rv != 0) { 2563 aprint_error_dev(sc->sc_dev, 2564 "unable to register with sysmon (rv = %d)\n", rv); 2565 goto out; 2566 } 2567 return 0; 2568 2569 out: 2570 free(sc->sc_sensor, M_DEVBUF); 2571 sysmon_envsys_destroy(sc->sc_sme); 2572 sc->sc_sme = NULL; 2573 return EINVAL; 2574 } 2575 2576 static void 2577 mfi_sensor_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 2578 { 2579 struct mfi_softc *sc = sme->sme_cookie; 2580 struct bioc_vol bv; 2581 int s; 2582 int error; 2583 2584 if (edata->sensor >= sc->sc_ld_cnt + 1) 2585 return; 2586 2587 if (edata->sensor == 0) { 2588 /* BBU */ 2589 struct mfi_bbu_status bbu_stat; 2590 int bbu_status; 2591 if ((sc->sc_info.mci_hw_present & MFI_INFO_HW_BBU) == 0) 2592 return; 2593 2594 KERNEL_LOCK(1, curlwp); 2595 s = splbio(); 2596 bbu_status = mfi_get_bbu(sc, &bbu_stat); 2597 splx(s); 2598 KERNEL_UNLOCK_ONE(curlwp); 2599 switch(bbu_status) { 2600 case MFI_BBU_GOOD: 2601 edata->value_cur = 1; 2602 edata->state = ENVSYS_SVALID; 2603 if (!sc->sc_bbuok) 2604 aprint_normal_dev(sc->sc_dev, 2605 "BBU state changed to good\n"); 2606 sc->sc_bbuok = true; 2607 break; 2608 case MFI_BBU_BAD: 2609 edata->value_cur = 0; 2610 edata->state = ENVSYS_SCRITICAL; 2611 if (sc->sc_bbuok) 2612 aprint_normal_dev(sc->sc_dev, 2613 "BBU state changed to bad\n"); 2614 sc->sc_bbuok = false; 2615 break; 2616 case MFI_BBU_UNKNOWN: 2617 default: 2618 edata->value_cur = 0; 2619 edata->state = ENVSYS_SINVALID; 2620 sc->sc_bbuok = false; 2621 break; 2622 } 2623 return; 2624 } 2625 2626 memset(&bv, 0, sizeof(bv)); 2627 bv.bv_volid = edata->sensor - 1; 2628 KERNEL_LOCK(1, curlwp); 2629 s = splbio(); 2630 error = mfi_ioctl_vol(sc, &bv); 2631 splx(s); 2632 KERNEL_UNLOCK_ONE(curlwp); 2633 if (error) 2634 bv.bv_status = BIOC_SVINVALID; 2635 2636 bio_vol_to_envsys(edata, &bv); 2637 } 2638 2639 #endif /* NBIO > 0 */ 2640 2641 static uint32_t 2642 mfi_xscale_fw_state(struct mfi_softc *sc) 2643 { 2644 return mfi_read(sc, MFI_OMSG0); 2645 } 2646 2647 static void 2648 mfi_xscale_intr_dis(struct mfi_softc *sc) 2649 { 2650 mfi_write(sc, MFI_OMSK, 0); 2651 } 2652 2653 static void 2654 mfi_xscale_intr_ena(struct mfi_softc *sc) 2655 { 2656 mfi_write(sc, MFI_OMSK, MFI_ENABLE_INTR); 2657 } 2658 2659 static int 2660 mfi_xscale_intr(struct mfi_softc *sc) 2661 { 2662 uint32_t status; 2663 2664 status = mfi_read(sc, MFI_OSTS); 2665 if (!ISSET(status, MFI_OSTS_INTR_VALID)) 2666 return 0; 2667 2668 /* write status back to acknowledge interrupt */ 2669 mfi_write(sc, MFI_OSTS, status); 2670 return 1; 2671 } 2672 2673 static void 2674 mfi_xscale_post(struct mfi_softc *sc, struct mfi_ccb *ccb) 2675 { 2676 bus_dmamap_sync(sc->sc_dmat, MFIMEM_MAP(sc->sc_frames), 2677 ccb->ccb_pframe - MFIMEM_DVA(sc->sc_frames), 2678 sc->sc_frames_size, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 2679 bus_dmamap_sync(sc->sc_dmat, MFIMEM_MAP(sc->sc_sense), 2680 ccb->ccb_psense - MFIMEM_DVA(sc->sc_sense), 2681 MFI_SENSE_SIZE, BUS_DMASYNC_PREREAD); 2682 2683 mfi_write(sc, MFI_IQP, (ccb->ccb_pframe >> 3) | 2684 ccb->ccb_extra_frames); 2685 ccb->ccb_state = MFI_CCB_RUNNING; 2686 } 2687 2688 static uint32_t 2689 mfi_ppc_fw_state(struct mfi_softc *sc) 2690 { 2691 return mfi_read(sc, MFI_OSP); 2692 } 2693 2694 static void 2695 mfi_ppc_intr_dis(struct mfi_softc *sc) 2696 { 2697 /* Taking a wild guess --dyoung */ 2698 mfi_write(sc, MFI_OMSK, ~(uint32_t)0x0); 2699 mfi_write(sc, MFI_ODC, 0xffffffff); 2700 } 2701 2702 static void 2703 mfi_ppc_intr_ena(struct mfi_softc *sc) 2704 { 2705 mfi_write(sc, MFI_ODC, 0xffffffff); 2706 mfi_write(sc, MFI_OMSK, ~0x80000004); 2707 } 2708 2709 static int 2710 mfi_ppc_intr(struct mfi_softc *sc) 2711 { 2712 uint32_t status; 2713 2714 status = mfi_read(sc, MFI_OSTS); 2715 if (!ISSET(status, MFI_OSTS_PPC_INTR_VALID)) 2716 return 0; 2717 2718 /* write status back to acknowledge interrupt */ 2719 mfi_write(sc, MFI_ODC, status); 2720 return 1; 2721 } 2722 2723 static void 2724 mfi_ppc_post(struct mfi_softc *sc, struct mfi_ccb *ccb) 2725 { 2726 mfi_write(sc, MFI_IQP, 0x1 | ccb->ccb_pframe | 2727 (ccb->ccb_extra_frames << 1)); 2728 ccb->ccb_state = MFI_CCB_RUNNING; 2729 } 2730 2731 u_int32_t 2732 mfi_gen2_fw_state(struct mfi_softc *sc) 2733 { 2734 return (mfi_read(sc, MFI_OSP)); 2735 } 2736 2737 void 2738 mfi_gen2_intr_dis(struct mfi_softc *sc) 2739 { 2740 mfi_write(sc, MFI_OMSK, 0xffffffff); 2741 mfi_write(sc, MFI_ODC, 0xffffffff); 2742 } 2743 2744 void 2745 mfi_gen2_intr_ena(struct mfi_softc *sc) 2746 { 2747 mfi_write(sc, MFI_ODC, 0xffffffff); 2748 mfi_write(sc, MFI_OMSK, ~MFI_OSTS_GEN2_INTR_VALID); 2749 } 2750 2751 int 2752 mfi_gen2_intr(struct mfi_softc *sc) 2753 { 2754 u_int32_t status; 2755 2756 status = mfi_read(sc, MFI_OSTS); 2757 if (!ISSET(status, MFI_OSTS_GEN2_INTR_VALID)) 2758 return (0); 2759 2760 /* write status back to acknowledge interrupt */ 2761 mfi_write(sc, MFI_ODC, status); 2762 2763 return (1); 2764 } 2765 2766 void 2767 mfi_gen2_post(struct mfi_softc *sc, struct mfi_ccb *ccb) 2768 { 2769 mfi_write(sc, MFI_IQP, 0x1 | ccb->ccb_pframe | 2770 (ccb->ccb_extra_frames << 1)); 2771 ccb->ccb_state = MFI_CCB_RUNNING; 2772 } 2773 2774 u_int32_t 2775 mfi_skinny_fw_state(struct mfi_softc *sc) 2776 { 2777 return (mfi_read(sc, MFI_OSP)); 2778 } 2779 2780 void 2781 mfi_skinny_intr_dis(struct mfi_softc *sc) 2782 { 2783 mfi_write(sc, MFI_OMSK, 0); 2784 } 2785 2786 void 2787 mfi_skinny_intr_ena(struct mfi_softc *sc) 2788 { 2789 mfi_write(sc, MFI_OMSK, ~0x00000001); 2790 } 2791 2792 int 2793 mfi_skinny_intr(struct mfi_softc *sc) 2794 { 2795 u_int32_t status; 2796 2797 status = mfi_read(sc, MFI_OSTS); 2798 if (!ISSET(status, MFI_OSTS_SKINNY_INTR_VALID)) 2799 return (0); 2800 2801 /* write status back to acknowledge interrupt */ 2802 mfi_write(sc, MFI_OSTS, status); 2803 2804 return (1); 2805 } 2806 2807 void 2808 mfi_skinny_post(struct mfi_softc *sc, struct mfi_ccb *ccb) 2809 { 2810 mfi_write(sc, MFI_IQPL, 0x1 | ccb->ccb_pframe | 2811 (ccb->ccb_extra_frames << 1)); 2812 mfi_write(sc, MFI_IQPH, 0x00000000); 2813 ccb->ccb_state = MFI_CCB_RUNNING; 2814 } 2815 2816 #define MFI_FUSION_ENABLE_INTERRUPT_MASK (0x00000008) 2817 2818 void 2819 mfi_tbolt_intr_ena(struct mfi_softc *sc) 2820 { 2821 mfi_write(sc, MFI_OMSK, ~MFI_FUSION_ENABLE_INTERRUPT_MASK); 2822 mfi_read(sc, MFI_OMSK); 2823 } 2824 2825 void 2826 mfi_tbolt_intr_dis(struct mfi_softc *sc) 2827 { 2828 mfi_write(sc, MFI_OMSK, 0xFFFFFFFF); 2829 mfi_read(sc, MFI_OMSK); 2830 } 2831 2832 int 2833 mfi_tbolt_intr(struct mfi_softc *sc) 2834 { 2835 int32_t status; 2836 2837 status = mfi_read(sc, MFI_OSTS); 2838 2839 if (ISSET(status, 0x1)) { 2840 mfi_write(sc, MFI_OSTS, status); 2841 mfi_read(sc, MFI_OSTS); 2842 if (ISSET(status, MFI_STATE_CHANGE_INTERRUPT)) 2843 return 0; 2844 return 1; 2845 } 2846 if (!ISSET(status, MFI_FUSION_ENABLE_INTERRUPT_MASK)) 2847 return 0; 2848 mfi_read(sc, MFI_OSTS); 2849 return 1; 2850 } 2851 2852 u_int32_t 2853 mfi_tbolt_fw_state(struct mfi_softc *sc) 2854 { 2855 return mfi_read(sc, MFI_OSP); 2856 } 2857 2858 void 2859 mfi_tbolt_post(struct mfi_softc *sc, struct mfi_ccb *ccb) 2860 { 2861 if (sc->sc_MFA_enabled) { 2862 if ((ccb->ccb_flags & MFI_CCB_F_TBOLT) == 0) 2863 mfi_tbolt_build_mpt_ccb(ccb); 2864 mfi_write(sc, MFI_IQPL, 2865 ccb->ccb_tb_request_desc.words & 0xFFFFFFFF); 2866 mfi_write(sc, MFI_IQPH, 2867 ccb->ccb_tb_request_desc.words >> 32); 2868 ccb->ccb_state = MFI_CCB_RUNNING; 2869 return; 2870 } 2871 uint64_t bus_add = ccb->ccb_pframe; 2872 bus_add |= (MFI_REQ_DESCRIPT_FLAGS_MFA 2873 << MFI_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); 2874 mfi_write(sc, MFI_IQPL, bus_add); 2875 mfi_write(sc, MFI_IQPH, bus_add >> 32); 2876 ccb->ccb_state = MFI_CCB_RUNNING; 2877 } 2878 2879 static void 2880 mfi_tbolt_build_mpt_ccb(struct mfi_ccb *ccb) 2881 { 2882 union mfi_mpi2_request_descriptor *req_desc = &ccb->ccb_tb_request_desc; 2883 struct mfi_mpi2_request_raid_scsi_io *io_req = ccb->ccb_tb_io_request; 2884 struct mpi25_ieee_sge_chain64 *mpi25_ieee_chain; 2885 2886 io_req->Function = MPI2_FUNCTION_PASSTHRU_IO_REQUEST; 2887 io_req->SGLOffset0 = 2888 offsetof(struct mfi_mpi2_request_raid_scsi_io, SGL) / 4; 2889 io_req->ChainOffset = 2890 offsetof(struct mfi_mpi2_request_raid_scsi_io, SGL) / 16; 2891 2892 mpi25_ieee_chain = 2893 (struct mpi25_ieee_sge_chain64 *)&io_req->SGL.IeeeChain; 2894 mpi25_ieee_chain->Address = ccb->ccb_pframe; 2895 2896 /* 2897 In MFI pass thru, nextChainOffset will always be zero to 2898 indicate the end of the chain. 2899 */ 2900 mpi25_ieee_chain->Flags= MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT 2901 | MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR; 2902 2903 /* setting the length to the maximum length */ 2904 mpi25_ieee_chain->Length = 1024; 2905 2906 req_desc->header.RequestFlags = (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO << 2907 MFI_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); 2908 ccb->ccb_flags |= MFI_CCB_F_TBOLT; 2909 bus_dmamap_sync(ccb->ccb_sc->sc_dmat, 2910 MFIMEM_MAP(ccb->ccb_sc->sc_tbolt_reqmsgpool), 2911 ccb->ccb_tb_pio_request - 2912 MFIMEM_DVA(ccb->ccb_sc->sc_tbolt_reqmsgpool), 2913 MEGASAS_THUNDERBOLT_NEW_MSG_SIZE, 2914 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 2915 } 2916 2917 /* 2918 * Description: 2919 * This function will prepare message pools for the Thunderbolt controller 2920 */ 2921 static int 2922 mfi_tbolt_init_desc_pool(struct mfi_softc *sc) 2923 { 2924 uint32_t offset = 0; 2925 uint8_t *addr = MFIMEM_KVA(sc->sc_tbolt_reqmsgpool); 2926 2927 /* Request Decriptors alignment restrictions */ 2928 KASSERT(((uintptr_t)addr & 0xFF) == 0); 2929 2930 /* Skip request message pool */ 2931 addr = &addr[MEGASAS_THUNDERBOLT_NEW_MSG_SIZE * (sc->sc_max_cmds + 1)]; 2932 2933 /* Reply Frame Pool is initialized */ 2934 sc->sc_reply_frame_pool = (struct mfi_mpi2_reply_header *) addr; 2935 KASSERT(((uintptr_t)addr & 0xFF) == 0); 2936 2937 offset = (uintptr_t)sc->sc_reply_frame_pool 2938 - (uintptr_t)MFIMEM_KVA(sc->sc_tbolt_reqmsgpool); 2939 sc->sc_reply_frame_busaddr = 2940 MFIMEM_DVA(sc->sc_tbolt_reqmsgpool) + offset; 2941 2942 /* initializing reply address to 0xFFFFFFFF */ 2943 memset((uint8_t *)sc->sc_reply_frame_pool, 0xFF, 2944 (MEGASAS_THUNDERBOLT_REPLY_SIZE * sc->sc_reply_pool_size)); 2945 2946 /* Skip Reply Frame Pool */ 2947 addr += MEGASAS_THUNDERBOLT_REPLY_SIZE * sc->sc_reply_pool_size; 2948 sc->sc_reply_pool_limit = (void *)addr; 2949 2950 offset = MEGASAS_THUNDERBOLT_REPLY_SIZE * sc->sc_reply_pool_size; 2951 sc->sc_sg_frame_busaddr = sc->sc_reply_frame_busaddr + offset; 2952 2953 /* initialize the last_reply_idx to 0 */ 2954 sc->sc_last_reply_idx = 0; 2955 offset = (sc->sc_sg_frame_busaddr + (MEGASAS_MAX_SZ_CHAIN_FRAME * 2956 sc->sc_max_cmds)) - MFIMEM_DVA(sc->sc_tbolt_reqmsgpool); 2957 KASSERT(offset <= sc->sc_tbolt_reqmsgpool->am_size); 2958 bus_dmamap_sync(sc->sc_dmat, MFIMEM_MAP(sc->sc_tbolt_reqmsgpool), 0, 2959 MFIMEM_MAP(sc->sc_tbolt_reqmsgpool)->dm_mapsize, 2960 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 2961 return 0; 2962 } 2963 2964 /* 2965 * This routine prepare and issue INIT2 frame to the Firmware 2966 */ 2967 2968 static int 2969 mfi_tbolt_init_MFI_queue(struct mfi_softc *sc) 2970 { 2971 struct mpi2_ioc_init_request *mpi2IocInit; 2972 struct mfi_init_frame *mfi_init; 2973 struct mfi_ccb *ccb; 2974 bus_addr_t phyAddress; 2975 mfi_address *mfiAddressTemp; 2976 int s; 2977 char *verbuf; 2978 char wqbuf[10]; 2979 2980 /* Check if initialization is already completed */ 2981 if (sc->sc_MFA_enabled) { 2982 return 1; 2983 } 2984 2985 mpi2IocInit = 2986 (struct mpi2_ioc_init_request *)MFIMEM_KVA(sc->sc_tbolt_ioc_init); 2987 2988 s = splbio(); 2989 if ((ccb = mfi_get_ccb(sc)) == NULL) { 2990 splx(s); 2991 return (EBUSY); 2992 } 2993 2994 2995 mfi_init = &ccb->ccb_frame->mfr_init; 2996 2997 memset(mpi2IocInit, 0, sizeof(struct mpi2_ioc_init_request)); 2998 mpi2IocInit->Function = MPI2_FUNCTION_IOC_INIT; 2999 mpi2IocInit->WhoInit = MPI2_WHOINIT_HOST_DRIVER; 3000 3001 /* set MsgVersion and HeaderVersion host driver was built with */ 3002 mpi2IocInit->MsgVersion = MPI2_VERSION; 3003 mpi2IocInit->HeaderVersion = MPI2_HEADER_VERSION; 3004 mpi2IocInit->SystemRequestFrameSize = MEGASAS_THUNDERBOLT_NEW_MSG_SIZE/4; 3005 mpi2IocInit->ReplyDescriptorPostQueueDepth = 3006 (uint16_t)sc->sc_reply_pool_size; 3007 mpi2IocInit->ReplyFreeQueueDepth = 0; /* Not supported by MR. */ 3008 3009 /* Get physical address of reply frame pool */ 3010 phyAddress = sc->sc_reply_frame_busaddr; 3011 mfiAddressTemp = 3012 (mfi_address *)&mpi2IocInit->ReplyDescriptorPostQueueAddress; 3013 mfiAddressTemp->u.addressLow = (uint32_t)phyAddress; 3014 mfiAddressTemp->u.addressHigh = (uint32_t)((uint64_t)phyAddress >> 32); 3015 3016 /* Get physical address of request message pool */ 3017 phyAddress = MFIMEM_DVA(sc->sc_tbolt_reqmsgpool); 3018 mfiAddressTemp = (mfi_address *)&mpi2IocInit->SystemRequestFrameBaseAddress; 3019 mfiAddressTemp->u.addressLow = (uint32_t)phyAddress; 3020 mfiAddressTemp->u.addressHigh = (uint32_t)((uint64_t)phyAddress >> 32); 3021 3022 mpi2IocInit->ReplyFreeQueueAddress = 0; /* Not supported by MR. */ 3023 mpi2IocInit->TimeStamp = time_uptime; 3024 3025 verbuf = MFIMEM_KVA(sc->sc_tbolt_verbuf); 3026 snprintf(verbuf, strlen(MEGASAS_VERSION) + 2, "%s\n", 3027 MEGASAS_VERSION); 3028 bus_dmamap_sync(sc->sc_dmat, MFIMEM_MAP(sc->sc_tbolt_verbuf), 0, 3029 MFIMEM_MAP(sc->sc_tbolt_verbuf)->dm_mapsize, BUS_DMASYNC_PREWRITE); 3030 mfi_init->driver_ver_lo = htole32(MFIMEM_DVA(sc->sc_tbolt_verbuf)); 3031 mfi_init->driver_ver_hi = 3032 htole32((uint64_t)MFIMEM_DVA(sc->sc_tbolt_verbuf) >> 32); 3033 3034 bus_dmamap_sync(sc->sc_dmat, MFIMEM_MAP(sc->sc_tbolt_ioc_init), 0, 3035 MFIMEM_MAP(sc->sc_tbolt_ioc_init)->dm_mapsize, 3036 BUS_DMASYNC_PREWRITE); 3037 /* Get the physical address of the mpi2 ioc init command */ 3038 phyAddress = MFIMEM_DVA(sc->sc_tbolt_ioc_init); 3039 mfi_init->mif_qinfo_new_addr_lo = htole32(phyAddress); 3040 mfi_init->mif_qinfo_new_addr_hi = htole32((uint64_t)phyAddress >> 32); 3041 3042 mfi_init->mif_header.mfh_cmd = MFI_CMD_INIT; 3043 mfi_init->mif_header.mfh_data_len = sizeof(struct mpi2_ioc_init_request); 3044 if (mfi_poll(ccb) != 0) { 3045 aprint_error_dev(sc->sc_dev, "failed to send IOC init2 " 3046 "command at 0x%" PRIx64 "\n", 3047 (uint64_t)ccb->ccb_pframe); 3048 splx(s); 3049 return 1; 3050 } 3051 bus_dmamap_sync(sc->sc_dmat, MFIMEM_MAP(sc->sc_tbolt_verbuf), 0, 3052 MFIMEM_MAP(sc->sc_tbolt_verbuf)->dm_mapsize, BUS_DMASYNC_POSTWRITE); 3053 bus_dmamap_sync(sc->sc_dmat, MFIMEM_MAP(sc->sc_tbolt_ioc_init), 0, 3054 MFIMEM_MAP(sc->sc_tbolt_ioc_init)->dm_mapsize, 3055 BUS_DMASYNC_POSTWRITE); 3056 mfi_put_ccb(ccb); 3057 splx(s); 3058 3059 if (mfi_init->mif_header.mfh_cmd_status == 0) { 3060 sc->sc_MFA_enabled = 1; 3061 } 3062 else { 3063 aprint_error_dev(sc->sc_dev, "Init command Failed %x\n", 3064 mfi_init->mif_header.mfh_cmd_status); 3065 return 1; 3066 } 3067 3068 snprintf(wqbuf, sizeof(wqbuf), "%swq", DEVNAME(sc)); 3069 if (workqueue_create(&sc->sc_ldsync_wq, wqbuf, mfi_tbolt_sync_map_info, 3070 sc, PRIBIO, IPL_BIO, 0) != 0) { 3071 aprint_error_dev(sc->sc_dev, "workqueue_create failed\n"); 3072 return 1; 3073 } 3074 workqueue_enqueue(sc->sc_ldsync_wq, &sc->sc_ldsync_wk, NULL); 3075 return 0; 3076 } 3077 3078 int 3079 mfi_tbolt_intrh(void *arg) 3080 { 3081 struct mfi_softc *sc = arg; 3082 struct mfi_ccb *ccb; 3083 union mfi_mpi2_reply_descriptor *desc; 3084 int smid, num_completed; 3085 3086 if (!mfi_tbolt_intr(sc)) 3087 return 0; 3088 3089 DNPRINTF(MFI_D_INTR, "%s: mfi_tbolt_intrh %#lx %#lx\n", DEVNAME(sc), 3090 (u_long)sc, (u_long)sc->sc_last_reply_idx); 3091 3092 KASSERT(sc->sc_last_reply_idx < sc->sc_reply_pool_size); 3093 3094 desc = (union mfi_mpi2_reply_descriptor *) 3095 ((uintptr_t)sc->sc_reply_frame_pool + 3096 sc->sc_last_reply_idx * MEGASAS_THUNDERBOLT_REPLY_SIZE); 3097 3098 bus_dmamap_sync(sc->sc_dmat, 3099 MFIMEM_MAP(sc->sc_tbolt_reqmsgpool), 3100 MEGASAS_THUNDERBOLT_NEW_MSG_SIZE * (sc->sc_max_cmds + 1), 3101 MEGASAS_THUNDERBOLT_REPLY_SIZE * sc->sc_reply_pool_size, 3102 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 3103 num_completed = 0; 3104 while ((desc->header.ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK) != 3105 MPI2_RPY_DESCRIPT_FLAGS_UNUSED) { 3106 smid = desc->header.SMID; 3107 KASSERT(smid > 0 && smid <= sc->sc_max_cmds); 3108 ccb = &sc->sc_ccb[smid - 1]; 3109 DNPRINTF(MFI_D_INTR, 3110 "%s: mfi_tbolt_intr SMID %#x reply_idx %#x " 3111 "desc %#" PRIx64 " ccb %p\n", DEVNAME(sc), smid, 3112 sc->sc_last_reply_idx, desc->words, ccb); 3113 KASSERT(ccb->ccb_state == MFI_CCB_RUNNING); 3114 if (ccb->ccb_flags & MFI_CCB_F_TBOLT_IO && 3115 ccb->ccb_tb_io_request->ChainOffset != 0) { 3116 bus_dmamap_sync(sc->sc_dmat, 3117 MFIMEM_MAP(sc->sc_tbolt_reqmsgpool), 3118 ccb->ccb_tb_psg_frame - 3119 MFIMEM_DVA(sc->sc_tbolt_reqmsgpool), 3120 MEGASAS_MAX_SZ_CHAIN_FRAME, BUS_DMASYNC_POSTREAD); 3121 } 3122 if (ccb->ccb_flags & MFI_CCB_F_TBOLT_IO) { 3123 bus_dmamap_sync(sc->sc_dmat, 3124 MFIMEM_MAP(sc->sc_tbolt_reqmsgpool), 3125 ccb->ccb_tb_pio_request - 3126 MFIMEM_DVA(sc->sc_tbolt_reqmsgpool), 3127 MEGASAS_THUNDERBOLT_NEW_MSG_SIZE, 3128 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 3129 } 3130 if (ccb->ccb_done) 3131 ccb->ccb_done(ccb); 3132 else 3133 ccb->ccb_state = MFI_CCB_DONE; 3134 sc->sc_last_reply_idx++; 3135 if (sc->sc_last_reply_idx >= sc->sc_reply_pool_size) { 3136 sc->sc_last_reply_idx = 0; 3137 } 3138 desc->words = ~0x0; 3139 /* Get the next reply descriptor */ 3140 desc = (union mfi_mpi2_reply_descriptor *) 3141 ((uintptr_t)sc->sc_reply_frame_pool + 3142 sc->sc_last_reply_idx * MEGASAS_THUNDERBOLT_REPLY_SIZE); 3143 num_completed++; 3144 } 3145 if (num_completed == 0) 3146 return 0; 3147 3148 bus_dmamap_sync(sc->sc_dmat, 3149 MFIMEM_MAP(sc->sc_tbolt_reqmsgpool), 3150 MEGASAS_THUNDERBOLT_NEW_MSG_SIZE * (sc->sc_max_cmds + 1), 3151 MEGASAS_THUNDERBOLT_REPLY_SIZE * sc->sc_reply_pool_size, 3152 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 3153 mfi_write(sc, MFI_RPI, sc->sc_last_reply_idx); 3154 return 1; 3155 } 3156 3157 3158 int 3159 mfi_tbolt_scsi_ld_io(struct mfi_ccb *ccb, struct scsipi_xfer *xs, 3160 uint64_t blockno, uint32_t blockcnt) 3161 { 3162 struct scsipi_periph *periph = xs->xs_periph; 3163 struct mfi_mpi2_request_raid_scsi_io *io_req; 3164 int sge_count; 3165 3166 DNPRINTF(MFI_D_CMD, "%s: mfi_tbolt_scsi_ld_io: %d\n", 3167 device_xname(periph->periph_channel->chan_adapter->adapt_dev), 3168 periph->periph_target); 3169 3170 if (!xs->data) 3171 return 1; 3172 3173 ccb->ccb_done = mfi_tbolt_scsi_ld_done; 3174 ccb->ccb_xs = xs; 3175 ccb->ccb_data = xs->data; 3176 ccb->ccb_len = xs->datalen; 3177 3178 io_req = ccb->ccb_tb_io_request; 3179 3180 /* Just the CDB length,rest of the Flags are zero */ 3181 io_req->IoFlags = xs->cmdlen; 3182 memset(io_req->CDB.CDB32, 0, 32); 3183 memcpy(io_req->CDB.CDB32, &xs->cmdstore, xs->cmdlen); 3184 3185 io_req->RaidContext.TargetID = periph->periph_target; 3186 io_req->RaidContext.Status = 0; 3187 io_req->RaidContext.exStatus = 0; 3188 io_req->RaidContext.timeoutValue = MFI_FUSION_FP_DEFAULT_TIMEOUT; 3189 io_req->Function = MPI2_FUNCTION_LD_IO_REQUEST; 3190 io_req->DevHandle = periph->periph_target; 3191 3192 ccb->ccb_tb_request_desc.header.RequestFlags = 3193 (MFI_REQ_DESCRIPT_FLAGS_LD_IO << MFI_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); 3194 io_req->DataLength = blockcnt * MFI_SECTOR_LEN; 3195 3196 if (xs->xs_control & XS_CTL_DATA_IN) { 3197 io_req->Control = MPI2_SCSIIO_CONTROL_READ; 3198 ccb->ccb_direction = MFI_DATA_IN; 3199 } else { 3200 io_req->Control = MPI2_SCSIIO_CONTROL_WRITE; 3201 ccb->ccb_direction = MFI_DATA_OUT; 3202 } 3203 3204 sge_count = mfi_tbolt_create_sgl(ccb, 3205 (xs->xs_control & XS_CTL_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK 3206 ); 3207 if (sge_count < 0) 3208 return 1; 3209 KASSERT(sge_count <= ccb->ccb_sc->sc_max_sgl); 3210 io_req->RaidContext.numSGE = sge_count; 3211 io_req->SGLFlags = MPI2_SGE_FLAGS_64_BIT_ADDRESSING; 3212 io_req->SGLOffset0 = 3213 offsetof(struct mfi_mpi2_request_raid_scsi_io, SGL) / 4; 3214 3215 io_req->SenseBufferLowAddress = htole32(ccb->ccb_psense); 3216 io_req->SenseBufferLength = MFI_SENSE_SIZE; 3217 3218 ccb->ccb_flags |= MFI_CCB_F_TBOLT | MFI_CCB_F_TBOLT_IO; 3219 bus_dmamap_sync(ccb->ccb_sc->sc_dmat, 3220 MFIMEM_MAP(ccb->ccb_sc->sc_tbolt_reqmsgpool), 3221 ccb->ccb_tb_pio_request - 3222 MFIMEM_DVA(ccb->ccb_sc->sc_tbolt_reqmsgpool), 3223 MEGASAS_THUNDERBOLT_NEW_MSG_SIZE, 3224 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 3225 3226 return 0; 3227 } 3228 3229 3230 static void 3231 mfi_tbolt_scsi_ld_done(struct mfi_ccb *ccb) 3232 { 3233 struct mfi_mpi2_request_raid_scsi_io *io_req = ccb->ccb_tb_io_request; 3234 mfi_scsi_xs_done(ccb, io_req->RaidContext.Status, 3235 io_req->RaidContext.exStatus); 3236 } 3237 3238 static int 3239 mfi_tbolt_create_sgl(struct mfi_ccb *ccb, int flags) 3240 { 3241 struct mfi_softc *sc = ccb->ccb_sc; 3242 bus_dma_segment_t *sgd; 3243 int error, i, sge_idx, sge_count; 3244 struct mfi_mpi2_request_raid_scsi_io *io_req; 3245 struct mpi25_ieee_sge_chain64 *sgl_ptr; 3246 3247 DNPRINTF(MFI_D_DMA, "%s: mfi_tbolt_create_sgl %#lx\n", DEVNAME(sc), 3248 (u_long)ccb->ccb_data); 3249 3250 if (!ccb->ccb_data) 3251 return -1; 3252 3253 KASSERT(flags == BUS_DMA_NOWAIT || !cpu_intr_p()); 3254 error = bus_dmamap_load(sc->sc_datadmat, ccb->ccb_dmamap, 3255 ccb->ccb_data, ccb->ccb_len, NULL, flags); 3256 if (error) { 3257 if (error == EFBIG) 3258 aprint_error_dev(sc->sc_dev, "more than %d dma segs\n", 3259 sc->sc_max_sgl); 3260 else 3261 aprint_error_dev(sc->sc_dev, 3262 "error %d loading dma map\n", error); 3263 return -1; 3264 } 3265 3266 io_req = ccb->ccb_tb_io_request; 3267 sgl_ptr = &io_req->SGL.IeeeChain.Chain64; 3268 sge_count = ccb->ccb_dmamap->dm_nsegs; 3269 sgd = ccb->ccb_dmamap->dm_segs; 3270 KASSERT(sge_count <= sc->sc_max_sgl); 3271 KASSERT(sge_count <= 3272 (MEGASAS_THUNDERBOLT_MAX_SGE_IN_MAINMSG - 1 + 3273 MEGASAS_THUNDERBOLT_MAX_SGE_IN_CHAINMSG)); 3274 3275 if (sge_count > MEGASAS_THUNDERBOLT_MAX_SGE_IN_MAINMSG) { 3276 /* One element to store the chain info */ 3277 sge_idx = MEGASAS_THUNDERBOLT_MAX_SGE_IN_MAINMSG - 1; 3278 DNPRINTF(MFI_D_DMA, 3279 "mfi sge_idx %d sge_count %d io_req paddr 0x%" PRIx64 "\n", 3280 sge_idx, sge_count, ccb->ccb_tb_pio_request); 3281 } else { 3282 sge_idx = sge_count; 3283 } 3284 3285 for (i = 0; i < sge_idx; i++) { 3286 sgl_ptr->Address = htole64(sgd[i].ds_addr); 3287 sgl_ptr->Length = htole32(sgd[i].ds_len); 3288 sgl_ptr->Flags = 0; 3289 if (sge_idx < sge_count) { 3290 DNPRINTF(MFI_D_DMA, 3291 "sgl %p %d 0x%" PRIx64 " len 0x%" PRIx32 3292 " flags 0x%x\n", sgl_ptr, i, 3293 sgl_ptr->Address, sgl_ptr->Length, 3294 sgl_ptr->Flags); 3295 } 3296 sgl_ptr++; 3297 } 3298 io_req->ChainOffset = 0; 3299 if (sge_idx < sge_count) { 3300 struct mpi25_ieee_sge_chain64 *sg_chain; 3301 io_req->ChainOffset = MEGASAS_THUNDERBOLT_CHAIN_OFF_MAINMSG; 3302 sg_chain = sgl_ptr; 3303 /* Prepare chain element */ 3304 sg_chain->NextChainOffset = 0; 3305 sg_chain->Flags = (MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT | 3306 MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR); 3307 sg_chain->Length = (sizeof(mpi2_sge_io_union) * 3308 (sge_count - sge_idx)); 3309 sg_chain->Address = ccb->ccb_tb_psg_frame; 3310 DNPRINTF(MFI_D_DMA, 3311 "sgl %p chain 0x%" PRIx64 " len 0x%" PRIx32 3312 " flags 0x%x\n", sg_chain, sg_chain->Address, 3313 sg_chain->Length, sg_chain->Flags); 3314 sgl_ptr = &ccb->ccb_tb_sg_frame->IeeeChain.Chain64; 3315 for (; i < sge_count; i++) { 3316 sgl_ptr->Address = htole64(sgd[i].ds_addr); 3317 sgl_ptr->Length = htole32(sgd[i].ds_len); 3318 sgl_ptr->Flags = 0; 3319 DNPRINTF(MFI_D_DMA, 3320 "sgl %p %d 0x%" PRIx64 " len 0x%" PRIx32 3321 " flags 0x%x\n", sgl_ptr, i, sgl_ptr->Address, 3322 sgl_ptr->Length, sgl_ptr->Flags); 3323 sgl_ptr++; 3324 } 3325 bus_dmamap_sync(sc->sc_dmat, 3326 MFIMEM_MAP(sc->sc_tbolt_reqmsgpool), 3327 ccb->ccb_tb_psg_frame - MFIMEM_DVA(sc->sc_tbolt_reqmsgpool), 3328 MEGASAS_MAX_SZ_CHAIN_FRAME, BUS_DMASYNC_PREREAD); 3329 } 3330 3331 if (ccb->ccb_direction == MFI_DATA_IN) { 3332 bus_dmamap_sync(sc->sc_datadmat, ccb->ccb_dmamap, 0, 3333 ccb->ccb_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD); 3334 } else { 3335 bus_dmamap_sync(sc->sc_datadmat, ccb->ccb_dmamap, 0, 3336 ccb->ccb_dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE); 3337 } 3338 return sge_count; 3339 } 3340 3341 /* 3342 * The ThunderBolt HW has an option for the driver to directly 3343 * access the underlying disks and operate on the RAID. To 3344 * do this there needs to be a capability to keep the RAID controller 3345 * and driver in sync. The FreeBSD driver does not take advantage 3346 * of this feature since it adds a lot of complexity and slows down 3347 * performance. Performance is gained by using the controller's 3348 * cache etc. 3349 * 3350 * Even though this driver doesn't access the disks directly, an 3351 * AEN like command is used to inform the RAID firmware to "sync" 3352 * with all LD's via the MFI_DCMD_LD_MAP_GET_INFO command. This 3353 * command in write mode will return when the RAID firmware has 3354 * detected a change to the RAID state. Examples of this type 3355 * of change are removing a disk. Once the command returns then 3356 * the driver needs to acknowledge this and "sync" all LD's again. 3357 * This repeats until we shutdown. Then we need to cancel this 3358 * pending command. 3359 * 3360 * If this is not done right the RAID firmware will not remove a 3361 * pulled drive and the RAID won't go degraded etc. Effectively, 3362 * stopping any RAID mangement to functions. 3363 * 3364 * Doing another LD sync, requires the use of an event since the 3365 * driver needs to do a mfi_wait_command and can't do that in an 3366 * interrupt thread. 3367 * 3368 * The driver could get the RAID state via the MFI_DCMD_LD_MAP_GET_INFO 3369 * That requires a bunch of structure and it is simplier to just do 3370 * the MFI_DCMD_LD_GET_LIST versus walking the RAID map. 3371 */ 3372 3373 void 3374 mfi_tbolt_sync_map_info(struct work *w, void *v) 3375 { 3376 struct mfi_softc *sc = v; 3377 int i; 3378 struct mfi_ccb *ccb = NULL; 3379 uint8_t mbox[MFI_MBOX_SIZE]; 3380 struct mfi_ld *ld_sync; 3381 size_t ld_size; 3382 int s; 3383 3384 DNPRINTF(MFI_D_SYNC, "%s: mfi_tbolt_sync_map_info\n", DEVNAME(sc)); 3385 again: 3386 ld_sync = NULL; 3387 s = splbio(); 3388 if (sc->sc_ldsync_ccb != NULL) { 3389 splx(s); 3390 return; 3391 } 3392 3393 if (mfi_mgmt_internal(sc, MR_DCMD_LD_GET_LIST, MFI_DATA_IN, 3394 sizeof(sc->sc_ld_list), &sc->sc_ld_list, NULL, false)) { 3395 aprint_error_dev(sc->sc_dev, "MR_DCMD_LD_GET_LIST failed\n"); 3396 goto err; 3397 } 3398 3399 ld_size = sizeof(*ld_sync) * sc->sc_ld_list.mll_no_ld; 3400 3401 ld_sync = malloc(ld_size, M_DEVBUF, M_WAITOK | M_ZERO); 3402 if (ld_sync == NULL) { 3403 aprint_error_dev(sc->sc_dev, "Failed to allocate sync\n"); 3404 goto err; 3405 } 3406 for (i = 0; i < sc->sc_ld_list.mll_no_ld; i++) { 3407 ld_sync[i] = sc->sc_ld_list.mll_list[i].mll_ld; 3408 } 3409 3410 if ((ccb = mfi_get_ccb(sc)) == NULL) { 3411 aprint_error_dev(sc->sc_dev, "Failed to get sync command\n"); 3412 goto err; 3413 } 3414 sc->sc_ldsync_ccb = ccb; 3415 3416 memset(mbox, 0, MFI_MBOX_SIZE); 3417 mbox[0] = sc->sc_ld_list.mll_no_ld; 3418 mbox[1] = MFI_DCMD_MBOX_PEND_FLAG; 3419 if (mfi_mgmt(ccb, NULL, MR_DCMD_LD_MAP_GET_INFO, MFI_DATA_OUT, 3420 ld_size, ld_sync, mbox)) { 3421 aprint_error_dev(sc->sc_dev, "Failed to create sync command\n"); 3422 goto err; 3423 } 3424 /* 3425 * we won't sleep on this command, so we have to override 3426 * the callback set up by mfi_mgmt() 3427 */ 3428 ccb->ccb_done = mfi_sync_map_complete; 3429 3430 mfi_post(sc, ccb); 3431 splx(s); 3432 return; 3433 3434 err: 3435 if (ld_sync) 3436 free(ld_sync, M_DEVBUF); 3437 if (ccb) 3438 mfi_put_ccb(ccb); 3439 sc->sc_ldsync_ccb = NULL; 3440 splx(s); 3441 kpause("ldsyncp", 0, hz, NULL); 3442 goto again; 3443 } 3444 3445 static void 3446 mfi_sync_map_complete(struct mfi_ccb *ccb) 3447 { 3448 struct mfi_softc *sc = ccb->ccb_sc; 3449 bool aborted = !sc->sc_running; 3450 3451 DNPRINTF(MFI_D_SYNC, "%s: mfi_sync_map_complete\n", 3452 DEVNAME(ccb->ccb_sc)); 3453 KASSERT(sc->sc_ldsync_ccb == ccb); 3454 mfi_mgmt_done(ccb); 3455 free(ccb->ccb_data, M_DEVBUF); 3456 if (ccb->ccb_flags & MFI_CCB_F_ERR) { 3457 aprint_error_dev(sc->sc_dev, "sync command failed\n"); 3458 aborted = true; 3459 } 3460 mfi_put_ccb(ccb); 3461 sc->sc_ldsync_ccb = NULL; 3462 3463 /* set it up again so the driver can catch more events */ 3464 if (!aborted) { 3465 workqueue_enqueue(sc->sc_ldsync_wq, &sc->sc_ldsync_wk, NULL); 3466 } 3467 } 3468 3469 static int 3470 mfifopen(dev_t dev, int flag, int mode, struct lwp *l) 3471 { 3472 struct mfi_softc *sc; 3473 3474 if ((sc = device_lookup_private(&mfi_cd, minor(dev))) == NULL) 3475 return (ENXIO); 3476 return (0); 3477 } 3478 3479 static int 3480 mfifclose(dev_t dev, int flag, int mode, struct lwp *l) 3481 { 3482 return (0); 3483 } 3484 3485 static int 3486 mfifioctl(dev_t dev, u_long cmd, void *data, int flag, 3487 struct lwp *l) 3488 { 3489 struct mfi_softc *sc; 3490 struct mfi_ioc_packet *ioc = data; 3491 uint8_t *udata; 3492 struct mfi_ccb *ccb = NULL; 3493 int ctx, i, s, error; 3494 union mfi_sense_ptr sense_ptr; 3495 3496 switch(cmd) { 3497 case MFI_CMD: 3498 sc = device_lookup_private(&mfi_cd, ioc->mfi_adapter_no); 3499 break; 3500 default: 3501 return ENOTTY; 3502 } 3503 if (sc == NULL) 3504 return (ENXIO); 3505 if (sc->sc_opened) 3506 return (EBUSY); 3507 3508 switch(cmd) { 3509 case MFI_CMD: 3510 error = kauth_authorize_device_passthru(l->l_cred, dev, 3511 KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_ALL, data); 3512 if (error) 3513 return error; 3514 if (ioc->mfi_sge_count > MAX_IOCTL_SGE) 3515 return EINVAL; 3516 s = splbio(); 3517 if ((ccb = mfi_get_ccb(sc)) == NULL) 3518 return ENOMEM; 3519 ccb->ccb_data = NULL; 3520 ctx = ccb->ccb_frame->mfr_header.mfh_context; 3521 memcpy(ccb->ccb_frame, ioc->mfi_frame.raw, 3522 sizeof(*ccb->ccb_frame)); 3523 ccb->ccb_frame->mfr_header.mfh_context = ctx; 3524 ccb->ccb_frame->mfr_header.mfh_scsi_status = 0; 3525 ccb->ccb_frame->mfr_header.mfh_pad0 = 0; 3526 ccb->ccb_frame_size = 3527 (sizeof(union mfi_sgl) * ioc->mfi_sge_count) + 3528 ioc->mfi_sgl_off; 3529 if (ioc->mfi_sge_count > 0) { 3530 ccb->ccb_sgl = (union mfi_sgl *) 3531 &ccb->ccb_frame->mfr_bytes[ioc->mfi_sgl_off]; 3532 } 3533 if (ccb->ccb_frame->mfr_header.mfh_flags & MFI_FRAME_DIR_READ) 3534 ccb->ccb_direction = MFI_DATA_IN; 3535 if (ccb->ccb_frame->mfr_header.mfh_flags & MFI_FRAME_DIR_WRITE) 3536 ccb->ccb_direction = MFI_DATA_OUT; 3537 ccb->ccb_len = ccb->ccb_frame->mfr_header.mfh_data_len; 3538 if (ccb->ccb_len > MAXPHYS) { 3539 error = ENOMEM; 3540 goto out; 3541 } 3542 if (ccb->ccb_len && 3543 (ccb->ccb_direction & (MFI_DATA_IN | MFI_DATA_OUT)) != 0) { 3544 udata = malloc(ccb->ccb_len, M_DEVBUF, M_WAITOK|M_ZERO); 3545 if (udata == NULL) { 3546 error = ENOMEM; 3547 goto out; 3548 } 3549 ccb->ccb_data = udata; 3550 if (ccb->ccb_direction & MFI_DATA_OUT) { 3551 for (i = 0; i < ioc->mfi_sge_count; i++) { 3552 error = copyin(ioc->mfi_sgl[i].iov_base, 3553 udata, ioc->mfi_sgl[i].iov_len); 3554 if (error) 3555 goto out; 3556 udata = &udata[ 3557 ioc->mfi_sgl[i].iov_len]; 3558 } 3559 } 3560 if (mfi_create_sgl(ccb, BUS_DMA_WAITOK)) { 3561 error = EIO; 3562 goto out; 3563 } 3564 } 3565 if (ccb->ccb_frame->mfr_header.mfh_cmd == MFI_CMD_PD_SCSI_IO) { 3566 ccb->ccb_frame->mfr_io.mif_sense_addr_lo = 3567 htole32(ccb->ccb_psense); 3568 ccb->ccb_frame->mfr_io.mif_sense_addr_hi = 0; 3569 } 3570 ccb->ccb_done = mfi_mgmt_done; 3571 mfi_post(sc, ccb); 3572 while (ccb->ccb_state != MFI_CCB_DONE) 3573 tsleep(ccb, PRIBIO, "mfi_fioc", 0); 3574 3575 if (ccb->ccb_direction & MFI_DATA_IN) { 3576 udata = ccb->ccb_data; 3577 for (i = 0; i < ioc->mfi_sge_count; i++) { 3578 error = copyout(udata, 3579 ioc->mfi_sgl[i].iov_base, 3580 ioc->mfi_sgl[i].iov_len); 3581 if (error) 3582 goto out; 3583 udata = &udata[ 3584 ioc->mfi_sgl[i].iov_len]; 3585 } 3586 } 3587 if (ioc->mfi_sense_len) { 3588 memcpy(&sense_ptr.sense_ptr_data[0], 3589 &ioc->mfi_frame.raw[ioc->mfi_sense_off], 3590 sizeof(sense_ptr.sense_ptr_data)); 3591 error = copyout(ccb->ccb_sense, 3592 sense_ptr.user_space, 3593 sizeof(sense_ptr.sense_ptr_data)); 3594 if (error) 3595 goto out; 3596 } 3597 memcpy(ioc->mfi_frame.raw, ccb->ccb_frame, 3598 sizeof(*ccb->ccb_frame)); 3599 break; 3600 default: 3601 printf("mfifioctl unhandled cmd 0x%lx\n", cmd); 3602 return ENOTTY; 3603 } 3604 3605 out: 3606 if (ccb->ccb_data) 3607 free(ccb->ccb_data, M_DEVBUF); 3608 if (ccb) 3609 mfi_put_ccb(ccb); 3610 splx(s); 3611 return error; 3612 } 3613