summaryrefslogtreecommitdiffstats
path: root/sys/dev/amr
diff options
context:
space:
mode:
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