Skip to content

Commit

Permalink
[SCSI] aacraid: respond to enclosure service events
Browse files Browse the repository at this point in the history
Added support to respond to enclosure service events
(controller AIFs) to add, online or offline physical targets
reported to sg. Also added online and offlining of arrays.
Removed an automatic variable definition in a sub block that
hid an earlier definition, determined to be inert as the
sub-block use did not interfere. Bumped the driver versioning
to stamp the addition of this feature.

Signed-off-by: Mark Salyzyn <aacraid@adaptec.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
  • Loading branch information
Salyzyn, Mark authored and James Bottomley committed Jan 23, 2008
1 parent d9aa3af commit 0995ad3
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 22 deletions.
5 changes: 4 additions & 1 deletion drivers/scsi/aacraid/aacraid.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*----------------------------------------------------------------------------*/

#ifndef AAC_DRIVER_BUILD
# define AAC_DRIVER_BUILD 2449
# define AAC_DRIVER_BUILD 2454
# define AAC_DRIVER_BRANCH "-ms"
#endif
#define MAXIMUM_NUM_CONTAINERS 32
Expand Down Expand Up @@ -1772,6 +1772,9 @@ extern struct aac_common aac_config;
#define AifEnConfigChange 3 /* Adapter configuration change */
#define AifEnContainerChange 4 /* Container configuration change */
#define AifEnDeviceFailure 5 /* SCSI device failed */
#define AifEnEnclosureManagement 13 /* EM_DRIVE_* */
#define EM_DRIVE_INSERTION 31
#define EM_DRIVE_REMOVAL 32
#define AifEnBatteryEvent 14 /* Change in Battery State */
#define AifEnAddContainer 15 /* A new array was created */
#define AifEnDeleteContainer 16 /* A container was deleted */
Expand Down
96 changes: 75 additions & 21 deletions drivers/scsi/aacraid/commsup.c
Original file line number Diff line number Diff line change
Expand Up @@ -775,20 +775,20 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
{
struct hw_fib * hw_fib = fibptr->hw_fib_va;
struct aac_aifcmd * aifcmd = (struct aac_aifcmd *)hw_fib->data;
u32 container;
u32 channel, id, lun, container;
struct scsi_device *device;
enum {
NOTHING,
DELETE,
ADD,
CHANGE
} device_config_needed;
} device_config_needed = NOTHING;

/* Sniff for container changes */

if (!dev || !dev->fsa_dev)
return;
container = (u32)-1;
container = channel = id = lun = (u32)-1;

/*
* We have set this up to try and minimize the number of
Expand Down Expand Up @@ -901,6 +901,36 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
case AifEnConfigChange:
break;

case AifEnEnclosureManagement:
switch (le32_to_cpu(((__le32 *)aifcmd->data)[3])) {
case EM_DRIVE_INSERTION:
case EM_DRIVE_REMOVAL:
container = le32_to_cpu(
((__le32 *)aifcmd->data)[2]);
if ((container >> 28))
break;
channel = (container >> 24) & 0xF;
if (channel >= dev->maximum_num_channels)
break;
id = container & 0xFFFF;
lun = (container >> 16) & 0xFF;
if (id >= dev->maximum_num_physicals) {
/* legacy dev_t ? */
if ((0x2000 <= id) || lun || channel ||
((channel = (id >> 7) & 0x3F) >=
dev->maximum_num_channels))
break;
lun = (id >> 4) & 7;
id &= 0xF;
}
channel = aac_phys_to_logical(channel);
device_config_needed =
(((__le32 *)aifcmd->data)[3]
== cpu_to_le32(EM_DRIVE_INSERTION)) ?
ADD : DELETE;
break;
}
break;
}

/*
Expand Down Expand Up @@ -969,7 +999,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
break;
}

device_config_needed = NOTHING;
if (device_config_needed == NOTHING)
for (container = 0; container < dev->maximum_num_containers;
++container) {
if ((dev->fsa_dev[container].config_waiting_on == 0) &&
Expand All @@ -978,6 +1008,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
device_config_needed =
dev->fsa_dev[container].config_needed;
dev->fsa_dev[container].config_needed = NOTHING;
channel = CONTAINER_TO_CHANNEL(container);
id = CONTAINER_TO_ID(container);
lun = CONTAINER_TO_LUN(container);
break;
}
}
Expand All @@ -1001,34 +1034,56 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
/*
* force reload of disk info via aac_probe_container
*/
if ((device_config_needed == CHANGE)
&& (dev->fsa_dev[container].valid == 1))
dev->fsa_dev[container].valid = 2;
if ((device_config_needed == CHANGE) ||
(device_config_needed == ADD))
if ((channel == CONTAINER_CHANNEL) &&
(device_config_needed != NOTHING)) {
if (dev->fsa_dev[container].valid == 1)
dev->fsa_dev[container].valid = 2;
aac_probe_container(dev, container);
device = scsi_device_lookup(dev->scsi_host_ptr,
CONTAINER_TO_CHANNEL(container),
CONTAINER_TO_ID(container),
CONTAINER_TO_LUN(container));
}
device = scsi_device_lookup(dev->scsi_host_ptr, channel, id, lun);
if (device) {
switch (device_config_needed) {
case DELETE:
if (scsi_device_online(device)) {
scsi_device_set_state(device, SDEV_OFFLINE);
sdev_printk(KERN_INFO, device,
"Device offlined - %s\n",
(channel == CONTAINER_CHANNEL) ?
"array deleted" :
"enclosure services event");
}
break;
case ADD:
if (!scsi_device_online(device)) {
sdev_printk(KERN_INFO, device,
"Device online - %s\n",
(channel == CONTAINER_CHANNEL) ?
"array created" :
"enclosure services event");
scsi_device_set_state(device, SDEV_RUNNING);
}
/* FALLTHRU */
case CHANGE:
if ((channel == CONTAINER_CHANNEL)
&& (!dev->fsa_dev[container].valid)) {
if (!scsi_device_online(device))
break;
scsi_device_set_state(device, SDEV_OFFLINE);
sdev_printk(KERN_INFO, device,
"Device offlined - %s\n",
"array failed");
break;
}
scsi_rescan_device(&device->sdev_gendev);

default:
break;
}
scsi_device_put(device);
device_config_needed = NOTHING;
}
if (device_config_needed == ADD) {
scsi_add_device(dev->scsi_host_ptr,
CONTAINER_TO_CHANNEL(container),
CONTAINER_TO_ID(container),
CONTAINER_TO_LUN(container));
}

if (device_config_needed == ADD)
scsi_add_device(dev->scsi_host_ptr, channel, id, lun);
}

static int _aac_reset_adapter(struct aac_dev *aac, int forced)
Expand Down Expand Up @@ -1469,7 +1524,6 @@ int aac_command_thread(void *data)
*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
aac_fib_adapter_complete(fib, (u16)sizeof(u32));
} else {
struct list_head *entry;
/* The u32 here is important and intended. We are using
32bit wrapping time to fit the adapter field */

Expand Down

0 comments on commit 0995ad3

Please sign in to comment.