aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 10:19:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 10:19:18 -0400
commit33cf23b0a535475aead57707cb9f4fe135a93544 (patch)
tree67e14f77f0eeab847a26a6cbfcb44eecb5fa2fda /drivers/message
parent7a9b149212f3716c598afe973b6261fd58453b7a (diff)
parent95bb335c0ebe96afe926387a1ef3a096bd884a82 (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.c177
-rw-r--r--drivers/message/fusion/mptbase.h5
-rw-r--r--drivers/message/fusion/mptctl.c181
-rw-r--r--drivers/message/fusion/mptfc.c22
-rw-r--r--drivers/message/fusion/mptsas.c55
-rw-r--r--drivers/message/fusion/mptsas.h2
-rw-r--r--drivers/message/fusion/mptscsih.c27
-rw-r--r--drivers/message/fusion/mptspi.c10
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}
6905EXPORT_SYMBOL(mpt_halt_firmware); 6910EXPORT_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 **/
6926int
6927mpt_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 **/
7066int
7067mpt_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}
7076EXPORT_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);
940extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked); 940extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
941extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); 941extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);
942extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); 942extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
943extern int mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
943extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); 944extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
944extern int mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); 945extern int mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
945extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); 946extern 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);
129static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, 129static 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);
131static 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 */
284static void
285mptctl_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
318static int 278static int
319mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) 279mptctl_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 306static int
347 * 307mptctl_do_taskmgmt(MPT_ADAPTER *ioc, u8 tm_type, u8 bus_id, u8 target_id)
348 * Bus reset code.
349 *
350 */
351static 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 */
453static void
454mptctl_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
116struct mptsas_discovery_event { 116struct 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 */