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