svn commit: r213272 - head/sys/dev/aac

Ed Maste emaste at FreeBSD.org
Wed Sep 29 14:22:00 UTC 2010


Author: emaste
Date: Wed Sep 29 14:22:00 2010
New Revision: 213272
URL: http://svn.freebsd.org/changeset/base/213272

Log:
  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.
  
  Submitted by:	Mark Johnston <mjohnston at sandvine dot com>

Modified:
  head/sys/dev/aac/aac.c
  head/sys/dev/aac/aac_cam.c
  head/sys/dev/aac/aacreg.h
  head/sys/dev/aac/aacvar.h

Modified: head/sys/dev/aac/aac.c
==============================================================================
--- head/sys/dev/aac/aac.c	Wed Sep 29 13:24:56 2010	(r213271)
+++ head/sys/dev/aac/aac.c	Wed Sep 29 14:22:00 2010	(r213272)
@@ -3216,6 +3216,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, "");
 
@@ -3324,6 +3325,27 @@ 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;
 		}

Modified: head/sys/dev/aac/aac_cam.c
==============================================================================
--- head/sys/dev/aac/aac_cam.c	Wed Sep 29 13:24:56 2010	(r213271)
+++ head/sys/dev/aac/aac_cam.c	Wed Sep 29 14:22:00 2010	(r213272)
@@ -37,12 +37,15 @@ __FBSDID("$FreeBSD$");
 #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,9 @@ 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 +107,43 @@ 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;
+
+	if (target_id == AAC_CAM_TARGET_WILDCARD)
+		target_id = CAM_TARGET_WILDCARD;
+
+	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 +184,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 +193,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 +217,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 +245,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;

Modified: head/sys/dev/aac/aacreg.h
==============================================================================
--- head/sys/dev/aac/aacreg.h	Wed Sep 29 13:24:56 2010	(r213271)
+++ head/sys/dev/aac/aacreg.h	Wed Sep 29 14:22:00 2010	(r213272)
@@ -935,6 +935,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 */

Modified: head/sys/dev/aac/aacvar.h
==============================================================================
--- head/sys/dev/aac/aacvar.h	Wed Sep 29 13:24:56 2010	(r213271)
+++ head/sys/dev/aac/aacvar.h	Wed Sep 29 14:22:00 2010	(r213272)
@@ -113,6 +113,7 @@ struct aac_container
 /*
  * Per-SIM data structure
  */
+struct aac_cam;
 struct aac_sim
 {
 	device_t		sim_dev;
@@ -120,6 +121,7 @@ struct aac_sim
 	int			BusNumber;
 	int			InitiatorBusId;
 	struct aac_softc	*aac_sc;
+	struct aac_cam		*aac_cam;
 	TAILQ_ENTRY(aac_sim)	sim_link;
 };
 
@@ -420,6 +422,9 @@ struct aac_softc
 	u_int32_t	aac_max_fib_size;		/* max. FIB size */
 	u_int32_t	aac_sg_tablesize;		/* max. sg count from host */
 	u_int32_t	aac_max_sectors;		/* max. I/O size from host (blocks) */
+#define AAC_CAM_TARGET_WILDCARD ~0
+	void			(*cam_rescan_cb)(struct aac_softc *, uint32_t,
+				    uint32_t);
 };
 
 /*


More information about the svn-src-all mailing list