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>
This commit is contained in:
parent
0ee8ad6723
commit
851f59d7e2
@ -3216,6 +3216,7 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
|
|||||||
struct aac_mntinforesp *mir;
|
struct aac_mntinforesp *mir;
|
||||||
int next, current, found;
|
int next, current, found;
|
||||||
int count = 0, added = 0, i = 0;
|
int count = 0, added = 0, i = 0;
|
||||||
|
uint32_t channel;
|
||||||
|
|
||||||
fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
|
fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
|
||||||
|
|
||||||
@ -3324,6 +3325,27 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
|
|||||||
|
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -37,12 +37,15 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
|
#include <sys/lock.h>
|
||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
#include <sys/module.h>
|
#include <sys/module.h>
|
||||||
|
#include <sys/mutex.h>
|
||||||
|
|
||||||
#include <cam/cam.h>
|
#include <cam/cam.h>
|
||||||
#include <cam/cam_ccb.h>
|
#include <cam/cam_ccb.h>
|
||||||
#include <cam/cam_debug.h>
|
#include <cam/cam_debug.h>
|
||||||
|
#include <cam/cam_periph.h>
|
||||||
#include <cam/cam_sim.h>
|
#include <cam/cam_sim.h>
|
||||||
#include <cam/cam_xpt_sim.h>
|
#include <cam/cam_xpt_sim.h>
|
||||||
#include <cam/scsi/scsi_all.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_action(struct cam_sim *, union ccb *);
|
||||||
static void aac_cam_poll(struct cam_sim *);
|
static void aac_cam_poll(struct cam_sim *);
|
||||||
static void aac_cam_complete(struct aac_command *);
|
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_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_abort_ccb(struct cam_sim *, union ccb *);
|
||||||
static u_int32_t aac_cam_term_io(struct cam_sim *, union ccb *);
|
static u_int32_t aac_cam_term_io(struct cam_sim *, union ccb *);
|
||||||
@ -100,6 +106,43 @@ MODULE_DEPEND(aacp, cam, 1, 1, 1);
|
|||||||
|
|
||||||
MALLOC_DEFINE(M_AACCAM, "aaccam", "AAC CAM info");
|
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
|
static void
|
||||||
aac_cam_event(struct aac_softc *sc, struct aac_event *event, void *arg)
|
aac_cam_event(struct aac_softc *sc, struct aac_event *event, void *arg)
|
||||||
{
|
{
|
||||||
@ -141,6 +184,7 @@ aac_cam_detach(device_t dev)
|
|||||||
|
|
||||||
camsc = (struct aac_cam *)device_get_softc(dev);
|
camsc = (struct aac_cam *)device_get_softc(dev);
|
||||||
sc = camsc->inf->aac_sc;
|
sc = camsc->inf->aac_sc;
|
||||||
|
camsc->inf->aac_cam = NULL;
|
||||||
|
|
||||||
mtx_lock(&sc->aac_io_lock);
|
mtx_lock(&sc->aac_io_lock);
|
||||||
|
|
||||||
@ -149,6 +193,8 @@ aac_cam_detach(device_t dev)
|
|||||||
xpt_bus_deregister(cam_sim_path(camsc->sim));
|
xpt_bus_deregister(cam_sim_path(camsc->sim));
|
||||||
cam_sim_free(camsc->sim, /*free_devq*/TRUE);
|
cam_sim_free(camsc->sim, /*free_devq*/TRUE);
|
||||||
|
|
||||||
|
sc->cam_rescan_cb = NULL;
|
||||||
|
|
||||||
mtx_unlock(&sc->aac_io_lock);
|
mtx_unlock(&sc->aac_io_lock);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
@ -171,6 +217,7 @@ aac_cam_attach(device_t dev)
|
|||||||
camsc = (struct aac_cam *)device_get_softc(dev);
|
camsc = (struct aac_cam *)device_get_softc(dev);
|
||||||
inf = (struct aac_sim *)device_get_ivars(dev);
|
inf = (struct aac_sim *)device_get_ivars(dev);
|
||||||
camsc->inf = inf;
|
camsc->inf = inf;
|
||||||
|
camsc->inf->aac_cam = camsc;
|
||||||
|
|
||||||
devq = cam_simq_alloc(inf->TargetsPerBus);
|
devq = cam_simq_alloc(inf->TargetsPerBus);
|
||||||
if (devq == NULL)
|
if (devq == NULL)
|
||||||
@ -198,6 +245,7 @@ aac_cam_attach(device_t dev)
|
|||||||
mtx_unlock(&inf->aac_sc->aac_io_lock);
|
mtx_unlock(&inf->aac_sc->aac_io_lock);
|
||||||
return (EIO);
|
return (EIO);
|
||||||
}
|
}
|
||||||
|
inf->aac_sc->cam_rescan_cb = aac_cam_rescan;
|
||||||
mtx_unlock(&inf->aac_sc->aac_io_lock);
|
mtx_unlock(&inf->aac_sc->aac_io_lock);
|
||||||
|
|
||||||
camsc->sim = sim;
|
camsc->sim = sim;
|
||||||
|
@ -935,6 +935,11 @@ struct aac_AifEnsEnclosureEvent {
|
|||||||
u_int32_t eventType; /* event type */
|
u_int32_t eventType; /* event type */
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
AIF_EM_DRIVE_INSERTION=31,
|
||||||
|
AIF_EM_DRIVE_REMOVAL
|
||||||
|
} aac_AifEMEventType;
|
||||||
|
|
||||||
struct aac_AifEnsBatteryEvent {
|
struct aac_AifEnsBatteryEvent {
|
||||||
AAC_NVBATT_TRANSITION transition_type; /* eg from low to ok */
|
AAC_NVBATT_TRANSITION transition_type; /* eg from low to ok */
|
||||||
AAC_NVBATTSTATUS current_state; /* current batt state */
|
AAC_NVBATTSTATUS current_state; /* current batt state */
|
||||||
|
@ -113,6 +113,7 @@ struct aac_container
|
|||||||
/*
|
/*
|
||||||
* Per-SIM data structure
|
* Per-SIM data structure
|
||||||
*/
|
*/
|
||||||
|
struct aac_cam;
|
||||||
struct aac_sim
|
struct aac_sim
|
||||||
{
|
{
|
||||||
device_t sim_dev;
|
device_t sim_dev;
|
||||||
@ -120,6 +121,7 @@ struct aac_sim
|
|||||||
int BusNumber;
|
int BusNumber;
|
||||||
int InitiatorBusId;
|
int InitiatorBusId;
|
||||||
struct aac_softc *aac_sc;
|
struct aac_softc *aac_sc;
|
||||||
|
struct aac_cam *aac_cam;
|
||||||
TAILQ_ENTRY(aac_sim) sim_link;
|
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_max_fib_size; /* max. FIB size */
|
||||||
u_int32_t aac_sg_tablesize; /* max. sg count from host */
|
u_int32_t aac_sg_tablesize; /* max. sg count from host */
|
||||||
u_int32_t aac_max_sectors; /* max. I/O size from host (blocks) */
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user