summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2016-10-24 05:27:53 +0000
committerYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2016-10-24 05:27:53 +0000
commit91345905186f5ca52d937ce67e97d4be4d319c55 (patch)
treea278ab0727dcfebe1e221d879dad650fafaa3f6c
parenta5320e56ee2e852556699189969cf501fec78bd0 (diff)
Backout last 2 revisions. Requested by deraadt.
-rw-r--r--sys/dev/pci/mfii.c848
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