aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-05-24 04:22:21 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-05-24 04:22:21 -0400
commit66643de455c27973ac31ad6de9f859d399916842 (patch)
tree7ebed7f051879007d4b11d6aaa9e65a1bcb0b08f /drivers/message
parent2c23d62abb820e19c54012520f08a198c2233a85 (diff)
parent387e2b0439026aa738a9edca15a57e5c0bcb4dfc (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: include/asm-powerpc/unistd.h include/asm-sparc/unistd.h include/asm-sparc64/unistd.h Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'drivers/message')
-rw-r--r--drivers/message/fusion/mptbase.c63
-rw-r--r--drivers/message/fusion/mptbase.h10
-rw-r--r--drivers/message/fusion/mptfc.c134
-rw-r--r--drivers/message/fusion/mptsas.c99
-rw-r--r--drivers/message/fusion/mptscsih.c50
-rw-r--r--drivers/message/fusion/mptspi.c68
6 files changed, 288 insertions, 136 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 266414ca2814..9080853fe283 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -1189,7 +1189,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1189 ioc->diagPending = 0; 1189 ioc->diagPending = 0;
1190 spin_lock_init(&ioc->diagLock); 1190 spin_lock_init(&ioc->diagLock);
1191 spin_lock_init(&ioc->fc_rescan_work_lock); 1191 spin_lock_init(&ioc->fc_rescan_work_lock);
1192 spin_lock_init(&ioc->fc_rport_lock);
1193 spin_lock_init(&ioc->initializing_hba_lock); 1192 spin_lock_init(&ioc->initializing_hba_lock);
1194 1193
1195 /* Initialize the event logging. 1194 /* Initialize the event logging.
@@ -5736,11 +5735,13 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5736 return rc; 5735 return rc;
5737} 5736}
5738 5737
5738# define EVENT_DESCR_STR_SZ 100
5739
5739/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5740/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5740static void 5741static void
5741EventDescriptionStr(u8 event, u32 evData0, char *evStr) 5742EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5742{ 5743{
5743 char *ds; 5744 char *ds = NULL;
5744 5745
5745 switch(event) { 5746 switch(event) {
5746 case MPI_EVENT_NONE: 5747 case MPI_EVENT_NONE:
@@ -5777,9 +5778,9 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5777 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP) 5778 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5778 ds = "Loop State(LIP) Change"; 5779 ds = "Loop State(LIP) Change";
5779 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE) 5780 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5780 ds = "Loop State(LPE) Change"; /* ??? */ 5781 ds = "Loop State(LPE) Change"; /* ??? */
5781 else 5782 else
5782 ds = "Loop State(LPB) Change"; /* ??? */ 5783 ds = "Loop State(LPB) Change"; /* ??? */
5783 break; 5784 break;
5784 case MPI_EVENT_LOGOUT: 5785 case MPI_EVENT_LOGOUT:
5785 ds = "Logout"; 5786 ds = "Logout";
@@ -5841,27 +5842,32 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5841 break; 5842 break;
5842 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: 5843 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5843 { 5844 {
5844 char buf[50];
5845 u8 id = (u8)(evData0); 5845 u8 id = (u8)(evData0);
5846 u8 ReasonCode = (u8)(evData0 >> 16); 5846 u8 ReasonCode = (u8)(evData0 >> 16);
5847 switch (ReasonCode) { 5847 switch (ReasonCode) {
5848 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: 5848 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
5849 sprintf(buf,"SAS Device Status Change: Added: id=%d", id); 5849 snprintf(evStr, EVENT_DESCR_STR_SZ,
5850 "SAS Device Status Change: Added: id=%d", id);
5850 break; 5851 break;
5851 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: 5852 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
5852 sprintf(buf,"SAS Device Status Change: Deleted: id=%d", id); 5853 snprintf(evStr, EVENT_DESCR_STR_SZ,
5854 "SAS Device Status Change: Deleted: id=%d", id);
5853 break; 5855 break;
5854 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: 5856 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
5855 sprintf(buf,"SAS Device Status Change: SMART Data: id=%d", id); 5857 snprintf(evStr, EVENT_DESCR_STR_SZ,
5858 "SAS Device Status Change: SMART Data: id=%d",
5859 id);
5856 break; 5860 break;
5857 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED: 5861 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
5858 sprintf(buf,"SAS Device Status Change: No Persistancy Added: id=%d", id); 5862 snprintf(evStr, EVENT_DESCR_STR_SZ,
5863 "SAS Device Status Change: No Persistancy "
5864 "Added: id=%d", id);
5859 break; 5865 break;
5860 default: 5866 default:
5861 sprintf(buf,"SAS Device Status Change: Unknown: id=%d", id); 5867 snprintf(evStr, EVENT_DESCR_STR_SZ,
5862 break; 5868 "SAS Device Status Change: Unknown: id=%d", id);
5869 break;
5863 } 5870 }
5864 ds = buf;
5865 break; 5871 break;
5866 } 5872 }
5867 case MPI_EVENT_ON_BUS_TIMER_EXPIRED: 5873 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
@@ -5878,41 +5884,46 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5878 break; 5884 break;
5879 case MPI_EVENT_SAS_PHY_LINK_STATUS: 5885 case MPI_EVENT_SAS_PHY_LINK_STATUS:
5880 { 5886 {
5881 char buf[50];
5882 u8 LinkRates = (u8)(evData0 >> 8); 5887 u8 LinkRates = (u8)(evData0 >> 8);
5883 u8 PhyNumber = (u8)(evData0); 5888 u8 PhyNumber = (u8)(evData0);
5884 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >> 5889 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
5885 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT; 5890 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
5886 switch (LinkRates) { 5891 switch (LinkRates) {
5887 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN: 5892 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
5888 sprintf(buf,"SAS PHY Link Status: Phy=%d:" 5893 snprintf(evStr, EVENT_DESCR_STR_SZ,
5894 "SAS PHY Link Status: Phy=%d:"
5889 " Rate Unknown",PhyNumber); 5895 " Rate Unknown",PhyNumber);
5890 break; 5896 break;
5891 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED: 5897 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
5892 sprintf(buf,"SAS PHY Link Status: Phy=%d:" 5898 snprintf(evStr, EVENT_DESCR_STR_SZ,
5899 "SAS PHY Link Status: Phy=%d:"
5893 " Phy Disabled",PhyNumber); 5900 " Phy Disabled",PhyNumber);
5894 break; 5901 break;
5895 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION: 5902 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
5896 sprintf(buf,"SAS PHY Link Status: Phy=%d:" 5903 snprintf(evStr, EVENT_DESCR_STR_SZ,
5904 "SAS PHY Link Status: Phy=%d:"
5897 " Failed Speed Nego",PhyNumber); 5905 " Failed Speed Nego",PhyNumber);
5898 break; 5906 break;
5899 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE: 5907 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
5900 sprintf(buf,"SAS PHY Link Status: Phy=%d:" 5908 snprintf(evStr, EVENT_DESCR_STR_SZ,
5909 "SAS PHY Link Status: Phy=%d:"
5901 " Sata OOB Completed",PhyNumber); 5910 " Sata OOB Completed",PhyNumber);
5902 break; 5911 break;
5903 case MPI_EVENT_SAS_PLS_LR_RATE_1_5: 5912 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
5904 sprintf(buf,"SAS PHY Link Status: Phy=%d:" 5913 snprintf(evStr, EVENT_DESCR_STR_SZ,
5914 "SAS PHY Link Status: Phy=%d:"
5905 " Rate 1.5 Gbps",PhyNumber); 5915 " Rate 1.5 Gbps",PhyNumber);
5906 break; 5916 break;
5907 case MPI_EVENT_SAS_PLS_LR_RATE_3_0: 5917 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
5908 sprintf(buf,"SAS PHY Link Status: Phy=%d:" 5918 snprintf(evStr, EVENT_DESCR_STR_SZ,
5919 "SAS PHY Link Status: Phy=%d:"
5909 " Rate 3.0 Gpbs",PhyNumber); 5920 " Rate 3.0 Gpbs",PhyNumber);
5910 break; 5921 break;
5911 default: 5922 default:
5912 sprintf(buf,"SAS PHY Link Status: Phy=%d", PhyNumber); 5923 snprintf(evStr, EVENT_DESCR_STR_SZ,
5924 "SAS PHY Link Status: Phy=%d", PhyNumber);
5913 break; 5925 break;
5914 } 5926 }
5915 ds = buf;
5916 break; 5927 break;
5917 } 5928 }
5918 case MPI_EVENT_SAS_DISCOVERY_ERROR: 5929 case MPI_EVENT_SAS_DISCOVERY_ERROR:
@@ -5921,9 +5932,8 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5921 case MPI_EVENT_IR_RESYNC_UPDATE: 5932 case MPI_EVENT_IR_RESYNC_UPDATE:
5922 { 5933 {
5923 u8 resync_complete = (u8)(evData0 >> 16); 5934 u8 resync_complete = (u8)(evData0 >> 16);
5924 char buf[40]; 5935 snprintf(evStr, EVENT_DESCR_STR_SZ,
5925 sprintf(buf,"IR Resync Update: Complete = %d:",resync_complete); 5936 "IR Resync Update: Complete = %d:",resync_complete);
5926 ds = buf;
5927 break; 5937 break;
5928 } 5938 }
5929 case MPI_EVENT_IR2: 5939 case MPI_EVENT_IR2:
@@ -5976,7 +5986,8 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5976 ds = "Unknown"; 5986 ds = "Unknown";
5977 break; 5987 break;
5978 } 5988 }
5979 strcpy(evStr,ds); 5989 if (ds)
5990 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
5980} 5991}
5981 5992
5982/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5993/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -5998,7 +6009,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
5998 int ii; 6009 int ii;
5999 int r = 0; 6010 int r = 0;
6000 int handlers = 0; 6011 int handlers = 0;
6001 char evStr[100]; 6012 char evStr[EVENT_DESCR_STR_SZ];
6002 u8 event; 6013 u8 event;
6003 6014
6004 /* 6015 /*
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index be7e8501b53c..f673cca507e1 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -76,8 +76,8 @@
76#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR 76#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
77#endif 77#endif
78 78
79#define MPT_LINUX_VERSION_COMMON "3.03.08" 79#define MPT_LINUX_VERSION_COMMON "3.03.09"
80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.08" 80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.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) \
@@ -489,7 +489,6 @@ typedef struct _RaidCfgData {
489 489
490#define MPT_RPORT_INFO_FLAGS_REGISTERED 0x01 /* rport registered */ 490#define MPT_RPORT_INFO_FLAGS_REGISTERED 0x01 /* rport registered */
491#define MPT_RPORT_INFO_FLAGS_MISSING 0x02 /* missing from DevPage0 scan */ 491#define MPT_RPORT_INFO_FLAGS_MISSING 0x02 /* missing from DevPage0 scan */
492#define MPT_RPORT_INFO_FLAGS_MAPPED_VDEV 0x04 /* target mapped in vdev */
493 492
494/* 493/*
495 * data allocated for each fc rport device 494 * data allocated for each fc rport device
@@ -501,7 +500,6 @@ struct mptfc_rport_info
501 struct scsi_target *starget; 500 struct scsi_target *starget;
502 FCDevicePage0_t pg0; 501 FCDevicePage0_t pg0;
503 u8 flags; 502 u8 flags;
504 u8 remap_needed;
505}; 503};
506 504
507/* 505/*
@@ -628,11 +626,11 @@ typedef struct _MPT_ADAPTER
628 struct work_struct mptscsih_persistTask; 626 struct work_struct mptscsih_persistTask;
629 627
630 struct list_head fc_rports; 628 struct list_head fc_rports;
631 spinlock_t fc_rport_lock; /* list and ri flags */
632 spinlock_t fc_rescan_work_lock; 629 spinlock_t fc_rescan_work_lock;
633 int fc_rescan_work_count; 630 int fc_rescan_work_count;
634 struct work_struct fc_rescan_work; 631 struct work_struct fc_rescan_work;
635 632 char fc_rescan_work_q_name[KOBJ_NAME_LEN];
633 struct workqueue_struct *fc_rescan_work_q;
636} MPT_ADAPTER; 634} MPT_ADAPTER;
637 635
638/* 636/*
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index b343f2a68b1c..856487741ef4 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -341,9 +341,6 @@ mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
341 rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low; 341 rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low;
342 rid->port_id = pg0->PortIdentifier; 342 rid->port_id = pg0->PortIdentifier;
343 rid->roles = FC_RPORT_ROLE_UNKNOWN; 343 rid->roles = FC_RPORT_ROLE_UNKNOWN;
344 rid->roles |= FC_RPORT_ROLE_FCP_TARGET;
345 if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR)
346 rid->roles |= FC_RPORT_ROLE_FCP_INITIATOR;
347 344
348 return 0; 345 return 0;
349} 346}
@@ -355,15 +352,18 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
355 struct fc_rport *rport; 352 struct fc_rport *rport;
356 struct mptfc_rport_info *ri; 353 struct mptfc_rport_info *ri;
357 int new_ri = 1; 354 int new_ri = 1;
358 u64 pn; 355 u64 pn, nn;
359 unsigned long flags;
360 VirtTarget *vtarget; 356 VirtTarget *vtarget;
357 u32 roles = FC_RPORT_ROLE_UNKNOWN;
361 358
362 if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0) 359 if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
363 return; 360 return;
364 361
362 roles |= FC_RPORT_ROLE_FCP_TARGET;
363 if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR)
364 roles |= FC_RPORT_ROLE_FCP_INITIATOR;
365
365 /* scan list looking for a match */ 366 /* scan list looking for a match */
366 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
367 list_for_each_entry(ri, &ioc->fc_rports, list) { 367 list_for_each_entry(ri, &ioc->fc_rports, list) {
368 pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low; 368 pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
369 if (pn == rport_ids.port_name) { /* match */ 369 if (pn == rport_ids.port_name) { /* match */
@@ -373,11 +373,9 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
373 } 373 }
374 } 374 }
375 if (new_ri) { /* allocate one */ 375 if (new_ri) { /* allocate one */
376 spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
377 ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL); 376 ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
378 if (!ri) 377 if (!ri)
379 return; 378 return;
380 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
381 list_add_tail(&ri->list, &ioc->fc_rports); 379 list_add_tail(&ri->list, &ioc->fc_rports);
382 } 380 }
383 381
@@ -387,14 +385,11 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
387 /* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */ 385 /* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */
388 if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) { 386 if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
389 ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED; 387 ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
390 spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
391 rport = fc_remote_port_add(ioc->sh, channel, &rport_ids); 388 rport = fc_remote_port_add(ioc->sh, channel, &rport_ids);
392 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
393 if (rport) { 389 if (rport) {
394 ri->rport = rport; 390 ri->rport = rport;
395 if (new_ri) /* may have been reset by user */ 391 if (new_ri) /* may have been reset by user */
396 rport->dev_loss_tmo = mptfc_dev_loss_tmo; 392 rport->dev_loss_tmo = mptfc_dev_loss_tmo;
397 *((struct mptfc_rport_info **)rport->dd_data) = ri;
398 /* 393 /*
399 * if already mapped, remap here. If not mapped, 394 * if already mapped, remap here. If not mapped,
400 * target_alloc will allocate vtarget and map, 395 * target_alloc will allocate vtarget and map,
@@ -406,16 +401,21 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
406 vtarget->target_id = pg0->CurrentTargetID; 401 vtarget->target_id = pg0->CurrentTargetID;
407 vtarget->bus_id = pg0->CurrentBus; 402 vtarget->bus_id = pg0->CurrentBus;
408 } 403 }
409 ri->remap_needed = 0;
410 } 404 }
405 *((struct mptfc_rport_info **)rport->dd_data) = ri;
406 /* scan will be scheduled once rport becomes a target */
407 fc_remote_port_rolechg(rport,roles);
408
409 pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
410 nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
411 dfcprintk ((MYIOC_s_INFO_FMT 411 dfcprintk ((MYIOC_s_INFO_FMT
412 "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, " 412 "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
413 "rport tid %d, tmo %d\n", 413 "rport tid %d, tmo %d\n",
414 ioc->name, 414 ioc->name,
415 ioc->sh->host_no, 415 ioc->sh->host_no,
416 pg0->PortIdentifier, 416 pg0->PortIdentifier,
417 pg0->WWNN, 417 (unsigned long long)nn,
418 pg0->WWPN, 418 (unsigned long long)pn,
419 pg0->CurrentTargetID, 419 pg0->CurrentTargetID,
420 ri->rport->scsi_target_id, 420 ri->rport->scsi_target_id,
421 ri->rport->dev_loss_tmo)); 421 ri->rport->dev_loss_tmo));
@@ -425,8 +425,6 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
425 ri = NULL; 425 ri = NULL;
426 } 426 }
427 } 427 }
428 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
429
430} 428}
431 429
432/* 430/*
@@ -476,7 +474,6 @@ mptfc_target_alloc(struct scsi_target *starget)
476 vtarget->target_id = ri->pg0.CurrentTargetID; 474 vtarget->target_id = ri->pg0.CurrentTargetID;
477 vtarget->bus_id = ri->pg0.CurrentBus; 475 vtarget->bus_id = ri->pg0.CurrentBus;
478 ri->starget = starget; 476 ri->starget = starget;
479 ri->remap_needed = 0;
480 rc = 0; 477 rc = 0;
481 } 478 }
482 } 479 }
@@ -502,10 +499,10 @@ mptfc_slave_alloc(struct scsi_device *sdev)
502 VirtDevice *vdev; 499 VirtDevice *vdev;
503 struct scsi_target *starget; 500 struct scsi_target *starget;
504 struct fc_rport *rport; 501 struct fc_rport *rport;
505 unsigned long flags;
506 502
507 503
508 rport = starget_to_rport(scsi_target(sdev)); 504 starget = scsi_target(sdev);
505 rport = starget_to_rport(starget);
509 506
510 if (!rport || fc_remote_port_chkready(rport)) 507 if (!rport || fc_remote_port_chkready(rport))
511 return -ENXIO; 508 return -ENXIO;
@@ -519,10 +516,8 @@ mptfc_slave_alloc(struct scsi_device *sdev)
519 return -ENOMEM; 516 return -ENOMEM;
520 } 517 }
521 518
522 spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags);
523 519
524 sdev->hostdata = vdev; 520 sdev->hostdata = vdev;
525 starget = scsi_target(sdev);
526 vtarget = starget->hostdata; 521 vtarget = starget->hostdata;
527 522
528 if (vtarget->num_luns == 0) { 523 if (vtarget->num_luns == 0) {
@@ -535,14 +530,16 @@ mptfc_slave_alloc(struct scsi_device *sdev)
535 vdev->vtarget = vtarget; 530 vdev->vtarget = vtarget;
536 vdev->lun = sdev->lun; 531 vdev->lun = sdev->lun;
537 532
538 spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
539
540 vtarget->num_luns++; 533 vtarget->num_luns++;
541 534
535
542#ifdef DMPT_DEBUG_FC 536#ifdef DMPT_DEBUG_FC
543 { 537 {
538 u64 nn, pn;
544 struct mptfc_rport_info *ri; 539 struct mptfc_rport_info *ri;
545 ri = *((struct mptfc_rport_info **)rport->dd_data); 540 ri = *((struct mptfc_rport_info **)rport->dd_data);
541 pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
542 nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
546 dfcprintk ((MYIOC_s_INFO_FMT 543 dfcprintk ((MYIOC_s_INFO_FMT
547 "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, " 544 "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
548 "CurrentTargetID %d, %x %llx %llx\n", 545 "CurrentTargetID %d, %x %llx %llx\n",
@@ -550,7 +547,9 @@ mptfc_slave_alloc(struct scsi_device *sdev)
550 sdev->host->host_no, 547 sdev->host->host_no,
551 vtarget->num_luns, 548 vtarget->num_luns,
552 sdev->id, ri->pg0.CurrentTargetID, 549 sdev->id, ri->pg0.CurrentTargetID,
553 ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN)); 550 ri->pg0.PortIdentifier,
551 (unsigned long long)pn,
552 (unsigned long long)nn));
554 } 553 }
555#endif 554#endif
556 555
@@ -570,11 +569,31 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
570 done(SCpnt); 569 done(SCpnt);
571 return 0; 570 return 0;
572 } 571 }
572
573 /* dd_data is null until finished adding target */
573 ri = *((struct mptfc_rport_info **)rport->dd_data); 574 ri = *((struct mptfc_rport_info **)rport->dd_data);
574 if (unlikely(ri->remap_needed)) 575 if (unlikely(!ri)) {
575 return SCSI_MLQUEUE_HOST_BUSY; 576 dfcprintk ((MYIOC_s_INFO_FMT
577 "mptfc_qcmd.%d: %d:%d, dd_data is null.\n",
578 ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name,
579 ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no,
580 SCpnt->device->id,SCpnt->device->lun));
581 SCpnt->result = DID_IMM_RETRY << 16;
582 done(SCpnt);
583 return 0;
584 }
576 585
577 return mptscsih_qcmd(SCpnt,done); 586 err = mptscsih_qcmd(SCpnt,done);
587#ifdef DMPT_DEBUG_FC
588 if (unlikely(err)) {
589 dfcprintk ((MYIOC_s_INFO_FMT
590 "mptfc_qcmd.%d: %d:%d, mptscsih_qcmd returns non-zero.\n",
591 ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name,
592 ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no,
593 SCpnt->device->id,SCpnt->device->lun));
594 }
595#endif
596 return err;
578} 597}
579 598
580static void 599static void
@@ -615,18 +634,17 @@ mptfc_rescan_devices(void *arg)
615 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; 634 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
616 int ii; 635 int ii;
617 int work_to_do; 636 int work_to_do;
637 u64 pn;
618 unsigned long flags; 638 unsigned long flags;
619 struct mptfc_rport_info *ri; 639 struct mptfc_rport_info *ri;
620 640
621 do { 641 do {
622 /* start by tagging all ports as missing */ 642 /* start by tagging all ports as missing */
623 spin_lock_irqsave(&ioc->fc_rport_lock,flags);
624 list_for_each_entry(ri, &ioc->fc_rports, list) { 643 list_for_each_entry(ri, &ioc->fc_rports, list) {
625 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) { 644 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
626 ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING; 645 ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
627 } 646 }
628 } 647 }
629 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
630 648
631 /* 649 /*
632 * now rescan devices known to adapter, 650 * now rescan devices known to adapter,
@@ -639,33 +657,24 @@ mptfc_rescan_devices(void *arg)
639 } 657 }
640 658
641 /* delete devices still missing */ 659 /* delete devices still missing */
642 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
643 list_for_each_entry(ri, &ioc->fc_rports, list) { 660 list_for_each_entry(ri, &ioc->fc_rports, list) {
644 /* if newly missing, delete it */ 661 /* if newly missing, delete it */
645 if ((ri->flags & (MPT_RPORT_INFO_FLAGS_REGISTERED | 662 if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
646 MPT_RPORT_INFO_FLAGS_MISSING))
647 == (MPT_RPORT_INFO_FLAGS_REGISTERED |
648 MPT_RPORT_INFO_FLAGS_MISSING)) {
649 663
650 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED| 664 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
651 MPT_RPORT_INFO_FLAGS_MISSING); 665 MPT_RPORT_INFO_FLAGS_MISSING);
652 ri->remap_needed = 1; 666 fc_remote_port_delete(ri->rport); /* won't sleep */
653 fc_remote_port_delete(ri->rport);
654 /*
655 * remote port not really deleted 'cause
656 * binding is by WWPN and driver only
657 * registers FCP_TARGETs but cannot trust
658 * data structures.
659 */
660 ri->rport = NULL; 667 ri->rport = NULL;
668
669 pn = (u64)ri->pg0.WWPN.High << 32 |
670 (u64)ri->pg0.WWPN.Low;
661 dfcprintk ((MYIOC_s_INFO_FMT 671 dfcprintk ((MYIOC_s_INFO_FMT
662 "mptfc_rescan.%d: %llx deleted\n", 672 "mptfc_rescan.%d: %llx deleted\n",
663 ioc->name, 673 ioc->name,
664 ioc->sh->host_no, 674 ioc->sh->host_no,
665 ri->pg0.WWPN)); 675 (unsigned long long)pn));
666 } 676 }
667 } 677 }
668 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
669 678
670 /* 679 /*
671 * allow multiple passes as target state 680 * allow multiple passes as target state
@@ -870,10 +879,23 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
870 goto out_mptfc_probe; 879 goto out_mptfc_probe;
871 } 880 }
872 881
873 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { 882 /* initialize workqueue */
874 mptfc_init_host_attr(ioc,ii); 883
875 mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev); 884 snprintf(ioc->fc_rescan_work_q_name, KOBJ_NAME_LEN, "mptfc_wq_%d",
876 } 885 sh->host_no);
886 ioc->fc_rescan_work_q =
887 create_singlethread_workqueue(ioc->fc_rescan_work_q_name);
888 if (!ioc->fc_rescan_work_q)
889 goto out_mptfc_probe;
890
891 /*
892 * scan for rports -
893 * by doing it via the workqueue, some locking is eliminated
894 */
895
896 ioc->fc_rescan_work_count = 1;
897 queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
898 flush_workqueue(ioc->fc_rescan_work_q);
877 899
878 return 0; 900 return 0;
879 901
@@ -949,8 +971,18 @@ mptfc_init(void)
949static void __devexit 971static void __devexit
950mptfc_remove(struct pci_dev *pdev) 972mptfc_remove(struct pci_dev *pdev)
951{ 973{
952 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 974 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
953 struct mptfc_rport_info *p, *n; 975 struct mptfc_rport_info *p, *n;
976 struct workqueue_struct *work_q;
977 unsigned long flags;
978
979 /* destroy workqueue */
980 if ((work_q=ioc->fc_rescan_work_q)) {
981 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
982 ioc->fc_rescan_work_q = NULL;
983 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
984 destroy_workqueue(work_q);
985 }
954 986
955 fc_remove_host(ioc->sh); 987 fc_remove_host(ioc->sh);
956 988
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index e9716b10acea..af6ec553ff7c 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -91,6 +91,7 @@ enum mptsas_hotplug_action {
91 MPTSAS_DEL_DEVICE, 91 MPTSAS_DEL_DEVICE,
92 MPTSAS_ADD_RAID, 92 MPTSAS_ADD_RAID,
93 MPTSAS_DEL_RAID, 93 MPTSAS_DEL_RAID,
94 MPTSAS_IGNORE_EVENT,
94}; 95};
95 96
96struct mptsas_hotplug_event { 97struct mptsas_hotplug_event {
@@ -298,6 +299,26 @@ mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
298 return rc; 299 return rc;
299} 300}
300 301
302/*
303 * Returns true if there is a scsi end device
304 */
305static inline int
306mptsas_is_end_device(struct mptsas_devinfo * attached)
307{
308 if ((attached->handle) &&
309 (attached->device_info &
310 MPI_SAS_DEVICE_INFO_END_DEVICE) &&
311 ((attached->device_info &
312 MPI_SAS_DEVICE_INFO_SSP_TARGET) |
313 (attached->device_info &
314 MPI_SAS_DEVICE_INFO_STP_TARGET) |
315 (attached->device_info &
316 MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
317 return 1;
318 else
319 return 0;
320}
321
301static int 322static int
302mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure, 323mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
303 u32 form, u32 form_specific) 324 u32 form, u32 form_specific)
@@ -872,7 +893,11 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
872 SasDevicePage0_t *buffer; 893 SasDevicePage0_t *buffer;
873 dma_addr_t dma_handle; 894 dma_addr_t dma_handle;
874 __le64 sas_address; 895 __le64 sas_address;
875 int error; 896 int error=0;
897
898 if (ioc->sas_discovery_runtime &&
899 mptsas_is_end_device(device_info))
900 goto out;
876 901
877 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION; 902 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
878 hdr.ExtPageLength = 0; 903 hdr.ExtPageLength = 0;
@@ -1009,7 +1034,11 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1009 CONFIGPARMS cfg; 1034 CONFIGPARMS cfg;
1010 SasExpanderPage1_t *buffer; 1035 SasExpanderPage1_t *buffer;
1011 dma_addr_t dma_handle; 1036 dma_addr_t dma_handle;
1012 int error; 1037 int error=0;
1038
1039 if (ioc->sas_discovery_runtime &&
1040 mptsas_is_end_device(&phy_info->attached))
1041 goto out;
1013 1042
1014 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION; 1043 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1015 hdr.ExtPageLength = 0; 1044 hdr.ExtPageLength = 0;
@@ -1068,26 +1097,6 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1068 return error; 1097 return error;
1069} 1098}
1070 1099
1071/*
1072 * Returns true if there is a scsi end device
1073 */
1074static inline int
1075mptsas_is_end_device(struct mptsas_devinfo * attached)
1076{
1077 if ((attached->handle) &&
1078 (attached->device_info &
1079 MPI_SAS_DEVICE_INFO_END_DEVICE) &&
1080 ((attached->device_info &
1081 MPI_SAS_DEVICE_INFO_SSP_TARGET) |
1082 (attached->device_info &
1083 MPI_SAS_DEVICE_INFO_STP_TARGET) |
1084 (attached->device_info &
1085 MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
1086 return 1;
1087 else
1088 return 0;
1089}
1090
1091static void 1100static void
1092mptsas_parse_device_info(struct sas_identify *identify, 1101mptsas_parse_device_info(struct sas_identify *identify,
1093 struct mptsas_devinfo *device_info) 1102 struct mptsas_devinfo *device_info)
@@ -1737,6 +1746,9 @@ mptsas_hotplug_work(void *arg)
1737 break; 1746 break;
1738 case MPTSAS_ADD_DEVICE: 1747 case MPTSAS_ADD_DEVICE:
1739 1748
1749 if (ev->phys_disk_num_valid)
1750 mpt_findImVolumes(ioc);
1751
1740 /* 1752 /*
1741 * Refresh sas device pg0 data 1753 * Refresh sas device pg0 data
1742 */ 1754 */
@@ -1868,6 +1880,9 @@ mptsas_hotplug_work(void *arg)
1868 scsi_device_put(sdev); 1880 scsi_device_put(sdev);
1869 mpt_findImVolumes(ioc); 1881 mpt_findImVolumes(ioc);
1870 break; 1882 break;
1883 case MPTSAS_IGNORE_EVENT:
1884 default:
1885 break;
1871 } 1886 }
1872 1887
1873 kfree(ev); 1888 kfree(ev);
@@ -1940,7 +1955,8 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc,
1940 EVENT_DATA_RAID *raid_event_data) 1955 EVENT_DATA_RAID *raid_event_data)
1941{ 1956{
1942 struct mptsas_hotplug_event *ev; 1957 struct mptsas_hotplug_event *ev;
1943 RAID_VOL0_STATUS * volumeStatus; 1958 int status = le32_to_cpu(raid_event_data->SettingsStatus);
1959 int state = (status >> 8) & 0xff;
1944 1960
1945 if (ioc->bus_type != SAS) 1961 if (ioc->bus_type != SAS)
1946 return; 1962 return;
@@ -1955,6 +1971,7 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc,
1955 INIT_WORK(&ev->work, mptsas_hotplug_work, ev); 1971 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1956 ev->ioc = ioc; 1972 ev->ioc = ioc;
1957 ev->id = raid_event_data->VolumeID; 1973 ev->id = raid_event_data->VolumeID;
1974 ev->event_type = MPTSAS_IGNORE_EVENT;
1958 1975
1959 switch (raid_event_data->ReasonCode) { 1976 switch (raid_event_data->ReasonCode) {
1960 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED: 1977 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
@@ -1966,6 +1983,25 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc,
1966 ev->phys_disk_num = raid_event_data->PhysDiskNum; 1983 ev->phys_disk_num = raid_event_data->PhysDiskNum;
1967 ev->event_type = MPTSAS_DEL_DEVICE; 1984 ev->event_type = MPTSAS_DEL_DEVICE;
1968 break; 1985 break;
1986 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
1987 switch (state) {
1988 case MPI_PD_STATE_ONLINE:
1989 ioc->raid_data.isRaid = 1;
1990 ev->phys_disk_num_valid = 1;
1991 ev->phys_disk_num = raid_event_data->PhysDiskNum;
1992 ev->event_type = MPTSAS_ADD_DEVICE;
1993 break;
1994 case MPI_PD_STATE_MISSING:
1995 case MPI_PD_STATE_NOT_COMPATIBLE:
1996 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
1997 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
1998 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
1999 ev->event_type = MPTSAS_DEL_DEVICE;
2000 break;
2001 default:
2002 break;
2003 }
2004 break;
1969 case MPI_EVENT_RAID_RC_VOLUME_DELETED: 2005 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
1970 ev->event_type = MPTSAS_DEL_RAID; 2006 ev->event_type = MPTSAS_DEL_RAID;
1971 break; 2007 break;
@@ -1973,11 +2009,18 @@ mptscsih_send_raid_event(MPT_ADAPTER *ioc,
1973 ev->event_type = MPTSAS_ADD_RAID; 2009 ev->event_type = MPTSAS_ADD_RAID;
1974 break; 2010 break;
1975 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED: 2011 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
1976 volumeStatus = (RAID_VOL0_STATUS *) & 2012 switch (state) {
1977 raid_event_data->SettingsStatus; 2013 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
1978 ev->event_type = (volumeStatus->State == 2014 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
1979 MPI_RAIDVOL0_STATUS_STATE_FAILED) ? 2015 ev->event_type = MPTSAS_DEL_RAID;
1980 MPTSAS_DEL_RAID : MPTSAS_ADD_RAID; 2016 break;
2017 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
2018 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
2019 ev->event_type = MPTSAS_ADD_RAID;
2020 break;
2021 default:
2022 break;
2023 }
1981 break; 2024 break;
1982 default: 2025 default:
1983 break; 2026 break;
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 3729062db317..84fa271eb8f4 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -632,7 +632,11 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
632 632
633 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */ 633 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
634 /* Spoof to SCSI Selection Timeout! */ 634 /* Spoof to SCSI Selection Timeout! */
635 sc->result = DID_NO_CONNECT << 16; 635 if (ioc->bus_type != FC)
636 sc->result = DID_NO_CONNECT << 16;
637 /* else fibre, just stall until rescan event */
638 else
639 sc->result = DID_REQUEUE << 16;
636 640
637 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF) 641 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
638 hd->sel_timeout[pScsiReq->TargetID]++; 642 hd->sel_timeout[pScsiReq->TargetID]++;
@@ -877,7 +881,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
877 struct scsi_cmnd *sc; 881 struct scsi_cmnd *sc;
878 882
879 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", 883 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
880 vdevice->target_id, vdevice->lun, max)); 884 vdevice->vtarget->target_id, vdevice->lun, max));
881 885
882 for (ii=0; ii < max; ii++) { 886 for (ii=0; ii < max; ii++) {
883 if ((sc = hd->ScsiLookup[ii]) != NULL) { 887 if ((sc = hd->ScsiLookup[ii]) != NULL) {
@@ -1645,7 +1649,6 @@ int
1645mptscsih_abort(struct scsi_cmnd * SCpnt) 1649mptscsih_abort(struct scsi_cmnd * SCpnt)
1646{ 1650{
1647 MPT_SCSI_HOST *hd; 1651 MPT_SCSI_HOST *hd;
1648 MPT_ADAPTER *ioc;
1649 MPT_FRAME_HDR *mf; 1652 MPT_FRAME_HDR *mf;
1650 u32 ctx2abort; 1653 u32 ctx2abort;
1651 int scpnt_idx; 1654 int scpnt_idx;
@@ -1663,14 +1666,6 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1663 return FAILED; 1666 return FAILED;
1664 } 1667 }
1665 1668
1666 ioc = hd->ioc;
1667 if (hd->resetPending) {
1668 return FAILED;
1669 }
1670
1671 if (hd->timeouts < -1)
1672 hd->timeouts++;
1673
1674 /* Find this command 1669 /* Find this command
1675 */ 1670 */
1676 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) { 1671 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
@@ -1684,6 +1679,13 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1684 return SUCCESS; 1679 return SUCCESS;
1685 } 1680 }
1686 1681
1682 if (hd->resetPending) {
1683 return FAILED;
1684 }
1685
1686 if (hd->timeouts < -1)
1687 hd->timeouts++;
1688
1687 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n", 1689 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1688 hd->ioc->name, SCpnt); 1690 hd->ioc->name, SCpnt);
1689 scsi_print_command(SCpnt); 1691 scsi_print_command(SCpnt);
@@ -1703,7 +1705,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1703 vdev = SCpnt->device->hostdata; 1705 vdev = SCpnt->device->hostdata;
1704 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, 1706 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1705 vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun, 1707 vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun,
1706 ctx2abort, mptscsih_get_tm_timeout(ioc)); 1708 ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
1707 1709
1708 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", 1710 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1709 hd->ioc->name, 1711 hd->ioc->name,
@@ -2521,15 +2523,15 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2521 2523
2522 /* 7. FC: Rescan for blocked rports which might have returned. 2524 /* 7. FC: Rescan for blocked rports which might have returned.
2523 */ 2525 */
2524 else if (ioc->bus_type == FC) { 2526 if (ioc->bus_type == FC) {
2525 int work_count;
2526 unsigned long flags;
2527
2528 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); 2527 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2529 work_count = ++ioc->fc_rescan_work_count; 2528 if (ioc->fc_rescan_work_q) {
2529 if (ioc->fc_rescan_work_count++ == 0) {
2530 queue_work(ioc->fc_rescan_work_q,
2531 &ioc->fc_rescan_work);
2532 }
2533 }
2530 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); 2534 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2531 if (work_count == 1)
2532 schedule_work(&ioc->fc_rescan_work);
2533 } 2535 }
2534 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name)); 2536 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2535 2537
@@ -2544,7 +2546,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2544{ 2546{
2545 MPT_SCSI_HOST *hd; 2547 MPT_SCSI_HOST *hd;
2546 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; 2548 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2547 int work_count;
2548 unsigned long flags; 2549 unsigned long flags;
2549 2550
2550 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", 2551 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
@@ -2569,10 +2570,13 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2569 2570
2570 case MPI_EVENT_RESCAN: /* 06 */ 2571 case MPI_EVENT_RESCAN: /* 06 */
2571 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); 2572 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2572 work_count = ++ioc->fc_rescan_work_count; 2573 if (ioc->fc_rescan_work_q) {
2574 if (ioc->fc_rescan_work_count++ == 0) {
2575 queue_work(ioc->fc_rescan_work_q,
2576 &ioc->fc_rescan_work);
2577 }
2578 }
2573 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); 2579 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2574 if (work_count == 1)
2575 schedule_work(&ioc->fc_rescan_work);
2576 break; 2580 break;
2577 2581
2578 /* 2582 /*
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 09c745b19cc8..f2a4d382ea19 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -783,6 +783,70 @@ static struct pci_device_id mptspi_pci_table[] = {
783}; 783};
784MODULE_DEVICE_TABLE(pci, mptspi_pci_table); 784MODULE_DEVICE_TABLE(pci, mptspi_pci_table);
785 785
786
787/*
788 * renegotiate for a given target
789 */
790static void
791mptspi_dv_renegotiate_work(void *data)
792{
793 struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data;
794 struct _MPT_SCSI_HOST *hd = wqw->hd;
795 struct scsi_device *sdev;
796
797 kfree(wqw);
798
799 shost_for_each_device(sdev, hd->ioc->sh)
800 mptspi_dv_device(hd, sdev);
801}
802
803static void
804mptspi_dv_renegotiate(struct _MPT_SCSI_HOST *hd)
805{
806 struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC);
807
808 if (!wqw)
809 return;
810
811 INIT_WORK(&wqw->work, mptspi_dv_renegotiate_work, wqw);
812 wqw->hd = hd;
813
814 schedule_work(&wqw->work);
815}
816
817/*
818 * spi module reset handler
819 */
820static int
821mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
822{
823 struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata;
824 int rc;
825
826 rc = mptscsih_ioc_reset(ioc, reset_phase);
827
828 if (reset_phase == MPT_IOC_POST_RESET)
829 mptspi_dv_renegotiate(hd);
830
831 return rc;
832}
833
834/*
835 * spi module resume handler
836 */
837static int
838mptspi_resume(struct pci_dev *pdev)
839{
840 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
841 struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata;
842 int rc;
843
844 rc = mptscsih_resume(pdev);
845 mptspi_dv_renegotiate(hd);
846
847 return rc;
848}
849
786/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 850/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
787/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 851/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
788/* 852/*
@@ -1032,7 +1096,7 @@ static struct pci_driver mptspi_driver = {
1032 .shutdown = mptscsih_shutdown, 1096 .shutdown = mptscsih_shutdown,
1033#ifdef CONFIG_PM 1097#ifdef CONFIG_PM
1034 .suspend = mptscsih_suspend, 1098 .suspend = mptscsih_suspend,
1035 .resume = mptscsih_resume, 1099 .resume = mptspi_resume,
1036#endif 1100#endif
1037}; 1101};
1038 1102
@@ -1061,7 +1125,7 @@ mptspi_init(void)
1061 ": Registered for IOC event notifications\n")); 1125 ": Registered for IOC event notifications\n"));
1062 } 1126 }
1063 1127
1064 if (mpt_reset_register(mptspiDoneCtx, mptscsih_ioc_reset) == 0) { 1128 if (mpt_reset_register(mptspiDoneCtx, mptspi_ioc_reset) == 0) {
1065 dprintk((KERN_INFO MYNAM 1129 dprintk((KERN_INFO MYNAM
1066 ": Registered for IOC reset notifications\n")); 1130 ": Registered for IOC reset notifications\n"));
1067 } 1131 }