[PATCH] trigger cam rescans in aac
Mark Johnston
mjohnston at sandvine.com
Thu Sep 23 14:30:42 UTC 2010
Hi,
Previously, the aac driver did not handle enclosure management AIFs,
which were raised during hot-swap events. Now such events trigger cam
rescans, as is done in the mps driver.
Any comments or suggestions would be appreciated.
Thanks,
-Mark
--- tmp/aac/aac.c 2010-09-16 13:24:53.000000000 -0400
+++ aac.c 2010-09-21 13:40:51.000000000 -0400
@@ -3209,6 +3209,7 @@ aac_handle_aif(struct aac_softc *sc, str
struct aac_mntinforesp *mir;
int next, current, found;
int count = 0, added = 0, i = 0;
+ uint32_t channel;
fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
@@ -3316,7 +3317,25 @@ aac_handle_aif(struct aac_softc *sc, str
}
break;
-
+ case AifEnEnclosureManagement:
+ switch (aif->data.EN.data.EEE.eventType) {
+ case AIF_EM_DRIVE_INSERTION:
+ case AIF_EM_DRIVE_REMOVAL:
+ channel = aif->data.EN.data.EEE.unitID;
+ if (sc->cam_rescan_cb != NULL)
+ sc->cam_rescan_cb(sc,
+ (channel >> 24) & 0xF,
+ (channel & 0xFFFF));
+ break;
+ }
+ break;
+ case AifEnAddJBOD:
+ case AifEnDeleteJBOD:
+ channel = aif->data.EN.data.ECE.container;
+ if (sc->cam_rescan_cb != NULL)
+ sc->cam_rescan_cb(sc, (channel >> 24) & 0xF,
+ AAC_CAM_TARGET_WILDCARD);
+ break;
default:
break;
}
--- tmp/aac/aac_cam.c 2010-09-16 13:24:53.000000000 -0400
+++ aac_cam.c 2010-09-21 13:40:21.000000000 -0400
@@ -37,12 +37,15 @@ __FBSDID("$FreeBSD: src/sys/dev/aac/aac_
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
+#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
+#include <sys/mutex.h>
#include <cam/cam.h>
#include <cam/cam_ccb.h>
#include <cam/cam_debug.h>
+#include <cam/cam_periph.h>
#include <cam/cam_sim.h>
#include <cam/cam_xpt_sim.h>
#include <cam/scsi/scsi_all.h>
@@ -76,6 +79,8 @@ static int aac_cam_detach(device_t dev);
static void aac_cam_action(struct cam_sim *, union ccb *);
static void aac_cam_poll(struct cam_sim *);
static void aac_cam_complete(struct aac_command *);
+static void aac_cam_rescan(struct aac_softc *sc, uint32_t channel,
+ uint32_t target_id);
static u_int32_t aac_cam_reset_bus(struct cam_sim *, union ccb *);
static u_int32_t aac_cam_abort_ccb(struct cam_sim *, union ccb *);
static u_int32_t aac_cam_term_io(struct cam_sim *, union ccb *);
@@ -101,6 +106,39 @@ MODULE_DEPEND(aacp, cam, 1, 1, 1);
MALLOC_DEFINE(M_AACCAM, "aaccam", "AAC CAM info");
static void
+aac_cam_rescan(struct aac_softc *sc, uint32_t channel, uint32_t target_id)
+{
+ union ccb *ccb;
+ struct aac_sim *sim;
+ struct aac_cam *camsc;
+
+ TAILQ_FOREACH(sim, &sc->aac_sim_tqh, sim_link) {
+ camsc = sim->aac_cam;
+ if (camsc == NULL || camsc->inf == NULL ||
+ camsc->inf->BusNumber != channel)
+ continue;
+
+ ccb = xpt_alloc_ccb_nowait();
+ if (ccb == NULL) {
+ device_printf(sc->aac_dev,
+ "Cannot allocate ccb for bus rescan.\n");
+ return;
+ }
+
+ if (xpt_create_path(&ccb->ccb_h.path, xpt_periph,
+ cam_sim_path(camsc->sim),
+ target_id, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
+ xpt_free_ccb(ccb);
+ device_printf(sc->aac_dev,
+ "Cannot create path for bus rescan.\n");
+ return;
+ }
+ xpt_rescan(ccb);
+ break;
+ }
+}
+
+static void
aac_cam_event(struct aac_softc *sc, struct aac_event *event, void *arg)
{
union ccb *ccb;
@@ -141,6 +179,7 @@ aac_cam_detach(device_t dev)
camsc = (struct aac_cam *)device_get_softc(dev);
sc = camsc->inf->aac_sc;
+ camsc->inf->aac_cam = NULL;
mtx_lock(&sc->aac_io_lock);
@@ -149,6 +188,8 @@ aac_cam_detach(device_t dev)
xpt_bus_deregister(cam_sim_path(camsc->sim));
cam_sim_free(camsc->sim, /*free_devq*/TRUE);
+ sc->cam_rescan_cb = NULL;
+
mtx_unlock(&sc->aac_io_lock);
return (0);
@@ -171,6 +212,7 @@ aac_cam_attach(device_t dev)
camsc = (struct aac_cam *)device_get_softc(dev);
inf = (struct aac_sim *)device_get_ivars(dev);
camsc->inf = inf;
+ camsc->inf->aac_cam = camsc;
devq = cam_simq_alloc(inf->TargetsPerBus);
if (devq == NULL)
@@ -198,6 +240,7 @@ aac_cam_attach(device_t dev)
mtx_unlock(&inf->aac_sc->aac_io_lock);
return (EIO);
}
+ inf->aac_sc->cam_rescan_cb = aac_cam_rescan;
mtx_unlock(&inf->aac_sc->aac_io_lock);
camsc->sim = sim;
@@ -611,4 +654,3 @@ aac_cam_term_io(struct cam_sim *sim, uni
{
return (CAM_UA_TERMIO);
}
-
--- tmp/aac/aacvar.h 2010-09-16 13:24:53.000000000 -0400
+++ aacvar.h 2010-09-21 13:41:14.000000000 -0400
@@ -120,6 +120,7 @@ struct aac_sim
int BusNumber;
int InitiatorBusId;
struct aac_softc *aac_sc;
+ struct aac_cam *aac_cam;
TAILQ_ENTRY(aac_sim) sim_link;
};
@@ -383,6 +384,9 @@ struct aac_softc
struct selinfo rcv_select;
struct proc *aifthread;
int aifflags;
+#define AAC_CAM_TARGET_WILDCARD ~0
+ void (*cam_rescan_cb)(struct aac_softc *, uint32_t,
+ uint32_t);
#define AAC_AIFFLAGS_RUNNING (1 << 0)
#define AAC_AIFFLAGS_AIF (1 << 1)
#define AAC_AIFFLAGS_EXIT (1 << 2)
--- tmp/aac/aacreg.h 2010-09-16 13:24:53.000000000 -0400
+++ aacreg.h 2010-09-20 14:27:52.000000000 -0400
@@ -885,6 +885,8 @@ typedef enum {
AifEnBatteryNeedsRecond, /* The battery needs reconditioning */
AifEnClusterEvent, /* Some cluster event */
AifEnDiskSetEvent, /* A disk set event occured. */
+ AifEnAddJBOD=31, /* A new JBOD type drive was created. */
+ AifEnDeleteJBOD, /* A JBOD type drive was deleted. */
AifDriverNotifyStart=199, /* Notifies for host driver go here */
/* Host driver notifications start here */
AifDenMorphComplete, /* A morph operation completed */
@@ -922,6 +924,11 @@ struct aac_AifEnsEnclosureEvent {
u_int32_t eventType; /* event type */
} __packed;
+typedef enum {
+ AIF_EM_DRIVE_INSERTION=31,
+ AIF_EM_DRIVE_REMOVAL
+} aac_AifEMEventType;
+
struct aac_AifEnsBatteryEvent {
AAC_NVBATT_TRANSITION transition_type; /* eg from low to ok */
AAC_NVBATTSTATUS current_state; /* current batt state */
More information about the freebsd-scsi
mailing list