diff options
author | YASUOKA Masahiko <yasuoka@cvs.openbsd.org> | 2016-10-24 05:27:53 +0000 |
---|---|---|
committer | YASUOKA Masahiko <yasuoka@cvs.openbsd.org> | 2016-10-24 05:27:53 +0000 |
commit | 91345905186f5ca52d937ce67e97d4be4d319c55 (patch) | |
tree | a278ab0727dcfebe1e221d879dad650fafaa3f6c | |
parent | a5320e56ee2e852556699189969cf501fec78bd0 (diff) |
Backout last 2 revisions. Requested by deraadt.
-rw-r--r-- | sys/dev/pci/mfii.c | 848 |
1 files changed, 3 insertions, 845 deletions
diff --git a/sys/dev/pci/mfii.c b/sys/dev/pci/mfii.c index c09177a8402..5efc8f409c7 100644 --- a/sys/dev/pci/mfii.c +++ b/sys/dev/pci/mfii.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mfii.c,v 1.27 2016/10/24 03:45:48 yasuoka Exp $ */ +/* $OpenBSD: mfii.c,v 1.28 2016/10/24 05:27:52 yasuoka Exp $ */ /* * Copyright (c) 2012 David Gwynne <dlg@openbsd.org> @@ -22,12 +22,9 @@ #include <sys/systm.h> #include <sys/malloc.h> #include <sys/device.h> -#include <sys/dkio.h> #include <sys/types.h> #include <sys/pool.h> -#include <sys/dkio.h> -#include <dev/biovar.h> #include <dev/pci/pcidevs.h> #include <dev/pci/pcivar.h> @@ -215,13 +212,6 @@ struct mfii_iop { u_int8_t sge_flag_eol; }; -struct mfii_cfg { - struct mfi_conf *cfg; - struct mfi_array *cfg_array; - struct mfi_ld_cfg *cfg_ld; - struct mfi_hotspare *cfg_hs; -}; - struct mfii_softc { struct device sc_dev; const struct mfii_iop *sc_iop; @@ -260,15 +250,11 @@ struct mfii_softc { struct scsi_iopool sc_iopool; struct mfi_ctrl_info sc_info; - - struct ksensor *sc_sensors; - struct ksensordev sc_sensordev; }; int mfii_match(struct device *, void *, void *); void mfii_attach(struct device *, struct device *, void *); int mfii_detach(struct device *, int); -int mfii_scsi_ioctl(struct scsi_link *, u_long, caddr_t, int); struct cfattach mfii_ca = { sizeof(struct mfii_softc), @@ -291,7 +277,7 @@ struct scsi_adapter mfii_switch = { scsi_minphys, NULL, /* probe */ NULL, /* unprobe */ - mfii_scsi_ioctl + NULL /* ioctl */ }; void mfii_pd_scsi_cmd(struct scsi_xfer *); @@ -348,26 +334,6 @@ int mfii_scsi_cmd_cdb(struct mfii_softc *, struct scsi_xfer *); int mfii_pd_scsi_cmd_cdb(struct mfii_softc *, struct scsi_xfer *); -int mfii_scsi_ioctl_cache(struct scsi_link *, u_int, - struct dk_cache *); -#if NBIO > 0 -int mfii_ioctl(struct device *, u_long, caddr_t); -int mfii_fill_cfg(struct mfii_softc *, struct mfii_cfg *); -int mfii_ioctl_inq(struct mfii_softc *, struct bioc_inq *); -int mfii_ioctl_vol(struct mfii_softc *, struct bioc_vol *); -int mfii_ioctl_disk(struct mfii_softc *, - struct bioc_disk *); -int mfii_ioctl_alarm(struct mfii_softc *, - struct bioc_alarm *); -int mfii_ioctl_blink(struct mfii_softc *, - struct bioc_blink *); -int mfii_ioctl_setstate(struct mfii_softc *, - struct bioc_setstate *); -int mfii_ioctl_patrol(struct mfii_softc *, - struct bioc_patrol *); -int mfii_create_sensors(struct mfii_softc *); -void mfii_refresh_sensors(void *); -#endif #define mfii_fw_state(_sc) mfii_read((_sc), MFI_OSP) @@ -540,8 +506,7 @@ mfii_attach(struct device *parent, struct device *self, void *aux) memset(&saa, 0, sizeof(saa)); saa.saa_sc_link = &sc->sc_link; - sc->sc_scsibus = (struct scsibus_softc *) - config_found(&sc->sc_dev, &saa, scsiprint); + config_found(&sc->sc_dev, &saa, scsiprint); mfii_syspd(sc); @@ -549,16 +514,6 @@ mfii_attach(struct device *parent, struct device *self, void *aux) mfii_write(sc, MFI_OSTS, 0xffffffff); mfii_write(sc, MFI_OMSK, ~MFII_OSTS_INTR_VALID); -#if NBIO > 0 - if (bio_register(&sc->sc_dev, mfii_ioctl) != 0) - panic("%s: controller registration failed", DEVNAME(sc)); - -#ifndef SMALL_KERNEL - if (mfii_create_sensors(sc) != 0) - printf("%s: unable to create sensors\n", DEVNAME(sc)); -#endif -#endif /* NBIO > 0 */ - return; free_sgl: mfii_dmamem_free(sc, sc->sc_sgl); @@ -666,10 +621,6 @@ mfii_detach(struct device *self, int flags) if (sc->sc_ih == NULL) return (0); - if (sc->sc_sensors) { - sensordev_deinstall(&sc->sc_sensordev); - free(sc->sc_sensors, M_DEVBUF, sc->sc_info.mci_lds_present); - } pci_intr_disestablish(sc->sc_pc, sc->sc_ih); mfii_dmamem_free(sc, sc->sc_sgl); mfii_dmamem_free(sc, sc->sc_requests); @@ -1114,10 +1065,6 @@ mfii_mgmt(struct mfii_softc *sc, struct mfii_ccb *ccb, hdr->mfh_flags = htole16(MFI_FRAME_DIR_WRITE); memcpy(dma_buf, buf, len); break; - default: - ccb->ccb_direction = MFII_DATA_NONE; - hdr->mfh_flags = htole16(MFI_FRAME_DIR_NONE); - break; } if (mfii_load_mfa(sc, ccb, &dcmd->mdf_sgl, @@ -1849,792 +1796,3 @@ destroy: return (1); } -int -mfii_scsi_ioctl(struct scsi_link *link, u_long cmd, caddr_t addr, int flag) -{ - switch (cmd) { - case DIOCGCACHE: - case DIOCSCACHE: - return mfii_scsi_ioctl_cache(link, cmd, - (struct dk_cache *)addr); - default: -#if NBIO > 0 - return mfii_ioctl(link->adapter_softc, cmd, addr); -#else - break; -#endif - } - return (ENOTTY); -} - -int -mfii_scsi_ioctl_cache(struct scsi_link *link, u_int cmd, struct dk_cache *dc) -{ - struct mfii_softc *sc = (struct mfii_softc *)link->adapter_softc; - struct mfi_ld_prop ldp; - uint8_t mbox[MFI_MBOX_SIZE]; - struct mfii_ccb *ccb; - int rv, wrenable, rdenable; - - memset(mbox, 0, sizeof(mbox)); - *((uint16_t *)&mbox[0]) = htole16(link->target); - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_LD_GET_PROPERTIES, mbox, - &ldp, sizeof(ldp), SCSI_DATA_IN|SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - if (rv != 0) - return (rv); - - if (letoh16(sc->sc_info.mci_memory_size) > 0) { - wrenable = ISSET(ldp.mlp_cur_cache_policy, - MR_LD_CACHE_ALLOW_WRITE_CACHE)? 1 : 0; - rdenable = ISSET(ldp.mlp_cur_cache_policy, - MR_LD_CACHE_ALLOW_READ_CACHE)? 1 : 0; - } else { - wrenable = ISSET(ldp.mlp_diskcache_policy, - MR_LD_DISK_CACHE_ENABLE)? 1 : 0; - rdenable = 0; - } - - if (cmd == DIOCGCACHE) { - dc->wrcache = wrenable; - dc->rdcache = rdenable; - return (0); - } - if (((dc->wrcache) ? 1 : 0) == wrenable && - ((dc->rdcache) ? 1 : 0) == rdenable) - return (0); - - mbox[0] = ldp.mlp_ld.mld_target; - mbox[1] = ldp.mlp_ld.mld_res; - *(uint16_t *)&mbox[2] = ldp.mlp_ld.mld_seq; - if (letoh16(sc->sc_info.mci_memory_size) > 0) { - if (dc->rdcache) - SET(ldp.mlp_cur_cache_policy, - MR_LD_CACHE_ALLOW_READ_CACHE); - else - CLR(ldp.mlp_cur_cache_policy, - MR_LD_CACHE_ALLOW_READ_CACHE); - if (dc->wrcache) - SET(ldp.mlp_cur_cache_policy, - MR_LD_CACHE_ALLOW_WRITE_CACHE); - else - CLR(ldp.mlp_cur_cache_policy, - MR_LD_CACHE_ALLOW_WRITE_CACHE); - } else { - if (dc->rdcache) - return (EOPNOTSUPP); - if (dc->wrcache) - ldp.mlp_diskcache_policy = MR_LD_DISK_CACHE_ENABLE; - else - ldp.mlp_diskcache_policy = MR_LD_DISK_CACHE_DISABLE; - } - - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_LD_SET_PROPERTIES, mbox, - &ldp, sizeof(ldp), SCSI_DATA_OUT|SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - - return (rv); -} - -#if NBIO > 0 -int -mfii_ioctl(struct device *dev, u_long cmd, caddr_t addr) -{ - struct mfii_softc *sc = (struct mfii_softc *)dev; - int rv = ENOTTY; - - switch (cmd) { - case BIOCINQ: - rv = mfii_ioctl_inq(sc, (struct bioc_inq *)addr); - break; - case BIOCVOL: - rv = mfii_ioctl_vol(sc, (struct bioc_vol *)addr); - break; - case BIOCDISK: - rv = mfii_ioctl_disk(sc, (struct bioc_disk *)addr); - break; - case BIOCALARM: - rv = mfii_ioctl_alarm(sc, (struct bioc_alarm *)addr); - break; - case BIOCBLINK: - rv = mfii_ioctl_blink(sc, (struct bioc_blink *)addr); - break; - case BIOCSETSTATE: - rv = mfii_ioctl_setstate(sc, (struct bioc_setstate *)addr); - break; - case BIOCPATROL: - rv = mfii_ioctl_patrol(sc, (struct bioc_patrol *)addr); - break; - } - - return (rv); -} - -int -mfii_fill_cfg(struct mfii_softc *sc, struct mfii_cfg *cfg) -{ - int rv, mfc_size; - struct mfi_conf *mfc; - struct mfii_ccb *ccb; - - mfc_size = sizeof(*mfc); - again: - mfc = malloc(mfc_size, M_TEMP, M_WAITOK | M_ZERO); - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_CONF_GET, NULL, - mfc, mfc_size, SCSI_DATA_IN|SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - if (rv == 0) { - mfc->mfc_size = letoh32(mfc->mfc_size); - mfc->mfc_no_array = letoh16(mfc->mfc_no_array); - mfc->mfc_array_size = letoh16(mfc->mfc_array_size); - mfc->mfc_no_ld = letoh16(mfc->mfc_no_ld); - mfc->mfc_ld_size = letoh16(mfc->mfc_ld_size); - mfc->mfc_no_hs = letoh16(mfc->mfc_no_hs); - mfc->mfc_hs_size = letoh16(mfc->mfc_hs_size); - - if (mfc_size < mfc->mfc_size) { - mfc_size = mfc->mfc_size; - free(mfc, M_TEMP, mfc_size); - goto again; - } - /* remember allocated size for free() */ - mfc->mfc_size = mfc_size; - - cfg->cfg = mfc; - cfg->cfg_array = (struct mfi_array *)((caddr_t)mfc + - offsetof(struct mfi_conf, mfc_array)); - cfg->cfg_ld = (struct mfi_ld_cfg *)((caddr_t)cfg->cfg_array + - mfc->mfc_array_size * mfc->mfc_no_array); - cfg->cfg_hs = (struct mfi_hotspare *)((caddr_t)cfg->cfg_ld + - mfc->mfc_ld_size * mfc->mfc_no_ld); - - return (0); - } - - free(mfc, M_TEMP, mfc_size); - return (rv); -} - -int -mfii_ioctl_inq(struct mfii_softc *sc, struct bioc_inq *bi) -{ - int rv; - struct mfii_cfg cfg = { .cfg = NULL }; - - rv = mfii_fill_cfg(sc, &cfg); - if (rv != 0) - return (rv); - - bi->bi_novol = cfg.cfg->mfc_no_ld + cfg.cfg->mfc_no_hs; - bi->bi_nodisk = letoh16(sc->sc_info.mci_pd_disks_present); - strlcpy(bi->bi_dev, DEVNAME(sc), sizeof(bi->bi_dev)); - - if (cfg.cfg != NULL) - free(cfg.cfg, M_TEMP, cfg.cfg->mfc_size); - - return (0); -} - -int -mfii_ioctl_vol(struct mfii_softc *sc, struct bioc_vol *bv) -{ - int rv; - struct mfii_cfg cfg = { .cfg = NULL }; - struct mfi_ld_cfg *ld; - struct mfi_ld_list *list = NULL; - struct scsi_link *link; - struct mfii_ccb *ccb; - uint8_t mbox[MFI_MBOX_SIZE]; - - if ((link = scsi_get_link(sc->sc_scsibus, bv->bv_volid, 0)) != NULL && - link->device_softc != NULL) { - struct device *dev = link->device_softc; - strlcpy(bv->bv_dev, dev->dv_xname, sizeof(bv->bv_dev)); - } - rv = mfii_fill_cfg(sc, &cfg); - if (rv != 0) - goto done; - - if (bv->bv_volid >= cfg.cfg->mfc_no_ld) { - int hsid; - struct mfi_pd_details *pd; - - hsid = bv->bv_volid - cfg.cfg->mfc_no_ld; - if (hsid >= cfg.cfg->mfc_no_hs) - return (EINVAL); - - pd = malloc(sizeof(*pd), M_TEMP, M_WAITOK | M_ZERO); - ccb = scsi_io_get(&sc->sc_iopool, 0); - memset(mbox, 0, sizeof(mbox)); - *((uint16_t *)&mbox[0]) = cfg.cfg_hs[hsid].mhs_pd.mfp_id; - rv = mfii_mgmt(sc, ccb, MR_DCMD_PD_GET_INFO, mbox, - pd, sizeof(*pd), SCSI_DATA_IN|SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - if (rv == 0) { - bv->bv_status = BIOC_SVONLINE; - bv->bv_size = letoh64(pd->mpd_size) * 512; - bv->bv_level = -1; - bv->bv_nodisk = 1; - } - free(pd, M_TEMP, sizeof(*pd)); - - goto done; - } - - list = malloc(sizeof(*list), M_TEMP, M_WAITOK | M_ZERO); - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_LD_GET_LIST, NULL, - list, sizeof(*list), SCSI_DATA_IN|SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - if (rv != 0) - goto done; - - if (bv->bv_volid >= letoh32(list->mll_no_ld)) { - rv = EINVAL; - goto done; - } - - switch (list->mll_list[bv->bv_volid].mll_state) { - case MFI_LD_OFFLINE: - bv->bv_status = BIOC_SVOFFLINE; - break; - case MFI_LD_PART_DEGRADED: - case MFI_LD_DEGRADED: - bv->bv_status = BIOC_SVDEGRADED; - break; - case MFI_LD_ONLINE: - bv->bv_status = BIOC_SVONLINE; - break; - default: - bv->bv_status = BIOC_SVINVALID; - break; - } - bv->bv_size = letoh64(list->mll_list[bv->bv_volid].mll_size) * 512; - - ld = cfg.cfg->mfc_ld + bv->bv_volid; - bv->bv_cache = - (ld->mlc_prop.mlp_cur_cache_policy & MR_LD_CACHE_WRITE_BACK) - ? BIOC_CVWRITEBACK : BIOC_CVWRITETHROUGH; - - switch (ld->mlc_parm.mpa_pri_raid) { - case MFI_DDF_PRL_RAID0: - bv->bv_level = 0; - break; - case MFI_DDF_PRL_RAID1: - case MFI_DDF_PRL_RAID1E: - bv->bv_level = 1; - break; - case MFI_DDF_PRL_RAID3: - bv->bv_level = 3; - break; - case MFI_DDF_PRL_RAID4: - bv->bv_level = 4; - break; - case MFI_DDF_PRL_RAID5: - case MFI_DDF_PRL_RAID5E: - case MFI_DDF_PRL_RAID5EE: - bv->bv_level = 5; - break; - case MFI_DDF_PRL_RAID6: - bv->bv_level = 6; - break; - case MFI_DDF_PRL_JBOD: - case MFI_DDF_PRL_CONCAT: - default: - bv->bv_level = 0; - break; - } - bv->bv_nodisk = - ld->mlc_parm.mpa_no_drv_per_span * ld->mlc_parm.mpa_span_depth; - done: - free(list, M_TEMP, sizeof(*list)); - if (cfg.cfg != NULL) - free(cfg.cfg, M_TEMP, cfg.cfg->mfc_size); - - return (rv); -} - -int -mfii_ioctl_disk(struct mfii_softc *sc, struct bioc_disk *bd) -{ - int rv, spanidx, diskidx, arrayidx, pdidx; - struct mfii_cfg cfg = { .cfg = NULL }; - struct mfi_ld_cfg *ld; - struct mfii_ccb *ccb; - struct scsi_inquiry_data *inq; - struct mfi_pd_details *pd_det = NULL; - uint8_t mbox[MFI_MBOX_SIZE]; - - rv = mfii_fill_cfg(sc, &cfg); - if (rv != 0) - goto done; - - if (bd->bd_volid >= cfg.cfg->mfc_no_ld) { - int hsid = bd->bd_volid - cfg.cfg->mfc_no_ld; - if (hsid >= cfg.cfg->mfc_no_hs) { - rv = EINVAL; - goto done; - } - pdidx = letoh16(cfg.cfg_hs[hsid].mhs_pd.mfp_id); - } else { - ld = cfg.cfg->mfc_ld + bd->bd_volid; - spanidx = bd->bd_diskid / ld->mlc_parm.mpa_no_drv_per_span; - diskidx = bd->bd_diskid % ld->mlc_parm.mpa_no_drv_per_span; - if (spanidx < 0 || MFI_MAX_SPAN <= spanidx) { - rv = EINVAL; - goto done; - } - arrayidx = - letoh16(ld[bd->bd_volid].mlc_span[spanidx].mls_index); - if (arrayidx < 0 || cfg.cfg->mfc_no_array <= arrayidx) { - rv = EINVAL; - goto done; - } - pdidx = letoh16( - cfg.cfg->mfc_array[arrayidx].pd[diskidx].mar_pd.mfp_id); - } - - memset(mbox, 0, sizeof(mbox)); - *((uint16_t *)&mbox[0]) = htole16(pdidx); - - pd_det = malloc(sizeof(*pd_det), M_TEMP, M_WAITOK | M_ZERO); - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_PD_GET_INFO, mbox, - pd_det, sizeof(*pd_det), SCSI_DATA_IN|SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - if (rv != 0) - goto done; - - bd->bd_channel = pd_det->mpd_enc_idx; - bd->bd_target = pd_det->mpd_enc_slot; - - switch (letoh16(pd_det->mpd_fw_state)) { - case MFI_PD_UNCONFIG_GOOD: - bd->bd_status = BIOC_SDUNUSED; - break; - case MFI_PD_UNCONFIG_BAD: - bd->bd_status = BIOC_SDINVALID; - break; - case MFI_PD_HOTSPARE: - bd->bd_status = BIOC_SDHOTSPARE; - break; - case MFI_PD_OFFLINE: - bd->bd_status = BIOC_SDOFFLINE; - break; - case MFI_PD_FAILED: - bd->bd_status = BIOC_SDFAILED; - break; - case MFI_PD_REBUILD: - bd->bd_status = BIOC_SDREBUILD; - break; - case MFI_PD_ONLINE: - bd->bd_status = BIOC_SDONLINE; - break; - case MFI_PD_COPYBACK: - case MFI_PD_SYSTEM: - bd->bd_status = BIOC_SDINVALID; - break; - } - bd->bd_size = letoh64(pd_det->mpd_size) * 512; - - inq = (struct scsi_inquiry_data *)pd_det->mpd_inq_data; - - memset(bd->bd_vendor, 0, sizeof(bd->bd_vendor)); - memcpy(bd->bd_vendor, inq->vendor, - MIN(sizeof(bd->bd_vendor) - 1, sizeof(inq->vendor))); - - rv = 0; - done: - free(pd_det, M_TEMP, sizeof(*pd_det)); - if (cfg.cfg != NULL) - free(cfg.cfg, M_TEMP, cfg.cfg->mfc_size); - - return (rv); -} - -int -mfii_ioctl_setstate(struct mfii_softc *sc, struct bioc_setstate *bs) -{ - int rv, i; - struct mfii_ccb *ccb; - struct mfi_pd_list *list = NULL; - struct mfi_pd_details *pd = NULL; - uint8_t mbox[MFI_MBOX_SIZE]; - - list = malloc(sizeof(*list), M_TEMP, M_WAITOK | M_ZERO); - pd = malloc(sizeof(*pd), M_TEMP, M_WAITOK | M_ZERO); - - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_PD_GET_LIST, NULL, - list, sizeof(*list), SCSI_DATA_IN | SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - if (rv != 0) - goto done; - - for (i = 0; i < letoh16(list->mpl_no_pd); i++) - if (list->mpl_address[i].mpa_enc_index == bs->bs_channel && - list->mpl_address[i].mpa_enc_slot == bs->bs_target) - break; - if (i >= letoh16(list->mpl_no_pd)) { - rv = EINVAL; - goto done; - } - - memset(mbox, 0, sizeof(mbox)); - *((uint16_t *)&mbox[0]) = list->mpl_address[i].mpa_pd_id; - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_PD_GET_INFO, mbox, - pd, sizeof(*pd), SCSI_DATA_IN | SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - if (rv != 0) - goto done; - - memset(mbox, 0, sizeof(mbox)); - *((uint16_t *)&mbox[0]) = pd->mpd_pd.mfp_id; - *((uint16_t *)&mbox[2]) = pd->mpd_pd.mfp_seq; - - switch (bs->bs_status) { - case BIOC_SSONLINE: - *((uint16_t *)&mbox[4]) = htole16(MFI_PD_ONLINE); - break; - case BIOC_SSOFFLINE: - *((uint16_t *)&mbox[4]) = htole16(MFI_PD_OFFLINE); - break; - case BIOC_SSHOTSPARE: - *((uint16_t *)&mbox[4]) = htole16(MFI_PD_HOTSPARE); - break; - case BIOC_SSREBUILD: - *((uint16_t *)&mbox[4]) = htole16(MFI_PD_REBUILD); - break; - default: - rv = EINVAL; - goto done; - } - - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_PD_SET_STATE, mbox, - NULL, 0, SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - - done: - free(list, M_TEMP, sizeof(*list)); - free(pd, M_TEMP, sizeof(*pd)); - - return (rv); -} - -int -mfii_ioctl_alarm(struct mfii_softc *sc, struct bioc_alarm *ba) -{ - struct mfii_ccb *ccb; - u_char spkr; - int rv, cmd, flags = 0; - - if (!ISSET(letoh32(sc->sc_info.mci_hw_present), MFI_INFO_HW_ALARM)) - return (ENXIO); - - switch (ba->ba_status) { - case BIOC_SADISABLE: - cmd = MR_DCMD_SPEAKER_DISABLE; - break; - case BIOC_SAENABLE: - cmd = MR_DCMD_SPEAKER_ENABLE; - break; - case BIOC_SASILENCE: - cmd = MR_DCMD_SPEAKER_SILENCE; - break; - case BIOC_GASTATUS: - cmd = MR_DCMD_SPEAKER_GET; - flags = SCSI_DATA_IN; - break; - case BIOC_SATEST: - cmd = MR_DCMD_SPEAKER_TEST; - break; - default: - return (EINVAL); - } - - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_PD_SET_STATE, NULL, - &spkr, sizeof(spkr), flags | SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - if (rv != 0) - return (rv); - - ba->ba_status = (ba->ba_status == BIOC_GASTATUS)? spkr : 0; - - return (rv); -} - -int -mfii_ioctl_blink(struct mfii_softc *sc, struct bioc_blink *bb) -{ - struct mfi_pd_list *list = NULL; - struct mfii_ccb *ccb; - uint8_t mbox[MFI_MBOX_SIZE]; - int rv, i, cmd; - - list = malloc(sizeof(*list), M_TEMP, M_WAITOK | M_ZERO); - - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_PD_GET_LIST, NULL, - list, sizeof(*list), SCSI_DATA_IN | SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - if (rv != 0) - goto done; - - for (i = 0; i < letoh16(list->mpl_no_pd); i++) - if (list->mpl_address[i].mpa_enc_index == bb->bb_channel && - list->mpl_address[i].mpa_enc_slot == bb->bb_target) - break; - if (i >= letoh16(list->mpl_no_pd)) { - rv = EINVAL; - goto done; - } - - memset(mbox, 0, sizeof(mbox)); - *((uint16_t *)&mbox[0]) = list->mpl_address[i].mpa_pd_id; - - switch (bb->bb_status) { - case BIOC_SBUNBLINK: - cmd = MR_DCMD_PD_UNBLINK; - break; - case BIOC_SBBLINK: - case BIOC_SBALARM: - cmd = MR_DCMD_PD_BLINK; - break; - default: - rv = EINVAL; - goto done; - } - - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, cmd, NULL, NULL, 0, SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - - done: - free(list, M_TEMP, sizeof(*list)); - - return (ENOTTY); -} - -int -mfii_ioctl_patrol(struct mfii_softc *sc, struct bioc_patrol *bp) -{ - int rv = EINVAL, cmd; - struct mfii_ccb *ccb; - struct mfi_pr_properties prop; - struct mfi_pr_status status; - uint32_t time; - - switch (bp->bp_opcode) { - case BIOC_SPSTOP: - case BIOC_SPSTART: - cmd = (bp->bp_opcode == BIOC_SPSTART) - ? MR_DCMD_PR_START : MR_DCMD_PR_STOP; - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, cmd, NULL, NULL, 0, SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - break; - - case BIOC_GPSTATUS: - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_PR_GET_PROPERTIES, NULL, - &prop, sizeof(prop), SCSI_DATA_IN | SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - if (rv != 0) - break; - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_PR_GET_STATUS, NULL, - &status, sizeof(status), SCSI_DATA_IN | SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - if (rv != 0) - break; - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_TIME_SECS_GET, NULL, - &time, sizeof(time), SCSI_DATA_IN | SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - if (rv != 0) - break; - time = letoh32(time); - - switch (prop.op_mode) { - case MFI_PR_OPMODE_AUTO: - bp->bp_mode = BIOC_SPMAUTO; - bp->bp_autoival = letoh32(prop.exec_freq); - bp->bp_autonext = letoh32(prop.next_exec); - bp->bp_autonow = time; - break; - case MFI_PR_OPMODE_MANUAL: - bp->bp_mode = BIOC_SPMMANUAL; - break; - case MFI_PR_OPMODE_DISABLED: - bp->bp_mode = BIOC_SPMDISABLED; - break; - } - - switch (status.state) { - case MFI_PR_STATE_STOPPED: - bp->bp_status = BIOC_SPSSTOPPED; - break; - case MFI_PR_STATE_READY: - bp->bp_status = BIOC_SPSREADY; - break; - case MFI_PR_STATE_ACTIVE: - bp->bp_status = BIOC_SPSACTIVE; - break; - case MFI_PR_STATE_ABORTED: - bp->bp_status = BIOC_SPSABORTED; - break; - } - break; - - case BIOC_SPDISABLE: - case BIOC_SPMANUAL: - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_PR_GET_PROPERTIES, NULL, - &prop, sizeof(prop), SCSI_DATA_IN | SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - if (rv != 0) - break; - prop.op_mode = (bp->bp_opcode == BIOC_SPDISABLE) - ? MFI_PR_OPMODE_DISABLED : MFI_PR_OPMODE_MANUAL; - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_PR_SET_PROPERTIES, NULL, - &prop, sizeof(prop), SCSI_DATA_OUT | SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - break; - - case BIOC_SPAUTO: - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_PR_GET_PROPERTIES, NULL, - &prop, sizeof(prop), SCSI_DATA_IN | SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - if (rv != 0) - break; - prop.op_mode = MFI_PR_OPMODE_AUTO; - - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_TIME_SECS_GET, NULL, - &time, sizeof(time), SCSI_DATA_IN | SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - if (rv != 0) - break; - time = letoh32(time); - if (bp->bp_autoival != 0) { - if (bp->bp_autoival == -1) - prop.exec_freq = htole32(0xffffffffUL); - else if (bp->bp_autoival > 0) - prop.exec_freq = htole32(bp->bp_autoival); - else { - rv = EINVAL; - break; - } - } - if (bp->bp_autonext != 0) { - if (bp->bp_autonext > 0) - prop.next_exec = - htole32(time + bp->bp_autonext); - else { - rv = EINVAL; - break; - } - } - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_PR_SET_PROPERTIES, NULL, - &prop, sizeof(prop), SCSI_DATA_OUT | SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - break; - } - - return (rv); -} - -#ifndef SMALL_KERNEL -int -mfii_create_sensors(struct mfii_softc *sc) -{ - int i, no_ld; - struct device *dev; - struct scsi_link *link; - - no_ld = letoh16(sc->sc_info.mci_lds_present); - - strlcpy(sc->sc_sensordev.xname, DEVNAME(sc), - sizeof(sc->sc_sensordev.xname)); - - sc->sc_sensors = mallocarray(no_ld, sizeof(struct ksensor), - M_DEVBUF, M_NOWAIT | M_ZERO); - if (sc->sc_sensors == NULL) - return (-1); - - for (i = 0; i < no_ld; i++) { - if ((link = scsi_get_link(sc->sc_scsibus, i, 0)) == NULL || - link->device_softc == NULL) - goto err; - - dev = link->device_softc; - sc->sc_sensors[i].type = SENSOR_DRIVE; - sc->sc_sensors[i].status = SENSOR_S_UNKNOWN; - strlcpy(sc->sc_sensors[i].desc, dev->dv_xname, - sizeof(sc->sc_sensors[i].desc)); - sensor_attach(&sc->sc_sensordev, &sc->sc_sensors[i]); - } - - if (sensor_task_register(sc, mfii_refresh_sensors, 10) == NULL) - goto err; - - sensordev_install(&sc->sc_sensordev); - - return (0); - err: - free(sc->sc_sensors, M_DEVBUF, no_ld); - - return (-1); -} - -void -mfii_refresh_sensors(void *arg) -{ - int i, rv; - struct mfi_ld_list *list = NULL; - struct mfii_softc *sc = arg; - struct mfii_ccb *ccb; - - list = malloc(sizeof(*list), M_TEMP, M_WAITOK | M_ZERO); - ccb = scsi_io_get(&sc->sc_iopool, 0); - rv = mfii_mgmt(sc, ccb, MR_DCMD_LD_GET_LIST, NULL, - list, sizeof(*list), SCSI_DATA_IN|SCSI_NOSLEEP); - scsi_io_put(&sc->sc_iopool, ccb); - - if (rv == 0) { - for (i = 0; i < letoh16(sc->sc_info.mci_lds_present); i++) { - switch (list->mll_list[i].mll_state) { - case MFI_LD_OFFLINE: - sc->sc_sensors[i].value = SENSOR_DRIVE_FAIL; - sc->sc_sensors[i].status = SENSOR_S_CRIT; - break; - case MFI_LD_PART_DEGRADED: - case MFI_LD_DEGRADED: - sc->sc_sensors[i].value = SENSOR_DRIVE_PFAIL; - sc->sc_sensors[i].status = SENSOR_S_WARN; - break; - case MFI_LD_ONLINE: - sc->sc_sensors[i].value = SENSOR_DRIVE_ONLINE; - sc->sc_sensors[i].status = SENSOR_S_OK; - break; - default: - sc->sc_sensors[i].value = 0; /* unknown */ - sc->sc_sensors[i].status = SENSOR_S_UNKNOWN; - break; - } - } - } - - free(list, M_TEMP, sizeof(*list)); -} -#endif -#endif |