aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2010-06-17 04:16:13 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 13:02:19 -0400
commitf3eedd698ebafd0fe8a292672604a2db61c2c00a (patch)
treeabe6d22775411a19953f23608bb1dc61a32bb57d /drivers/scsi/mpt2sas
parent7fbae67a3faa90abcbe949f1494769c84e51e189 (diff)
[SCSI] mpt2sas: Redesign Raid devices event handling using pd_handles per HBA
Actual problem : Driver may receiving the top level expander removal event prior to all the individual PD removal events, hence the driver is breaking down all the PDs in advanced to the actaul PD UNHIDE event. Driver sends multiple Target Resets to the same volume handle for each individual PD removal. FIX DESCRIPTION: To fix this issue, the entire PD device handshake protocal has to be moved to interrupt context so the breakdown occurs immediately after the actual UNHIDE event arrives. The driver will only issue one Target Reset to the volume handle, occurring after the FAILED or MISSING volume status event arrives from interrupt context. For the PD UNHIDE event, the driver will issue target resets to the PD handles, followed by OP_REMOVE. The driver will set the "deteleted" flag during interrupt context. A "pd_handle" bitmask was introduced so the driver has a list of known pds during entire life of the PD; this replaces the "hidden_raid_component" flag handle in the sas_device object. Each bit in the bitmask represents a device handle. The bit in the bitmask would be toggled ON/OFF when the HIDE/UNHIDE events arrive; also this pd_handle bitmask would bould be refreshed across host resets. Here we kept older behavior of sending target reset to volume when there is a single drive pull, wait for the reply, then send target resets to the PDs. We kept this behavior so the driver will behave the same for older versions of firmware. 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.c17
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h14
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c463
3 files changed, 391 insertions, 103 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 3774b0742b2b..bb8acf781690 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -3468,6 +3468,12 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3468 kfree(delayed_tr); 3468 kfree(delayed_tr);
3469 } 3469 }
3470 3470
3471 list_for_each_entry_safe(delayed_tr, delayed_tr_next,
3472 &ioc->delayed_tr_volume_list, list) {
3473 list_del(&delayed_tr->list);
3474 kfree(delayed_tr);
3475 }
3476
3471 /* initialize the scsi lookup free list */ 3477 /* initialize the scsi lookup free list */
3472 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); 3478 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
3473 INIT_LIST_HEAD(&ioc->free_list); 3479 INIT_LIST_HEAD(&ioc->free_list);
@@ -3622,6 +3628,15 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3622 3628
3623 init_waitqueue_head(&ioc->reset_wq); 3629 init_waitqueue_head(&ioc->reset_wq);
3624 3630
3631 /* allocate memory pd handle bitmask list */
3632 ioc->pd_handles_sz = (ioc->facts.MaxDevHandle / 8);
3633 if (ioc->facts.MaxDevHandle % 8)
3634 ioc->pd_handles_sz++;
3635 ioc->pd_handles = kzalloc(ioc->pd_handles_sz,
3636 GFP_KERNEL);
3637 if (!ioc->pd_handles)
3638 goto out_free_resources;
3639
3625 ioc->fwfault_debug = mpt2sas_fwfault_debug; 3640 ioc->fwfault_debug = mpt2sas_fwfault_debug;
3626 3641
3627 /* base internal command bits */ 3642 /* base internal command bits */
@@ -3691,6 +3706,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3691 mpt2sas_base_free_resources(ioc); 3706 mpt2sas_base_free_resources(ioc);
3692 _base_release_memory_pools(ioc); 3707 _base_release_memory_pools(ioc);
3693 pci_set_drvdata(ioc->pdev, NULL); 3708 pci_set_drvdata(ioc->pdev, NULL);
3709 kfree(ioc->pd_handles);
3694 kfree(ioc->tm_cmds.reply); 3710 kfree(ioc->tm_cmds.reply);
3695 kfree(ioc->transport_cmds.reply); 3711 kfree(ioc->transport_cmds.reply);
3696 kfree(ioc->scsih_cmds.reply); 3712 kfree(ioc->scsih_cmds.reply);
@@ -3726,6 +3742,7 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
3726 mpt2sas_base_free_resources(ioc); 3742 mpt2sas_base_free_resources(ioc);
3727 _base_release_memory_pools(ioc); 3743 _base_release_memory_pools(ioc);
3728 pci_set_drvdata(ioc->pdev, NULL); 3744 pci_set_drvdata(ioc->pdev, NULL);
3745 kfree(ioc->pd_handles);
3729 kfree(ioc->pfacts); 3746 kfree(ioc->pfacts);
3730 kfree(ioc->ctl_cmds.reply); 3747 kfree(ioc->ctl_cmds.reply);
3731 kfree(ioc->base_cmds.reply); 3748 kfree(ioc->base_cmds.reply);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index e2c5cee6450e..6fdee1680a6b 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -276,7 +276,6 @@ struct _internal_cmd {
276 * @channel: target channel 276 * @channel: target channel
277 * @slot: number number 277 * @slot: number number
278 * @phy: phy identifier provided in sas device page 0 278 * @phy: phy identifier provided in sas device page 0
279 * @hidden_raid_component: set to 1 when this is a raid member
280 * @responding: used in _scsih_sas_device_mark_responding 279 * @responding: used in _scsih_sas_device_mark_responding
281 */ 280 */
282struct _sas_device { 281struct _sas_device {
@@ -295,7 +294,6 @@ struct _sas_device {
295 int channel; 294 int channel;
296 u16 slot; 295 u16 slot;
297 u8 phy; 296 u8 phy;
298 u8 hidden_raid_component;
299 u8 responding; 297 u8 responding;
300}; 298};
301 299
@@ -489,6 +487,8 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
489 * @ctl_cb_idx: clt internal commands 487 * @ctl_cb_idx: clt internal commands
490 * @base_cb_idx: base internal commands 488 * @base_cb_idx: base internal commands
491 * @config_cb_idx: base internal commands 489 * @config_cb_idx: base internal commands
490 * @tm_tr_cb_idx : device removal target reset handshake
491 * @tm_tr_volume_cb_idx : volume removal target reset
492 * @base_cmds: 492 * @base_cmds:
493 * @transport_cmds: 493 * @transport_cmds:
494 * @scsih_cmds: 494 * @scsih_cmds:
@@ -517,6 +517,9 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
517 * @sas_device_lock: 517 * @sas_device_lock:
518 * @io_missing_delay: time for IO completed by fw when PDR enabled 518 * @io_missing_delay: time for IO completed by fw when PDR enabled
519 * @device_missing_delay: time for device missing by fw when PDR enabled 519 * @device_missing_delay: time for device missing by fw when PDR enabled
520 * @sas_id : used for setting volume target IDs
521 * @pd_handles : bitmask for PD handles
522 * @pd_handles_sz : size of pd_handle bitmask
520 * @config_page_sz: config page size 523 * @config_page_sz: config page size
521 * @config_page: reserve memory for config page payload 524 * @config_page: reserve memory for config page payload
522 * @config_page_dma: 525 * @config_page_dma:
@@ -569,6 +572,8 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
569 * @reply_post_free_dma: 572 * @reply_post_free_dma:
570 * @reply_post_free_dma_pool: 573 * @reply_post_free_dma_pool:
571 * @reply_post_host_index: head index in the pool where FW completes IO 574 * @reply_post_host_index: head index in the pool where FW completes IO
575 * @delayed_tr_list: target reset link list
576 * @delayed_tr_volume_list: volume target reset link list
572 */ 577 */
573struct MPT2SAS_ADAPTER { 578struct MPT2SAS_ADAPTER {
574 struct list_head list; 579 struct list_head list;
@@ -627,6 +632,7 @@ struct MPT2SAS_ADAPTER {
627 u8 base_cb_idx; 632 u8 base_cb_idx;
628 u8 config_cb_idx; 633 u8 config_cb_idx;
629 u8 tm_tr_cb_idx; 634 u8 tm_tr_cb_idx;
635 u8 tm_tr_volume_cb_idx;
630 u8 tm_sas_control_cb_idx; 636 u8 tm_sas_control_cb_idx;
631 struct _internal_cmd base_cmds; 637 struct _internal_cmd base_cmds;
632 struct _internal_cmd transport_cmds; 638 struct _internal_cmd transport_cmds;
@@ -670,6 +676,9 @@ struct MPT2SAS_ADAPTER {
670 u16 device_missing_delay; 676 u16 device_missing_delay;
671 int sas_id; 677 int sas_id;
672 678
679 void *pd_handles;
680 u16 pd_handles_sz;
681
673 /* config page */ 682 /* config page */
674 u16 config_page_sz; 683 u16 config_page_sz;
675 void *config_page; 684 void *config_page;
@@ -741,6 +750,7 @@ struct MPT2SAS_ADAPTER {
741 u32 reply_post_host_index; 750 u32 reply_post_host_index;
742 751
743 struct list_head delayed_tr_list; 752 struct list_head delayed_tr_list;
753 struct list_head delayed_tr_volume_list;
744 754
745 /* diag buffer support */ 755 /* diag buffer support */
746 u8 *diag_buffer[MPI2_DIAG_BUF_TYPE_COUNT]; 756 u8 *diag_buffer[MPI2_DIAG_BUF_TYPE_COUNT];
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index db12e184d1d9..b327d60fad1b 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -70,6 +70,8 @@ static void _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
70 struct _sas_node *sas_expander); 70 struct _sas_node *sas_expander);
71static void _firmware_event_work(struct work_struct *work); 71static void _firmware_event_work(struct work_struct *work);
72 72
73static u8 _scsih_check_for_pending_tm(struct MPT2SAS_ADAPTER *ioc, u16 smid);
74
73/* global parameters */ 75/* global parameters */
74LIST_HEAD(mpt2sas_ioc_list); 76LIST_HEAD(mpt2sas_ioc_list);
75 77
@@ -84,6 +86,7 @@ static u8 config_cb_idx = -1;
84static int mpt_ids; 86static int mpt_ids;
85 87
86static u8 tm_tr_cb_idx = -1 ; 88static u8 tm_tr_cb_idx = -1 ;
89static u8 tm_tr_volume_cb_idx = -1 ;
87static u8 tm_sas_control_cb_idx = -1; 90static u8 tm_sas_control_cb_idx = -1;
88 91
89/* command line options */ 92/* command line options */
@@ -1226,7 +1229,7 @@ _scsih_target_alloc(struct scsi_target *starget)
1226 sas_device->starget = starget; 1229 sas_device->starget = starget;
1227 sas_device->id = starget->id; 1230 sas_device->id = starget->id;
1228 sas_device->channel = starget->channel; 1231 sas_device->channel = starget->channel;
1229 if (sas_device->hidden_raid_component) 1232 if (test_bit(sas_device->handle, ioc->pd_handles))
1230 sas_target_priv_data->flags |= 1233 sas_target_priv_data->flags |=
1231 MPT_TARGET_FLAGS_RAID_COMPONENT; 1234 MPT_TARGET_FLAGS_RAID_COMPONENT;
1232 } 1235 }
@@ -2583,6 +2586,7 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2583 Mpi2SCSITaskManagementRequest_t *mpi_request; 2586 Mpi2SCSITaskManagementRequest_t *mpi_request;
2584 u16 smid; 2587 u16 smid;
2585 struct _sas_device *sas_device; 2588 struct _sas_device *sas_device;
2589 struct MPT2SAS_TARGET *sas_target_priv_data;
2586 unsigned long flags; 2590 unsigned long flags;
2587 struct _tr_list *delayed_tr; 2591 struct _tr_list *delayed_tr;
2588 2592
@@ -2592,11 +2596,20 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2592 return; 2596 return;
2593 } 2597 }
2594 2598
2599 /* if PD, then return */
2600 if (test_bit(handle, ioc->pd_handles))
2601 return;
2602
2595 spin_lock_irqsave(&ioc->sas_device_lock, flags); 2603 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2596 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 2604 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2597 if (sas_device && sas_device->hidden_raid_component) { 2605 if (sas_device && sas_device->starget &&
2598 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 2606 sas_device->starget->hostdata) {
2599 return; 2607 sas_target_priv_data = sas_device->starget->hostdata;
2608 sas_target_priv_data->deleted = 1;
2609 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2610 "setting delete flag: handle(0x%04x), "
2611 "sas_addr(0x%016llx)\n", ioc->name, handle,
2612 (unsigned long long) sas_device->sas_address));
2600 } 2613 }
2601 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 2614 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2602 2615
@@ -2659,6 +2672,99 @@ _scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
2659} 2672}
2660 2673
2661/** 2674/**
2675 * _scsih_tm_tr_volume_send - send target reset request for volumes
2676 * @ioc: per adapter object
2677 * @handle: device handle
2678 * Context: interrupt time.
2679 *
2680 * This is designed to send muliple task management request at the same
2681 * time to the fifo. If the fifo is full, we will append the request,
2682 * and process it in a future completion.
2683 */
2684static void
2685_scsih_tm_tr_volume_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2686{
2687 Mpi2SCSITaskManagementRequest_t *mpi_request;
2688 u16 smid;
2689 struct _tr_list *delayed_tr;
2690
2691 if (ioc->shost_recovery || ioc->remove_host) {
2692 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in "
2693 "progress!\n", __func__, ioc->name));
2694 return;
2695 }
2696
2697 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_volume_cb_idx);
2698 if (!smid) {
2699 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
2700 if (!delayed_tr)
2701 return;
2702 INIT_LIST_HEAD(&delayed_tr->list);
2703 delayed_tr->handle = handle;
2704 list_add_tail(&delayed_tr->list, &ioc->delayed_tr_volume_list);
2705 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2706 "DELAYED:tr:handle(0x%04x), (open)\n",
2707 ioc->name, handle));
2708 return;
2709 }
2710
2711 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "tr_send:handle(0x%04x), "
2712 "(open), smid(%d), cb(%d)\n", ioc->name, handle, smid,
2713 ioc->tm_tr_volume_cb_idx));
2714 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
2715 memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t));
2716 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
2717 mpi_request->DevHandle = cpu_to_le16(handle);
2718 mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
2719 mpt2sas_base_put_smid_hi_priority(ioc, smid);
2720}
2721
2722/**
2723 * _scsih_tm_volume_tr_complete - target reset completion
2724 * @ioc: per adapter object
2725 * @smid: system request message index
2726 * @msix_index: MSIX table index supplied by the OS
2727 * @reply: reply message frame(lower 32bit addr)
2728 * Context: interrupt time.
2729 *
2730 * Return 1 meaning mf should be freed from _base_interrupt
2731 * 0 means the mf is freed from this function.
2732 */
2733static u8
2734_scsih_tm_volume_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
2735 u8 msix_index, u32 reply)
2736{
2737 u16 handle;
2738 Mpi2SCSITaskManagementRequest_t *mpi_request_tm;
2739 Mpi2SCSITaskManagementReply_t *mpi_reply =
2740 mpt2sas_base_get_reply_virt_addr(ioc, reply);
2741
2742 if (ioc->shost_recovery || ioc->remove_host) {
2743 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in "
2744 "progress!\n", __func__, ioc->name));
2745 return 1;
2746 }
2747
2748 mpi_request_tm = mpt2sas_base_get_msg_frame(ioc, smid);
2749 handle = le16_to_cpu(mpi_request_tm->DevHandle);
2750 if (handle != le16_to_cpu(mpi_reply->DevHandle)) {
2751 dewtprintk(ioc, printk("spurious interrupt: "
2752 "handle(0x%04x:0x%04x), smid(%d)!!!\n", handle,
2753 le16_to_cpu(mpi_reply->DevHandle), smid));
2754 return 0;
2755 }
2756
2757 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2758 "tr_complete:handle(0x%04x), (open) smid(%d), ioc_status(0x%04x), "
2759 "loginfo(0x%08x), completed(%d)\n", ioc->name,
2760 handle, smid, le16_to_cpu(mpi_reply->IOCStatus),
2761 le32_to_cpu(mpi_reply->IOCLogInfo),
2762 le32_to_cpu(mpi_reply->TerminationCount)));
2763
2764 return _scsih_check_for_pending_tm(ioc, smid);
2765}
2766
2767/**
2662 * _scsih_tm_tr_complete - 2768 * _scsih_tm_tr_complete -
2663 * @ioc: per adapter object 2769 * @ioc: per adapter object
2664 * @smid: system request message index 2770 * @smid: system request message index
@@ -2684,7 +2790,6 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2684 mpt2sas_base_get_reply_virt_addr(ioc, reply); 2790 mpt2sas_base_get_reply_virt_addr(ioc, reply);
2685 Mpi2SasIoUnitControlRequest_t *mpi_request; 2791 Mpi2SasIoUnitControlRequest_t *mpi_request;
2686 u16 smid_sas_ctrl; 2792 u16 smid_sas_ctrl;
2687 struct _tr_list *delayed_tr;
2688 2793
2689 if (ioc->shost_recovery || ioc->remove_host) { 2794 if (ioc->shost_recovery || ioc->remove_host) {
2690 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in " 2795 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: host reset in "
@@ -2725,6 +2830,35 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2725 mpi_request->DevHandle = mpi_request_tm->DevHandle; 2830 mpi_request->DevHandle = mpi_request_tm->DevHandle;
2726 mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl); 2831 mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl);
2727 2832
2833 return _scsih_check_for_pending_tm(ioc, smid);
2834}
2835
2836/**
2837 * _scsih_check_for_pending_tm - check for pending task management
2838 * @ioc: per adapter object
2839 * @smid: system request message index
2840 *
2841 * This will check delayed target reset list, and feed the
2842 * next reqeust.
2843 *
2844 * Return 1 meaning mf should be freed from _base_interrupt
2845 * 0 means the mf is freed from this function.
2846 */
2847static u8
2848_scsih_check_for_pending_tm(struct MPT2SAS_ADAPTER *ioc, u16 smid)
2849{
2850 struct _tr_list *delayed_tr;
2851
2852 if (!list_empty(&ioc->delayed_tr_volume_list)) {
2853 delayed_tr = list_entry(ioc->delayed_tr_volume_list.next,
2854 struct _tr_list, list);
2855 mpt2sas_base_free_smid(ioc, smid);
2856 _scsih_tm_tr_volume_send(ioc, delayed_tr->handle);
2857 list_del(&delayed_tr->list);
2858 kfree(delayed_tr);
2859 return 0;
2860 }
2861
2728 if (!list_empty(&ioc->delayed_tr_list)) { 2862 if (!list_empty(&ioc->delayed_tr_list)) {
2729 delayed_tr = list_entry(ioc->delayed_tr_list.next, 2863 delayed_tr = list_entry(ioc->delayed_tr_list.next,
2730 struct _tr_list, list); 2864 struct _tr_list, list);
@@ -2732,8 +2866,9 @@ _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2732 _scsih_tm_tr_send(ioc, delayed_tr->handle); 2866 _scsih_tm_tr_send(ioc, delayed_tr->handle);
2733 list_del(&delayed_tr->list); 2867 list_del(&delayed_tr->list);
2734 kfree(delayed_tr); 2868 kfree(delayed_tr);
2735 return 0; /* tells base_interrupt not to free mf */ 2869 return 0;
2736 } 2870 }
2871
2737 return 1; 2872 return 1;
2738} 2873}
2739 2874
@@ -2817,6 +2952,165 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc,
2817} 2952}
2818 2953
2819/** 2954/**
2955 * _scsih_set_volume_delete_flag - setting volume delete flag
2956 * @ioc: per adapter object
2957 * @handle: device handle
2958 *
2959 * This
2960 * Return nothing.
2961 */
2962static void
2963_scsih_set_volume_delete_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2964{
2965 struct _raid_device *raid_device;
2966 struct MPT2SAS_TARGET *sas_target_priv_data;
2967 unsigned long flags;
2968
2969 spin_lock_irqsave(&ioc->raid_device_lock, flags);
2970 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
2971 if (raid_device && raid_device->starget &&
2972 raid_device->starget->hostdata) {
2973 sas_target_priv_data =
2974 raid_device->starget->hostdata;
2975 sas_target_priv_data->deleted = 1;
2976 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
2977 "setting delete flag: handle(0x%04x), "
2978 "wwid(0x%016llx)\n", ioc->name, handle,
2979 (unsigned long long) raid_device->wwid));
2980 }
2981 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
2982}
2983
2984/**
2985 * _scsih_set_volume_handle_for_tr - set handle for target reset to volume
2986 * @handle: input handle
2987 * @a: handle for volume a
2988 * @b: handle for volume b
2989 *
2990 * IR firmware only supports two raid volumes. The purpose of this
2991 * routine is to set the volume handle in either a or b. When the given
2992 * input handle is non-zero, or when a and b have not been set before.
2993 */
2994static void
2995_scsih_set_volume_handle_for_tr(u16 handle, u16 *a, u16 *b)
2996{
2997 if (!handle || handle == *a || handle == *b)
2998 return;
2999 if (!*a)
3000 *a = handle;
3001 else if (!*b)
3002 *b = handle;
3003}
3004
3005/**
3006 * _scsih_check_ir_config_unhide_events - check for UNHIDE events
3007 * @ioc: per adapter object
3008 * @event_data: the event data payload
3009 * Context: interrupt time.
3010 *
3011 * This routine will send target reset to volume, followed by target
3012 * resets to the PDs. This is called when a PD has been removed, or
3013 * volume has been deleted or removed. When the target reset is sent
3014 * to volume, the PD target resets need to be queued to start upon
3015 * completion of the volume target reset.
3016 *
3017 * Return nothing.
3018 */
3019static void
3020_scsih_check_ir_config_unhide_events(struct MPT2SAS_ADAPTER *ioc,
3021 Mpi2EventDataIrConfigChangeList_t *event_data)
3022{
3023 Mpi2EventIrConfigElement_t *element;
3024 int i;
3025 u16 handle, volume_handle, a, b;
3026 struct _tr_list *delayed_tr;
3027
3028 a = 0;
3029 b = 0;
3030
3031 /* Volume Resets for Deleted or Removed */
3032 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
3033 for (i = 0; i < event_data->NumElements; i++, element++) {
3034 if (element->ReasonCode ==
3035 MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED ||
3036 element->ReasonCode ==
3037 MPI2_EVENT_IR_CHANGE_RC_REMOVED) {
3038 volume_handle = le16_to_cpu(element->VolDevHandle);
3039 _scsih_set_volume_delete_flag(ioc, volume_handle);
3040 _scsih_set_volume_handle_for_tr(volume_handle, &a, &b);
3041 }
3042 }
3043
3044 /* Volume Resets for UNHIDE events */
3045 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
3046 for (i = 0; i < event_data->NumElements; i++, element++) {
3047 if (le32_to_cpu(event_data->Flags) &
3048 MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG)
3049 continue;
3050 if (element->ReasonCode == MPI2_EVENT_IR_CHANGE_RC_UNHIDE) {
3051 volume_handle = le16_to_cpu(element->VolDevHandle);
3052 _scsih_set_volume_handle_for_tr(volume_handle, &a, &b);
3053 }
3054 }
3055
3056 if (a)
3057 _scsih_tm_tr_volume_send(ioc, a);
3058 if (b)
3059 _scsih_tm_tr_volume_send(ioc, b);
3060
3061 /* PD target resets */
3062 element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
3063 for (i = 0; i < event_data->NumElements; i++, element++) {
3064 if (element->ReasonCode != MPI2_EVENT_IR_CHANGE_RC_UNHIDE)
3065 continue;
3066 handle = le16_to_cpu(element->PhysDiskDevHandle);
3067 volume_handle = le16_to_cpu(element->VolDevHandle);
3068 clear_bit(handle, ioc->pd_handles);
3069 if (!volume_handle)
3070 _scsih_tm_tr_send(ioc, handle);
3071 else if (volume_handle == a || volume_handle == b) {
3072 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
3073 BUG_ON(!delayed_tr);
3074 INIT_LIST_HEAD(&delayed_tr->list);
3075 delayed_tr->handle = handle;
3076 list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list);
3077 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
3078 "DELAYED:tr:handle(0x%04x), (open)\n", ioc->name,
3079 handle));
3080 } else
3081 _scsih_tm_tr_send(ioc, handle);
3082 }
3083}
3084
3085
3086/**
3087 * _scsih_check_volume_delete_events - set delete flag for volumes
3088 * @ioc: per adapter object
3089 * @event_data: the event data payload
3090 * Context: interrupt time.
3091 *
3092 * This will handle the case when the cable connected to entire volume is
3093 * pulled. We will take care of setting the deleted flag so normal IO will
3094 * not be sent.
3095 *
3096 * Return nothing.
3097 */
3098static void
3099_scsih_check_volume_delete_events(struct MPT2SAS_ADAPTER *ioc,
3100 Mpi2EventDataIrVolume_t *event_data)
3101{
3102 u32 state;
3103
3104 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
3105 return;
3106 state = le32_to_cpu(event_data->NewValue);
3107 if (state == MPI2_RAID_VOL_STATE_MISSING || state ==
3108 MPI2_RAID_VOL_STATE_FAILED)
3109 _scsih_set_volume_delete_flag(ioc,
3110 le16_to_cpu(event_data->VolDevHandle));
3111}
3112
3113/**
2820 * _scsih_flush_running_cmds - completing outstanding commands. 3114 * _scsih_flush_running_cmds - completing outstanding commands.
2821 * @ioc: per adapter object 3115 * @ioc: per adapter object
2822 * 3116 *
@@ -4204,7 +4498,6 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
4204 sas_device->device_info = device_info; 4498 sas_device->device_info = device_info;
4205 sas_device->sas_address = sas_address; 4499 sas_device->sas_address = sas_address;
4206 sas_device->phy = sas_device_pg0.PhyNum; 4500 sas_device->phy = sas_device_pg0.PhyNum;
4207 sas_device->hidden_raid_component = is_pd;
4208 4501
4209 /* get enclosure_logical_id */ 4502 /* get enclosure_logical_id */
4210 if (sas_device->enclosure_handle && !(mpt2sas_config_get_enclosure_pg0( 4503 if (sas_device->enclosure_handle && !(mpt2sas_config_get_enclosure_pg0(
@@ -4225,62 +4518,6 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
4225} 4518}
4226 4519
4227/** 4520/**
4228 * _scsih_remove_pd_device - removing sas device pd object
4229 * @ioc: per adapter object
4230 * @sas_device_delete: the sas_device object
4231 *
4232 * For hidden raid components, we do driver-fw handshake from
4233 * hotplug work threads.
4234 * Return nothing.
4235 */
4236static void
4237_scsih_remove_pd_device(struct MPT2SAS_ADAPTER *ioc, struct _sas_device
4238 sas_device)
4239{
4240 Mpi2SasIoUnitControlReply_t mpi_reply;
4241 Mpi2SasIoUnitControlRequest_t mpi_request;
4242 u16 vol_handle, handle;
4243
4244 handle = sas_device.handle;
4245 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: handle(0x%04x),"
4246 " sas_addr(0x%016llx)\n", ioc->name, __func__, handle,
4247 (unsigned long long) sas_device.sas_address));
4248
4249 vol_handle = sas_device.volume_handle;
4250 if (!vol_handle)
4251 return;
4252 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset: "
4253 "handle(0x%04x)\n", ioc->name, vol_handle));
4254 mpt2sas_scsih_issue_tm(ioc, vol_handle, 0, 0, 0,
4255 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30, NULL);
4256 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset "
4257 "done: handle(0x%04x)\n", ioc->name, vol_handle));
4258 if (ioc->shost_recovery)
4259 return;
4260
4261 /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */
4262 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: handle"
4263 "(0x%04x)\n", ioc->name, handle));
4264 memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
4265 mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
4266 mpi_request.Operation = MPI2_SAS_OP_REMOVE_DEVICE;
4267 mpi_request.DevHandle = cpu_to_le16(handle);
4268 if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply,
4269 &mpi_request)) != 0)
4270 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
4271 ioc->name, __FILE__, __LINE__, __func__);
4272
4273 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: ioc_status"
4274 "(0x%04x), loginfo(0x%08x)\n", ioc->name,
4275 le16_to_cpu(mpi_reply.IOCStatus),
4276 le32_to_cpu(mpi_reply.IOCLogInfo)));
4277
4278 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit: handle(0x%04x),"
4279 " sas_addr(0x%016llx)\n", ioc->name, __func__, handle,
4280 (unsigned long long) sas_device.sas_address));
4281}
4282
4283/**
4284 * _scsih_remove_device - removing sas device object 4521 * _scsih_remove_device - removing sas device object
4285 * @ioc: per adapter object 4522 * @ioc: per adapter object
4286 * @sas_device_delete: the sas_device object 4523 * @sas_device_delete: the sas_device object
@@ -4310,9 +4547,6 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc,
4310 sas_target_priv_data->deleted = 1; 4547 sas_target_priv_data->deleted = 1;
4311 } 4548 }
4312 4549
4313 if (sas_device_backup.hidden_raid_component)
4314 _scsih_remove_pd_device(ioc, sas_device_backup);
4315
4316 _scsih_ublock_io_device(ioc, sas_device_backup.handle); 4550 _scsih_ublock_io_device(ioc, sas_device_backup.handle);
4317 4551
4318 mpt2sas_transport_port_remove(ioc, sas_device_backup.sas_address, 4552 mpt2sas_transport_port_remove(ioc, sas_device_backup.sas_address,
@@ -4909,17 +5143,15 @@ _scsih_sas_volume_add(struct MPT2SAS_ADAPTER *ioc,
4909/** 5143/**
4910 * _scsih_sas_volume_delete - delete volume 5144 * _scsih_sas_volume_delete - delete volume
4911 * @ioc: per adapter object 5145 * @ioc: per adapter object
4912 * @element: IR config element data 5146 * @handle: volume device handle
4913 * Context: user. 5147 * Context: user.
4914 * 5148 *
4915 * Return nothing. 5149 * Return nothing.
4916 */ 5150 */
4917static void 5151static void
4918_scsih_sas_volume_delete(struct MPT2SAS_ADAPTER *ioc, 5152_scsih_sas_volume_delete(struct MPT2SAS_ADAPTER *ioc, u16 handle)
4919 Mpi2EventIrConfigElement_t *element)
4920{ 5153{
4921 struct _raid_device *raid_device; 5154 struct _raid_device *raid_device;
4922 u16 handle = le16_to_cpu(element->VolDevHandle);
4923 unsigned long flags; 5155 unsigned long flags;
4924 struct MPT2SAS_TARGET *sas_target_priv_data; 5156 struct MPT2SAS_TARGET *sas_target_priv_data;
4925 5157
@@ -4933,6 +5165,9 @@ _scsih_sas_volume_delete(struct MPT2SAS_ADAPTER *ioc,
4933 sas_target_priv_data->deleted = 1; 5165 sas_target_priv_data->deleted = 1;
4934 scsi_remove_target(&raid_device->starget->dev); 5166 scsi_remove_target(&raid_device->starget->dev);
4935 } 5167 }
5168 printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), wwid"
5169 "(0x%016llx)\n", ioc->name, raid_device->handle,
5170 (unsigned long long) raid_device->wwid);
4936 _scsih_raid_device_remove(ioc, raid_device); 5171 _scsih_raid_device_remove(ioc, raid_device);
4937} 5172}
4938 5173
@@ -4961,7 +5196,7 @@ _scsih_sas_pd_expose(struct MPT2SAS_ADAPTER *ioc,
4961 /* exposing raid component */ 5196 /* exposing raid component */
4962 sas_device->volume_handle = 0; 5197 sas_device->volume_handle = 0;
4963 sas_device->volume_wwid = 0; 5198 sas_device->volume_wwid = 0;
4964 sas_device->hidden_raid_component = 0; 5199 clear_bit(handle, ioc->pd_handles);
4965 _scsih_reprobe_target(sas_device->starget, 0); 5200 _scsih_reprobe_target(sas_device->starget, 0);
4966} 5201}
4967 5202
@@ -4992,7 +5227,7 @@ _scsih_sas_pd_hide(struct MPT2SAS_ADAPTER *ioc,
4992 &sas_device->volume_handle); 5227 &sas_device->volume_handle);
4993 mpt2sas_config_get_volume_wwid(ioc, sas_device->volume_handle, 5228 mpt2sas_config_get_volume_wwid(ioc, sas_device->volume_handle,
4994 &sas_device->volume_wwid); 5229 &sas_device->volume_wwid);
4995 sas_device->hidden_raid_component = 1; 5230 set_bit(handle, ioc->pd_handles);
4996 _scsih_reprobe_target(sas_device->starget, 1); 5231 _scsih_reprobe_target(sas_device->starget, 1);
4997} 5232}
4998 5233
@@ -5041,13 +5276,13 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc,
5041 u64 sas_address; 5276 u64 sas_address;
5042 u16 parent_handle; 5277 u16 parent_handle;
5043 5278
5279 set_bit(handle, ioc->pd_handles);
5280
5044 spin_lock_irqsave(&ioc->sas_device_lock, flags); 5281 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5045 sas_device = _scsih_sas_device_find_by_handle(ioc, handle); 5282 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
5046 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 5283 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5047 if (sas_device) { 5284 if (sas_device)
5048 sas_device->hidden_raid_component = 1;
5049 return; 5285 return;
5050 }
5051 5286
5052 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, 5287 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
5053 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { 5288 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
@@ -5191,7 +5426,8 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc,
5191 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: 5426 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
5192 case MPI2_EVENT_IR_CHANGE_RC_REMOVED: 5427 case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
5193 if (!foreign_config) 5428 if (!foreign_config)
5194 _scsih_sas_volume_delete(ioc, element); 5429 _scsih_sas_volume_delete(ioc,
5430 le16_to_cpu(element->VolDevHandle));
5195 break; 5431 break;
5196 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: 5432 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
5197 _scsih_sas_pd_hide(ioc, element); 5433 _scsih_sas_pd_hide(ioc, element);
@@ -5227,7 +5463,6 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc,
5227 u16 handle; 5463 u16 handle;
5228 u32 state; 5464 u32 state;
5229 int rc; 5465 int rc;
5230 struct MPT2SAS_TARGET *sas_target_priv_data;
5231 Mpi2EventDataIrVolume_t *event_data = fw_event->event_data; 5466 Mpi2EventDataIrVolume_t *event_data = fw_event->event_data;
5232 5467
5233 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED) 5468 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
@@ -5239,26 +5474,20 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc,
5239 "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle, 5474 "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle,
5240 le32_to_cpu(event_data->PreviousValue), state)); 5475 le32_to_cpu(event_data->PreviousValue), state));
5241 5476
5242 spin_lock_irqsave(&ioc->raid_device_lock, flags);
5243 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
5244 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
5245
5246 switch (state) { 5477 switch (state) {
5247 case MPI2_RAID_VOL_STATE_MISSING: 5478 case MPI2_RAID_VOL_STATE_MISSING:
5248 case MPI2_RAID_VOL_STATE_FAILED: 5479 case MPI2_RAID_VOL_STATE_FAILED:
5249 if (!raid_device) 5480 _scsih_sas_volume_delete(ioc, handle);
5250 break;
5251 if (raid_device->starget) {
5252 sas_target_priv_data = raid_device->starget->hostdata;
5253 sas_target_priv_data->deleted = 1;
5254 scsi_remove_target(&raid_device->starget->dev);
5255 }
5256 _scsih_raid_device_remove(ioc, raid_device);
5257 break; 5481 break;
5258 5482
5259 case MPI2_RAID_VOL_STATE_ONLINE: 5483 case MPI2_RAID_VOL_STATE_ONLINE:
5260 case MPI2_RAID_VOL_STATE_DEGRADED: 5484 case MPI2_RAID_VOL_STATE_DEGRADED:
5261 case MPI2_RAID_VOL_STATE_OPTIMAL: 5485 case MPI2_RAID_VOL_STATE_OPTIMAL:
5486
5487 spin_lock_irqsave(&ioc->raid_device_lock, flags);
5488 raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
5489 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
5490
5262 if (raid_device) 5491 if (raid_device)
5263 break; 5492 break;
5264 5493
@@ -5327,19 +5556,21 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
5327 "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle, 5556 "old(0x%08x), new(0x%08x)\n", ioc->name, __func__, handle,
5328 le32_to_cpu(event_data->PreviousValue), state)); 5557 le32_to_cpu(event_data->PreviousValue), state));
5329 5558
5330 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5331 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
5332 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5333
5334 switch (state) { 5559 switch (state) {
5335 case MPI2_RAID_PD_STATE_ONLINE: 5560 case MPI2_RAID_PD_STATE_ONLINE:
5336 case MPI2_RAID_PD_STATE_DEGRADED: 5561 case MPI2_RAID_PD_STATE_DEGRADED:
5337 case MPI2_RAID_PD_STATE_REBUILDING: 5562 case MPI2_RAID_PD_STATE_REBUILDING:
5338 case MPI2_RAID_PD_STATE_OPTIMAL: 5563 case MPI2_RAID_PD_STATE_OPTIMAL:
5339 if (sas_device) { 5564 case MPI2_RAID_PD_STATE_HOT_SPARE:
5340 sas_device->hidden_raid_component = 1; 5565
5566 set_bit(handle, ioc->pd_handles);
5567
5568 spin_lock_irqsave(&ioc->sas_device_lock, flags);
5569 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
5570 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
5571
5572 if (sas_device)
5341 return; 5573 return;
5342 }
5343 5574
5344 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, 5575 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
5345 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, 5576 &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
@@ -5369,7 +5600,6 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
5369 case MPI2_RAID_PD_STATE_OFFLINE: 5600 case MPI2_RAID_PD_STATE_OFFLINE:
5370 case MPI2_RAID_PD_STATE_NOT_CONFIGURED: 5601 case MPI2_RAID_PD_STATE_NOT_CONFIGURED:
5371 case MPI2_RAID_PD_STATE_NOT_COMPATIBLE: 5602 case MPI2_RAID_PD_STATE_NOT_COMPATIBLE:
5372 case MPI2_RAID_PD_STATE_HOT_SPARE:
5373 default: 5603 default:
5374 break; 5604 break;
5375 } 5605 }
@@ -5497,7 +5727,7 @@ _scsih_task_set_full(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
5497 sas_address = sas_device->sas_address; 5727 sas_address = sas_device->sas_address;
5498 5728
5499 /* if hidden raid component, then change to volume characteristics */ 5729 /* if hidden raid component, then change to volume characteristics */
5500 if (sas_device->hidden_raid_component && sas_device->volume_handle) { 5730 if (test_bit(handle, ioc->pd_handles) && sas_device->volume_handle) {
5501 spin_lock_irqsave(&ioc->raid_device_lock, flags); 5731 spin_lock_irqsave(&ioc->raid_device_lock, flags);
5502 raid_device = _scsih_raid_device_find_by_handle( 5732 raid_device = _scsih_raid_device_find_by_handle(
5503 ioc, sas_device->volume_handle); 5733 ioc, sas_device->volume_handle);
@@ -5722,9 +5952,11 @@ static void
5722_scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc) 5952_scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
5723{ 5953{
5724 Mpi2RaidVolPage1_t volume_pg1; 5954 Mpi2RaidVolPage1_t volume_pg1;
5955 Mpi2RaidPhysDiskPage0_t pd_pg0;
5725 Mpi2ConfigReply_t mpi_reply; 5956 Mpi2ConfigReply_t mpi_reply;
5726 u16 ioc_status; 5957 u16 ioc_status;
5727 u16 handle; 5958 u16 handle;
5959 u8 phys_disk_num;
5728 5960
5729 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__); 5961 printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, __func__);
5730 5962
@@ -5742,6 +5974,21 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
5742 _scsih_mark_responding_raid_device(ioc, 5974 _scsih_mark_responding_raid_device(ioc,
5743 le64_to_cpu(volume_pg1.WWID), handle); 5975 le64_to_cpu(volume_pg1.WWID), handle);
5744 } 5976 }
5977
5978 /* refresh the pd_handles */
5979 phys_disk_num = 0xFF;
5980 memset(ioc->pd_handles, 0, ioc->pd_handles_sz);
5981 while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
5982 &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM,
5983 phys_disk_num))) {
5984 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
5985 MPI2_IOCSTATUS_MASK;
5986 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
5987 break;
5988 phys_disk_num = pd_pg0.PhysDiskNum;
5989 handle = le16_to_cpu(pd_pg0.DevHandle);
5990 set_bit(handle, ioc->pd_handles);
5991 }
5745} 5992}
5746 5993
5747/** 5994/**
@@ -6060,14 +6307,21 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
6060 (Mpi2EventDataSasTopologyChangeList_t *) 6307 (Mpi2EventDataSasTopologyChangeList_t *)
6061 mpi_reply->EventData); 6308 mpi_reply->EventData);
6062 break; 6309 break;
6063 6310 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
6311 _scsih_check_ir_config_unhide_events(ioc,
6312 (Mpi2EventDataIrConfigChangeList_t *)
6313 mpi_reply->EventData);
6314 break;
6315 case MPI2_EVENT_IR_VOLUME:
6316 _scsih_check_volume_delete_events(ioc,
6317 (Mpi2EventDataIrVolume_t *)
6318 mpi_reply->EventData);
6319 break;
6064 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: 6320 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
6065 case MPI2_EVENT_IR_OPERATION_STATUS: 6321 case MPI2_EVENT_IR_OPERATION_STATUS:
6066 case MPI2_EVENT_SAS_DISCOVERY: 6322 case MPI2_EVENT_SAS_DISCOVERY:
6067 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: 6323 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
6068 case MPI2_EVENT_IR_VOLUME:
6069 case MPI2_EVENT_IR_PHYSICAL_DISK: 6324 case MPI2_EVENT_IR_PHYSICAL_DISK:
6070 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
6071 case MPI2_EVENT_TASK_SET_FULL: 6325 case MPI2_EVENT_TASK_SET_FULL:
6072 break; 6326 break;
6073 6327
@@ -6574,6 +6828,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
6574 ioc->scsih_cb_idx = scsih_cb_idx; 6828 ioc->scsih_cb_idx = scsih_cb_idx;
6575 ioc->config_cb_idx = config_cb_idx; 6829 ioc->config_cb_idx = config_cb_idx;
6576 ioc->tm_tr_cb_idx = tm_tr_cb_idx; 6830 ioc->tm_tr_cb_idx = tm_tr_cb_idx;
6831 ioc->tm_tr_volume_cb_idx = tm_tr_volume_cb_idx;
6577 ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx; 6832 ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx;
6578 ioc->logging_level = logging_level; 6833 ioc->logging_level = logging_level;
6579 /* misc semaphores and spin locks */ 6834 /* misc semaphores and spin locks */
@@ -6592,6 +6847,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
6592 INIT_LIST_HEAD(&ioc->raid_device_list); 6847 INIT_LIST_HEAD(&ioc->raid_device_list);
6593 INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list); 6848 INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list);
6594 INIT_LIST_HEAD(&ioc->delayed_tr_list); 6849 INIT_LIST_HEAD(&ioc->delayed_tr_list);
6850 INIT_LIST_HEAD(&ioc->delayed_tr_volume_list);
6595 6851
6596 /* init shost parameters */ 6852 /* init shost parameters */
6597 shost->max_cmd_len = 32; 6853 shost->max_cmd_len = 32;
@@ -6894,6 +7150,10 @@ _scsih_init(void)
6894 7150
6895 tm_tr_cb_idx = mpt2sas_base_register_callback_handler( 7151 tm_tr_cb_idx = mpt2sas_base_register_callback_handler(
6896 _scsih_tm_tr_complete); 7152 _scsih_tm_tr_complete);
7153
7154 tm_tr_volume_cb_idx = mpt2sas_base_register_callback_handler(
7155 _scsih_tm_volume_tr_complete);
7156
6897 tm_sas_control_cb_idx = mpt2sas_base_register_callback_handler( 7157 tm_sas_control_cb_idx = mpt2sas_base_register_callback_handler(
6898 _scsih_sas_control_complete); 7158 _scsih_sas_control_complete);
6899 7159
@@ -6933,6 +7193,7 @@ _scsih_exit(void)
6933 mpt2sas_base_release_callback_handler(ctl_cb_idx); 7193 mpt2sas_base_release_callback_handler(ctl_cb_idx);
6934 7194
6935 mpt2sas_base_release_callback_handler(tm_tr_cb_idx); 7195 mpt2sas_base_release_callback_handler(tm_tr_cb_idx);
7196 mpt2sas_base_release_callback_handler(tm_tr_volume_cb_idx);
6936 mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx); 7197 mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx);
6937 7198
6938 /* raid transport support */ 7199 /* raid transport support */