diff options
author | Kashyap, Desai <kashyap.desai@lsi.com> | 2010-03-09 07:04:13 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-04-11 10:23:29 -0400 |
commit | 1278b11f46d9f34097f44ecc417148f27e8997fe (patch) | |
tree | 986281490f5692194f64ce6e79aa5580a9f36bb8 /drivers/scsi/mpt2sas | |
parent | 40956059fb2ef717f1e864a6685e7cd31758fc2b (diff) |
[SCSI] mpt2sas : Device removal algorithm in interrupt context only
external host not connecting after controller reboot: The
problem is : devices are not coming back after having the cable
disconnected then reconnected. The problem is because the
driver/firmware device removal handshake is failing. Due to this failure,
the controller firmware is not sending out device add events when the target
is reconnected. This is root caused to a race in the driver/firmware device
removal algorithm. There is duplicate code in both interrupt and user
context; where target reset is being issue from user context path while
sas_iounit_control(OP_REMOVE) is being sent from interrupt context. An
active target_reset will fail the OP_REMOVE. To fix this problem, the
duplicate code has been removed from user context path.
Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/mpt2sas')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.h | 11 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 307 |
2 files changed, 123 insertions, 195 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index 199424d22346..142b694c9de5 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h | |||
@@ -259,16 +259,6 @@ struct _internal_cmd { | |||
259 | u16 smid; | 259 | u16 smid; |
260 | }; | 260 | }; |
261 | 261 | ||
262 | /* | ||
263 | * SAS Topology Structures | ||
264 | */ | ||
265 | |||
266 | #define MPTSAS_STATE_TR_SEND 0x0001 | ||
267 | #define MPTSAS_STATE_TR_COMPLETE 0x0002 | ||
268 | #define MPTSAS_STATE_CNTRL_SEND 0x0004 | ||
269 | #define MPTSAS_STATE_CNTRL_COMPLETE 0x0008 | ||
270 | |||
271 | #define MPT2SAS_REQ_SAS_CNTRL 0x0010 | ||
272 | 262 | ||
273 | /** | 263 | /** |
274 | * struct _sas_device - attached device information | 264 | * struct _sas_device - attached device information |
@@ -306,7 +296,6 @@ struct _sas_device { | |||
306 | u16 slot; | 296 | u16 slot; |
307 | u8 hidden_raid_component; | 297 | u8 hidden_raid_component; |
308 | u8 responding; | 298 | u8 responding; |
309 | u16 state; | ||
310 | }; | 299 | }; |
311 | 300 | ||
312 | /** | 301 | /** |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 72a945373964..6d9f99720b48 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
@@ -2546,25 +2546,24 @@ static void | |||
2546 | _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle) | 2546 | _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle) |
2547 | { | 2547 | { |
2548 | Mpi2SCSITaskManagementRequest_t *mpi_request; | 2548 | Mpi2SCSITaskManagementRequest_t *mpi_request; |
2549 | struct MPT2SAS_TARGET *sas_target_priv_data; | ||
2550 | u16 smid; | 2549 | u16 smid; |
2551 | struct _sas_device *sas_device; | 2550 | struct _sas_device *sas_device; |
2552 | unsigned long flags; | 2551 | unsigned long flags; |
2553 | struct _tr_list *delayed_tr; | 2552 | struct _tr_list *delayed_tr; |
2554 | 2553 | ||
2555 | if (ioc->shost_recovery) { | 2554 | if (ioc->shost_recovery || ioc->remove_host) { |
2556 | printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", | 2555 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in " |
2557 | __func__, ioc->name); | 2556 | "progress!\n", __func__, ioc->name)); |
2558 | return; | 2557 | return; |
2559 | } | 2558 | } |
2560 | 2559 | ||
2561 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 2560 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
2562 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 2561 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); |
2563 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 2562 | if (sas_device && sas_device->hidden_raid_component) { |
2564 | 2563 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | |
2565 | /* skip is hidden raid component */ | ||
2566 | if (sas_device && sas_device->hidden_raid_component) | ||
2567 | return; | 2564 | return; |
2565 | } | ||
2566 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
2568 | 2567 | ||
2569 | smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); | 2568 | smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); |
2570 | if (!smid) { | 2569 | if (!smid) { |
@@ -2573,36 +2572,16 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
2573 | return; | 2572 | return; |
2574 | INIT_LIST_HEAD(&delayed_tr->list); | 2573 | INIT_LIST_HEAD(&delayed_tr->list); |
2575 | delayed_tr->handle = handle; | 2574 | delayed_tr->handle = handle; |
2576 | delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL; | 2575 | list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list); |
2577 | list_add_tail(&delayed_tr->list, | ||
2578 | &ioc->delayed_tr_list); | ||
2579 | if (sas_device && sas_device->starget) { | ||
2580 | dewtprintk(ioc, starget_printk(KERN_INFO, | ||
2581 | sas_device->starget, "DELAYED:tr:handle(0x%04x), " | ||
2582 | "(open)\n", handle)); | ||
2583 | } else { | ||
2584 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT | ||
2585 | "DELAYED:tr:handle(0x%04x), (open)\n", | ||
2586 | ioc->name, handle)); | ||
2587 | } | ||
2588 | return; | ||
2589 | } | ||
2590 | |||
2591 | if (sas_device) { | ||
2592 | sas_device->state |= MPTSAS_STATE_TR_SEND; | ||
2593 | sas_device->state |= MPT2SAS_REQ_SAS_CNTRL; | ||
2594 | if (sas_device->starget && sas_device->starget->hostdata) { | ||
2595 | sas_target_priv_data = sas_device->starget->hostdata; | ||
2596 | sas_target_priv_data->tm_busy = 1; | ||
2597 | dewtprintk(ioc, starget_printk(KERN_INFO, | ||
2598 | sas_device->starget, "tr:handle(0x%04x), (open)\n", | ||
2599 | handle)); | ||
2600 | } | ||
2601 | } else { | ||
2602 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT | 2576 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT |
2603 | "tr:handle(0x%04x), (open)\n", ioc->name, handle)); | 2577 | "DELAYED:tr:handle(0x%04x), (open)\n", |
2578 | ioc->name, handle)); | ||
2579 | return; | ||
2604 | } | 2580 | } |
2605 | 2581 | ||
2582 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "tr_send:handle(0x%04x), " | ||
2583 | "(open), smid(%d), cb(%d)\n", ioc->name, handle, smid, | ||
2584 | ioc->tm_tr_cb_idx)); | ||
2606 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); | 2585 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); |
2607 | memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t)); | 2586 | memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t)); |
2608 | mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; | 2587 | mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; |
@@ -2632,35 +2611,15 @@ static u8 | |||
2632 | _scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, | 2611 | _scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, |
2633 | u8 msix_index, u32 reply) | 2612 | u8 msix_index, u32 reply) |
2634 | { | 2613 | { |
2635 | unsigned long flags; | ||
2636 | u16 handle; | ||
2637 | struct _sas_device *sas_device; | ||
2638 | Mpi2SasIoUnitControlReply_t *mpi_reply = | 2614 | Mpi2SasIoUnitControlReply_t *mpi_reply = |
2639 | mpt2sas_base_get_reply_virt_addr(ioc, reply); | 2615 | mpt2sas_base_get_reply_virt_addr(ioc, reply); |
2640 | 2616 | ||
2641 | handle = le16_to_cpu(mpi_reply->DevHandle); | 2617 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT |
2642 | 2618 | "sc_complete:handle(0x%04x), (open) " | |
2643 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 2619 | "smid(%d), ioc_status(0x%04x), loginfo(0x%08x)\n", |
2644 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 2620 | ioc->name, le16_to_cpu(mpi_reply->DevHandle), smid, |
2645 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 2621 | le16_to_cpu(mpi_reply->IOCStatus), |
2646 | 2622 | le32_to_cpu(mpi_reply->IOCLogInfo))); | |
2647 | if (sas_device) { | ||
2648 | sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE; | ||
2649 | if (sas_device->starget) | ||
2650 | dewtprintk(ioc, starget_printk(KERN_INFO, | ||
2651 | sas_device->starget, | ||
2652 | "sc_complete:handle(0x%04x), " | ||
2653 | "ioc_status(0x%04x), loginfo(0x%08x)\n", | ||
2654 | handle, le16_to_cpu(mpi_reply->IOCStatus), | ||
2655 | le32_to_cpu(mpi_reply->IOCLogInfo))); | ||
2656 | } else { | ||
2657 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT | ||
2658 | "sc_complete:handle(0x%04x), " | ||
2659 | "ioc_status(0x%04x), loginfo(0x%08x)\n", | ||
2660 | ioc->name, handle, le16_to_cpu(mpi_reply->IOCStatus), | ||
2661 | le32_to_cpu(mpi_reply->IOCLogInfo))); | ||
2662 | } | ||
2663 | |||
2664 | return 1; | 2623 | return 1; |
2665 | } | 2624 | } |
2666 | 2625 | ||
@@ -2684,87 +2643,63 @@ static u8 | |||
2684 | _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | 2643 | _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, |
2685 | u32 reply) | 2644 | u32 reply) |
2686 | { | 2645 | { |
2687 | unsigned long flags; | ||
2688 | u16 handle; | 2646 | u16 handle; |
2689 | struct _sas_device *sas_device; | 2647 | Mpi2SCSITaskManagementRequest_t *mpi_request_tm; |
2690 | Mpi2SCSITaskManagementReply_t *mpi_reply = | 2648 | Mpi2SCSITaskManagementReply_t *mpi_reply = |
2691 | mpt2sas_base_get_reply_virt_addr(ioc, reply); | 2649 | mpt2sas_base_get_reply_virt_addr(ioc, reply); |
2692 | Mpi2SasIoUnitControlRequest_t *mpi_request; | 2650 | Mpi2SasIoUnitControlRequest_t *mpi_request; |
2693 | u16 smid_sas_ctrl; | 2651 | u16 smid_sas_ctrl; |
2694 | struct MPT2SAS_TARGET *sas_target_priv_data; | ||
2695 | struct _tr_list *delayed_tr; | 2652 | struct _tr_list *delayed_tr; |
2696 | u8 rc; | ||
2697 | |||
2698 | handle = le16_to_cpu(mpi_reply->DevHandle); | ||
2699 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
2700 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | ||
2701 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
2702 | 2653 | ||
2703 | if (sas_device) { | 2654 | if (ioc->shost_recovery || ioc->remove_host) { |
2704 | sas_device->state |= MPTSAS_STATE_TR_COMPLETE; | 2655 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in " |
2705 | if (sas_device->starget) { | 2656 | "progress!\n", __func__, ioc->name)); |
2706 | dewtprintk(ioc, starget_printk(KERN_INFO, | 2657 | return 1; |
2707 | sas_device->starget, "tr_complete:handle(0x%04x), " | ||
2708 | "(%s) ioc_status(0x%04x), loginfo(0x%08x), " | ||
2709 | "completed(%d)\n", sas_device->handle, | ||
2710 | (sas_device->state & MPT2SAS_REQ_SAS_CNTRL) ? | ||
2711 | "open" : "active", | ||
2712 | le16_to_cpu(mpi_reply->IOCStatus), | ||
2713 | le32_to_cpu(mpi_reply->IOCLogInfo), | ||
2714 | le32_to_cpu(mpi_reply->TerminationCount))); | ||
2715 | if (sas_device->starget->hostdata) { | ||
2716 | sas_target_priv_data = | ||
2717 | sas_device->starget->hostdata; | ||
2718 | sas_target_priv_data->tm_busy = 0; | ||
2719 | } | ||
2720 | } | ||
2721 | } else { | ||
2722 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT | ||
2723 | "tr_complete:handle(0x%04x), (open) ioc_status(0x%04x), " | ||
2724 | "loginfo(0x%08x), completed(%d)\n", ioc->name, | ||
2725 | handle, le16_to_cpu(mpi_reply->IOCStatus), | ||
2726 | le32_to_cpu(mpi_reply->IOCLogInfo), | ||
2727 | le32_to_cpu(mpi_reply->TerminationCount))); | ||
2728 | } | 2658 | } |
2729 | 2659 | ||
2730 | if (!list_empty(&ioc->delayed_tr_list)) { | 2660 | mpi_request_tm = mpt2sas_base_get_msg_frame(ioc, smid); |
2731 | delayed_tr = list_entry(ioc->delayed_tr_list.next, | 2661 | handle = le16_to_cpu(mpi_request_tm->DevHandle); |
2732 | struct _tr_list, list); | 2662 | if (handle != le16_to_cpu(mpi_reply->DevHandle)) { |
2733 | mpt2sas_base_free_smid(ioc, smid); | 2663 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "spurious interrupt: " |
2734 | if (delayed_tr->state & MPT2SAS_REQ_SAS_CNTRL) | 2664 | "handle(0x%04x:0x%04x), smid(%d)!!!\n", ioc->name, handle, |
2735 | _scsih_tm_tr_send(ioc, delayed_tr->handle); | 2665 | le16_to_cpu(mpi_reply->DevHandle), smid)); |
2736 | list_del(&delayed_tr->list); | 2666 | return 0; |
2737 | kfree(delayed_tr); | ||
2738 | rc = 0; /* tells base_interrupt not to free mf */ | ||
2739 | } else | ||
2740 | rc = 1; | ||
2741 | |||
2742 | if (sas_device && !(sas_device->state & MPT2SAS_REQ_SAS_CNTRL)) | ||
2743 | return rc; | ||
2744 | |||
2745 | if (ioc->shost_recovery) { | ||
2746 | printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", | ||
2747 | __func__, ioc->name); | ||
2748 | return rc; | ||
2749 | } | 2667 | } |
2750 | 2668 | ||
2669 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT | ||
2670 | "tr_complete:handle(0x%04x), (open) smid(%d), ioc_status(0x%04x), " | ||
2671 | "loginfo(0x%08x), completed(%d)\n", ioc->name, | ||
2672 | handle, smid, le16_to_cpu(mpi_reply->IOCStatus), | ||
2673 | le32_to_cpu(mpi_reply->IOCLogInfo), | ||
2674 | le32_to_cpu(mpi_reply->TerminationCount))); | ||
2675 | |||
2751 | smid_sas_ctrl = mpt2sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx); | 2676 | smid_sas_ctrl = mpt2sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx); |
2752 | if (!smid_sas_ctrl) { | 2677 | if (!smid_sas_ctrl) { |
2753 | printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", | 2678 | printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", |
2754 | ioc->name, __func__); | 2679 | ioc->name, __func__); |
2755 | return rc; | 2680 | return 1; |
2756 | } | 2681 | } |
2757 | 2682 | ||
2758 | if (sas_device) | 2683 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sc_send:handle(0x%04x), " |
2759 | sas_device->state |= MPTSAS_STATE_CNTRL_SEND; | 2684 | "(open), smid(%d), cb(%d)\n", ioc->name, handle, smid_sas_ctrl, |
2760 | 2685 | ioc->tm_sas_control_cb_idx)); | |
2761 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl); | 2686 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl); |
2762 | memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); | 2687 | memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); |
2763 | mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; | 2688 | mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; |
2764 | mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; | 2689 | mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; |
2765 | mpi_request->DevHandle = mpi_reply->DevHandle; | 2690 | mpi_request->DevHandle = mpi_request_tm->DevHandle; |
2766 | mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl); | 2691 | mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl); |
2767 | return rc; | 2692 | |
2693 | if (!list_empty(&ioc->delayed_tr_list)) { | ||
2694 | delayed_tr = list_entry(ioc->delayed_tr_list.next, | ||
2695 | struct _tr_list, list); | ||
2696 | mpt2sas_base_free_smid(ioc, smid); | ||
2697 | _scsih_tm_tr_send(ioc, delayed_tr->handle); | ||
2698 | list_del(&delayed_tr->list); | ||
2699 | kfree(delayed_tr); | ||
2700 | return 0; /* tells base_interrupt not to free mf */ | ||
2701 | } | ||
2702 | return 1; | ||
2768 | } | 2703 | } |
2769 | 2704 | ||
2770 | /** | 2705 | /** |
@@ -4101,67 +4036,38 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd) | |||
4101 | } | 4036 | } |
4102 | 4037 | ||
4103 | /** | 4038 | /** |
4104 | * _scsih_remove_device - removing sas device object | 4039 | * _scsih_remove_pd_device - removing sas device pd object |
4105 | * @ioc: per adapter object | 4040 | * @ioc: per adapter object |
4106 | * @sas_device: the sas_device object | 4041 | * @sas_device_delete: the sas_device object |
4107 | * | 4042 | * |
4043 | * For hidden raid components, we do driver-fw handshake from | ||
4044 | * hotplug work threads. | ||
4108 | * Return nothing. | 4045 | * Return nothing. |
4109 | */ | 4046 | */ |
4110 | static void | 4047 | static void |
4111 | _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, struct _sas_device | 4048 | _scsih_remove_pd_device(struct MPT2SAS_ADAPTER *ioc, struct _sas_device |
4112 | *sas_device) | 4049 | sas_device) |
4113 | { | 4050 | { |
4114 | struct MPT2SAS_TARGET *sas_target_priv_data; | ||
4115 | Mpi2SasIoUnitControlReply_t mpi_reply; | 4051 | Mpi2SasIoUnitControlReply_t mpi_reply; |
4116 | Mpi2SasIoUnitControlRequest_t mpi_request; | 4052 | Mpi2SasIoUnitControlRequest_t mpi_request; |
4117 | u16 device_handle, handle; | 4053 | u16 vol_handle, handle; |
4118 | 4054 | ||
4119 | if (!sas_device) | 4055 | handle = sas_device.handle; |
4120 | return; | ||
4121 | |||
4122 | handle = sas_device->handle; | ||
4123 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle(0x%04x)," | 4056 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle(0x%04x)," |
4124 | " sas_addr(0x%016llx)\n", ioc->name, __func__, handle, | 4057 | " sas_addr(0x%016llx)\n", ioc->name, __func__, handle, |
4125 | (unsigned long long) sas_device->sas_address)); | 4058 | (unsigned long long) sas_device.sas_address)); |
4126 | |||
4127 | if (sas_device->starget && sas_device->starget->hostdata) { | ||
4128 | sas_target_priv_data = sas_device->starget->hostdata; | ||
4129 | sas_target_priv_data->deleted = 1; | ||
4130 | } | ||
4131 | |||
4132 | if (ioc->remove_host || ioc->shost_recovery || !handle) | ||
4133 | goto out; | ||
4134 | 4059 | ||
4135 | if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) { | 4060 | vol_handle = sas_device.volume_handle; |
4136 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip " | 4061 | if (!vol_handle) |
4137 | "target_reset handle(0x%04x)\n", ioc->name, | 4062 | return; |
4138 | handle)); | 4063 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset: " |
4139 | goto skip_tr; | 4064 | "handle(0x%04x)\n", ioc->name, vol_handle)); |
4140 | } | 4065 | mpt2sas_scsih_issue_tm(ioc, vol_handle, 0, |
4141 | 4066 | MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30); | |
4142 | /* Target Reset to flush out all the outstanding IO */ | 4067 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset " |
4143 | device_handle = (sas_device->hidden_raid_component) ? | 4068 | "done: handle(0x%04x)\n", ioc->name, vol_handle)); |
4144 | sas_device->volume_handle : handle; | 4069 | if (ioc->shost_recovery) |
4145 | if (device_handle) { | 4070 | return; |
4146 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset: " | ||
4147 | "handle(0x%04x)\n", ioc->name, device_handle)); | ||
4148 | mutex_lock(&ioc->tm_cmds.mutex); | ||
4149 | mpt2sas_scsih_issue_tm(ioc, device_handle, 0, | ||
4150 | MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 10); | ||
4151 | ioc->tm_cmds.status = MPT2_CMD_NOT_USED; | ||
4152 | mutex_unlock(&ioc->tm_cmds.mutex); | ||
4153 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset " | ||
4154 | "done: handle(0x%04x)\n", ioc->name, device_handle)); | ||
4155 | if (ioc->shost_recovery) | ||
4156 | goto out; | ||
4157 | } | ||
4158 | skip_tr: | ||
4159 | |||
4160 | if ((sas_device->state & MPTSAS_STATE_CNTRL_COMPLETE)) { | ||
4161 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip " | ||
4162 | "sas_cntrl handle(0x%04x)\n", ioc->name, handle)); | ||
4163 | goto out; | ||
4164 | } | ||
4165 | 4071 | ||
4166 | /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */ | 4072 | /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */ |
4167 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: handle" | 4073 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: handle" |
@@ -4169,34 +4075,68 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, struct _sas_device | |||
4169 | memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); | 4075 | memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); |
4170 | mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; | 4076 | mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; |
4171 | mpi_request.Operation = MPI2_SAS_OP_REMOVE_DEVICE; | 4077 | mpi_request.Operation = MPI2_SAS_OP_REMOVE_DEVICE; |
4172 | mpi_request.DevHandle = handle; | 4078 | mpi_request.DevHandle = cpu_to_le16(handle); |
4173 | mpi_request.VF_ID = 0; /* TODO */ | ||
4174 | mpi_request.VP_ID = 0; | ||
4175 | if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply, | 4079 | if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply, |
4176 | &mpi_request)) != 0) { | 4080 | &mpi_request)) != 0) |
4177 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | 4081 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", |
4178 | ioc->name, __FILE__, __LINE__, __func__); | 4082 | ioc->name, __FILE__, __LINE__, __func__); |
4179 | } | ||
4180 | 4083 | ||
4181 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: ioc_status" | 4084 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: ioc_status" |
4182 | "(0x%04x), loginfo(0x%08x)\n", ioc->name, | 4085 | "(0x%04x), loginfo(0x%08x)\n", ioc->name, |
4183 | le16_to_cpu(mpi_reply.IOCStatus), | 4086 | le16_to_cpu(mpi_reply.IOCStatus), |
4184 | le32_to_cpu(mpi_reply.IOCLogInfo))); | 4087 | le32_to_cpu(mpi_reply.IOCLogInfo))); |
4185 | 4088 | ||
4186 | out: | 4089 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit: handle(0x%04x)," |
4090 | " sas_addr(0x%016llx)\n", ioc->name, __func__, handle, | ||
4091 | (unsigned long long) sas_device.sas_address)); | ||
4092 | } | ||
4093 | |||
4094 | /** | ||
4095 | * _scsih_remove_device - removing sas device object | ||
4096 | * @ioc: per adapter object | ||
4097 | * @sas_device_delete: the sas_device object | ||
4098 | * | ||
4099 | * Return nothing. | ||
4100 | */ | ||
4101 | static void | ||
4102 | _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, | ||
4103 | struct _sas_device *sas_device) | ||
4104 | { | ||
4105 | struct _sas_device sas_device_backup; | ||
4106 | struct MPT2SAS_TARGET *sas_target_priv_data; | ||
4187 | 4107 | ||
4188 | _scsih_ublock_io_device(ioc, handle); | 4108 | if (!sas_device) |
4109 | return; | ||
4110 | |||
4111 | memcpy(&sas_device_backup, sas_device, sizeof(struct _sas_device)); | ||
4112 | _scsih_sas_device_remove(ioc, sas_device); | ||
4189 | 4113 | ||
4190 | mpt2sas_transport_port_remove(ioc, sas_device->sas_address, | 4114 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: " |
4191 | sas_device->sas_address_parent); | 4115 | "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, |
4116 | sas_device_backup.handle, (unsigned long long) | ||
4117 | sas_device_backup.sas_address)); | ||
4118 | |||
4119 | if (sas_device_backup.starget && sas_device_backup.starget->hostdata) { | ||
4120 | sas_target_priv_data = sas_device_backup.starget->hostdata; | ||
4121 | sas_target_priv_data->deleted = 1; | ||
4122 | } | ||
4123 | |||
4124 | if (sas_device_backup.hidden_raid_component) | ||
4125 | _scsih_remove_pd_device(ioc, sas_device_backup); | ||
4126 | |||
4127 | _scsih_ublock_io_device(ioc, sas_device_backup.handle); | ||
4128 | |||
4129 | mpt2sas_transport_port_remove(ioc, sas_device_backup.sas_address, | ||
4130 | sas_device_backup.sas_address_parent); | ||
4192 | 4131 | ||
4193 | printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" | 4132 | printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr" |
4194 | "(0x%016llx)\n", ioc->name, handle, | 4133 | "(0x%016llx)\n", ioc->name, sas_device_backup.handle, |
4195 | (unsigned long long) sas_device->sas_address); | 4134 | (unsigned long long) sas_device_backup.sas_address); |
4196 | _scsih_sas_device_remove(ioc, sas_device); | ||
4197 | 4135 | ||
4198 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit: handle" | 4136 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit: " |
4199 | "(0x%04x)\n", ioc->name, __func__, handle)); | 4137 | "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, |
4138 | sas_device_backup.handle, (unsigned long long) | ||
4139 | sas_device_backup.sas_address)); | ||
4200 | } | 4140 | } |
4201 | 4141 | ||
4202 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 4142 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
@@ -5442,7 +5382,6 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | |||
5442 | if (sas_device->sas_address == sas_address && | 5382 | if (sas_device->sas_address == sas_address && |
5443 | sas_device->slot == slot && sas_device->starget) { | 5383 | sas_device->slot == slot && sas_device->starget) { |
5444 | sas_device->responding = 1; | 5384 | sas_device->responding = 1; |
5445 | sas_device->state = 0; | ||
5446 | starget = sas_device->starget; | 5385 | starget = sas_device->starget; |
5447 | sas_target_priv_data = starget->hostdata; | 5386 | sas_target_priv_data = starget->hostdata; |
5448 | sas_target_priv_data->tm_busy = 0; | 5387 | sas_target_priv_data->tm_busy = 0; |