aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/message/fusion/mptsas.c133
-rw-r--r--drivers/message/fusion/mptsas.h6
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,
121static void mptsas_send_expander_event(struct fw_event_work *fw_event); 121static void mptsas_send_expander_event(struct fw_event_work *fw_event);
122static void mptsas_not_responding_devices(MPT_ADAPTER *ioc); 122static void mptsas_not_responding_devices(MPT_ADAPTER *ioc);
123static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc); 123static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc);
124static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
124static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id); 125static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
125 126
126static void mptsas_print_phy_data(MPT_ADAPTER *ioc, 127static 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 **/
770static void
771mptsas_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
3660static void
3661mptsas_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
3615static struct mptsas_phyinfo * 3748static struct mptsas_phyinfo *
3616mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address) 3749mptsas_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
88struct mptsas_hotplug_event { 94struct mptsas_hotplug_event {