summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorps <ps@FreeBSD.org>2005-04-19 06:11:16 +0000
committerps <ps@FreeBSD.org>2005-04-19 06:11:16 +0000
commitb7632e9a5b90b6ef37dd38fcab327427cdeb3f06 (patch)
tree416f88ea01b7a9d7e66acf562fc6b6fea366d168 /sys
parent046acb18c8690d260693e3ba39b540e242aa729b (diff)
downloadFreeBSD-src-b7632e9a5b90b6ef37dd38fcab327427cdeb3f06.zip
FreeBSD-src-b7632e9a5b90b6ef37dd38fcab327427cdeb3f06.tar.gz
Provide a way to soft reset a proxy controller such as an MSA20 or
MSA500. This is useful if you need to reset one of the storage arrays on reboot.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ciss/ciss.c55
-rw-r--r--sys/dev/ciss/cissreg.h1
-rw-r--r--sys/dev/ciss/cissvar.h2
3 files changed, 58 insertions, 0 deletions
diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c
index 6d2c83e..31fc4c8 100644
--- a/sys/dev/ciss/ciss.c
+++ b/sys/dev/ciss/ciss.c
@@ -83,6 +83,7 @@
#include <sys/stat.h>
#include <sys/kthread.h>
#include <sys/queue.h>
+#include <sys/sysctl.h>
#include <cam/cam.h>
#include <cam/cam_ccb.h>
@@ -130,6 +131,8 @@ static int ciss_identify_logical(struct ciss_softc *sc, struct ciss_ldrive *ld);
static int ciss_get_ldrive_status(struct ciss_softc *sc, struct ciss_ldrive *ld);
static int ciss_update_config(struct ciss_softc *sc);
static int ciss_accept_media(struct ciss_softc *sc, struct ciss_ldrive *ld);
+static void ciss_init_sysctl(struct ciss_softc *sc);
+static void ciss_soft_reset(struct ciss_softc *sc);
static void ciss_free(struct ciss_softc *sc);
static void ciss_spawn_notify_thread(struct ciss_softc *sc);
static void ciss_kill_notify_thread(struct ciss_softc *sc);
@@ -408,6 +411,11 @@ ciss_attach(device_t dev)
ciss_initq_notify(sc);
/*
+ * Initalize device sysctls.
+ */
+ ciss_init_sysctl(sc);
+
+ /*
* Initialise command/request pool.
*/
if ((error = ciss_init_requests(sc)) != 0)
@@ -505,9 +513,21 @@ ciss_shutdown(device_t dev)
/* flush adapter cache */
ciss_flush_adapter(sc);
+ if (sc->ciss_soft_reset)
+ ciss_soft_reset(sc);
+
return(0);
}
+static void
+ciss_init_sysctl(struct ciss_softc *sc)
+{
+
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->ciss_dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(sc->ciss_dev)),
+ OID_AUTO, "soft_reset", CTLFLAG_RW, &sc->ciss_soft_reset, 0, "");
+}
+
/************************************************************************
* Perform PCI-specific attachment actions.
*/
@@ -767,6 +787,41 @@ out:
return(error);
}
+static void
+ciss_soft_reset(struct ciss_softc *sc)
+{
+ struct ciss_request *cr = NULL;
+ struct ciss_command *cc;
+ int i, error = 0;
+
+ for (i = 0; i < sc->ciss_max_logical_bus; i++) {
+ /* only reset proxy controllers */
+ if (sc->ciss_controllers[i].physical.bus == 0)
+ continue;
+
+ if ((error = ciss_get_request(sc, &cr)) != 0)
+ break;
+
+ if ((error = ciss_get_bmic_request(sc, &cr, CISS_BMIC_SOFT_RESET,
+ NULL, 0)) != 0)
+ break;
+
+ cc = CISS_FIND_COMMAND(cr);
+ cc->header.address = sc->ciss_controllers[i];
+
+ if ((error = ciss_synch_request(cr, 60 * 1000)) != 0)
+ break;
+
+ ciss_release_request(cr);
+ }
+
+ if (error)
+ ciss_printf(sc, "error resetting controller (%d)\n", error);
+
+ if (cr != NULL)
+ ciss_release_request(cr);
+}
+
/************************************************************************
* Allocate memory for the adapter command structures, initialise
* the request structures.
diff --git a/sys/dev/ciss/cissreg.h b/sys/dev/ciss/cissreg.h
index b621ce4..65fad48 100644
--- a/sys/dev/ciss/cissreg.h
+++ b/sys/dev/ciss/cissreg.h
@@ -449,6 +449,7 @@ struct ciss_config_table
#define CISS_BMIC_ID_PDRIVE 0x15
#define CISS_BMIC_BLINK_PDRIVE 0x16
#define CISS_BMIC_SENSE_BLINK_PDRIVE 0x17
+#define CISS_BMIC_SOFT_RESET 0x40
#define CISS_BMIC_FLUSH_CACHE 0xc2
#define CISS_BMIC_ACCEPT_MEDIA 0xe0
diff --git a/sys/dev/ciss/cissvar.h b/sys/dev/ciss/cissvar.h
index 5657ea0..24f8126 100644
--- a/sys/dev/ciss/cissvar.h
+++ b/sys/dev/ciss/cissvar.h
@@ -237,6 +237,8 @@ struct ciss_softc
struct cam_devq *ciss_cam_devq;
struct cam_sim **ciss_cam_sim;
+ int ciss_soft_reset;
+
int ciss_flags;
#define CISS_FLAG_NOTIFY_OK (1<<0) /* notify command running OK */
#define CISS_FLAG_CONTROL_OPEN (1<<1) /* control device is open */
OpenPOWER on IntegriCloud