aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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