diff options
author | ps <ps@FreeBSD.org> | 2005-04-19 06:11:16 +0000 |
---|---|---|
committer | ps <ps@FreeBSD.org> | 2005-04-19 06:11:16 +0000 |
commit | b7632e9a5b90b6ef37dd38fcab327427cdeb3f06 (patch) | |
tree | 416f88ea01b7a9d7e66acf562fc6b6fea366d168 /sys/dev/ciss | |
parent | 046acb18c8690d260693e3ba39b540e242aa729b (diff) | |
download | FreeBSD-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/dev/ciss')
-rw-r--r-- | sys/dev/ciss/ciss.c | 55 | ||||
-rw-r--r-- | sys/dev/ciss/cissreg.h | 1 | ||||
-rw-r--r-- | sys/dev/ciss/cissvar.h | 2 |
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 */ |