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 { |
