aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2010-03-18 09:43:10 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-04-11 10:24:04 -0400
commit7d757f18554070e917f61e7caedf395f940cf853 (patch)
tree5b77bd5276ee5c02959e4d680420a035eb3c6891 /drivers/message
parentd0f698c46141e1d179fb3a86a0ae668d2fd12916 (diff)
[SCSI] mptfusion: Updated SCSI IO IOCTL error handling.
Behavior changes only for IOCTLs that time out. Current behavior of Bus Reset remains the same for RAID Passthru Timeouts Current behavior of Diagnostic reset for any other type of IOCTL remains the same CHANGE: For IOCTL SCSI IOs that timeout, a Target Reset TM is sent, instead of Bus Reset. All error handing from that point is the same as what the driver currently does, which is to say that if the Device Reset TM fails it escalates do diagnostic reset. Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/message')
-rw-r--r--drivers/message/fusion/mptctl.c161
1 files changed, 86 insertions, 75 deletions
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index e6d71e20fa09..e7fab5de16e7 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_Soft_Hard_ResetHandler(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