diff options
Diffstat (limited to 'sys/dev/amr')
-rw-r--r-- | sys/dev/amr/amr.c | 31 | ||||
-rw-r--r-- | sys/dev/amr/amr_cam.c | 51 | ||||
-rw-r--r-- | sys/dev/amr/amrvar.h | 9 |
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 |