diff options
Diffstat (limited to 'drivers/message')
-rw-r--r-- | drivers/message/fusion/mptbase.c | 63 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.h | 10 | ||||
-rw-r--r-- | drivers/message/fusion/mptfc.c | 134 | ||||
-rw-r--r-- | drivers/message/fusion/mptsas.c | 99 | ||||
-rw-r--r-- | drivers/message/fusion/mptscsih.c | 50 | ||||
-rw-r--r-- | drivers/message/fusion/mptspi.c | 68 |
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 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
5740 | static void | 5741 | static void |
5741 | EventDescriptionStr(u8 event, u32 evData0, char *evStr) | 5742 | EventDescriptionStr(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 | ||
580 | static void | 599 | static 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) | |||
949 | static void __devexit | 971 | static void __devexit |
950 | mptfc_remove(struct pci_dev *pdev) | 972 | mptfc_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 | ||
96 | struct mptsas_hotplug_event { | 97 | struct 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 | */ | ||
305 | static inline int | ||
306 | mptsas_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 | |||
301 | static int | 322 | static int |
302 | mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure, | 323 | mptsas_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 | */ | ||
1074 | static inline int | ||
1075 | mptsas_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 | |||
1091 | static void | 1100 | static void |
1092 | mptsas_parse_device_info(struct sas_identify *identify, | 1101 | mptsas_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 | |||
1645 | mptscsih_abort(struct scsi_cmnd * SCpnt) | 1649 | mptscsih_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 | }; |
784 | MODULE_DEVICE_TABLE(pci, mptspi_pci_table); | 784 | MODULE_DEVICE_TABLE(pci, mptspi_pci_table); |
785 | 785 | ||
786 | |||
787 | /* | ||
788 | * renegotiate for a given target | ||
789 | */ | ||
790 | static void | ||
791 | mptspi_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 | |||
803 | static void | ||
804 | mptspi_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 | */ | ||
820 | static int | ||
821 | mptspi_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 | */ | ||
837 | static int | ||
838 | mptspi_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 | } |