aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2009-09-23 07:52:37 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-10-29 13:03:08 -0400
commita28eb222e3890a4ce190a430e24c483d2b5bb13b (patch)
treea0e0a297c7dc627a5c2c34687f17349d22772688
parentc5e039be7e81168a9156e801cfef2adae72e775b (diff)
[SCSI] mpt2sas: Expander remove fails when it is processing another expander add.
This handles the case where driver receives a expander removal event while it is in the middle of processing an expander add event. The existing implementation will stop processing futher device adds when a expander delete arrives on top of add expander add. Due to a sanity check in the driver, the devices there were not added, were never handshaked to firmware with the device removal handshake protocal. Since the driver didnt' do the handshake, the controller never provide further add events. To fix this issue, the sanity check was removed so the driver will always do the device removal handshake protocal. Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> Signed-off-by: Eric Moore <Eric.moore@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c109
1 files changed, 62 insertions, 47 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 8822cda852ba..d4e890d8b992 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -2386,16 +2386,10 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2386 2386
2387 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2387 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2388 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2388 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2389 if (!sas_device) {
2390 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2391 printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
2392 ioc->name, __func__);
2393 return;
2394 }
2395 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 2389 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2396 2390
2397 /* skip is hidden raid component */ 2391 /* skip is hidden raid component */
2398 if (sas_device->hidden_raid_component) 2392 if (sas_device && sas_device->hidden_raid_component)
2399 return; 2393 return;
2400 2394
2401 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); 2395 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
@@ -2408,18 +2402,31 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2408 delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL; 2402 delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL;
2409 list_add_tail(&delayed_tr->list, 2403 list_add_tail(&delayed_tr->list,
2410 &ioc->delayed_tr_list); 2404 &ioc->delayed_tr_list);
2411 if (sas_device->starget) 2405 if (sas_device && sas_device->starget) {
2412 dewtprintk(ioc, starget_printk(KERN_INFO, 2406 dewtprintk(ioc, starget_printk(KERN_INFO,
2413 sas_device->starget, "DELAYED:tr:handle(0x%04x), " 2407 sas_device->starget, "DELAYED:tr:handle(0x%04x), "
2414 "(open)\n", sas_device->handle)); 2408 "(open)\n", handle));
2409 } else {
2410 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2411 "DELAYED:tr:handle(0x%04x), (open)\n",
2412 ioc->name, handle));
2413 }
2415 return; 2414 return;
2416 } 2415 }
2417 2416
2418 if (sas_device->starget && sas_device->starget->hostdata) { 2417 if (sas_device) {
2419 sas_target_priv_data = sas_device->starget->hostdata; 2418 sas_device->state |= MPTSAS_STATE_TR_SEND;
2420 sas_target_priv_data->tm_busy = 1; 2419 sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
2421 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, 2420 if (sas_device->starget && sas_device->starget->hostdata) {
2422 "tr:handle(0x%04x), (open)\n", sas_device->handle)); 2421 sas_target_priv_data = sas_device->starget->hostdata;
2422 sas_target_priv_data->tm_busy = 1;
2423 dewtprintk(ioc, starget_printk(KERN_INFO,
2424 sas_device->starget, "tr:handle(0x%04x), (open)\n",
2425 handle));
2426 }
2427 } else {
2428 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2429 "tr:handle(0x%04x), (open)\n", ioc->name, handle));
2423 } 2430 }
2424 2431
2425 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 2432 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
@@ -2427,8 +2434,6 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2427 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; 2434 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
2428 mpi_request->DevHandle = cpu_to_le16(handle); 2435 mpi_request->DevHandle = cpu_to_le16(handle);
2429 mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; 2436 mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
2430 sas_device->state |= MPTSAS_STATE_TR_SEND;
2431 sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
2432 mpt2sas_base_put_smid_hi_priority(ioc, smid); 2437 mpt2sas_base_put_smid_hi_priority(ioc, smid);
2433} 2438}
2434 2439
@@ -2463,21 +2468,25 @@ _scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
2463 2468
2464 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2469 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2465 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2470 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2466 if (!sas_device) {
2467 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2468 printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
2469 ioc->name, __func__);
2470 return 1;
2471 }
2472 sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE;
2473 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 2471 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2474 2472
2475 if (sas_device->starget) 2473 if (sas_device) {
2476 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, 2474 sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE;
2475 if (sas_device->starget)
2476 dewtprintk(ioc, starget_printk(KERN_INFO,
2477 sas_device->starget,
2478 "sc_complete:handle(0x%04x), "
2479 "ioc_status(0x%04x), loginfo(0x%08x)\n",
2480 handle, le16_to_cpu(mpi_reply->IOCStatus),
2481 le32_to_cpu(mpi_reply->IOCLogInfo)));
2482 } else {
2483 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2477 "sc_complete:handle(0x%04x), " 2484 "sc_complete:handle(0x%04x), "
2478 "ioc_status(0x%04x), loginfo(0x%08x)\n", 2485 "ioc_status(0x%04x), loginfo(0x%08x)\n",
2479 handle, le16_to_cpu(mpi_reply->IOCStatus), 2486 ioc->name, handle, le16_to_cpu(mpi_reply->IOCStatus),
2480 le32_to_cpu(mpi_reply->IOCLogInfo))); 2487 le32_to_cpu(mpi_reply->IOCLogInfo)));
2488 }
2489
2481 return 1; 2490 return 1;
2482} 2491}
2483 2492
@@ -2515,28 +2524,33 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2515 handle = le16_to_cpu(mpi_reply->DevHandle); 2524 handle = le16_to_cpu(mpi_reply->DevHandle);
2516 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2525 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2517 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2526 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2518 if (!sas_device) {
2519 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2520 printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
2521 ioc->name, __func__);
2522 return 1;
2523 }
2524 sas_device->state |= MPTSAS_STATE_TR_COMPLETE;
2525 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 2527 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2526 2528
2527 if (sas_device->starget) 2529 if (sas_device) {
2528 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, 2530 sas_device->state |= MPTSAS_STATE_TR_COMPLETE;
2529 "tr_complete:handle(0x%04x), (%s) ioc_status(0x%04x), " 2531 if (sas_device->starget) {
2530 "loginfo(0x%08x), completed(%d)\n", 2532 dewtprintk(ioc, starget_printk(KERN_INFO,
2531 sas_device->handle, (sas_device->state & 2533 sas_device->starget, "tr_complete:handle(0x%04x), "
2532 MPT2SAS_REQ_SAS_CNTRL) ? "open" : "active", 2534 "(%s) ioc_status(0x%04x), loginfo(0x%08x), "
2533 le16_to_cpu(mpi_reply->IOCStatus), 2535 "completed(%d)\n", sas_device->handle,
2536 (sas_device->state & MPT2SAS_REQ_SAS_CNTRL) ?
2537 "open" : "active",
2538 le16_to_cpu(mpi_reply->IOCStatus),
2539 le32_to_cpu(mpi_reply->IOCLogInfo),
2540 le32_to_cpu(mpi_reply->TerminationCount)));
2541 if (sas_device->starget->hostdata) {
2542 sas_target_priv_data =
2543 sas_device->starget->hostdata;
2544 sas_target_priv_data->tm_busy = 0;
2545 }
2546 }
2547 } else {
2548 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2549 "tr_complete:handle(0x%04x), (open) ioc_status(0x%04x), "
2550 "loginfo(0x%08x), completed(%d)\n", ioc->name,
2551 handle, le16_to_cpu(mpi_reply->IOCStatus),
2534 le32_to_cpu(mpi_reply->IOCLogInfo), 2552 le32_to_cpu(mpi_reply->IOCLogInfo),
2535 le32_to_cpu(mpi_reply->TerminationCount))); 2553 le32_to_cpu(mpi_reply->TerminationCount)));
2536
2537 if (sas_device->starget && sas_device->starget->hostdata) {
2538 sas_target_priv_data = sas_device->starget->hostdata;
2539 sas_target_priv_data->tm_busy = 0;
2540 } 2554 }
2541 2555
2542 if (!list_empty(&ioc->delayed_tr_list)) { 2556 if (!list_empty(&ioc->delayed_tr_list)) {
@@ -2551,8 +2565,7 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2551 } else 2565 } else
2552 rc = 1; 2566 rc = 1;
2553 2567
2554 2568 if (sas_device && !(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
2555 if (!(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
2556 return rc; 2569 return rc;
2557 2570
2558 if (ioc->shost_recovery) { 2571 if (ioc->shost_recovery) {
@@ -2568,12 +2581,14 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2568 return rc; 2581 return rc;
2569 } 2582 }
2570 2583
2584 if (sas_device)
2585 sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
2586
2571 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl); 2587 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl);
2572 memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); 2588 memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
2573 mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 2589 mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
2574 mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; 2590 mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
2575 mpi_request->DevHandle = mpi_reply->DevHandle; 2591 mpi_request->DevHandle = mpi_reply->DevHandle;
2576 sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
2577 mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl); 2592 mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl);
2578 return rc; 2593 return rc;
2579} 2594}