diff options
| author | David Woodhouse <dwmw2@infradead.org> | 2006-05-24 04:22:21 -0400 |
|---|---|---|
| committer | David Woodhouse <dwmw2@infradead.org> | 2006-05-24 04:22:21 -0400 |
| commit | 66643de455c27973ac31ad6de9f859d399916842 (patch) | |
| tree | 7ebed7f051879007d4b11d6aaa9e65a1bcb0b08f /drivers/message/fusion | |
| parent | 2c23d62abb820e19c54012520f08a198c2233a85 (diff) | |
| parent | 387e2b0439026aa738a9edca15a57e5c0bcb4dfc (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/fusion')
| -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 | } |
