Skip to content

Commit

Permalink
[SCSI] mpt fusion: Queue full event handling
Browse files Browse the repository at this point in the history
FW will report Queue full event to Driver and driver will handle this queue
full event to SCSI Mid layer.

Signed-off-by: Kashyap Desai <kadesai@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
  • Loading branch information
Kashyap, Desai authored and James Bottomley committed Jun 9, 2009
1 parent a7938b0 commit 57e9851
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 0 deletions.
133 changes: 133 additions & 0 deletions drivers/message/fusion/mptsas.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ static void mptsas_expander_delete(MPT_ADAPTER *ioc,
static void mptsas_send_expander_event(struct fw_event_work *fw_event);
static void mptsas_not_responding_devices(MPT_ADAPTER *ioc);
static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc);
static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);

static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
Expand Down Expand Up @@ -680,6 +681,18 @@ mptsas_add_device_component_starget_ir(MPT_ADAPTER *ioc,
mptsas_add_device_component_by_fw(ioc, phys_disk.PhysDiskBus,
phys_disk.PhysDiskID);

mutex_lock(&ioc->sas_device_info_mutex);
list_for_each_entry(sas_info, &ioc->sas_device_info_list,
list) {
if (!sas_info->is_logical_volume &&
(sas_info->fw.channel == phys_disk.PhysDiskBus &&
sas_info->fw.id == phys_disk.PhysDiskID)) {
sas_info->is_hidden_raid_component = 1;
sas_info->volume_id = starget->id;
}
}
mutex_unlock(&ioc->sas_device_info_mutex);

}

/*
Expand Down Expand Up @@ -746,6 +759,29 @@ mptsas_add_device_component_starget(MPT_ADAPTER *ioc,
phy_info->attached.slot, enclosure_info.enclosure_logical_id);
}

/**
* mptsas_del_device_component_by_os - Once a device has been removed, we
* mark the entry in the list as being cached
* @ioc: Pointer to MPT_ADAPTER structure
* @channel: os mapped id's
* @id:
*
**/
static void
mptsas_del_device_component_by_os(MPT_ADAPTER *ioc, u8 channel, u8 id)
{
struct mptsas_device_info *sas_info, *next;

/*
* Set is_cached flag
*/
list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
list) {
if (sas_info->os.channel == channel && sas_info->os.id == id)
sas_info->is_cached = 1;
}
}

/**
* mptsas_del_device_components - Cleaning the list
* @ioc: Pointer to MPT_ADAPTER structure
Expand Down Expand Up @@ -1576,6 +1612,9 @@ mptsas_firmware_event_work(struct work_struct *work)
case MPI_EVENT_SAS_PHY_LINK_STATUS:
mptsas_send_link_status_event(fw_event);
break;
case MPI_EVENT_QUEUE_FULL:
mptsas_handle_queue_full_event(fw_event);
break;
}
}

Expand Down Expand Up @@ -1705,6 +1744,9 @@ mptsas_target_destroy(struct scsi_target *starget)

vtarget = starget->hostdata;

mptsas_del_device_component_by_os(ioc, starget->channel,
starget->id);


if (starget->channel == MPTSAS_RAID_CHANNEL)
goto out;
Expand Down Expand Up @@ -3398,6 +3440,8 @@ mptsas_not_responding_devices(MPT_ADAPTER *ioc)
mutex_lock(&ioc->sas_device_info_mutex);
redo_device_scan:
list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) {
if (sas_info->is_cached)
continue;
if (!sas_info->is_logical_volume) {
sas_device.handle = 0;
retry_count = 0;
Expand Down Expand Up @@ -3612,6 +3656,95 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
}
}


static void
mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
{
MPT_ADAPTER *ioc;
EventDataQueueFull_t *qfull_data;
struct mptsas_device_info *sas_info;
struct scsi_device *sdev;
int depth;
int id = -1;
int channel = -1;
int fw_id, fw_channel;
u16 current_depth;


ioc = fw_event->ioc;
qfull_data = (EventDataQueueFull_t *)fw_event->event_data;
fw_id = qfull_data->TargetID;
fw_channel = qfull_data->Bus;
current_depth = le16_to_cpu(qfull_data->CurrentDepth);

/* if hidden raid component, look for the volume id */
mutex_lock(&ioc->sas_device_info_mutex);
if (mptscsih_is_phys_disk(ioc, fw_channel, fw_id)) {
list_for_each_entry(sas_info, &ioc->sas_device_info_list,
list) {
if (sas_info->is_cached ||
sas_info->is_logical_volume)
continue;
if (sas_info->is_hidden_raid_component &&
(sas_info->fw.channel == fw_channel &&
sas_info->fw.id == fw_id)) {
id = sas_info->volume_id;
channel = MPTSAS_RAID_CHANNEL;
goto out;
}
}
} else {
list_for_each_entry(sas_info, &ioc->sas_device_info_list,
list) {
if (sas_info->is_cached ||
sas_info->is_hidden_raid_component ||
sas_info->is_logical_volume)
continue;
if (sas_info->fw.channel == fw_channel &&
sas_info->fw.id == fw_id) {
id = sas_info->os.id;
channel = sas_info->os.channel;
goto out;
}
}

}

out:
mutex_unlock(&ioc->sas_device_info_mutex);

if (id != -1) {
shost_for_each_device(sdev, ioc->sh) {
if (sdev->id == id && sdev->channel == channel) {
if (current_depth > sdev->queue_depth) {
sdev_printk(KERN_INFO, sdev,
"strange observation, the queue "
"depth is (%d) meanwhile fw queue "
"depth (%d)\n", sdev->queue_depth,
current_depth);
continue;
}
depth = scsi_track_queue_full(sdev,
current_depth - 1);
if (depth > 0)
sdev_printk(KERN_INFO, sdev,
"Queue depth reduced to (%d)\n",
depth);
else if (depth < 0)
sdev_printk(KERN_INFO, sdev,
"Tagged Command Queueing is being "
"disabled\n");
else if (depth == 0)
sdev_printk(KERN_INFO, sdev,
"Queue depth not changed yet\n");
}
}
}

mptsas_free_fw_event(ioc, fw_event);
}


static struct mptsas_phyinfo *
mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
{
Expand Down
6 changes: 6 additions & 0 deletions drivers/message/fusion/mptsas.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ struct mptsas_device_info {
u16 slot; /* enclosure slot id */
u64 enclosure_logical_id; /*enclosure address */
u8 is_logical_volume; /* is this logical volume */
/* this belongs to volume */
u8 is_hidden_raid_component;
/* this valid when is_hidden_raid_component set */
u8 volume_id;
/* cached data for a removed device */
u8 is_cached;
};

struct mptsas_hotplug_event {
Expand Down

0 comments on commit 57e9851

Please sign in to comment.