diff options
author | Kashyap, Desai <kashyap.desai@lsi.com> | 2009-05-29 07:25:09 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-06-09 18:44:39 -0400 |
commit | 57e985136bfafdfcd72c4c7d91115955d225677e (patch) | |
tree | 8b09842b7bfcc3b451f507d294ebe9626b2df81d /drivers/message | |
parent | a7938b0bb3b458fe0723608be3db6c4ed8d79a8c (diff) |
[SCSI] mpt fusion: Queue full event handling
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>
Diffstat (limited to 'drivers/message')
-rw-r--r-- | drivers/message/fusion/mptsas.c | 133 | ||||
-rw-r--r-- | drivers/message/fusion/mptsas.h | 6 |
2 files changed, 139 insertions, 0 deletions
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 72158237f5e8..10a12d846e85 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -121,6 +121,7 @@ static void mptsas_expander_delete(MPT_ADAPTER *ioc, | |||
121 | static void mptsas_send_expander_event(struct fw_event_work *fw_event); | 121 | static void mptsas_send_expander_event(struct fw_event_work *fw_event); |
122 | static void mptsas_not_responding_devices(MPT_ADAPTER *ioc); | 122 | static void mptsas_not_responding_devices(MPT_ADAPTER *ioc); |
123 | static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc); | 123 | static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc); |
124 | static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event); | ||
124 | static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id); | 125 | static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id); |
125 | 126 | ||
126 | static void mptsas_print_phy_data(MPT_ADAPTER *ioc, | 127 | static void mptsas_print_phy_data(MPT_ADAPTER *ioc, |
@@ -680,6 +681,18 @@ mptsas_add_device_component_starget_ir(MPT_ADAPTER *ioc, | |||
680 | mptsas_add_device_component_by_fw(ioc, phys_disk.PhysDiskBus, | 681 | mptsas_add_device_component_by_fw(ioc, phys_disk.PhysDiskBus, |
681 | phys_disk.PhysDiskID); | 682 | phys_disk.PhysDiskID); |
682 | 683 | ||
684 | mutex_lock(&ioc->sas_device_info_mutex); | ||
685 | list_for_each_entry(sas_info, &ioc->sas_device_info_list, | ||
686 | list) { | ||
687 | if (!sas_info->is_logical_volume && | ||
688 | (sas_info->fw.channel == phys_disk.PhysDiskBus && | ||
689 | sas_info->fw.id == phys_disk.PhysDiskID)) { | ||
690 | sas_info->is_hidden_raid_component = 1; | ||
691 | sas_info->volume_id = starget->id; | ||
692 | } | ||
693 | } | ||
694 | mutex_unlock(&ioc->sas_device_info_mutex); | ||
695 | |||
683 | } | 696 | } |
684 | 697 | ||
685 | /* | 698 | /* |
@@ -747,6 +760,29 @@ mptsas_add_device_component_starget(MPT_ADAPTER *ioc, | |||
747 | } | 760 | } |
748 | 761 | ||
749 | /** | 762 | /** |
763 | * mptsas_del_device_component_by_os - Once a device has been removed, we | ||
764 | * mark the entry in the list as being cached | ||
765 | * @ioc: Pointer to MPT_ADAPTER structure | ||
766 | * @channel: os mapped id's | ||
767 | * @id: | ||
768 | * | ||
769 | **/ | ||
770 | static void | ||
771 | mptsas_del_device_component_by_os(MPT_ADAPTER *ioc, u8 channel, u8 id) | ||
772 | { | ||
773 | struct mptsas_device_info *sas_info, *next; | ||
774 | |||
775 | /* | ||
776 | * Set is_cached flag | ||
777 | */ | ||
778 | list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list, | ||
779 | list) { | ||
780 | if (sas_info->os.channel == channel && sas_info->os.id == id) | ||
781 | sas_info->is_cached = 1; | ||
782 | } | ||
783 | } | ||
784 | |||
785 | /** | ||
750 | * mptsas_del_device_components - Cleaning the list | 786 | * mptsas_del_device_components - Cleaning the list |
751 | * @ioc: Pointer to MPT_ADAPTER structure | 787 | * @ioc: Pointer to MPT_ADAPTER structure |
752 | * | 788 | * |
@@ -1576,6 +1612,9 @@ mptsas_firmware_event_work(struct work_struct *work) | |||
1576 | case MPI_EVENT_SAS_PHY_LINK_STATUS: | 1612 | case MPI_EVENT_SAS_PHY_LINK_STATUS: |
1577 | mptsas_send_link_status_event(fw_event); | 1613 | mptsas_send_link_status_event(fw_event); |
1578 | break; | 1614 | break; |
1615 | case MPI_EVENT_QUEUE_FULL: | ||
1616 | mptsas_handle_queue_full_event(fw_event); | ||
1617 | break; | ||
1579 | } | 1618 | } |
1580 | } | 1619 | } |
1581 | 1620 | ||
@@ -1705,6 +1744,9 @@ mptsas_target_destroy(struct scsi_target *starget) | |||
1705 | 1744 | ||
1706 | vtarget = starget->hostdata; | 1745 | vtarget = starget->hostdata; |
1707 | 1746 | ||
1747 | mptsas_del_device_component_by_os(ioc, starget->channel, | ||
1748 | starget->id); | ||
1749 | |||
1708 | 1750 | ||
1709 | if (starget->channel == MPTSAS_RAID_CHANNEL) | 1751 | if (starget->channel == MPTSAS_RAID_CHANNEL) |
1710 | goto out; | 1752 | goto out; |
@@ -3398,6 +3440,8 @@ mptsas_not_responding_devices(MPT_ADAPTER *ioc) | |||
3398 | mutex_lock(&ioc->sas_device_info_mutex); | 3440 | mutex_lock(&ioc->sas_device_info_mutex); |
3399 | redo_device_scan: | 3441 | redo_device_scan: |
3400 | list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) { | 3442 | list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) { |
3443 | if (sas_info->is_cached) | ||
3444 | continue; | ||
3401 | if (!sas_info->is_logical_volume) { | 3445 | if (!sas_info->is_logical_volume) { |
3402 | sas_device.handle = 0; | 3446 | sas_device.handle = 0; |
3403 | retry_count = 0; | 3447 | retry_count = 0; |
@@ -3612,6 +3656,95 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc) | |||
3612 | } | 3656 | } |
3613 | } | 3657 | } |
3614 | 3658 | ||
3659 | |||
3660 | static void | ||
3661 | mptsas_handle_queue_full_event(struct fw_event_work *fw_event) | ||
3662 | { | ||
3663 | MPT_ADAPTER *ioc; | ||
3664 | EventDataQueueFull_t *qfull_data; | ||
3665 | struct mptsas_device_info *sas_info; | ||
3666 | struct scsi_device *sdev; | ||
3667 | int depth; | ||
3668 | int id = -1; | ||
3669 | int channel = -1; | ||
3670 | int fw_id, fw_channel; | ||
3671 | u16 current_depth; | ||
3672 | |||
3673 | |||
3674 | ioc = fw_event->ioc; | ||
3675 | qfull_data = (EventDataQueueFull_t *)fw_event->event_data; | ||
3676 | fw_id = qfull_data->TargetID; | ||
3677 | fw_channel = qfull_data->Bus; | ||
3678 | current_depth = le16_to_cpu(qfull_data->CurrentDepth); | ||
3679 | |||
3680 | /* if hidden raid component, look for the volume id */ | ||
3681 | mutex_lock(&ioc->sas_device_info_mutex); | ||
3682 | if (mptscsih_is_phys_disk(ioc, fw_channel, fw_id)) { | ||
3683 | list_for_each_entry(sas_info, &ioc->sas_device_info_list, | ||
3684 | list) { | ||
3685 | if (sas_info->is_cached || | ||
3686 | sas_info->is_logical_volume) | ||
3687 | continue; | ||
3688 | if (sas_info->is_hidden_raid_component && | ||
3689 | (sas_info->fw.channel == fw_channel && | ||
3690 | sas_info->fw.id == fw_id)) { | ||
3691 | id = sas_info->volume_id; | ||
3692 | channel = MPTSAS_RAID_CHANNEL; | ||
3693 | goto out; | ||
3694 | } | ||
3695 | } | ||
3696 | } else { | ||
3697 | list_for_each_entry(sas_info, &ioc->sas_device_info_list, | ||
3698 | list) { | ||
3699 | if (sas_info->is_cached || | ||
3700 | sas_info->is_hidden_raid_component || | ||
3701 | sas_info->is_logical_volume) | ||
3702 | continue; | ||
3703 | if (sas_info->fw.channel == fw_channel && | ||
3704 | sas_info->fw.id == fw_id) { | ||
3705 | id = sas_info->os.id; | ||
3706 | channel = sas_info->os.channel; | ||
3707 | goto out; | ||
3708 | } | ||
3709 | } | ||
3710 | |||
3711 | } | ||
3712 | |||
3713 | out: | ||
3714 | mutex_unlock(&ioc->sas_device_info_mutex); | ||
3715 | |||
3716 | if (id != -1) { | ||
3717 | shost_for_each_device(sdev, ioc->sh) { | ||
3718 | if (sdev->id == id && sdev->channel == channel) { | ||
3719 | if (current_depth > sdev->queue_depth) { | ||
3720 | sdev_printk(KERN_INFO, sdev, | ||
3721 | "strange observation, the queue " | ||
3722 | "depth is (%d) meanwhile fw queue " | ||
3723 | "depth (%d)\n", sdev->queue_depth, | ||
3724 | current_depth); | ||
3725 | continue; | ||
3726 | } | ||
3727 | depth = scsi_track_queue_full(sdev, | ||
3728 | current_depth - 1); | ||
3729 | if (depth > 0) | ||
3730 | sdev_printk(KERN_INFO, sdev, | ||
3731 | "Queue depth reduced to (%d)\n", | ||
3732 | depth); | ||
3733 | else if (depth < 0) | ||
3734 | sdev_printk(KERN_INFO, sdev, | ||
3735 | "Tagged Command Queueing is being " | ||
3736 | "disabled\n"); | ||
3737 | else if (depth == 0) | ||
3738 | sdev_printk(KERN_INFO, sdev, | ||
3739 | "Queue depth not changed yet\n"); | ||
3740 | } | ||
3741 | } | ||
3742 | } | ||
3743 | |||
3744 | mptsas_free_fw_event(ioc, fw_event); | ||
3745 | } | ||
3746 | |||
3747 | |||
3615 | static struct mptsas_phyinfo * | 3748 | static struct mptsas_phyinfo * |
3616 | mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address) | 3749 | mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address) |
3617 | { | 3750 | { |
diff --git a/drivers/message/fusion/mptsas.h b/drivers/message/fusion/mptsas.h index 57258b60369e..953c2bfcf6aa 100644 --- a/drivers/message/fusion/mptsas.h +++ b/drivers/message/fusion/mptsas.h | |||
@@ -83,6 +83,12 @@ struct mptsas_device_info { | |||
83 | u16 slot; /* enclosure slot id */ | 83 | u16 slot; /* enclosure slot id */ |
84 | u64 enclosure_logical_id; /*enclosure address */ | 84 | u64 enclosure_logical_id; /*enclosure address */ |
85 | u8 is_logical_volume; /* is this logical volume */ | 85 | u8 is_logical_volume; /* is this logical volume */ |
86 | /* this belongs to volume */ | ||
87 | u8 is_hidden_raid_component; | ||
88 | /* this valid when is_hidden_raid_component set */ | ||
89 | u8 volume_id; | ||
90 | /* cached data for a removed device */ | ||
91 | u8 is_cached; | ||
86 | }; | 92 | }; |
87 | 93 | ||
88 | struct mptsas_hotplug_event { | 94 | struct mptsas_hotplug_event { |