summaryrefslogtreecommitdiffstats
path: root/sys/dev/amr
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2008-11-03 00:53:54 +0000
committerscottl <scottl@FreeBSD.org>2008-11-03 00:53:54 +0000
commit6de3633d944db2576d517db9f4b51a88a9df6670 (patch)
treed8bbdf137911f37c46a1ac784c971f0fa237d5f7 /sys/dev/amr
parentbd5c63c83ea976832f7550a827fef3e15159b558 (diff)
downloadFreeBSD-src-6de3633d944db2576d517db9f4b51a88a9df6670.zip
FreeBSD-src-6de3633d944db2576d517db9f4b51a88a9df6670.tar.gz
Move the CAM passthrough code into a true module so that it doesn't have to be
compiled into the main AMR driver. It's code that is nice to have but not required for normal operation, and it is reported to cause problems for some people.
Diffstat (limited to 'sys/dev/amr')
-rw-r--r--sys/dev/amr/amr.c31
-rw-r--r--sys/dev/amr/amr_cam.c51
-rw-r--r--sys/dev/amr/amrvar.h9
3 files changed, 58 insertions, 33 deletions
diff --git a/sys/dev/amr/amr.c b/sys/dev/amr/amr.c
index 192f128..6b75ebb 100644
--- a/sys/dev/amr/amr.c
+++ b/sys/dev/amr/amr.c
@@ -88,13 +88,6 @@ __FBSDID("$FreeBSD$");
#define AMR_DEFINE_TABLES
#include <dev/amr/amr_tables.h>
-/*
- * The CAM interface appears to be completely broken. Disable it.
- */
-#ifndef AMR_ENABLE_CAM
-#define AMR_ENABLE_CAM 1
-#endif
-
SYSCTL_NODE(_hw, OID_AUTO, amr, CTLFLAG_RD, 0, "AMR driver parameters");
static d_open_t amr_open;
@@ -202,6 +195,7 @@ MALLOC_DEFINE(M_AMR, "amr", "AMR memory");
int
amr_attach(struct amr_softc *sc)
{
+ device_t child;
debug_called(1);
@@ -259,14 +253,16 @@ amr_attach(struct amr_softc *sc)
*/
amr_init_sysctl(sc);
-#if AMR_ENABLE_CAM != 0
/*
* Attach our 'real' SCSI channels to CAM.
*/
- if (amr_cam_attach(sc))
- return(ENXIO);
- debug(2, "CAM attach done");
-#endif
+ child = device_add_child(sc->amr_dev, "amrp", -1);
+ sc->amr_pass = child;
+ if (child != NULL) {
+ device_set_softc(child, sc);
+ device_set_desc(child, "SCSI Passthrough Bus");
+ bus_generic_attach(sc->amr_dev);
+ }
/*
* Create the control device.
@@ -391,10 +387,9 @@ amr_free(struct amr_softc *sc)
{
struct amr_command_cluster *acc;
-#if AMR_ENABLE_CAM != 0
/* detach from CAM */
- amr_cam_detach(sc);
-#endif
+ if (sc->amr_pass != NULL)
+ device_delete_child(sc->amr_dev, sc->amr_pass);
/* cancel status timeout */
untimeout(amr_periodic, sc, sc->amr_timeout);
@@ -1240,11 +1235,9 @@ amr_startio(struct amr_softc *sc)
if (ac == NULL)
(void)amr_bio_command(sc, &ac);
-#if AMR_ENABLE_CAM != 0
/* if that failed, build a command from a ccb */
- if (ac == NULL)
- (void)amr_cam_command(sc, &ac);
-#endif
+ if ((ac == NULL) && (sc->amr_cam_command != NULL))
+ sc->amr_cam_command(sc, &ac);
/* if we don't have anything to do, give up */
if (ac == NULL)
diff --git a/sys/dev/amr/amr_cam.c b/sys/dev/amr/amr_cam.c
index 65913d1..bcd036e 100644
--- a/sys/dev/amr/amr_cam.c
+++ b/sys/dev/amr/amr_cam.c
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
+#include <sys/module.h>
#include <sys/bio.h>
#include <sys/bus.h>
@@ -82,9 +83,31 @@ __FBSDID("$FreeBSD$");
#include <dev/amr/amrreg.h>
#include <dev/amr/amrvar.h>
+static int amr_cam_probe(device_t dev);
+static int amr_cam_attach(device_t dev);
+static int amr_cam_detach(device_t dev);
static void amr_cam_action(struct cam_sim *sim, union ccb *ccb);
static void amr_cam_poll(struct cam_sim *sim);
static void amr_cam_complete(struct amr_command *ac);
+static int amr_cam_command(struct amr_softc *sc, struct amr_command **acp);
+
+static devclass_t amr_pass_devclass;
+
+static device_method_t amr_pass_methods[] = {
+ DEVMETHOD(device_probe, amr_cam_probe),
+ DEVMETHOD(device_attach, amr_cam_attach),
+ DEVMETHOD(device_detach, amr_cam_detach),
+ { 0, 0 }
+};
+
+static driver_t amr_pass_driver = {
+ "amrp",
+ amr_pass_methods,
+ 0
+};
+
+DRIVER_MODULE(amrp, amr, amr_pass_driver, amr_pass_devclass, 0, 0);
+MODULE_DEPEND(amrp, cam, 1, 1, 1);
MALLOC_DEFINE(M_AMRCAM, "amrcam", "AMR CAM memory");
@@ -115,14 +138,23 @@ amr_dequeue_ccb(struct amr_softc *sc)
return(ccb);
}
+static int
+amr_cam_probe(device_t dev)
+{
+ return (0);
+}
+
/********************************************************************************
* Attach our 'real' SCSI channels to CAM
*/
-int
-amr_cam_attach(struct amr_softc *sc)
+static int
+amr_cam_attach(device_t dev)
{
+ struct amr_softc *sc;
struct cam_devq *devq;
- int chn, error;
+ int chn, error;
+
+ sc = device_get_softc(dev);
/* initialise the ccb queue */
TAILQ_INIT(&sc->amr_cam_ccbq);
@@ -134,7 +166,7 @@ amr_cam_attach(struct amr_softc *sc)
* during detach.
*/
if ((devq = cam_simq_alloc(AMR_MAX_SCSI_CMDS)) == NULL)
- return(ENOMEM);
+ return(ENOMEM);
sc->amr_cam_devq = devq;
/*
@@ -165,17 +197,20 @@ amr_cam_attach(struct amr_softc *sc)
* XXX we should scan the config and work out which devices are
* actually protected.
*/
+ sc->amr_cam_command = amr_cam_command;
return(0);
}
/********************************************************************************
* Disconnect ourselves from CAM
*/
-void
-amr_cam_detach(struct amr_softc *sc)
+static int
+amr_cam_detach(device_t dev)
{
+ struct amr_softc *sc;
int chn;
+ sc = device_get_softc(dev);
mtx_lock(&sc->amr_list_lock);
for (chn = 0; chn < sc->amr_maxchan; chn++) {
/*
@@ -191,6 +226,8 @@ amr_cam_detach(struct amr_softc *sc)
/* Now free the devq */
if (sc->amr_cam_devq != NULL)
cam_simq_free(sc->amr_cam_devq);
+
+ return (0);
}
/***********************************************************************
@@ -379,7 +416,7 @@ amr_cam_action(struct cam_sim *sim, union ccb *ccb)
* Convert a CAM CCB off the top of the CCB queue to a passthrough SCSI
* command.
*/
-int
+static int
amr_cam_command(struct amr_softc *sc, struct amr_command **acp)
{
struct amr_command *ac;
diff --git a/sys/dev/amr/amrvar.h b/sys/dev/amr/amrvar.h
index e208c53..7dc0fb4 100644
--- a/sys/dev/amr/amrvar.h
+++ b/sys/dev/amr/amrvar.h
@@ -253,6 +253,8 @@ struct amr_softc
int support_ext_cdb; /* greater than 10 byte cdb support */
/* misc glue */
+ device_t amr_pass;
+ int (*amr_cam_command)(struct amr_softc *sc, struct amr_command **acp);
struct intr_config_hook amr_ich; /* wait-for-interrupts probe hook */
struct callout_handle amr_timeout; /* periodic status check */
int amr_allow_vol_config;
@@ -277,13 +279,6 @@ extern struct amr_command *amr_alloccmd(struct amr_softc *sc);
extern void amr_releasecmd(struct amr_command *ac);
/*
- * CAM interface
- */
-extern int amr_cam_attach(struct amr_softc *sc);
-extern void amr_cam_detach(struct amr_softc *sc);
-extern int amr_cam_command(struct amr_softc *sc, struct amr_command **acp);
-
-/*
* MegaRAID logical disk driver
*/
struct amrd_softc
OpenPOWER on IntegriCloud