Loading drivers/message/fusion/mptsas.c +133 −0 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); } /* Loading Loading @@ -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 Loading Loading @@ -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; } } Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) { Loading drivers/message/fusion/mptsas.h +6 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading
drivers/message/fusion/mptsas.c +133 −0 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); } /* Loading Loading @@ -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 Loading Loading @@ -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; } } Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) { Loading
drivers/message/fusion/mptsas.h +6 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading