aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/message/fusion/mptbase.h6
-rw-r--r--drivers/message/fusion/mptsas.c169
2 files changed, 172 insertions, 3 deletions
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 8d1aadb6b4ac..11fc8f3960a6 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -76,8 +76,8 @@
76#define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR 76#define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR
77#endif 77#endif
78 78
79#define MPT_LINUX_VERSION_COMMON "3.04.08" 79#define MPT_LINUX_VERSION_COMMON "3.04.09"
80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.08" 80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.09"
81#define WHAT_MAGIC_STRING "@" "(" "#" ")" 81#define WHAT_MAGIC_STRING "@" "(" "#" ")"
82 82
83#define show_mptmod_ver(s,ver) \ 83#define show_mptmod_ver(s,ver) \
@@ -711,6 +711,7 @@ typedef struct _MPT_ADAPTER
711 u16 hba_port_num_phy; 711 u16 hba_port_num_phy;
712 struct list_head sas_device_info_list; 712 struct list_head sas_device_info_list;
713 struct mutex sas_device_info_mutex; 713 struct mutex sas_device_info_mutex;
714 u8 old_sas_discovery_protocal;
714 u8 sas_discovery_quiesce_io; 715 u8 sas_discovery_quiesce_io;
715 int sas_index; /* index refrencing */ 716 int sas_index; /* index refrencing */
716 MPT_MGMT sas_mgmt; 717 MPT_MGMT sas_mgmt;
@@ -741,6 +742,7 @@ typedef struct _MPT_ADAPTER
741 spinlock_t fault_reset_work_lock; 742 spinlock_t fault_reset_work_lock;
742 743
743 u8 sg_addr_size; 744 u8 sg_addr_size;
745 u8 in_rescan;
744 u8 SGE_size; 746 u8 SGE_size;
745 747
746} MPT_ADAPTER; 748} MPT_ADAPTER;
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 7f2f76f0db3f..6aa91268afe9 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -119,6 +119,8 @@ static struct mptsas_portinfo *mptsas_find_portinfo_by_sas_address
119static void mptsas_expander_delete(MPT_ADAPTER *ioc, 119static void mptsas_expander_delete(MPT_ADAPTER *ioc,
120 struct mptsas_portinfo *port_info, u8 force); 120 struct mptsas_portinfo *port_info, u8 force);
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);
123static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc);
122 124
123static void mptsas_print_phy_data(MPT_ADAPTER *ioc, 125static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
124 MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) 126 MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
@@ -844,6 +846,24 @@ mptsas_queue_device_delete(MPT_ADAPTER *ioc,
844 mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1)); 846 mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
845} 847}
846 848
849static void
850mptsas_queue_rescan(MPT_ADAPTER *ioc)
851{
852 struct fw_event_work *fw_event;
853 int sz;
854
855 sz = offsetof(struct fw_event_work, event_data);
856 fw_event = kzalloc(sz, GFP_ATOMIC);
857 if (!fw_event) {
858 printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
859 ioc->name, __func__, __LINE__);
860 return;
861 }
862 fw_event->event = -1;
863 fw_event->ioc = ioc;
864 mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
865}
866
847 867
848/** 868/**
849 * mptsas_target_reset 869 * mptsas_target_reset
@@ -1100,6 +1120,7 @@ mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1100 complete(&ioc->sas_mgmt.done); 1120 complete(&ioc->sas_mgmt.done);
1101 } 1121 }
1102 mptsas_cleanup_fw_event_q(ioc); 1122 mptsas_cleanup_fw_event_q(ioc);
1123 mptsas_queue_rescan(ioc);
1103 mptsas_fw_event_on(ioc); 1124 mptsas_fw_event_on(ioc);
1104 break; 1125 break;
1105 default: 1126 default:
@@ -1406,6 +1427,23 @@ mptsas_firmware_event_work(struct work_struct *work)
1406 container_of(work, struct fw_event_work, work.work); 1427 container_of(work, struct fw_event_work, work.work);
1407 MPT_ADAPTER *ioc = fw_event->ioc; 1428 MPT_ADAPTER *ioc = fw_event->ioc;
1408 1429
1430 /* special rescan topology handling */
1431 if (fw_event->event == -1) {
1432 if (ioc->in_rescan) {
1433 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1434 "%s: rescan ignored as it is in progress\n",
1435 ioc->name, __func__));
1436 return;
1437 }
1438 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: rescan after "
1439 "reset\n", ioc->name, __func__));
1440 ioc->in_rescan = 1;
1441 mptsas_not_responding_devices(ioc);
1442 mptsas_scan_sas_topology(ioc);
1443 ioc->in_rescan = 0;
1444 mptsas_free_fw_event(ioc, fw_event);
1445 return;
1446 }
1409 1447
1410 /* events handling turned off during host reset */ 1448 /* events handling turned off during host reset */
1411 if (ioc->fw_events_off) { 1449 if (ioc->fw_events_off) {
@@ -3153,8 +3191,15 @@ mptsas_send_link_status_event(struct fw_event_work *fw_event)
3153 if (link_rate == MPI_SAS_IOUNIT0_RATE_1_5 || 3191 if (link_rate == MPI_SAS_IOUNIT0_RATE_1_5 ||
3154 link_rate == MPI_SAS_IOUNIT0_RATE_3_0) { 3192 link_rate == MPI_SAS_IOUNIT0_RATE_3_0) {
3155 3193
3156 if (!port_info) 3194 if (!port_info) {
3195 if (ioc->old_sas_discovery_protocal) {
3196 port_info = mptsas_expander_add(ioc,
3197 le16_to_cpu(link_data->DevHandle));
3198 if (port_info)
3199 goto out;
3200 }
3157 goto out; 3201 goto out;
3202 }
3158 3203
3159 if (port_info == ioc->hba_port_info) 3204 if (port_info == ioc->hba_port_info)
3160 mptsas_probe_hba_phys(ioc); 3205 mptsas_probe_hba_phys(ioc);
@@ -3176,6 +3221,121 @@ mptsas_send_link_status_event(struct fw_event_work *fw_event)
3176 mptsas_free_fw_event(ioc, fw_event); 3221 mptsas_free_fw_event(ioc, fw_event);
3177} 3222}
3178 3223
3224static void
3225mptsas_not_responding_devices(MPT_ADAPTER *ioc)
3226{
3227 struct mptsas_portinfo buffer, *port_info;
3228 struct mptsas_device_info *sas_info;
3229 struct mptsas_devinfo sas_device;
3230 u32 handle;
3231 VirtTarget *vtarget = NULL;
3232 struct mptsas_phyinfo *phy_info;
3233 u8 found_expander;
3234 int retval, retry_count;
3235 unsigned long flags;
3236
3237 mpt_findImVolumes(ioc);
3238
3239 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3240 if (ioc->ioc_reset_in_progress) {
3241 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3242 "%s: exiting due to a parallel reset \n", ioc->name,
3243 __func__));
3244 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3245 return;
3246 }
3247 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3248
3249 /* devices, logical volumes */
3250 mutex_lock(&ioc->sas_device_info_mutex);
3251 redo_device_scan:
3252 list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) {
3253 sas_device.handle = 0;
3254 retry_count = 0;
3255retry_page:
3256 retval = mptsas_sas_device_pg0(ioc, &sas_device,
3257 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID
3258 << MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3259 (sas_info->fw.channel << 8) +
3260 sas_info->fw.id);
3261
3262 if (sas_device.handle)
3263 continue;
3264 if (retval == -EBUSY) {
3265 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3266 if (ioc->ioc_reset_in_progress) {
3267 dfailprintk(ioc,
3268 printk(MYIOC_s_DEBUG_FMT
3269 "%s: exiting due to reset\n",
3270 ioc->name, __func__));
3271 spin_unlock_irqrestore
3272 (&ioc->taskmgmt_lock, flags);
3273 mutex_unlock(&ioc->sas_device_info_mutex);
3274 return;
3275 }
3276 spin_unlock_irqrestore(&ioc->taskmgmt_lock,
3277 flags);
3278 }
3279
3280 if (retval && (retval != -ENODEV)) {
3281 if (retry_count < 10) {
3282 retry_count++;
3283 goto retry_page;
3284 } else {
3285 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3286 "%s: Config page retry exceeded retry "
3287 "count deleting device 0x%llx\n",
3288 ioc->name, __func__,
3289 sas_info->sas_address));
3290 }
3291 }
3292
3293 /* delete device */
3294 vtarget = mptsas_find_vtarget(ioc,
3295 sas_info->fw.channel, sas_info->fw.id);
3296 if (vtarget)
3297 vtarget->deleted = 1;
3298 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3299 sas_info->sas_address);
3300 if (phy_info) {
3301 mptsas_del_end_device(ioc, phy_info);
3302 goto redo_device_scan;
3303 }
3304 }
3305 mutex_unlock(&ioc->sas_device_info_mutex);
3306
3307 /* expanders */
3308 mutex_lock(&ioc->sas_topology_mutex);
3309 redo_expander_scan:
3310 list_for_each_entry(port_info, &ioc->sas_topology, list) {
3311
3312 if (port_info->phy_info &&
3313 (!(port_info->phy_info[0].identify.device_info &
3314 MPI_SAS_DEVICE_INFO_SMP_TARGET)))
3315 continue;
3316 found_expander = 0;
3317 handle = 0xFFFF;
3318 while (!mptsas_sas_expander_pg0(ioc, &buffer,
3319 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3320 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle) &&
3321 !found_expander) {
3322
3323 handle = buffer.phy_info[0].handle;
3324 if (buffer.phy_info[0].identify.sas_address ==
3325 port_info->phy_info[0].identify.sas_address) {
3326 found_expander = 1;
3327 }
3328 kfree(buffer.phy_info);
3329 }
3330
3331 if (!found_expander) {
3332 mptsas_expander_delete(ioc, port_info, 0);
3333 goto redo_expander_scan;
3334 }
3335 }
3336 mutex_lock(&ioc->sas_topology_mutex);
3337}
3338
3179/** 3339/**
3180 * mptsas_probe_expanders - adding expanders 3340 * mptsas_probe_expanders - adding expanders
3181 * @ioc: Pointer to MPT_ADAPTER structure 3341 * @ioc: Pointer to MPT_ADAPTER structure
@@ -3895,6 +4055,8 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
3895 MpiEventDataSasExpanderStatusChange_t *expander_data = 4055 MpiEventDataSasExpanderStatusChange_t *expander_data =
3896 (MpiEventDataSasExpanderStatusChange_t *)reply->Data; 4056 (MpiEventDataSasExpanderStatusChange_t *)reply->Data;
3897 4057
4058 if (ioc->old_sas_discovery_protocal)
4059 return 0;
3898 4060
3899 if (expander_data->ReasonCode == 4061 if (expander_data->ReasonCode ==
3900 MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING && 4062 MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING &&
@@ -3910,6 +4072,8 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
3910 4072
3911 discovery_status = le32_to_cpu(discovery_data->DiscoveryStatus); 4073 discovery_status = le32_to_cpu(discovery_data->DiscoveryStatus);
3912 ioc->sas_discovery_quiesce_io = discovery_status ? 1 : 0; 4074 ioc->sas_discovery_quiesce_io = discovery_status ? 1 : 0;
4075 if (ioc->old_sas_discovery_protocal && !discovery_status)
4076 mptsas_queue_rescan(ioc);
3913 return 0; 4077 return 0;
3914 } 4078 }
3915 case MPI_EVENT_INTEGRATED_RAID: 4079 case MPI_EVENT_INTEGRATED_RAID:
@@ -4117,6 +4281,9 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
4117 goto out_mptsas_probe; 4281 goto out_mptsas_probe;
4118 } 4282 }
4119 4283
4284 /* older firmware doesn't support expander events */
4285 if ((ioc->facts.HeaderVersion >> 8) < 0xE)
4286 ioc->old_sas_discovery_protocal = 1;
4120 mptsas_scan_sas_topology(ioc); 4287 mptsas_scan_sas_topology(ioc);
4121 mptsas_fw_event_on(ioc); 4288 mptsas_fw_event_on(ioc);
4122 return 0; 4289 return 0;