diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 10:19:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 10:19:18 -0400 |
commit | 33cf23b0a535475aead57707cb9f4fe135a93544 (patch) | |
tree | 67e14f77f0eeab847a26a6cbfcb44eecb5fa2fda /drivers/message | |
parent | 7a9b149212f3716c598afe973b6261fd58453b7a (diff) | |
parent | 95bb335c0ebe96afe926387a1ef3a096bd884a82 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (182 commits)
[SCSI] aacraid: add an ifdef'd device delete case instead of taking the device offline
[SCSI] aacraid: prohibit access to array container space
[SCSI] aacraid: add support for handling ATA pass-through commands.
[SCSI] aacraid: expose physical devices for models with newer firmware
[SCSI] aacraid: respond automatically to volumes added by config tool
[SCSI] fcoe: fix fcoe module ref counting
[SCSI] libfcoe: FIP Keep-Alive messages for VPorts are sent with incorrect port_id and wwn
[SCSI] libfcoe: Fix incorrect MAC address clearing
[SCSI] fcoe: fix a circular locking issue with rtnl and sysfs mutex
[SCSI] libfc: Move the port_id into lport
[SCSI] fcoe: move link speed checking into its own routine
[SCSI] libfc: Remove extra pointer check
[SCSI] libfc: Remove unused fc_get_host_port_type
[SCSI] fcoe: fixes wrong error exit in fcoe_create
[SCSI] libfc: set seq_id for incoming sequence
[SCSI] qla2xxx: Updates to ISP82xx support.
[SCSI] qla2xxx: Optionally disable target reset.
[SCSI] qla2xxx: ensure flash operation and host reset via sg_reset are mutually exclusive
[SCSI] qla2xxx: Silence bogus warning by gcc for wrap and did.
[SCSI] qla2xxx: T10 DIF support added.
...
Diffstat (limited to 'drivers/message')
-rw-r--r-- | drivers/message/fusion/mptbase.c | 177 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.h | 5 | ||||
-rw-r--r-- | drivers/message/fusion/mptctl.c | 181 | ||||
-rw-r--r-- | drivers/message/fusion/mptfc.c | 22 | ||||
-rw-r--r-- | drivers/message/fusion/mptsas.c | 55 | ||||
-rw-r--r-- | drivers/message/fusion/mptsas.h | 2 | ||||
-rw-r--r-- | drivers/message/fusion/mptscsih.c | 27 | ||||
-rw-r--r-- | drivers/message/fusion/mptspi.c | 10 |
8 files changed, 370 insertions, 109 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 5382b5a44aff..a6a57011ba6c 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -5064,7 +5064,7 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode) | |||
5064 | if (!timeleft) { | 5064 | if (!timeleft) { |
5065 | printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n", | 5065 | printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n", |
5066 | ioc->name, __func__); | 5066 | ioc->name, __func__); |
5067 | mpt_HardResetHandler(ioc, CAN_SLEEP); | 5067 | mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); |
5068 | mpt_free_msg_frame(ioc, mf); | 5068 | mpt_free_msg_frame(ioc, mf); |
5069 | } | 5069 | } |
5070 | goto out; | 5070 | goto out; |
@@ -6456,10 +6456,15 @@ out: | |||
6456 | issue_hard_reset = 0; | 6456 | issue_hard_reset = 0; |
6457 | printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", | 6457 | printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", |
6458 | ioc->name, __func__); | 6458 | ioc->name, __func__); |
6459 | mpt_HardResetHandler(ioc, CAN_SLEEP); | 6459 | if (retry_count == 0) { |
6460 | if (mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP) != 0) | ||
6461 | retry_count++; | ||
6462 | } else | ||
6463 | mpt_HardResetHandler(ioc, CAN_SLEEP); | ||
6464 | |||
6460 | mpt_free_msg_frame(ioc, mf); | 6465 | mpt_free_msg_frame(ioc, mf); |
6461 | /* attempt one retry for a timed out command */ | 6466 | /* attempt one retry for a timed out command */ |
6462 | if (!retry_count) { | 6467 | if (retry_count < 2) { |
6463 | printk(MYIOC_s_INFO_FMT | 6468 | printk(MYIOC_s_INFO_FMT |
6464 | "Attempting Retry Config request" | 6469 | "Attempting Retry Config request" |
6465 | " type 0x%x, page 0x%x," | 6470 | " type 0x%x, page 0x%x," |
@@ -6904,6 +6909,172 @@ mpt_halt_firmware(MPT_ADAPTER *ioc) | |||
6904 | } | 6909 | } |
6905 | EXPORT_SYMBOL(mpt_halt_firmware); | 6910 | EXPORT_SYMBOL(mpt_halt_firmware); |
6906 | 6911 | ||
6912 | /** | ||
6913 | * mpt_SoftResetHandler - Issues a less expensive reset | ||
6914 | * @ioc: Pointer to MPT_ADAPTER structure | ||
6915 | * @sleepFlag: Indicates if sleep or schedule must be called. | ||
6916 | |||
6917 | * | ||
6918 | * Returns 0 for SUCCESS or -1 if FAILED. | ||
6919 | * | ||
6920 | * Message Unit Reset - instructs the IOC to reset the Reply Post and | ||
6921 | * Free FIFO's. All the Message Frames on Reply Free FIFO are discarded. | ||
6922 | * All posted buffers are freed, and event notification is turned off. | ||
6923 | * IOC doesnt reply to any outstanding request. This will transfer IOC | ||
6924 | * to READY state. | ||
6925 | **/ | ||
6926 | int | ||
6927 | mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag) | ||
6928 | { | ||
6929 | int rc; | ||
6930 | int ii; | ||
6931 | u8 cb_idx; | ||
6932 | unsigned long flags; | ||
6933 | u32 ioc_state; | ||
6934 | unsigned long time_count; | ||
6935 | |||
6936 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler Entered!\n", | ||
6937 | ioc->name)); | ||
6938 | |||
6939 | ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK; | ||
6940 | |||
6941 | if (mpt_fwfault_debug) | ||
6942 | mpt_halt_firmware(ioc); | ||
6943 | |||
6944 | if (ioc_state == MPI_IOC_STATE_FAULT || | ||
6945 | ioc_state == MPI_IOC_STATE_RESET) { | ||
6946 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT | ||
6947 | "skipping, either in FAULT or RESET state!\n", ioc->name)); | ||
6948 | return -1; | ||
6949 | } | ||
6950 | |||
6951 | if (ioc->bus_type == FC) { | ||
6952 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT | ||
6953 | "skipping, because the bus type is FC!\n", ioc->name)); | ||
6954 | return -1; | ||
6955 | } | ||
6956 | |||
6957 | spin_lock_irqsave(&ioc->taskmgmt_lock, flags); | ||
6958 | if (ioc->ioc_reset_in_progress) { | ||
6959 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); | ||
6960 | return -1; | ||
6961 | } | ||
6962 | ioc->ioc_reset_in_progress = 1; | ||
6963 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); | ||
6964 | |||
6965 | rc = -1; | ||
6966 | |||
6967 | for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { | ||
6968 | if (MptResetHandlers[cb_idx]) | ||
6969 | mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET); | ||
6970 | } | ||
6971 | |||
6972 | spin_lock_irqsave(&ioc->taskmgmt_lock, flags); | ||
6973 | if (ioc->taskmgmt_in_progress) { | ||
6974 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); | ||
6975 | return -1; | ||
6976 | } | ||
6977 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); | ||
6978 | /* Disable reply interrupts (also blocks FreeQ) */ | ||
6979 | CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); | ||
6980 | ioc->active = 0; | ||
6981 | time_count = jiffies; | ||
6982 | |||
6983 | rc = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag); | ||
6984 | |||
6985 | for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { | ||
6986 | if (MptResetHandlers[cb_idx]) | ||
6987 | mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET); | ||
6988 | } | ||
6989 | |||
6990 | if (rc) | ||
6991 | goto out; | ||
6992 | |||
6993 | ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK; | ||
6994 | if (ioc_state != MPI_IOC_STATE_READY) | ||
6995 | goto out; | ||
6996 | |||
6997 | for (ii = 0; ii < 5; ii++) { | ||
6998 | /* Get IOC facts! Allow 5 retries */ | ||
6999 | rc = GetIocFacts(ioc, sleepFlag, | ||
7000 | MPT_HOSTEVENT_IOC_RECOVER); | ||
7001 | if (rc == 0) | ||
7002 | break; | ||
7003 | if (sleepFlag == CAN_SLEEP) | ||
7004 | msleep(100); | ||
7005 | else | ||
7006 | mdelay(100); | ||
7007 | } | ||
7008 | if (ii == 5) | ||
7009 | goto out; | ||
7010 | |||
7011 | rc = PrimeIocFifos(ioc); | ||
7012 | if (rc != 0) | ||
7013 | goto out; | ||
7014 | |||
7015 | rc = SendIocInit(ioc, sleepFlag); | ||
7016 | if (rc != 0) | ||
7017 | goto out; | ||
7018 | |||
7019 | rc = SendEventNotification(ioc, 1, sleepFlag); | ||
7020 | if (rc != 0) | ||
7021 | goto out; | ||
7022 | |||
7023 | if (ioc->hard_resets < -1) | ||
7024 | ioc->hard_resets++; | ||
7025 | |||
7026 | /* | ||
7027 | * At this point, we know soft reset succeeded. | ||
7028 | */ | ||
7029 | |||
7030 | ioc->active = 1; | ||
7031 | CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM); | ||
7032 | |||
7033 | out: | ||
7034 | spin_lock_irqsave(&ioc->taskmgmt_lock, flags); | ||
7035 | ioc->ioc_reset_in_progress = 0; | ||
7036 | ioc->taskmgmt_quiesce_io = 0; | ||
7037 | ioc->taskmgmt_in_progress = 0; | ||
7038 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); | ||
7039 | |||
7040 | if (ioc->active) { /* otherwise, hard reset coming */ | ||
7041 | for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { | ||
7042 | if (MptResetHandlers[cb_idx]) | ||
7043 | mpt_signal_reset(cb_idx, ioc, | ||
7044 | MPT_IOC_POST_RESET); | ||
7045 | } | ||
7046 | } | ||
7047 | |||
7048 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT | ||
7049 | "SoftResetHandler: completed (%d seconds): %s\n", | ||
7050 | ioc->name, jiffies_to_msecs(jiffies - time_count)/1000, | ||
7051 | ((rc == 0) ? "SUCCESS" : "FAILED"))); | ||
7052 | |||
7053 | return rc; | ||
7054 | } | ||
7055 | |||
7056 | /** | ||
7057 | * mpt_Soft_Hard_ResetHandler - Try less expensive reset | ||
7058 | * @ioc: Pointer to MPT_ADAPTER structure | ||
7059 | * @sleepFlag: Indicates if sleep or schedule must be called. | ||
7060 | |||
7061 | * | ||
7062 | * Returns 0 for SUCCESS or -1 if FAILED. | ||
7063 | * Try for softreset first, only if it fails go for expensive | ||
7064 | * HardReset. | ||
7065 | **/ | ||
7066 | int | ||
7067 | mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag) { | ||
7068 | int ret = -1; | ||
7069 | |||
7070 | ret = mpt_SoftResetHandler(ioc, sleepFlag); | ||
7071 | if (ret == 0) | ||
7072 | return ret; | ||
7073 | ret = mpt_HardResetHandler(ioc, sleepFlag); | ||
7074 | return ret; | ||
7075 | } | ||
7076 | EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler); | ||
7077 | |||
6907 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 7078 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
6908 | /* | 7079 | /* |
6909 | * Reset Handling | 7080 | * Reset Handling |
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 9718c8f2e959..b613eb3d4706 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
@@ -76,8 +76,8 @@ | |||
76 | #define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR | 76 | #define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR |
77 | #endif | 77 | #endif |
78 | 78 | ||
79 | #define MPT_LINUX_VERSION_COMMON "3.04.14" | 79 | #define MPT_LINUX_VERSION_COMMON "3.04.15" |
80 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.14" | 80 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.15" |
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) \ |
@@ -940,6 +940,7 @@ extern int mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp); | |||
940 | extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked); | 940 | extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked); |
941 | extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); | 941 | extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); |
942 | extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); | 942 | extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); |
943 | extern int mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag); | ||
943 | extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); | 944 | extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); |
944 | extern int mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); | 945 | extern int mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); |
945 | extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); | 946 | extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); |
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index caa8f568a41c..f06b29193b4e 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c | |||
@@ -128,7 +128,6 @@ static MptSge_t *kbuf_alloc_2_sgl(int bytes, u32 dir, int sge_offset, int *frags | |||
128 | struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc); | 128 | struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc); |
129 | static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, | 129 | static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, |
130 | struct buflist *buflist, MPT_ADAPTER *ioc); | 130 | struct buflist *buflist, MPT_ADAPTER *ioc); |
131 | static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function); | ||
132 | 131 | ||
133 | /* | 132 | /* |
134 | * Reset Handler cleanup function | 133 | * Reset Handler cleanup function |
@@ -275,45 +274,6 @@ mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply) | |||
275 | return 1; | 274 | return 1; |
276 | } | 275 | } |
277 | 276 | ||
278 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
279 | /* mptctl_timeout_expired | ||
280 | * | ||
281 | * Expecting an interrupt, however timed out. | ||
282 | * | ||
283 | */ | ||
284 | static void | ||
285 | mptctl_timeout_expired(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) | ||
286 | { | ||
287 | unsigned long flags; | ||
288 | |||
289 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": %s\n", | ||
290 | ioc->name, __func__)); | ||
291 | |||
292 | if (mpt_fwfault_debug) | ||
293 | mpt_halt_firmware(ioc); | ||
294 | |||
295 | spin_lock_irqsave(&ioc->taskmgmt_lock, flags); | ||
296 | if (ioc->ioc_reset_in_progress) { | ||
297 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); | ||
298 | CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status) | ||
299 | mpt_free_msg_frame(ioc, mf); | ||
300 | return; | ||
301 | } | ||
302 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); | ||
303 | |||
304 | |||
305 | if (!mptctl_bus_reset(ioc, mf->u.hdr.Function)) | ||
306 | return; | ||
307 | |||
308 | /* Issue a reset for this device. | ||
309 | * The IOC is not responding. | ||
310 | */ | ||
311 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling HardReset! \n", | ||
312 | ioc->name)); | ||
313 | CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status) | ||
314 | mpt_HardResetHandler(ioc, CAN_SLEEP); | ||
315 | mpt_free_msg_frame(ioc, mf); | ||
316 | } | ||
317 | 277 | ||
318 | static int | 278 | static int |
319 | mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | 279 | mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) |
@@ -343,12 +303,8 @@ mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
343 | return 0; | 303 | return 0; |
344 | } | 304 | } |
345 | 305 | ||
346 | /* mptctl_bus_reset | 306 | static int |
347 | * | 307 | mptctl_do_taskmgmt(MPT_ADAPTER *ioc, u8 tm_type, u8 bus_id, u8 target_id) |
348 | * Bus reset code. | ||
349 | * | ||
350 | */ | ||
351 | static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function) | ||
352 | { | 308 | { |
353 | MPT_FRAME_HDR *mf; | 309 | MPT_FRAME_HDR *mf; |
354 | SCSITaskMgmt_t *pScsiTm; | 310 | SCSITaskMgmt_t *pScsiTm; |
@@ -359,13 +315,6 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function) | |||
359 | unsigned long time_count; | 315 | unsigned long time_count; |
360 | u16 iocstatus; | 316 | u16 iocstatus; |
361 | 317 | ||
362 | /* bus reset is only good for SCSI IO, RAID PASSTHRU */ | ||
363 | if (!(function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH || | ||
364 | function == MPI_FUNCTION_SCSI_IO_REQUEST)) { | ||
365 | dtmprintk(ioc, printk(MYIOC_s_WARN_FMT | ||
366 | "TaskMgmt, not SCSI_IO!!\n", ioc->name)); | ||
367 | return -EPERM; | ||
368 | } | ||
369 | 318 | ||
370 | mutex_lock(&ioc->taskmgmt_cmds.mutex); | 319 | mutex_lock(&ioc->taskmgmt_cmds.mutex); |
371 | if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) { | 320 | if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) { |
@@ -375,15 +324,14 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function) | |||
375 | 324 | ||
376 | retval = 0; | 325 | retval = 0; |
377 | 326 | ||
378 | /* Send request | ||
379 | */ | ||
380 | mf = mpt_get_msg_frame(mptctl_taskmgmt_id, ioc); | 327 | mf = mpt_get_msg_frame(mptctl_taskmgmt_id, ioc); |
381 | if (mf == NULL) { | 328 | if (mf == NULL) { |
382 | dtmprintk(ioc, printk(MYIOC_s_WARN_FMT | 329 | dtmprintk(ioc, |
383 | "TaskMgmt, no msg frames!!\n", ioc->name)); | 330 | printk(MYIOC_s_WARN_FMT "TaskMgmt, no msg frames!!\n", |
331 | ioc->name)); | ||
384 | mpt_clear_taskmgmt_in_progress_flag(ioc); | 332 | mpt_clear_taskmgmt_in_progress_flag(ioc); |
385 | retval = -ENOMEM; | 333 | retval = -ENOMEM; |
386 | goto mptctl_bus_reset_done; | 334 | goto tm_done; |
387 | } | 335 | } |
388 | 336 | ||
389 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n", | 337 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n", |
@@ -392,10 +340,13 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function) | |||
392 | pScsiTm = (SCSITaskMgmt_t *) mf; | 340 | pScsiTm = (SCSITaskMgmt_t *) mf; |
393 | memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t)); | 341 | memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t)); |
394 | pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; | 342 | pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; |
395 | pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS; | 343 | pScsiTm->TaskType = tm_type; |
396 | pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION; | 344 | if ((tm_type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && |
397 | pScsiTm->TargetID = 0; | 345 | (ioc->bus_type == FC)) |
398 | pScsiTm->Bus = 0; | 346 | pScsiTm->MsgFlags = |
347 | MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION; | ||
348 | pScsiTm->TargetID = target_id; | ||
349 | pScsiTm->Bus = bus_id; | ||
399 | pScsiTm->ChainOffset = 0; | 350 | pScsiTm->ChainOffset = 0; |
400 | pScsiTm->Reserved = 0; | 351 | pScsiTm->Reserved = 0; |
401 | pScsiTm->Reserved1 = 0; | 352 | pScsiTm->Reserved1 = 0; |
@@ -413,17 +364,16 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function) | |||
413 | timeout = 30; | 364 | timeout = 30; |
414 | break; | 365 | break; |
415 | case SPI: | 366 | case SPI: |
416 | default: | 367 | default: |
417 | timeout = 2; | 368 | timeout = 10; |
418 | break; | 369 | break; |
419 | } | 370 | } |
420 | 371 | ||
421 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT | 372 | dtmprintk(ioc, |
422 | "TaskMgmt type=%d timeout=%ld\n", | 373 | printk(MYIOC_s_DEBUG_FMT "TaskMgmt type=%d timeout=%ld\n", |
423 | ioc->name, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, timeout)); | 374 | ioc->name, tm_type, timeout)); |
424 | 375 | ||
425 | INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status) | 376 | INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status) |
426 | CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status) | ||
427 | time_count = jiffies; | 377 | time_count = jiffies; |
428 | if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) && | 378 | if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) && |
429 | (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) | 379 | (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) |
@@ -432,17 +382,20 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function) | |||
432 | retval = mpt_send_handshake_request(mptctl_taskmgmt_id, ioc, | 382 | retval = mpt_send_handshake_request(mptctl_taskmgmt_id, ioc, |
433 | sizeof(SCSITaskMgmt_t), (u32 *)pScsiTm, CAN_SLEEP); | 383 | sizeof(SCSITaskMgmt_t), (u32 *)pScsiTm, CAN_SLEEP); |
434 | if (retval != 0) { | 384 | if (retval != 0) { |
435 | dfailprintk(ioc, printk(MYIOC_s_ERR_FMT | 385 | dfailprintk(ioc, |
386 | printk(MYIOC_s_ERR_FMT | ||
436 | "TaskMgmt send_handshake FAILED!" | 387 | "TaskMgmt send_handshake FAILED!" |
437 | " (ioc %p, mf %p, rc=%d) \n", ioc->name, | 388 | " (ioc %p, mf %p, rc=%d) \n", ioc->name, |
438 | ioc, mf, retval)); | 389 | ioc, mf, retval)); |
390 | mpt_free_msg_frame(ioc, mf); | ||
439 | mpt_clear_taskmgmt_in_progress_flag(ioc); | 391 | mpt_clear_taskmgmt_in_progress_flag(ioc); |
440 | goto mptctl_bus_reset_done; | 392 | goto tm_done; |
441 | } | 393 | } |
442 | } | 394 | } |
443 | 395 | ||
444 | /* Now wait for the command to complete */ | 396 | /* Now wait for the command to complete */ |
445 | ii = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done, timeout*HZ); | 397 | ii = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done, timeout*HZ); |
398 | |||
446 | if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) { | 399 | if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) { |
447 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT | 400 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT |
448 | "TaskMgmt failed\n", ioc->name)); | 401 | "TaskMgmt failed\n", ioc->name)); |
@@ -452,14 +405,14 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function) | |||
452 | retval = 0; | 405 | retval = 0; |
453 | else | 406 | else |
454 | retval = -1; /* return failure */ | 407 | retval = -1; /* return failure */ |
455 | goto mptctl_bus_reset_done; | 408 | goto tm_done; |
456 | } | 409 | } |
457 | 410 | ||
458 | if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) { | 411 | if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) { |
459 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT | 412 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT |
460 | "TaskMgmt failed\n", ioc->name)); | 413 | "TaskMgmt failed\n", ioc->name)); |
461 | retval = -1; /* return failure */ | 414 | retval = -1; /* return failure */ |
462 | goto mptctl_bus_reset_done; | 415 | goto tm_done; |
463 | } | 416 | } |
464 | 417 | ||
465 | pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply; | 418 | pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply; |
@@ -467,7 +420,7 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function) | |||
467 | "TaskMgmt fw_channel = %d, fw_id = %d, task_type=0x%02X, " | 420 | "TaskMgmt fw_channel = %d, fw_id = %d, task_type=0x%02X, " |
468 | "iocstatus=0x%04X\n\tloginfo=0x%08X, response_code=0x%02X, " | 421 | "iocstatus=0x%04X\n\tloginfo=0x%08X, response_code=0x%02X, " |
469 | "term_cmnds=%d\n", ioc->name, pScsiTmReply->Bus, | 422 | "term_cmnds=%d\n", ioc->name, pScsiTmReply->Bus, |
470 | pScsiTmReply->TargetID, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, | 423 | pScsiTmReply->TargetID, tm_type, |
471 | le16_to_cpu(pScsiTmReply->IOCStatus), | 424 | le16_to_cpu(pScsiTmReply->IOCStatus), |
472 | le32_to_cpu(pScsiTmReply->IOCLogInfo), | 425 | le32_to_cpu(pScsiTmReply->IOCLogInfo), |
473 | pScsiTmReply->ResponseCode, | 426 | pScsiTmReply->ResponseCode, |
@@ -485,13 +438,71 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function) | |||
485 | retval = -1; /* return failure */ | 438 | retval = -1; /* return failure */ |
486 | } | 439 | } |
487 | 440 | ||
488 | 441 | tm_done: | |
489 | mptctl_bus_reset_done: | ||
490 | mutex_unlock(&ioc->taskmgmt_cmds.mutex); | 442 | mutex_unlock(&ioc->taskmgmt_cmds.mutex); |
491 | CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status) | 443 | CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status) |
492 | return retval; | 444 | return retval; |
493 | } | 445 | } |
494 | 446 | ||
447 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
448 | /* mptctl_timeout_expired | ||
449 | * | ||
450 | * Expecting an interrupt, however timed out. | ||
451 | * | ||
452 | */ | ||
453 | static void | ||
454 | mptctl_timeout_expired(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) | ||
455 | { | ||
456 | unsigned long flags; | ||
457 | int ret_val = -1; | ||
458 | SCSIIORequest_t *scsi_req = (SCSIIORequest_t *) mf; | ||
459 | u8 function = mf->u.hdr.Function; | ||
460 | |||
461 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": %s\n", | ||
462 | ioc->name, __func__)); | ||
463 | |||
464 | if (mpt_fwfault_debug) | ||
465 | mpt_halt_firmware(ioc); | ||
466 | |||
467 | spin_lock_irqsave(&ioc->taskmgmt_lock, flags); | ||
468 | if (ioc->ioc_reset_in_progress) { | ||
469 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); | ||
470 | CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status) | ||
471 | mpt_free_msg_frame(ioc, mf); | ||
472 | return; | ||
473 | } | ||
474 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); | ||
475 | |||
476 | |||
477 | CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status) | ||
478 | |||
479 | if (ioc->bus_type == SAS) { | ||
480 | if (function == MPI_FUNCTION_SCSI_IO_REQUEST) | ||
481 | ret_val = mptctl_do_taskmgmt(ioc, | ||
482 | MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, | ||
483 | scsi_req->Bus, scsi_req->TargetID); | ||
484 | else if (function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) | ||
485 | ret_val = mptctl_do_taskmgmt(ioc, | ||
486 | MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, | ||
487 | scsi_req->Bus, 0); | ||
488 | if (!ret_val) | ||
489 | return; | ||
490 | } else { | ||
491 | if ((function == MPI_FUNCTION_SCSI_IO_REQUEST) || | ||
492 | (function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) | ||
493 | ret_val = mptctl_do_taskmgmt(ioc, | ||
494 | MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, | ||
495 | scsi_req->Bus, 0); | ||
496 | if (!ret_val) | ||
497 | return; | ||
498 | } | ||
499 | |||
500 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling Reset! \n", | ||
501 | ioc->name)); | ||
502 | mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); | ||
503 | mpt_free_msg_frame(ioc, mf); | ||
504 | } | ||
505 | |||
495 | 506 | ||
496 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 507 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
497 | /* mptctl_ioc_reset | 508 | /* mptctl_ioc_reset |
@@ -1318,6 +1329,8 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) | |||
1318 | if (ioc->sh) { | 1329 | if (ioc->sh) { |
1319 | shost_for_each_device(sdev, ioc->sh) { | 1330 | shost_for_each_device(sdev, ioc->sh) { |
1320 | vdevice = sdev->hostdata; | 1331 | vdevice = sdev->hostdata; |
1332 | if (vdevice == NULL || vdevice->vtarget == NULL) | ||
1333 | continue; | ||
1321 | if (vdevice->vtarget->tflags & | 1334 | if (vdevice->vtarget->tflags & |
1322 | MPT_TARGET_FLAGS_RAID_COMPONENT) | 1335 | MPT_TARGET_FLAGS_RAID_COMPONENT) |
1323 | continue; | 1336 | continue; |
@@ -1439,6 +1452,8 @@ mptctl_gettargetinfo (unsigned long arg) | |||
1439 | if (!maxWordsLeft) | 1452 | if (!maxWordsLeft) |
1440 | continue; | 1453 | continue; |
1441 | vdevice = sdev->hostdata; | 1454 | vdevice = sdev->hostdata; |
1455 | if (vdevice == NULL || vdevice->vtarget == NULL) | ||
1456 | continue; | ||
1442 | if (vdevice->vtarget->tflags & | 1457 | if (vdevice->vtarget->tflags & |
1443 | MPT_TARGET_FLAGS_RAID_COMPONENT) | 1458 | MPT_TARGET_FLAGS_RAID_COMPONENT) |
1444 | continue; | 1459 | continue; |
@@ -1967,6 +1982,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1967 | struct scsi_target *starget = scsi_target(sdev); | 1982 | struct scsi_target *starget = scsi_target(sdev); |
1968 | VirtTarget *vtarget = starget->hostdata; | 1983 | VirtTarget *vtarget = starget->hostdata; |
1969 | 1984 | ||
1985 | if (vtarget == NULL) | ||
1986 | continue; | ||
1987 | |||
1970 | if ((pScsiReq->TargetID == vtarget->id) && | 1988 | if ((pScsiReq->TargetID == vtarget->id) && |
1971 | (pScsiReq->Bus == vtarget->channel) && | 1989 | (pScsiReq->Bus == vtarget->channel) && |
1972 | (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)) | 1990 | (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)) |
@@ -2991,6 +3009,14 @@ static int __init mptctl_init(void) | |||
2991 | } | 3009 | } |
2992 | 3010 | ||
2993 | mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER); | 3011 | mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER); |
3012 | if (!mptctl_taskmgmt_id || mptctl_taskmgmt_id >= MPT_MAX_PROTOCOL_DRIVERS) { | ||
3013 | printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n"); | ||
3014 | mpt_deregister(mptctl_id); | ||
3015 | misc_deregister(&mptctl_miscdev); | ||
3016 | err = -EBUSY; | ||
3017 | goto out_fail; | ||
3018 | } | ||
3019 | |||
2994 | mpt_reset_register(mptctl_id, mptctl_ioc_reset); | 3020 | mpt_reset_register(mptctl_id, mptctl_ioc_reset); |
2995 | mpt_event_register(mptctl_id, mptctl_event_process); | 3021 | mpt_event_register(mptctl_id, mptctl_event_process); |
2996 | 3022 | ||
@@ -3010,12 +3036,15 @@ static void mptctl_exit(void) | |||
3010 | printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n", | 3036 | printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n", |
3011 | mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor); | 3037 | mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor); |
3012 | 3038 | ||
3039 | /* De-register event handler from base module */ | ||
3040 | mpt_event_deregister(mptctl_id); | ||
3041 | |||
3013 | /* De-register reset handler from base module */ | 3042 | /* De-register reset handler from base module */ |
3014 | mpt_reset_deregister(mptctl_id); | 3043 | mpt_reset_deregister(mptctl_id); |
3015 | 3044 | ||
3016 | /* De-register callback handler from base module */ | 3045 | /* De-register callback handler from base module */ |
3046 | mpt_deregister(mptctl_taskmgmt_id); | ||
3017 | mpt_deregister(mptctl_id); | 3047 | mpt_deregister(mptctl_id); |
3018 | mpt_reset_deregister(mptctl_taskmgmt_id); | ||
3019 | 3048 | ||
3020 | mpt_device_driver_deregister(MPTCTL_DRIVER); | 3049 | mpt_device_driver_deregister(MPTCTL_DRIVER); |
3021 | 3050 | ||
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 33f7256055b1..b5f03ad81568 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
@@ -482,6 +482,7 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) | |||
482 | if (vtarget) { | 482 | if (vtarget) { |
483 | vtarget->id = pg0->CurrentTargetID; | 483 | vtarget->id = pg0->CurrentTargetID; |
484 | vtarget->channel = pg0->CurrentBus; | 484 | vtarget->channel = pg0->CurrentBus; |
485 | vtarget->deleted = 0; | ||
485 | } | 486 | } |
486 | } | 487 | } |
487 | *((struct mptfc_rport_info **)rport->dd_data) = ri; | 488 | *((struct mptfc_rport_info **)rport->dd_data) = ri; |
@@ -1092,6 +1093,8 @@ mptfc_setup_reset(struct work_struct *work) | |||
1092 | container_of(work, MPT_ADAPTER, fc_setup_reset_work); | 1093 | container_of(work, MPT_ADAPTER, fc_setup_reset_work); |
1093 | u64 pn; | 1094 | u64 pn; |
1094 | struct mptfc_rport_info *ri; | 1095 | struct mptfc_rport_info *ri; |
1096 | struct scsi_target *starget; | ||
1097 | VirtTarget *vtarget; | ||
1095 | 1098 | ||
1096 | /* reset about to happen, delete (block) all rports */ | 1099 | /* reset about to happen, delete (block) all rports */ |
1097 | list_for_each_entry(ri, &ioc->fc_rports, list) { | 1100 | list_for_each_entry(ri, &ioc->fc_rports, list) { |
@@ -1099,6 +1102,12 @@ mptfc_setup_reset(struct work_struct *work) | |||
1099 | ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED; | 1102 | ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED; |
1100 | fc_remote_port_delete(ri->rport); /* won't sleep */ | 1103 | fc_remote_port_delete(ri->rport); /* won't sleep */ |
1101 | ri->rport = NULL; | 1104 | ri->rport = NULL; |
1105 | starget = ri->starget; | ||
1106 | if (starget) { | ||
1107 | vtarget = starget->hostdata; | ||
1108 | if (vtarget) | ||
1109 | vtarget->deleted = 1; | ||
1110 | } | ||
1102 | 1111 | ||
1103 | pn = (u64)ri->pg0.WWPN.High << 32 | | 1112 | pn = (u64)ri->pg0.WWPN.High << 32 | |
1104 | (u64)ri->pg0.WWPN.Low; | 1113 | (u64)ri->pg0.WWPN.Low; |
@@ -1119,6 +1128,8 @@ mptfc_rescan_devices(struct work_struct *work) | |||
1119 | int ii; | 1128 | int ii; |
1120 | u64 pn; | 1129 | u64 pn; |
1121 | struct mptfc_rport_info *ri; | 1130 | struct mptfc_rport_info *ri; |
1131 | struct scsi_target *starget; | ||
1132 | VirtTarget *vtarget; | ||
1122 | 1133 | ||
1123 | /* start by tagging all ports as missing */ | 1134 | /* start by tagging all ports as missing */ |
1124 | list_for_each_entry(ri, &ioc->fc_rports, list) { | 1135 | list_for_each_entry(ri, &ioc->fc_rports, list) { |
@@ -1146,6 +1157,12 @@ mptfc_rescan_devices(struct work_struct *work) | |||
1146 | MPT_RPORT_INFO_FLAGS_MISSING); | 1157 | MPT_RPORT_INFO_FLAGS_MISSING); |
1147 | fc_remote_port_delete(ri->rport); /* won't sleep */ | 1158 | fc_remote_port_delete(ri->rport); /* won't sleep */ |
1148 | ri->rport = NULL; | 1159 | ri->rport = NULL; |
1160 | starget = ri->starget; | ||
1161 | if (starget) { | ||
1162 | vtarget = starget->hostdata; | ||
1163 | if (vtarget) | ||
1164 | vtarget->deleted = 1; | ||
1165 | } | ||
1149 | 1166 | ||
1150 | pn = (u64)ri->pg0.WWPN.High << 32 | | 1167 | pn = (u64)ri->pg0.WWPN.High << 32 | |
1151 | (u64)ri->pg0.WWPN.Low; | 1168 | (u64)ri->pg0.WWPN.Low; |
@@ -1358,6 +1375,9 @@ mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | |||
1358 | unsigned long flags; | 1375 | unsigned long flags; |
1359 | int rc=1; | 1376 | int rc=1; |
1360 | 1377 | ||
1378 | if (ioc->bus_type != FC) | ||
1379 | return 0; | ||
1380 | |||
1361 | devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", | 1381 | devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", |
1362 | ioc->name, event)); | 1382 | ioc->name, event)); |
1363 | 1383 | ||
@@ -1396,7 +1416,7 @@ mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) | |||
1396 | unsigned long flags; | 1416 | unsigned long flags; |
1397 | 1417 | ||
1398 | rc = mptscsih_ioc_reset(ioc,reset_phase); | 1418 | rc = mptscsih_ioc_reset(ioc,reset_phase); |
1399 | if (rc == 0) | 1419 | if ((ioc->bus_type != FC) || (!rc)) |
1400 | return rc; | 1420 | return rc; |
1401 | 1421 | ||
1402 | 1422 | ||
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 76687126b573..ac000e83db0e 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -1894,7 +1894,7 @@ static struct scsi_host_template mptsas_driver_template = { | |||
1894 | .module = THIS_MODULE, | 1894 | .module = THIS_MODULE, |
1895 | .proc_name = "mptsas", | 1895 | .proc_name = "mptsas", |
1896 | .proc_info = mptscsih_proc_info, | 1896 | .proc_info = mptscsih_proc_info, |
1897 | .name = "MPT SPI Host", | 1897 | .name = "MPT SAS Host", |
1898 | .info = mptscsih_info, | 1898 | .info = mptscsih_info, |
1899 | .queuecommand = mptsas_qcmd, | 1899 | .queuecommand = mptsas_qcmd, |
1900 | .target_alloc = mptsas_target_alloc, | 1900 | .target_alloc = mptsas_target_alloc, |
@@ -2038,11 +2038,13 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset) | |||
2038 | 2038 | ||
2039 | timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, | 2039 | timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, |
2040 | 10 * HZ); | 2040 | 10 * HZ); |
2041 | if (!timeleft) { | 2041 | if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) { |
2042 | /* On timeout reset the board */ | 2042 | error = -ETIME; |
2043 | mpt_free_msg_frame(ioc, mf); | 2043 | mpt_free_msg_frame(ioc, mf); |
2044 | mpt_HardResetHandler(ioc, CAN_SLEEP); | 2044 | if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET) |
2045 | error = -ETIMEDOUT; | 2045 | goto out_unlock; |
2046 | if (!timeleft) | ||
2047 | mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); | ||
2046 | goto out_unlock; | 2048 | goto out_unlock; |
2047 | } | 2049 | } |
2048 | 2050 | ||
@@ -2223,11 +2225,14 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, | |||
2223 | mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf); | 2225 | mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf); |
2224 | 2226 | ||
2225 | timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ); | 2227 | timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ); |
2226 | if (!timeleft) { | 2228 | if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) { |
2227 | printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __func__); | 2229 | ret = -ETIME; |
2228 | /* On timeout reset the board */ | 2230 | mpt_free_msg_frame(ioc, mf); |
2229 | mpt_HardResetHandler(ioc, CAN_SLEEP); | 2231 | mf = NULL; |
2230 | ret = -ETIMEDOUT; | 2232 | if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET) |
2233 | goto unmap; | ||
2234 | if (!timeleft) | ||
2235 | mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); | ||
2231 | goto unmap; | 2236 | goto unmap; |
2232 | } | 2237 | } |
2233 | mf = NULL; | 2238 | mf = NULL; |
@@ -2518,6 +2523,12 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info, | |||
2518 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; | 2523 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; |
2519 | 2524 | ||
2520 | error = mpt_config(ioc, &cfg); | 2525 | error = mpt_config(ioc, &cfg); |
2526 | |||
2527 | if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) { | ||
2528 | error = -ENODEV; | ||
2529 | goto out_free_consistent; | ||
2530 | } | ||
2531 | |||
2521 | if (error) | 2532 | if (error) |
2522 | goto out_free_consistent; | 2533 | goto out_free_consistent; |
2523 | 2534 | ||
@@ -2594,14 +2605,14 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info, | |||
2594 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; | 2605 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; |
2595 | 2606 | ||
2596 | error = mpt_config(ioc, &cfg); | 2607 | error = mpt_config(ioc, &cfg); |
2597 | if (error) | 2608 | if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) { |
2598 | goto out_free_consistent; | ||
2599 | |||
2600 | if (!buffer->NumPhys) { | ||
2601 | error = -ENODEV; | 2609 | error = -ENODEV; |
2602 | goto out_free_consistent; | 2610 | goto out_free_consistent; |
2603 | } | 2611 | } |
2604 | 2612 | ||
2613 | if (error) | ||
2614 | goto out_free_consistent; | ||
2615 | |||
2605 | /* save config data */ | 2616 | /* save config data */ |
2606 | port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1; | 2617 | port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1; |
2607 | port_info->phy_info = kcalloc(port_info->num_phys, | 2618 | port_info->phy_info = kcalloc(port_info->num_phys, |
@@ -2677,7 +2688,7 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, | |||
2677 | 2688 | ||
2678 | if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) { | 2689 | if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) { |
2679 | error = -ENODEV; | 2690 | error = -ENODEV; |
2680 | goto out; | 2691 | goto out_free_consistent; |
2681 | } | 2692 | } |
2682 | 2693 | ||
2683 | if (error) | 2694 | if (error) |
@@ -2833,7 +2844,7 @@ mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc, | |||
2833 | if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET) | 2844 | if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET) |
2834 | goto out_free; | 2845 | goto out_free; |
2835 | if (!timeleft) | 2846 | if (!timeleft) |
2836 | mpt_HardResetHandler(ioc, CAN_SLEEP); | 2847 | mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); |
2837 | goto out_free; | 2848 | goto out_free; |
2838 | } | 2849 | } |
2839 | 2850 | ||
@@ -4098,6 +4109,7 @@ mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id) | |||
4098 | cfg.pageAddr = (channel << 8) + id; | 4109 | cfg.pageAddr = (channel << 8) + id; |
4099 | cfg.cfghdr.hdr = &hdr; | 4110 | cfg.cfghdr.hdr = &hdr; |
4100 | cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; | 4111 | cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; |
4112 | cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT; | ||
4101 | 4113 | ||
4102 | if (mpt_config(ioc, &cfg) != 0) | 4114 | if (mpt_config(ioc, &cfg) != 0) |
4103 | goto out; | 4115 | goto out; |
@@ -4717,7 +4729,7 @@ mptsas_broadcast_primative_work(struct fw_event_work *fw_event) | |||
4717 | if (issue_reset) { | 4729 | if (issue_reset) { |
4718 | printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", | 4730 | printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", |
4719 | ioc->name, __func__); | 4731 | ioc->name, __func__); |
4720 | mpt_HardResetHandler(ioc, CAN_SLEEP); | 4732 | mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); |
4721 | } | 4733 | } |
4722 | mptsas_free_fw_event(ioc, fw_event); | 4734 | mptsas_free_fw_event(ioc, fw_event); |
4723 | } | 4735 | } |
@@ -4779,6 +4791,9 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) | |||
4779 | struct fw_event_work *fw_event; | 4791 | struct fw_event_work *fw_event; |
4780 | unsigned long delay; | 4792 | unsigned long delay; |
4781 | 4793 | ||
4794 | if (ioc->bus_type != SAS) | ||
4795 | return 0; | ||
4796 | |||
4782 | /* events turned off due to host reset or driver unloading */ | 4797 | /* events turned off due to host reset or driver unloading */ |
4783 | if (ioc->fw_events_off) | 4798 | if (ioc->fw_events_off) |
4784 | return 0; | 4799 | return 0; |
@@ -5073,6 +5088,12 @@ static void __devexit mptsas_remove(struct pci_dev *pdev) | |||
5073 | struct mptsas_portinfo *p, *n; | 5088 | struct mptsas_portinfo *p, *n; |
5074 | int i; | 5089 | int i; |
5075 | 5090 | ||
5091 | if (!ioc->sh) { | ||
5092 | printk(MYIOC_s_INFO_FMT "IOC is in Target mode\n", ioc->name); | ||
5093 | mpt_detach(pdev); | ||
5094 | return; | ||
5095 | } | ||
5096 | |||
5076 | mptsas_shutdown(pdev); | 5097 | mptsas_shutdown(pdev); |
5077 | 5098 | ||
5078 | mptsas_del_device_components(ioc); | 5099 | mptsas_del_device_components(ioc); |
diff --git a/drivers/message/fusion/mptsas.h b/drivers/message/fusion/mptsas.h index 953c2bfcf6aa..7b249edbda78 100644 --- a/drivers/message/fusion/mptsas.h +++ b/drivers/message/fusion/mptsas.h | |||
@@ -110,7 +110,7 @@ struct fw_event_work { | |||
110 | MPT_ADAPTER *ioc; | 110 | MPT_ADAPTER *ioc; |
111 | u32 event; | 111 | u32 event; |
112 | u8 retries; | 112 | u8 retries; |
113 | u8 event_data[1]; | 113 | u8 __attribute__((aligned(4))) event_data[1]; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | struct mptsas_discovery_event { | 116 | struct mptsas_discovery_event { |
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 6796597dcee0..7bd4c0fc23cc 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -1149,11 +1149,6 @@ mptscsih_remove(struct pci_dev *pdev) | |||
1149 | MPT_SCSI_HOST *hd; | 1149 | MPT_SCSI_HOST *hd; |
1150 | int sz1; | 1150 | int sz1; |
1151 | 1151 | ||
1152 | if(!host) { | ||
1153 | mpt_detach(pdev); | ||
1154 | return; | ||
1155 | } | ||
1156 | |||
1157 | scsi_remove_host(host); | 1152 | scsi_remove_host(host); |
1158 | 1153 | ||
1159 | if((hd = shost_priv(host)) == NULL) | 1154 | if((hd = shost_priv(host)) == NULL) |
@@ -1711,7 +1706,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, | |||
1711 | if (issue_hard_reset) { | 1706 | if (issue_hard_reset) { |
1712 | printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", | 1707 | printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", |
1713 | ioc->name, __func__); | 1708 | ioc->name, __func__); |
1714 | retval = mpt_HardResetHandler(ioc, CAN_SLEEP); | 1709 | retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); |
1715 | mpt_free_msg_frame(ioc, mf); | 1710 | mpt_free_msg_frame(ioc, mf); |
1716 | } | 1711 | } |
1717 | 1712 | ||
@@ -1728,6 +1723,7 @@ mptscsih_get_tm_timeout(MPT_ADAPTER *ioc) | |||
1728 | case FC: | 1723 | case FC: |
1729 | return 40; | 1724 | return 40; |
1730 | case SAS: | 1725 | case SAS: |
1726 | return 30; | ||
1731 | case SPI: | 1727 | case SPI: |
1732 | default: | 1728 | default: |
1733 | return 10; | 1729 | return 10; |
@@ -1777,7 +1773,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1777 | ioc->name, SCpnt)); | 1773 | ioc->name, SCpnt)); |
1778 | SCpnt->result = DID_NO_CONNECT << 16; | 1774 | SCpnt->result = DID_NO_CONNECT << 16; |
1779 | SCpnt->scsi_done(SCpnt); | 1775 | SCpnt->scsi_done(SCpnt); |
1780 | retval = 0; | 1776 | retval = SUCCESS; |
1781 | goto out; | 1777 | goto out; |
1782 | } | 1778 | } |
1783 | 1779 | ||
@@ -1792,6 +1788,17 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1792 | goto out; | 1788 | goto out; |
1793 | } | 1789 | } |
1794 | 1790 | ||
1791 | /* Task aborts are not supported for volumes. | ||
1792 | */ | ||
1793 | if (vdevice->vtarget->raidVolume) { | ||
1794 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT | ||
1795 | "task abort: raid volume (sc=%p)\n", | ||
1796 | ioc->name, SCpnt)); | ||
1797 | SCpnt->result = DID_RESET << 16; | ||
1798 | retval = FAILED; | ||
1799 | goto out; | ||
1800 | } | ||
1801 | |||
1795 | /* Find this command | 1802 | /* Find this command |
1796 | */ | 1803 | */ |
1797 | if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(ioc, SCpnt)) < 0) { | 1804 | if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(ioc, SCpnt)) < 0) { |
@@ -1991,7 +1998,7 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt) | |||
1991 | /* If our attempts to reset the host failed, then return a failed | 1998 | /* If our attempts to reset the host failed, then return a failed |
1992 | * status. The host will be taken off line by the SCSI mid-layer. | 1999 | * status. The host will be taken off line by the SCSI mid-layer. |
1993 | */ | 2000 | */ |
1994 | retval = mpt_HardResetHandler(ioc, CAN_SLEEP); | 2001 | retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); |
1995 | if (retval < 0) | 2002 | if (retval < 0) |
1996 | status = FAILED; | 2003 | status = FAILED; |
1997 | else | 2004 | else |
@@ -2344,6 +2351,8 @@ mptscsih_slave_destroy(struct scsi_device *sdev) | |||
2344 | starget = scsi_target(sdev); | 2351 | starget = scsi_target(sdev); |
2345 | vtarget = starget->hostdata; | 2352 | vtarget = starget->hostdata; |
2346 | vdevice = sdev->hostdata; | 2353 | vdevice = sdev->hostdata; |
2354 | if (!vdevice) | ||
2355 | return; | ||
2347 | 2356 | ||
2348 | mptscsih_search_running_cmds(hd, vdevice); | 2357 | mptscsih_search_running_cmds(hd, vdevice); |
2349 | vtarget->num_luns--; | 2358 | vtarget->num_luns--; |
@@ -3040,7 +3049,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) | |||
3040 | if (!timeleft) { | 3049 | if (!timeleft) { |
3041 | printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", | 3050 | printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", |
3042 | ioc->name, __func__); | 3051 | ioc->name, __func__); |
3043 | mpt_HardResetHandler(ioc, CAN_SLEEP); | 3052 | mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); |
3044 | mpt_free_msg_frame(ioc, mf); | 3053 | mpt_free_msg_frame(ioc, mf); |
3045 | } | 3054 | } |
3046 | goto out; | 3055 | goto out; |
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index e44365193fdf..1abaa5d01ae3 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c | |||
@@ -210,6 +210,10 @@ mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, | |||
210 | target->maxOffset = offset; | 210 | target->maxOffset = offset; |
211 | target->maxWidth = width; | 211 | target->maxWidth = width; |
212 | 212 | ||
213 | spi_min_period(scsi_target(sdev)) = factor; | ||
214 | spi_max_offset(scsi_target(sdev)) = offset; | ||
215 | spi_max_width(scsi_target(sdev)) = width; | ||
216 | |||
213 | target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO; | 217 | target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO; |
214 | 218 | ||
215 | /* Disable unused features. | 219 | /* Disable unused features. |
@@ -558,6 +562,7 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget, | |||
558 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; | 562 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; |
559 | cfg.dir = 0; | 563 | cfg.dir = 0; |
560 | cfg.pageAddr = starget->id; | 564 | cfg.pageAddr = starget->id; |
565 | cfg.timeout = 60; | ||
561 | 566 | ||
562 | if (mpt_config(ioc, &cfg)) { | 567 | if (mpt_config(ioc, &cfg)) { |
563 | starget_printk(KERN_ERR, starget, MYIOC_s_FMT "mpt_config failed\n", ioc->name); | 568 | starget_printk(KERN_ERR, starget, MYIOC_s_FMT "mpt_config failed\n", ioc->name); |
@@ -1152,6 +1157,9 @@ mptspi_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | |||
1152 | u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; | 1157 | u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; |
1153 | struct _MPT_SCSI_HOST *hd = shost_priv(ioc->sh); | 1158 | struct _MPT_SCSI_HOST *hd = shost_priv(ioc->sh); |
1154 | 1159 | ||
1160 | if (ioc->bus_type != SPI) | ||
1161 | return 0; | ||
1162 | |||
1155 | if (hd && event == MPI_EVENT_INTEGRATED_RAID) { | 1163 | if (hd && event == MPI_EVENT_INTEGRATED_RAID) { |
1156 | int reason | 1164 | int reason |
1157 | = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16; | 1165 | = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16; |
@@ -1283,6 +1291,8 @@ mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) | |||
1283 | int rc; | 1291 | int rc; |
1284 | 1292 | ||
1285 | rc = mptscsih_ioc_reset(ioc, reset_phase); | 1293 | rc = mptscsih_ioc_reset(ioc, reset_phase); |
1294 | if ((ioc->bus_type != SPI) || (!rc)) | ||
1295 | return rc; | ||
1286 | 1296 | ||
1287 | /* only try to do a renegotiation if we're properly set up | 1297 | /* only try to do a renegotiation if we're properly set up |
1288 | * if we get an ioc fault on bringup, ioc->sh will be NULL */ | 1298 | * if we get an ioc fault on bringup, ioc->sh will be NULL */ |