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