version 1.17, 2008/04/22 22:49:49 |
version 1.17.2.6, 2010/08/11 22:53:28 |
Line 70 static void mfi_put_ccb(struct mfi_ccb |
|
Line 70 static void mfi_put_ccb(struct mfi_ccb |
|
static int mfi_init_ccb(struct mfi_softc *); |
static int mfi_init_ccb(struct mfi_softc *); |
|
|
static struct mfi_mem *mfi_allocmem(struct mfi_softc *, size_t); |
static struct mfi_mem *mfi_allocmem(struct mfi_softc *, size_t); |
static void mfi_freemem(struct mfi_softc *, struct mfi_mem *); |
static void mfi_freemem(struct mfi_softc *, struct mfi_mem **); |
|
|
static int mfi_transition_firmware(struct mfi_softc *); |
static int mfi_transition_firmware(struct mfi_softc *); |
static int mfi_initialize_firmware(struct mfi_softc *); |
static int mfi_initialize_firmware(struct mfi_softc *); |
Line 85 static int mfi_scsi_ld(struct mfi_ccb * |
|
Line 85 static int mfi_scsi_ld(struct mfi_ccb * |
|
static int mfi_scsi_io(struct mfi_ccb *, struct scsipi_xfer *, |
static int mfi_scsi_io(struct mfi_ccb *, struct scsipi_xfer *, |
uint32_t, uint32_t); |
uint32_t, uint32_t); |
static void mfi_scsi_xs_done(struct mfi_ccb *); |
static void mfi_scsi_xs_done(struct mfi_ccb *); |
static int mfi_mgmt(struct mfi_softc *, uint32_t, uint32_t, |
static int mfi_mgmt_internal(struct mfi_softc *, |
uint32_t, void *, uint8_t *); |
uint32_t, uint32_t, uint32_t, void *, uint8_t *); |
|
static int mfi_mgmt(struct mfi_ccb *,struct scsipi_xfer *, |
|
uint32_t, uint32_t, uint32_t, void *, uint8_t *); |
static void mfi_mgmt_done(struct mfi_ccb *); |
static void mfi_mgmt_done(struct mfi_ccb *); |
|
|
#if NBIO > 0 |
#if NBIO > 0 |
static int mfi_ioctl(struct device *, u_long, void *); |
static int mfi_ioctl(device_t, u_long, void *); |
static int mfi_ioctl_inq(struct mfi_softc *, struct bioc_inq *); |
static int mfi_ioctl_inq(struct mfi_softc *, struct bioc_inq *); |
static int mfi_ioctl_vol(struct mfi_softc *, struct bioc_vol *); |
static int mfi_ioctl_vol(struct mfi_softc *, struct bioc_vol *); |
static int mfi_ioctl_disk(struct mfi_softc *, struct bioc_disk *); |
static int mfi_ioctl_disk(struct mfi_softc *, struct bioc_disk *); |
Line 102 static int mfi_ioctl_setstate(struct mf |
|
Line 104 static int mfi_ioctl_setstate(struct mf |
|
struct bioc_setstate *); |
struct bioc_setstate *); |
static int mfi_bio_hs(struct mfi_softc *, int, int, void *); |
static int mfi_bio_hs(struct mfi_softc *, int, int, void *); |
static int mfi_create_sensors(struct mfi_softc *); |
static int mfi_create_sensors(struct mfi_softc *); |
|
static int mfi_destroy_sensors(struct mfi_softc *); |
static void mfi_sensor_refresh(struct sysmon_envsys *, |
static void mfi_sensor_refresh(struct sysmon_envsys *, |
envsys_data_t *); |
envsys_data_t *); |
#endif /* NBIO > 0 */ |
#endif /* NBIO > 0 */ |
|
|
static uint32_t mfi_xscale_fw_state(struct mfi_softc *sc); |
static uint32_t mfi_xscale_fw_state(struct mfi_softc *sc); |
static void mfi_xscale_intr_ena(struct mfi_softc *sc); |
static void mfi_xscale_intr_ena(struct mfi_softc *sc); |
|
static void mfi_xscale_intr_dis(struct mfi_softc *sc); |
static int mfi_xscale_intr(struct mfi_softc *sc); |
static int mfi_xscale_intr(struct mfi_softc *sc); |
static void mfi_xscale_post(struct mfi_softc *sc, struct mfi_ccb *ccb); |
static void mfi_xscale_post(struct mfi_softc *sc, struct mfi_ccb *ccb); |
|
|
static const struct mfi_iop_ops mfi_iop_xscale = { |
static const struct mfi_iop_ops mfi_iop_xscale = { |
mfi_xscale_fw_state, |
mfi_xscale_fw_state, |
|
mfi_xscale_intr_dis, |
mfi_xscale_intr_ena, |
mfi_xscale_intr_ena, |
mfi_xscale_intr, |
mfi_xscale_intr, |
mfi_xscale_post |
mfi_xscale_post |
}; |
}; |
|
|
static uint32_t mfi_ppc_fw_state(struct mfi_softc *sc); |
static uint32_t mfi_ppc_fw_state(struct mfi_softc *sc); |
static void mfi_ppc_intr_ena(struct mfi_softc *sc); |
static void mfi_ppc_intr_ena(struct mfi_softc *sc); |
|
static void mfi_ppc_intr_dis(struct mfi_softc *sc); |
static int mfi_ppc_intr(struct mfi_softc *sc); |
static int mfi_ppc_intr(struct mfi_softc *sc); |
static void mfi_ppc_post(struct mfi_softc *sc, struct mfi_ccb *ccb); |
static void mfi_ppc_post(struct mfi_softc *sc, struct mfi_ccb *ccb); |
|
|
static const struct mfi_iop_ops mfi_iop_ppc = { |
static const struct mfi_iop_ops mfi_iop_ppc = { |
mfi_ppc_fw_state, |
mfi_ppc_fw_state, |
|
mfi_ppc_intr_dis, |
mfi_ppc_intr_ena, |
mfi_ppc_intr_ena, |
mfi_ppc_intr, |
mfi_ppc_intr, |
mfi_ppc_post |
mfi_ppc_post |
}; |
}; |
|
|
|
uint32_t mfi_gen2_fw_state(struct mfi_softc *sc); |
|
void mfi_gen2_intr_ena(struct mfi_softc *sc); |
|
void mfi_gen2_intr_dis(struct mfi_softc *sc); |
|
int mfi_gen2_intr(struct mfi_softc *sc); |
|
void mfi_gen2_post(struct mfi_softc *sc, struct mfi_ccb *ccb); |
|
|
|
static const struct mfi_iop_ops mfi_iop_gen2 = { |
|
mfi_gen2_fw_state, |
|
mfi_gen2_intr_dis, |
|
mfi_gen2_intr_ena, |
|
mfi_gen2_intr, |
|
mfi_gen2_post |
|
}; |
|
|
#define mfi_fw_state(_s) ((_s)->sc_iop->mio_fw_state(_s)) |
#define mfi_fw_state(_s) ((_s)->sc_iop->mio_fw_state(_s)) |
#define mfi_intr_enable(_s) ((_s)->sc_iop->mio_intr_ena(_s)) |
#define mfi_intr_enable(_s) ((_s)->sc_iop->mio_intr_ena(_s)) |
|
#define mfi_intr_disable(_s) ((_s)->sc_iop->mio_intr_dis(_s)) |
#define mfi_my_intr(_s) ((_s)->sc_iop->mio_intr(_s)) |
#define mfi_my_intr(_s) ((_s)->sc_iop->mio_intr(_s)) |
#define mfi_post(_s, _c) ((_s)->sc_iop->mio_post((_s), (_c))) |
#define mfi_post(_s, _c) ((_s)->sc_iop->mio_post((_s), (_c))) |
|
|
Line 178 mfi_put_ccb(struct mfi_ccb *ccb) |
|
Line 200 mfi_put_ccb(struct mfi_ccb *ccb) |
|
} |
} |
|
|
static int |
static int |
|
mfi_destroy_ccb(struct mfi_softc *sc) |
|
{ |
|
struct mfi_ccb *ccb; |
|
uint32_t i; |
|
|
|
DNPRINTF(MFI_D_CCB, "%s: mfi_init_ccb\n", DEVNAME(sc)); |
|
|
|
|
|
for (i = 0; (ccb = mfi_get_ccb(sc)) != NULL; i++) { |
|
/* create a dma map for transfer */ |
|
bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap); |
|
} |
|
|
|
if (i < sc->sc_max_cmds) |
|
return EBUSY; |
|
|
|
free(sc->sc_ccb, M_DEVBUF); |
|
|
|
return 0; |
|
} |
|
|
|
static int |
mfi_init_ccb(struct mfi_softc *sc) |
mfi_init_ccb(struct mfi_softc *sc) |
{ |
{ |
struct mfi_ccb *ccb; |
struct mfi_ccb *ccb; |
Line 282 mfi_allocmem(struct mfi_softc *sc, size_ |
|
Line 326 mfi_allocmem(struct mfi_softc *sc, size_ |
|
|
|
if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, |
if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, |
BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mm->am_map) != 0) |
BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mm->am_map) != 0) |
goto amfree; |
goto amfree; |
|
|
if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &mm->am_seg, 1, |
if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &mm->am_seg, 1, |
&nsegs, BUS_DMA_NOWAIT) != 0) |
&nsegs, BUS_DMA_NOWAIT) != 0) |
|
|
} |
} |
|
|
static void |
static void |
mfi_freemem(struct mfi_softc *sc, struct mfi_mem *mm) |
mfi_freemem(struct mfi_softc *sc, struct mfi_mem **mmp) |
{ |
{ |
|
struct mfi_mem *mm = *mmp; |
|
|
|
if (mm == NULL) |
|
return; |
|
|
|
*mmp = NULL; |
|
|
DNPRINTF(MFI_D_MEM, "%s: mfi_freemem: %p\n", DEVNAME(sc), mm); |
DNPRINTF(MFI_D_MEM, "%s: mfi_freemem: %p\n", DEVNAME(sc), mm); |
|
|
bus_dmamap_unload(sc->sc_dmat, mm->am_map); |
bus_dmamap_unload(sc->sc_dmat, mm->am_map); |
Line 329 mfi_freemem(struct mfi_softc *sc, struct |
|
Line 380 mfi_freemem(struct mfi_softc *sc, struct |
|
static int |
static int |
mfi_transition_firmware(struct mfi_softc *sc) |
mfi_transition_firmware(struct mfi_softc *sc) |
{ |
{ |
int32_t fw_state, cur_state; |
uint32_t fw_state, cur_state; |
int max_wait, i; |
int max_wait, i; |
|
|
fw_state = mfi_fw_state(sc) & MFI_STATE_MASK; |
fw_state = mfi_fw_state(sc) & MFI_STATE_MASK; |
Line 436 mfi_get_info(struct mfi_softc *sc) |
|
Line 487 mfi_get_info(struct mfi_softc *sc) |
|
#endif |
#endif |
DNPRINTF(MFI_D_MISC, "%s: mfi_get_info\n", DEVNAME(sc)); |
DNPRINTF(MFI_D_MISC, "%s: mfi_get_info\n", DEVNAME(sc)); |
|
|
if (mfi_mgmt(sc, MR_DCMD_CTRL_GET_INFO, MFI_DATA_IN, |
if (mfi_mgmt_internal(sc, MR_DCMD_CTRL_GET_INFO, MFI_DATA_IN, |
sizeof(sc->sc_info), &sc->sc_info, NULL)) |
sizeof(sc->sc_info), &sc->sc_info, NULL)) |
return 1; |
return 1; |
|
|
Line 599 mfiminphys(struct buf *bp) |
|
Line 650 mfiminphys(struct buf *bp) |
|
} |
} |
|
|
int |
int |
|
mfi_rescan(device_t self, const char *ifattr, const int *locators) |
|
{ |
|
struct mfi_softc *sc = device_private(self); |
|
|
|
if (sc->sc_child != NULL) |
|
return 0; |
|
|
|
sc->sc_child = config_found_sm_loc(self, ifattr, locators, &sc->sc_chan, |
|
scsiprint, NULL); |
|
|
|
return 0; |
|
} |
|
|
|
void |
|
mfi_childdetached(device_t self, device_t child) |
|
{ |
|
struct mfi_softc *sc = device_private(self); |
|
|
|
KASSERT(self == sc->sc_dev); |
|
KASSERT(child == sc->sc_child); |
|
|
|
if (child == sc->sc_child) |
|
sc->sc_child = NULL; |
|
} |
|
|
|
int |
|
mfi_detach(struct mfi_softc *sc, int flags) |
|
{ |
|
int error; |
|
|
|
DNPRINTF(MFI_D_MISC, "%s: mfi_detach\n", DEVNAME(sc)); |
|
|
|
if ((error = config_detach_children(sc->sc_dev, flags)) != 0) |
|
return error; |
|
|
|
#if NBIO > 0 |
|
mfi_destroy_sensors(sc); |
|
bio_unregister(sc->sc_dev); |
|
#endif /* NBIO > 0 */ |
|
|
|
mfi_intr_disable(sc); |
|
|
|
/* TBD: shutdown firmware */ |
|
|
|
if ((error = mfi_destroy_ccb(sc)) != 0) |
|
return error; |
|
|
|
mfi_freemem(sc, &sc->sc_sense); |
|
|
|
mfi_freemem(sc, &sc->sc_frames); |
|
|
|
mfi_freemem(sc, &sc->sc_pcq); |
|
|
|
return 0; |
|
} |
|
|
|
int |
mfi_attach(struct mfi_softc *sc, enum mfi_iop iop) |
mfi_attach(struct mfi_softc *sc, enum mfi_iop iop) |
{ |
{ |
struct scsipi_adapter *adapt = &sc->sc_adapt; |
struct scsipi_adapter *adapt = &sc->sc_adapt; |
Line 615 mfi_attach(struct mfi_softc *sc, enum mf |
|
Line 723 mfi_attach(struct mfi_softc *sc, enum mf |
|
case MFI_IOP_PPC: |
case MFI_IOP_PPC: |
sc->sc_iop = &mfi_iop_ppc; |
sc->sc_iop = &mfi_iop_ppc; |
break; |
break; |
|
case MFI_IOP_GEN2: |
|
sc->sc_iop = &mfi_iop_gen2; |
|
break; |
default: |
default: |
panic("%s: unknown iop %d", DEVNAME(sc), iop); |
panic("%s: unknown iop %d", DEVNAME(sc), iop); |
} |
} |
Line 699 mfi_attach(struct mfi_softc *sc, enum mf |
|
Line 810 mfi_attach(struct mfi_softc *sc, enum mf |
|
sc->sc_ld[i].ld_present = 1; |
sc->sc_ld[i].ld_present = 1; |
|
|
memset(adapt, 0, sizeof(*adapt)); |
memset(adapt, 0, sizeof(*adapt)); |
adapt->adapt_dev = &sc->sc_dev; |
adapt->adapt_dev = sc->sc_dev; |
adapt->adapt_nchannels = 1; |
adapt->adapt_nchannels = 1; |
if (sc->sc_ld_cnt) |
if (sc->sc_ld_cnt) |
adapt->adapt_openings = sc->sc_max_cmds / sc->sc_ld_cnt; |
adapt->adapt_openings = sc->sc_max_cmds / sc->sc_ld_cnt; |
Line 718 mfi_attach(struct mfi_softc *sc, enum mf |
|
Line 829 mfi_attach(struct mfi_softc *sc, enum mf |
|
chan->chan_ntargets = MFI_MAX_LD; |
chan->chan_ntargets = MFI_MAX_LD; |
chan->chan_id = MFI_MAX_LD; |
chan->chan_id = MFI_MAX_LD; |
|
|
(void)config_found(&sc->sc_dev, &sc->sc_chan, scsiprint); |
mfi_rescan(sc->sc_dev, "scsi", NULL); |
|
|
/* enable interrupts */ |
/* enable interrupts */ |
mfi_intr_enable(sc); |
mfi_intr_enable(sc); |
|
|
#if NBIO > 0 |
#if NBIO > 0 |
if (bio_register(&sc->sc_dev, mfi_ioctl) != 0) |
if (bio_register(sc->sc_dev, mfi_ioctl) != 0) |
panic("%s: controller registration failed", DEVNAME(sc)); |
panic("%s: controller registration failed", DEVNAME(sc)); |
if (mfi_create_sensors(sc) != 0) |
if (mfi_create_sensors(sc) != 0) |
aprint_error("%s: unable to create sensors\n", DEVNAME(sc)); |
aprint_error("%s: unable to create sensors\n", DEVNAME(sc)); |
Line 732 mfi_attach(struct mfi_softc *sc, enum mf |
|
Line 843 mfi_attach(struct mfi_softc *sc, enum mf |
|
|
|
return 0; |
return 0; |
noinit: |
noinit: |
mfi_freemem(sc, sc->sc_sense); |
mfi_freemem(sc, &sc->sc_sense); |
nosense: |
nosense: |
mfi_freemem(sc, sc->sc_frames); |
mfi_freemem(sc, &sc->sc_frames); |
noframe: |
noframe: |
mfi_freemem(sc, sc->sc_pcq); |
mfi_freemem(sc, &sc->sc_pcq); |
nopcq: |
nopcq: |
return 1; |
return 1; |
} |
} |
Line 788 mfi_poll(struct mfi_ccb *ccb) |
|
Line 899 mfi_poll(struct mfi_ccb *ccb) |
|
ccb->ccb_flags |= MFI_CCB_F_ERR; |
ccb->ccb_flags |= MFI_CCB_F_ERR; |
return 1; |
return 1; |
} |
} |
|
|
return 0; |
return 0; |
} |
} |
|
|
Line 1001 mfi_scsipi_request(struct scsipi_channel |
|
Line 1112 mfi_scsipi_request(struct scsipi_channel |
|
struct scsipi_periph *periph; |
struct scsipi_periph *periph; |
struct scsipi_xfer *xs; |
struct scsipi_xfer *xs; |
struct scsipi_adapter *adapt = chan->chan_adapter; |
struct scsipi_adapter *adapt = chan->chan_adapter; |
struct mfi_softc *sc = (void *) adapt->adapt_dev; |
struct mfi_softc *sc = device_private(adapt->adapt_dev); |
struct mfi_ccb *ccb; |
struct mfi_ccb *ccb; |
struct scsi_rw_6 *rw; |
struct scsi_rw_6 *rw; |
struct scsipi_rw_10 *rwb; |
struct scsipi_rw_10 *rwb; |
Line 1073 mfi_scsipi_request(struct scsipi_channel |
|
Line 1184 mfi_scsipi_request(struct scsipi_channel |
|
break; |
break; |
|
|
case SCSI_SYNCHRONIZE_CACHE_10: |
case SCSI_SYNCHRONIZE_CACHE_10: |
mfi_put_ccb(ccb); /* we don't need this */ |
|
|
|
mbox[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE; |
mbox[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE; |
if (mfi_mgmt(sc, MR_DCMD_CTRL_CACHE_FLUSH, MFI_DATA_NONE, |
if (mfi_mgmt(ccb, xs, |
0, NULL, mbox)) |
MR_DCMD_CTRL_CACHE_FLUSH, MFI_DATA_NONE, 0, NULL, mbox)) { |
|
mfi_put_ccb(ccb); |
goto stuffup; |
goto stuffup; |
xs->error = XS_NOERROR; |
} |
xs->status = SCSI_OK; |
break; |
xs->resid = 0; |
|
scsipi_done(xs); |
|
splx(s); |
|
return; |
|
/* NOTREACHED */ |
|
|
|
/* hand it of to the firmware and let it deal with it */ |
/* hand it of to the firmware and let it deal with it */ |
case SCSI_TEST_UNIT_READY: |
case SCSI_TEST_UNIT_READY: |
/* save off sd? after autoconf */ |
/* save off sd? after autoconf */ |
if (!cold) /* XXX bogus */ |
if (!cold) /* XXX bogus */ |
strlcpy(sc->sc_ld[target].ld_dev, device_xname(&sc->sc_dev), |
strlcpy(sc->sc_ld[target].ld_dev, device_xname(sc->sc_dev), |
sizeof(sc->sc_ld[target].ld_dev)); |
sizeof(sc->sc_ld[target].ld_dev)); |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |
|
|
Line 1110 mfi_scsipi_request(struct scsipi_channel |
|
Line 1215 mfi_scsipi_request(struct scsipi_channel |
|
/* XXX check for sense in ccb->ccb_sense? */ |
/* XXX check for sense in ccb->ccb_sense? */ |
printf("%s: mfi_scsipi_request poll failed\n", |
printf("%s: mfi_scsipi_request poll failed\n", |
DEVNAME(sc)); |
DEVNAME(sc)); |
mfi_put_ccb(ccb); |
memset(&xs->sense, 0, sizeof(xs->sense)); |
bzero(&xs->sense, sizeof(xs->sense)); |
|
xs->sense.scsi_sense.response_code = |
xs->sense.scsi_sense.response_code = |
SSD_RCODE_VALID | SSD_RCODE_CURRENT; |
SSD_RCODE_VALID | SSD_RCODE_CURRENT; |
xs->sense.scsi_sense.flags = SKEY_ILLEGAL_REQUEST; |
xs->sense.scsi_sense.flags = SKEY_ILLEGAL_REQUEST; |
Line 1211 mfi_create_sgl(struct mfi_ccb *ccb, int |
|
Line 1315 mfi_create_sgl(struct mfi_ccb *ccb, int |
|
} |
} |
|
|
static int |
static int |
mfi_mgmt(struct mfi_softc *sc, uint32_t opc, uint32_t dir, uint32_t len, |
mfi_mgmt_internal(struct mfi_softc *sc, uint32_t opc, uint32_t dir, |
void *buf, uint8_t *mbox) |
uint32_t len, void *buf, uint8_t *mbox) |
{ |
{ |
struct mfi_ccb *ccb; |
struct mfi_ccb *ccb; |
struct mfi_dcmd_frame *dcmd; |
|
int rv = 1; |
int rv = 1; |
|
|
DNPRINTF(MFI_D_MISC, "%s: mfi_mgmt %#x\n", DEVNAME(sc), opc); |
|
|
|
if ((ccb = mfi_get_ccb(sc)) == NULL) |
if ((ccb = mfi_get_ccb(sc)) == NULL) |
return rv; |
return rv; |
|
rv = mfi_mgmt(ccb, NULL, opc, dir, len, buf, mbox); |
|
if (rv) |
|
return rv; |
|
|
|
if (cold) { |
|
if (mfi_poll(ccb)) |
|
goto done; |
|
} else { |
|
mfi_post(sc, ccb); |
|
|
|
DNPRINTF(MFI_D_MISC, "%s: mfi_mgmt_internal sleeping\n", |
|
DEVNAME(sc)); |
|
while (ccb->ccb_state != MFI_CCB_DONE) |
|
tsleep(ccb, PRIBIO, "mfi_mgmt", 0); |
|
|
|
if (ccb->ccb_flags & MFI_CCB_F_ERR) |
|
goto done; |
|
} |
|
rv = 0; |
|
|
|
done: |
|
mfi_put_ccb(ccb); |
|
return rv; |
|
} |
|
|
|
static int |
|
mfi_mgmt(struct mfi_ccb *ccb, struct scsipi_xfer *xs, |
|
uint32_t opc, uint32_t dir, uint32_t len, void *buf, uint8_t *mbox) |
|
{ |
|
struct mfi_dcmd_frame *dcmd; |
|
|
|
DNPRINTF(MFI_D_MISC, "%s: mfi_mgmt %#x\n", DEVNAME(ccb->ccb_sc), opc); |
|
|
dcmd = &ccb->ccb_frame->mfr_dcmd; |
dcmd = &ccb->ccb_frame->mfr_dcmd; |
memset(dcmd->mdf_mbox, 0, MFI_MBOX_SIZE); |
memset(dcmd->mdf_mbox, 0, MFI_MBOX_SIZE); |
Line 1231 mfi_mgmt(struct mfi_softc *sc, uint32_t |
|
Line 1364 mfi_mgmt(struct mfi_softc *sc, uint32_t |
|
dcmd->mdf_opcode = opc; |
dcmd->mdf_opcode = opc; |
dcmd->mdf_header.mfh_data_len = 0; |
dcmd->mdf_header.mfh_data_len = 0; |
ccb->ccb_direction = dir; |
ccb->ccb_direction = dir; |
|
ccb->ccb_xs = xs; |
ccb->ccb_done = mfi_mgmt_done; |
ccb->ccb_done = mfi_mgmt_done; |
|
|
ccb->ccb_frame_size = MFI_DCMD_FRAME_SIZE; |
ccb->ccb_frame_size = MFI_DCMD_FRAME_SIZE; |
Line 1246 mfi_mgmt(struct mfi_softc *sc, uint32_t |
|
Line 1380 mfi_mgmt(struct mfi_softc *sc, uint32_t |
|
ccb->ccb_sgl = &dcmd->mdf_sgl; |
ccb->ccb_sgl = &dcmd->mdf_sgl; |
|
|
if (mfi_create_sgl(ccb, BUS_DMA_WAITOK)) |
if (mfi_create_sgl(ccb, BUS_DMA_WAITOK)) |
goto done; |
return 1; |
} |
|
|
|
if (cold) { |
|
if (mfi_poll(ccb)) |
|
goto done; |
|
} else { |
|
mfi_post(sc, ccb); |
|
|
|
DNPRINTF(MFI_D_MISC, "%s: mfi_mgmt sleeping\n", DEVNAME(sc)); |
|
while (ccb->ccb_state != MFI_CCB_DONE) |
|
tsleep(ccb, PRIBIO, "mfi_mgmt", 0); |
|
|
|
if (ccb->ccb_flags & MFI_CCB_F_ERR) |
|
goto done; |
|
} |
} |
|
return 0; |
rv = 0; |
|
|
|
done: |
|
mfi_put_ccb(ccb); |
|
return rv; |
|
} |
} |
|
|
static void |
static void |
mfi_mgmt_done(struct mfi_ccb *ccb) |
mfi_mgmt_done(struct mfi_ccb *ccb) |
{ |
{ |
|
struct scsipi_xfer *xs = ccb->ccb_xs; |
struct mfi_softc *sc = ccb->ccb_sc; |
struct mfi_softc *sc = ccb->ccb_sc; |
struct mfi_frame_header *hdr = &ccb->ccb_frame->mfr_header; |
struct mfi_frame_header *hdr = &ccb->ccb_frame->mfr_header; |
|
|
Line 1294 mfi_mgmt_done(struct mfi_ccb *ccb) |
|
Line 1410 mfi_mgmt_done(struct mfi_ccb *ccb) |
|
ccb->ccb_flags |= MFI_CCB_F_ERR; |
ccb->ccb_flags |= MFI_CCB_F_ERR; |
|
|
ccb->ccb_state = MFI_CCB_DONE; |
ccb->ccb_state = MFI_CCB_DONE; |
|
if (xs) { |
wakeup(ccb); |
if (hdr->mfh_cmd_status != MFI_STAT_OK) { |
|
xs->error = XS_DRIVER_STUFFUP; |
|
} else { |
|
xs->error = XS_NOERROR; |
|
xs->status = SCSI_OK; |
|
xs->resid = 0; |
|
} |
|
mfi_put_ccb(ccb); |
|
scsipi_done(xs); |
|
} else |
|
wakeup(ccb); |
} |
} |
|
|
#if NBIO > 0 |
#if NBIO > 0 |
int |
int |
mfi_ioctl(struct device *dev, u_long cmd, void *addr) |
mfi_ioctl(device_t dev, u_long cmd, void *addr) |
{ |
{ |
struct mfi_softc *sc = (struct mfi_softc *)dev; |
struct mfi_softc *sc = device_private(dev); |
int error = 0; |
int error = 0; |
int s = splbio(); |
int s; |
|
|
|
KERNEL_LOCK(1, curlwp); |
|
s = splbio(); |
|
|
DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl ", DEVNAME(sc)); |
DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl ", DEVNAME(sc)); |
|
|
Line 1344 mfi_ioctl(struct device *dev, u_long cmd |
|
Line 1473 mfi_ioctl(struct device *dev, u_long cmd |
|
error = EINVAL; |
error = EINVAL; |
} |
} |
splx(s); |
splx(s); |
|
KERNEL_UNLOCK_ONE(curlwp); |
|
|
DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl return %x\n", DEVNAME(sc), error); |
DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl return %x\n", DEVNAME(sc), error); |
return error; |
return error; |
Line 1365 mfi_ioctl_inq(struct mfi_softc *sc, stru |
|
Line 1495 mfi_ioctl_inq(struct mfi_softc *sc, stru |
|
|
|
/* get figures */ |
/* get figures */ |
cfg = malloc(sizeof *cfg, M_DEVBUF, M_WAITOK); |
cfg = malloc(sizeof *cfg, M_DEVBUF, M_WAITOK); |
if (mfi_mgmt(sc, MD_DCMD_CONF_GET, MFI_DATA_IN, sizeof *cfg, cfg, NULL)) |
if (mfi_mgmt_internal(sc, MD_DCMD_CONF_GET, MFI_DATA_IN, |
|
sizeof *cfg, cfg, NULL)) |
goto freeme; |
goto freeme; |
|
|
strlcpy(bi->bi_dev, DEVNAME(sc), sizeof(bi->bi_dev)); |
strlcpy(bi->bi_dev, DEVNAME(sc), sizeof(bi->bi_dev)); |
Line 1387 mfi_ioctl_vol(struct mfi_softc *sc, stru |
|
Line 1518 mfi_ioctl_vol(struct mfi_softc *sc, stru |
|
DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_vol %#x\n", |
DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_vol %#x\n", |
DEVNAME(sc), bv->bv_volid); |
DEVNAME(sc), bv->bv_volid); |
|
|
if (mfi_mgmt(sc, MR_DCMD_LD_GET_LIST, MFI_DATA_IN, |
if (mfi_mgmt_internal(sc, MR_DCMD_LD_GET_LIST, MFI_DATA_IN, |
sizeof(sc->sc_ld_list), &sc->sc_ld_list, NULL)) |
sizeof(sc->sc_ld_list), &sc->sc_ld_list, NULL)) |
goto done; |
goto done; |
|
|
Line 1396 mfi_ioctl_vol(struct mfi_softc *sc, stru |
|
Line 1527 mfi_ioctl_vol(struct mfi_softc *sc, stru |
|
DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_vol target %#x\n", |
DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_vol target %#x\n", |
DEVNAME(sc), mbox[0]); |
DEVNAME(sc), mbox[0]); |
|
|
if (mfi_mgmt(sc, MR_DCMD_LD_GET_INFO, MFI_DATA_IN, |
if (mfi_mgmt_internal(sc, MR_DCMD_LD_GET_INFO, MFI_DATA_IN, |
sizeof(sc->sc_ld_details), &sc->sc_ld_details, mbox)) |
sizeof(sc->sc_ld_details), &sc->sc_ld_details, mbox)) |
goto done; |
goto done; |
|
|
Line 1488 mfi_ioctl_disk(struct mfi_softc *sc, str |
|
Line 1619 mfi_ioctl_disk(struct mfi_softc *sc, str |
|
|
|
/* send single element command to retrieve size for full structure */ |
/* send single element command to retrieve size for full structure */ |
cfg = malloc(sizeof *cfg, M_DEVBUF, M_WAITOK); |
cfg = malloc(sizeof *cfg, M_DEVBUF, M_WAITOK); |
if (mfi_mgmt(sc, MD_DCMD_CONF_GET, MFI_DATA_IN, sizeof *cfg, cfg, NULL)) |
if (mfi_mgmt_internal(sc, MD_DCMD_CONF_GET, MFI_DATA_IN, |
|
sizeof *cfg, cfg, NULL)) |
goto freeme; |
goto freeme; |
|
|
size = cfg->mfc_size; |
size = cfg->mfc_size; |
Line 1496 mfi_ioctl_disk(struct mfi_softc *sc, str |
|
Line 1628 mfi_ioctl_disk(struct mfi_softc *sc, str |
|
|
|
/* memory for read config */ |
/* memory for read config */ |
cfg = malloc(size, M_DEVBUF, M_WAITOK|M_ZERO); |
cfg = malloc(size, M_DEVBUF, M_WAITOK|M_ZERO); |
if (mfi_mgmt(sc, MD_DCMD_CONF_GET, MFI_DATA_IN, size, cfg, NULL)) |
if (mfi_mgmt_internal(sc, MD_DCMD_CONF_GET, MFI_DATA_IN, |
|
size, cfg, NULL)) |
goto freeme; |
goto freeme; |
|
|
ar = cfg->mfc_array; |
ar = cfg->mfc_array; |
Line 1560 mfi_ioctl_disk(struct mfi_softc *sc, str |
|
Line 1693 mfi_ioctl_disk(struct mfi_softc *sc, str |
|
/* get the remaining fields */ |
/* get the remaining fields */ |
*((uint16_t *)&mbox) = ar[arr].pd[disk].mar_pd.mfp_id; |
*((uint16_t *)&mbox) = ar[arr].pd[disk].mar_pd.mfp_id; |
memset(pd, 0, sizeof(*pd)); |
memset(pd, 0, sizeof(*pd)); |
if (mfi_mgmt(sc, MR_DCMD_PD_GET_INFO, MFI_DATA_IN, |
if (mfi_mgmt_internal(sc, MR_DCMD_PD_GET_INFO, MFI_DATA_IN, |
sizeof *pd, pd, mbox)) |
sizeof *pd, pd, mbox)) |
goto freeme; |
goto freeme; |
|
|
Line 1620 mfi_ioctl_alarm(struct mfi_softc *sc, st |
|
Line 1753 mfi_ioctl_alarm(struct mfi_softc *sc, st |
|
return EINVAL; |
return EINVAL; |
} |
} |
|
|
if (mfi_mgmt(sc, opc, dir, sizeof(ret), &ret, NULL)) |
if (mfi_mgmt_internal(sc, opc, dir, sizeof(ret), &ret, NULL)) |
rv = EINVAL; |
rv = EINVAL; |
else |
else |
if (ba->ba_opcode == BIOC_GASTATUS) |
if (ba->ba_opcode == BIOC_GASTATUS) |
Line 1648 mfi_ioctl_blink(struct mfi_softc *sc, st |
|
Line 1781 mfi_ioctl_blink(struct mfi_softc *sc, st |
|
|
|
pd = malloc(MFI_PD_LIST_SIZE, M_DEVBUF, M_WAITOK); |
pd = malloc(MFI_PD_LIST_SIZE, M_DEVBUF, M_WAITOK); |
|
|
if (mfi_mgmt(sc, MR_DCMD_PD_GET_LIST, MFI_DATA_IN, |
if (mfi_mgmt_internal(sc, MR_DCMD_PD_GET_LIST, MFI_DATA_IN, |
MFI_PD_LIST_SIZE, pd, NULL)) |
MFI_PD_LIST_SIZE, pd, NULL)) |
goto done; |
goto done; |
|
|
Line 1664 mfi_ioctl_blink(struct mfi_softc *sc, st |
|
Line 1797 mfi_ioctl_blink(struct mfi_softc *sc, st |
|
|
|
memset(mbox, 0, sizeof mbox); |
memset(mbox, 0, sizeof mbox); |
|
|
*((uint16_t *)&mbox) = pd->mpl_address[i].mpa_pd_id;; |
*((uint16_t *)&mbox) = pd->mpl_address[i].mpa_pd_id; |
|
|
switch (bb->bb_status) { |
switch (bb->bb_status) { |
case BIOC_SBUNBLINK: |
case BIOC_SBUNBLINK: |
Line 1683 mfi_ioctl_blink(struct mfi_softc *sc, st |
|
Line 1816 mfi_ioctl_blink(struct mfi_softc *sc, st |
|
} |
} |
|
|
|
|
if (mfi_mgmt(sc, cmd, MFI_DATA_NONE, 0, NULL, mbox)) |
if (mfi_mgmt_internal(sc, cmd, MFI_DATA_NONE, 0, NULL, mbox)) |
goto done; |
goto done; |
|
|
rv = 0; |
rv = 0; |
Line 1705 mfi_ioctl_setstate(struct mfi_softc *sc, |
|
Line 1838 mfi_ioctl_setstate(struct mfi_softc *sc, |
|
|
|
pd = malloc(MFI_PD_LIST_SIZE, M_DEVBUF, M_WAITOK); |
pd = malloc(MFI_PD_LIST_SIZE, M_DEVBUF, M_WAITOK); |
|
|
if (mfi_mgmt(sc, MR_DCMD_PD_GET_LIST, MFI_DATA_IN, |
if (mfi_mgmt_internal(sc, MR_DCMD_PD_GET_LIST, MFI_DATA_IN, |
MFI_PD_LIST_SIZE, pd, NULL)) |
MFI_PD_LIST_SIZE, pd, NULL)) |
goto done; |
goto done; |
|
|
Line 1721 mfi_ioctl_setstate(struct mfi_softc *sc, |
|
Line 1854 mfi_ioctl_setstate(struct mfi_softc *sc, |
|
|
|
memset(mbox, 0, sizeof mbox); |
memset(mbox, 0, sizeof mbox); |
|
|
*((uint16_t *)&mbox) = pd->mpl_address[i].mpa_pd_id;; |
*((uint16_t *)&mbox) = pd->mpl_address[i].mpa_pd_id; |
|
|
switch (bs->bs_status) { |
switch (bs->bs_status) { |
case BIOC_SSONLINE: |
case BIOC_SSONLINE: |
Line 1750 mfi_ioctl_setstate(struct mfi_softc *sc, |
|
Line 1883 mfi_ioctl_setstate(struct mfi_softc *sc, |
|
} |
} |
|
|
|
|
if (mfi_mgmt(sc, MD_DCMD_PD_SET_STATE, MFI_DATA_NONE, 0, NULL, mbox)) |
if (mfi_mgmt_internal(sc, MD_DCMD_PD_SET_STATE, MFI_DATA_NONE, |
|
0, NULL, mbox)) |
goto done; |
goto done; |
|
|
rv = 0; |
rv = 0; |
Line 1782 mfi_bio_hs(struct mfi_softc *sc, int vol |
|
Line 1916 mfi_bio_hs(struct mfi_softc *sc, int vol |
|
|
|
/* send single element command to retrieve size for full structure */ |
/* send single element command to retrieve size for full structure */ |
cfg = malloc(sizeof *cfg, M_DEVBUF, M_WAITOK); |
cfg = malloc(sizeof *cfg, M_DEVBUF, M_WAITOK); |
if (mfi_mgmt(sc, MD_DCMD_CONF_GET, MFI_DATA_IN, sizeof *cfg, cfg, NULL)) |
if (mfi_mgmt_internal(sc, MD_DCMD_CONF_GET, MFI_DATA_IN, |
|
sizeof *cfg, cfg, NULL)) |
goto freeme; |
goto freeme; |
|
|
size = cfg->mfc_size; |
size = cfg->mfc_size; |
Line 1790 mfi_bio_hs(struct mfi_softc *sc, int vol |
|
Line 1925 mfi_bio_hs(struct mfi_softc *sc, int vol |
|
|
|
/* memory for read config */ |
/* memory for read config */ |
cfg = malloc(size, M_DEVBUF, M_WAITOK|M_ZERO); |
cfg = malloc(size, M_DEVBUF, M_WAITOK|M_ZERO); |
if (mfi_mgmt(sc, MD_DCMD_CONF_GET, MFI_DATA_IN, size, cfg, NULL)) |
if (mfi_mgmt_internal(sc, MD_DCMD_CONF_GET, MFI_DATA_IN, |
|
size, cfg, NULL)) |
goto freeme; |
goto freeme; |
|
|
/* calculate offset to hs structure */ |
/* calculate offset to hs structure */ |
Line 1815 mfi_bio_hs(struct mfi_softc *sc, int vol |
|
Line 1951 mfi_bio_hs(struct mfi_softc *sc, int vol |
|
/* get pd fields */ |
/* get pd fields */ |
memset(mbox, 0, sizeof mbox); |
memset(mbox, 0, sizeof mbox); |
*((uint16_t *)&mbox) = hs[i].mhs_pd.mfp_id; |
*((uint16_t *)&mbox) = hs[i].mhs_pd.mfp_id; |
if (mfi_mgmt(sc, MR_DCMD_PD_GET_INFO, MFI_DATA_IN, |
if (mfi_mgmt_internal(sc, MR_DCMD_PD_GET_INFO, MFI_DATA_IN, |
sizeof *pd, pd, mbox)) { |
sizeof *pd, pd, mbox)) { |
DNPRINTF(MFI_D_IOCTL, "%s: mfi_vol_hs illegal PD\n", |
DNPRINTF(MFI_D_IOCTL, "%s: mfi_vol_hs illegal PD\n", |
DEVNAME(sc)); |
DEVNAME(sc)); |
|
|
} |
} |
|
|
static int |
static int |
|
mfi_destroy_sensors(struct mfi_softc *sc) |
|
{ |
|
if (sc->sc_sme == NULL) |
|
return 0; |
|
sysmon_envsys_unregister(sc->sc_sme); |
|
sc->sc_sme = NULL; |
|
free(sc->sc_sensor, M_DEVBUF); |
|
return 0; |
|
} |
|
|
|
static int |
mfi_create_sensors(struct mfi_softc *sc) |
mfi_create_sensors(struct mfi_softc *sc) |
{ |
{ |
int i; |
int i; |
int nsensors = sc->sc_ld_cnt; |
int nsensors = sc->sc_ld_cnt; |
|
int rv; |
|
|
sc->sc_sme = sysmon_envsys_create(); |
sc->sc_sme = sysmon_envsys_create(); |
sc->sc_sensor = malloc(sizeof(envsys_data_t) * nsensors, |
sc->sc_sensor = malloc(sizeof(envsys_data_t) * nsensors, |
Line 1873 mfi_create_sensors(struct mfi_softc *sc) |
|
Line 2021 mfi_create_sensors(struct mfi_softc *sc) |
|
|
|
for (i = 0; i < nsensors; i++) { |
for (i = 0; i < nsensors; i++) { |
sc->sc_sensor[i].units = ENVSYS_DRIVE; |
sc->sc_sensor[i].units = ENVSYS_DRIVE; |
sc->sc_sensor[i].monitor = true; |
|
/* Enable monitoring for drive state changes */ |
/* Enable monitoring for drive state changes */ |
sc->sc_sensor[i].flags |= ENVSYS_FMONSTCHANGED; |
sc->sc_sensor[i].flags |= ENVSYS_FMONSTCHANGED; |
/* logical drives */ |
/* logical drives */ |
Line 1888 mfi_create_sensors(struct mfi_softc *sc) |
|
Line 2035 mfi_create_sensors(struct mfi_softc *sc) |
|
sc->sc_sme->sme_name = DEVNAME(sc); |
sc->sc_sme->sme_name = DEVNAME(sc); |
sc->sc_sme->sme_cookie = sc; |
sc->sc_sme->sme_cookie = sc; |
sc->sc_sme->sme_refresh = mfi_sensor_refresh; |
sc->sc_sme->sme_refresh = mfi_sensor_refresh; |
if (sysmon_envsys_register(sc->sc_sme)) { |
rv = sysmon_envsys_register(sc->sc_sme); |
aprint_error("%s: unable to register with sysmon\n", |
if (rv != 0) { |
DEVNAME(sc)); |
aprint_error("%s: unable to register with sysmon (rv = %d)\n", |
|
DEVNAME(sc), rv); |
goto out; |
goto out; |
} |
} |
return 0; |
return 0; |
Line 1898 mfi_create_sensors(struct mfi_softc *sc) |
|
Line 2046 mfi_create_sensors(struct mfi_softc *sc) |
|
out: |
out: |
free(sc->sc_sensor, M_DEVBUF); |
free(sc->sc_sensor, M_DEVBUF); |
sysmon_envsys_destroy(sc->sc_sme); |
sysmon_envsys_destroy(sc->sc_sme); |
|
sc->sc_sme = NULL; |
return EINVAL; |
return EINVAL; |
} |
} |
|
|
Line 1907 mfi_sensor_refresh(struct sysmon_envsys |
|
Line 2056 mfi_sensor_refresh(struct sysmon_envsys |
|
struct mfi_softc *sc = sme->sme_cookie; |
struct mfi_softc *sc = sme->sme_cookie; |
struct bioc_vol bv; |
struct bioc_vol bv; |
int s; |
int s; |
|
int error; |
|
|
if (edata->sensor >= sc->sc_ld_cnt) |
if (edata->sensor >= sc->sc_ld_cnt) |
return; |
return; |
|
|
bzero(&bv, sizeof(bv)); |
memset(&bv, 0, sizeof(bv)); |
bv.bv_volid = edata->sensor; |
bv.bv_volid = edata->sensor; |
|
KERNEL_LOCK(1, curlwp); |
s = splbio(); |
s = splbio(); |
if (mfi_ioctl_vol(sc, &bv)) { |
error = mfi_ioctl_vol(sc, &bv); |
splx(s); |
|
return; |
|
} |
|
splx(s); |
splx(s); |
|
KERNEL_UNLOCK_ONE(curlwp); |
|
if (error) |
|
return; |
|
|
switch(bv.bv_status) { |
switch(bv.bv_status) { |
case BIOC_SVOFFLINE: |
case BIOC_SVOFFLINE: |
Line 1952 mfi_xscale_fw_state(struct mfi_softc *sc |
|
Line 2103 mfi_xscale_fw_state(struct mfi_softc *sc |
|
{ |
{ |
return mfi_read(sc, MFI_OMSG0); |
return mfi_read(sc, MFI_OMSG0); |
} |
} |
|
|
|
static void |
|
mfi_xscale_intr_dis(struct mfi_softc *sc) |
|
{ |
|
mfi_write(sc, MFI_OMSK, 0); |
|
} |
|
|
static void |
static void |
mfi_xscale_intr_ena(struct mfi_softc *sc) |
mfi_xscale_intr_ena(struct mfi_softc *sc) |
{ |
{ |
mfi_write(sc, MFI_OMSK, MFI_ENABLE_INTR); |
mfi_write(sc, MFI_OMSK, MFI_ENABLE_INTR); |
} |
} |
|
|
static int |
static int |
mfi_xscale_intr(struct mfi_softc *sc) |
mfi_xscale_intr(struct mfi_softc *sc) |
{ |
{ |
Line 1972 mfi_xscale_intr(struct mfi_softc *sc) |
|
Line 2129 mfi_xscale_intr(struct mfi_softc *sc) |
|
mfi_write(sc, MFI_OSTS, status); |
mfi_write(sc, MFI_OSTS, status); |
return 1; |
return 1; |
} |
} |
|
|
static void |
static void |
mfi_xscale_post(struct mfi_softc *sc, struct mfi_ccb *ccb) |
mfi_xscale_post(struct mfi_softc *sc, struct mfi_ccb *ccb) |
{ |
{ |
Line 1986 mfi_xscale_post(struct mfi_softc *sc, st |
|
Line 2143 mfi_xscale_post(struct mfi_softc *sc, st |
|
mfi_write(sc, MFI_IQP, (ccb->ccb_pframe >> 3) | |
mfi_write(sc, MFI_IQP, (ccb->ccb_pframe >> 3) | |
ccb->ccb_extra_frames); |
ccb->ccb_extra_frames); |
} |
} |
|
|
static uint32_t |
static uint32_t |
mfi_ppc_fw_state(struct mfi_softc *sc) |
mfi_ppc_fw_state(struct mfi_softc *sc) |
{ |
{ |
return mfi_read(sc, MFI_OSP); |
return mfi_read(sc, MFI_OSP); |
} |
} |
|
|
|
static void |
|
mfi_ppc_intr_dis(struct mfi_softc *sc) |
|
{ |
|
/* Taking a wild guess --dyoung */ |
|
mfi_write(sc, MFI_OMSK, ~(uint32_t)0x0); |
|
mfi_write(sc, MFI_ODC, 0xffffffff); |
|
} |
|
|
static void |
static void |
mfi_ppc_intr_ena(struct mfi_softc *sc) |
mfi_ppc_intr_ena(struct mfi_softc *sc) |
{ |
{ |
mfi_write(sc, MFI_ODC, 0xffffffff); |
mfi_write(sc, MFI_ODC, 0xffffffff); |
mfi_write(sc, MFI_OMSK, ~0x80000004); |
mfi_write(sc, MFI_OMSK, ~0x80000004); |
} |
} |
|
|
static int |
static int |
mfi_ppc_intr(struct mfi_softc *sc) |
mfi_ppc_intr(struct mfi_softc *sc) |
{ |
{ |
uint32_t status; |
uint32_t status; |
|
|
status = mfi_read(sc, MFI_OSTS); |
status = mfi_read(sc, MFI_OSTS); |
if (!ISSET(status, MFI_OSTS_PPC_INTR_VALID)) |
if (!ISSET(status, MFI_OSTS_PPC_INTR_VALID)) |
return 0; |
return 0; |
|
|
/* write status back to acknowledge interrupt */ |
/* write status back to acknowledge interrupt */ |
mfi_write(sc, MFI_ODC, status); |
mfi_write(sc, MFI_ODC, status); |
return 1; |
return 1; |
} |
} |
|
|
static void |
static void |
mfi_ppc_post(struct mfi_softc *sc, struct mfi_ccb *ccb) |
mfi_ppc_post(struct mfi_softc *sc, struct mfi_ccb *ccb) |
{ |
{ |
mfi_write(sc, MFI_IQP, 0x1 | ccb->ccb_pframe | |
mfi_write(sc, MFI_IQP, 0x1 | ccb->ccb_pframe | |
(ccb->ccb_extra_frames << 1)); |
(ccb->ccb_extra_frames << 1)); |
} |
} |
|
|
|
u_int32_t |
|
mfi_gen2_fw_state(struct mfi_softc *sc) |
|
{ |
|
return (mfi_read(sc, MFI_OSP)); |
|
} |
|
|
|
void |
|
mfi_gen2_intr_dis(struct mfi_softc *sc) |
|
{ |
|
mfi_write(sc, MFI_OMSK, 0xffffffff); |
|
mfi_write(sc, MFI_ODC, 0xffffffff); |
|
} |
|
|
|
void |
|
mfi_gen2_intr_ena(struct mfi_softc *sc) |
|
{ |
|
mfi_write(sc, MFI_ODC, 0xffffffff); |
|
mfi_write(sc, MFI_OMSK, ~MFI_OSTS_GEN2_INTR_VALID); |
|
} |
|
|
|
int |
|
mfi_gen2_intr(struct mfi_softc *sc) |
|
{ |
|
u_int32_t status; |
|
|
|
status = mfi_read(sc, MFI_OSTS); |
|
if (!ISSET(status, MFI_OSTS_GEN2_INTR_VALID)) |
|
return (0); |
|
|
|
/* write status back to acknowledge interrupt */ |
|
mfi_write(sc, MFI_ODC, status); |
|
|
|
return (1); |
|
} |
|
|
|
void |
|
mfi_gen2_post(struct mfi_softc *sc, struct mfi_ccb *ccb) |
|
{ |
|
mfi_write(sc, MFI_IQP, 0x1 | ccb->ccb_pframe | |
|
(ccb->ccb_extra_frames << 1)); |
|
} |