diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 462453ee0bda..2df11daad85b 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2013 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2014 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -73,7 +73,7 @@ lpfc_rport_data_from_scsi_device(struct scsi_device *sdev) | |||
73 | { | 73 | { |
74 | struct lpfc_vport *vport = (struct lpfc_vport *)sdev->host->hostdata; | 74 | struct lpfc_vport *vport = (struct lpfc_vport *)sdev->host->hostdata; |
75 | 75 | ||
76 | if (vport->phba->cfg_EnableXLane) | 76 | if (vport->phba->cfg_fof) |
77 | return ((struct lpfc_device_data *)sdev->hostdata)->rport_data; | 77 | return ((struct lpfc_device_data *)sdev->hostdata)->rport_data; |
78 | else | 78 | else |
79 | return (struct lpfc_rport_data *)sdev->hostdata; | 79 | return (struct lpfc_rport_data *)sdev->hostdata; |
@@ -3462,7 +3462,7 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
3462 | * If the OAS driver feature is enabled and the lun is enabled for | 3462 | * If the OAS driver feature is enabled and the lun is enabled for |
3463 | * OAS, set the oas iocb related flags. | 3463 | * OAS, set the oas iocb related flags. |
3464 | */ | 3464 | */ |
3465 | if ((phba->cfg_EnableXLane) && ((struct lpfc_device_data *) | 3465 | if ((phba->cfg_fof) && ((struct lpfc_device_data *) |
3466 | scsi_cmnd->device->hostdata)->oas_enabled) | 3466 | scsi_cmnd->device->hostdata)->oas_enabled) |
3467 | lpfc_cmd->cur_iocbq.iocb_flag |= LPFC_IO_OAS; | 3467 | lpfc_cmd->cur_iocbq.iocb_flag |= LPFC_IO_OAS; |
3468 | return 0; | 3468 | return 0; |
@@ -4314,6 +4314,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, | |||
4314 | fcp_cmnd->fcpCntl1 = SIMPLE_Q; | 4314 | fcp_cmnd->fcpCntl1 = SIMPLE_Q; |
4315 | 4315 | ||
4316 | sli4 = (phba->sli_rev == LPFC_SLI_REV4); | 4316 | sli4 = (phba->sli_rev == LPFC_SLI_REV4); |
4317 | piocbq->iocb.un.fcpi.fcpi_XRdy = 0; | ||
4317 | 4318 | ||
4318 | /* | 4319 | /* |
4319 | * There are three possibilities here - use scatter-gather segment, use | 4320 | * There are three possibilities here - use scatter-gather segment, use |
@@ -4782,7 +4783,9 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
4782 | struct lpfc_scsi_buf *lpfc_cmd; | 4783 | struct lpfc_scsi_buf *lpfc_cmd; |
4783 | IOCB_t *cmd, *icmd; | 4784 | IOCB_t *cmd, *icmd; |
4784 | int ret = SUCCESS, status = 0; | 4785 | int ret = SUCCESS, status = 0; |
4785 | unsigned long flags; | 4786 | struct lpfc_sli_ring *pring_s4; |
4787 | int ring_number, ret_val; | ||
4788 | unsigned long flags, iflags; | ||
4786 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); | 4789 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); |
4787 | 4790 | ||
4788 | status = fc_block_scsi_eh(cmnd); | 4791 | status = fc_block_scsi_eh(cmnd); |
@@ -4833,6 +4836,14 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
4833 | 4836 | ||
4834 | BUG_ON(iocb->context1 != lpfc_cmd); | 4837 | BUG_ON(iocb->context1 != lpfc_cmd); |
4835 | 4838 | ||
4839 | /* abort issued in recovery is still in progress */ | ||
4840 | if (iocb->iocb_flag & LPFC_DRIVER_ABORTED) { | ||
4841 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, | ||
4842 | "3389 SCSI Layer I/O Abort Request is pending\n"); | ||
4843 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
4844 | goto wait_for_cmpl; | ||
4845 | } | ||
4846 | |||
4836 | abtsiocb = __lpfc_sli_get_iocbq(phba); | 4847 | abtsiocb = __lpfc_sli_get_iocbq(phba); |
4837 | if (abtsiocb == NULL) { | 4848 | if (abtsiocb == NULL) { |
4838 | ret = FAILED; | 4849 | ret = FAILED; |
@@ -4871,11 +4882,23 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
4871 | 4882 | ||
4872 | abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; | 4883 | abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; |
4873 | abtsiocb->vport = vport; | 4884 | abtsiocb->vport = vport; |
4885 | if (phba->sli_rev == LPFC_SLI_REV4) { | ||
4886 | ring_number = MAX_SLI3_CONFIGURED_RINGS + iocb->fcp_wqidx; | ||
4887 | pring_s4 = &phba->sli.ring[ring_number]; | ||
4888 | /* Note: both hbalock and ring_lock must be set here */ | ||
4889 | spin_lock_irqsave(&pring_s4->ring_lock, iflags); | ||
4890 | ret_val = __lpfc_sli_issue_iocb(phba, pring_s4->ringno, | ||
4891 | abtsiocb, 0); | ||
4892 | spin_unlock_irqrestore(&pring_s4->ring_lock, iflags); | ||
4893 | } else { | ||
4894 | ret_val = __lpfc_sli_issue_iocb(phba, LPFC_FCP_RING, | ||
4895 | abtsiocb, 0); | ||
4896 | } | ||
4874 | /* no longer need the lock after this point */ | 4897 | /* no longer need the lock after this point */ |
4875 | spin_unlock_irqrestore(&phba->hbalock, flags); | 4898 | spin_unlock_irqrestore(&phba->hbalock, flags); |
4876 | 4899 | ||
4877 | if (lpfc_sli_issue_iocb(phba, LPFC_FCP_RING, abtsiocb, 0) == | 4900 | |
4878 | IOCB_ERROR) { | 4901 | if (ret_val == IOCB_ERROR) { |
4879 | lpfc_sli_release_iocbq(phba, abtsiocb); | 4902 | lpfc_sli_release_iocbq(phba, abtsiocb); |
4880 | ret = FAILED; | 4903 | ret = FAILED; |
4881 | goto out; | 4904 | goto out; |
@@ -4885,12 +4908,16 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
4885 | lpfc_sli_handle_fast_ring_event(phba, | 4908 | lpfc_sli_handle_fast_ring_event(phba, |
4886 | &phba->sli.ring[LPFC_FCP_RING], HA_R0RE_REQ); | 4909 | &phba->sli.ring[LPFC_FCP_RING], HA_R0RE_REQ); |
4887 | 4910 | ||
4911 | wait_for_cmpl: | ||
4888 | lpfc_cmd->waitq = &waitq; | 4912 | lpfc_cmd->waitq = &waitq; |
4889 | /* Wait for abort to complete */ | 4913 | /* Wait for abort to complete */ |
4890 | wait_event_timeout(waitq, | 4914 | wait_event_timeout(waitq, |
4891 | (lpfc_cmd->pCmd != cmnd), | 4915 | (lpfc_cmd->pCmd != cmnd), |
4892 | msecs_to_jiffies(2*vport->cfg_devloss_tmo*1000)); | 4916 | msecs_to_jiffies(2*vport->cfg_devloss_tmo*1000)); |
4917 | |||
4918 | spin_lock_irqsave(shost->host_lock, flags); | ||
4893 | lpfc_cmd->waitq = NULL; | 4919 | lpfc_cmd->waitq = NULL; |
4920 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
4894 | 4921 | ||
4895 | if (lpfc_cmd->pCmd == cmnd) { | 4922 | if (lpfc_cmd->pCmd == cmnd) { |
4896 | ret = FAILED; | 4923 | ret = FAILED; |
@@ -5172,8 +5199,9 @@ lpfc_reset_flush_io_context(struct lpfc_vport *vport, uint16_t tgt_id, | |||
5172 | 5199 | ||
5173 | cnt = lpfc_sli_sum_iocb(vport, tgt_id, lun_id, context); | 5200 | cnt = lpfc_sli_sum_iocb(vport, tgt_id, lun_id, context); |
5174 | if (cnt) | 5201 | if (cnt) |
5175 | lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring], | 5202 | lpfc_sli_abort_taskmgmt(vport, |
5176 | tgt_id, lun_id, context); | 5203 | &phba->sli.ring[phba->sli.fcp_ring], |
5204 | tgt_id, lun_id, context); | ||
5177 | later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies; | 5205 | later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies; |
5178 | while (time_after(later, jiffies) && cnt) { | 5206 | while (time_after(later, jiffies) && cnt) { |
5179 | schedule_timeout_uninterruptible(msecs_to_jiffies(20)); | 5207 | schedule_timeout_uninterruptible(msecs_to_jiffies(20)); |
@@ -5491,7 +5519,7 @@ lpfc_slave_alloc(struct scsi_device *sdev) | |||
5491 | if (!rport || fc_remote_port_chkready(rport)) | 5519 | if (!rport || fc_remote_port_chkready(rport)) |
5492 | return -ENXIO; | 5520 | return -ENXIO; |
5493 | 5521 | ||
5494 | if (phba->cfg_EnableXLane) { | 5522 | if (phba->cfg_fof) { |
5495 | 5523 | ||
5496 | /* | 5524 | /* |
5497 | * Check to see if the device data structure for the lun | 5525 | * Check to see if the device data structure for the lun |
@@ -5616,7 +5644,7 @@ lpfc_slave_destroy(struct scsi_device *sdev) | |||
5616 | struct lpfc_device_data *device_data = sdev->hostdata; | 5644 | struct lpfc_device_data *device_data = sdev->hostdata; |
5617 | 5645 | ||
5618 | atomic_dec(&phba->sdev_cnt); | 5646 | atomic_dec(&phba->sdev_cnt); |
5619 | if ((phba->cfg_EnableXLane) && (device_data)) { | 5647 | if ((phba->cfg_fof) && (device_data)) { |
5620 | spin_lock_irqsave(&phba->devicelock, flags); | 5648 | spin_lock_irqsave(&phba->devicelock, flags); |
5621 | device_data->available = false; | 5649 | device_data->available = false; |
5622 | if (!device_data->oas_enabled) | 5650 | if (!device_data->oas_enabled) |
@@ -5655,7 +5683,7 @@ lpfc_create_device_data(struct lpfc_hba *phba, struct lpfc_name *vport_wwpn, | |||
5655 | int memory_flags; | 5683 | int memory_flags; |
5656 | 5684 | ||
5657 | if (unlikely(!phba) || !vport_wwpn || !target_wwpn || | 5685 | if (unlikely(!phba) || !vport_wwpn || !target_wwpn || |
5658 | !(phba->cfg_EnableXLane)) | 5686 | !(phba->cfg_fof)) |
5659 | return NULL; | 5687 | return NULL; |
5660 | 5688 | ||
5661 | /* Attempt to create the device data to contain lun info */ | 5689 | /* Attempt to create the device data to contain lun info */ |
@@ -5693,7 +5721,7 @@ lpfc_delete_device_data(struct lpfc_hba *phba, | |||
5693 | { | 5721 | { |
5694 | 5722 | ||
5695 | if (unlikely(!phba) || !lun_info || | 5723 | if (unlikely(!phba) || !lun_info || |
5696 | !(phba->cfg_EnableXLane)) | 5724 | !(phba->cfg_fof)) |
5697 | return; | 5725 | return; |
5698 | 5726 | ||
5699 | if (!list_empty(&lun_info->listentry)) | 5727 | if (!list_empty(&lun_info->listentry)) |
@@ -5727,7 +5755,7 @@ __lpfc_get_device_data(struct lpfc_hba *phba, struct list_head *list, | |||
5727 | struct lpfc_device_data *lun_info; | 5755 | struct lpfc_device_data *lun_info; |
5728 | 5756 | ||
5729 | if (unlikely(!phba) || !list || !vport_wwpn || !target_wwpn || | 5757 | if (unlikely(!phba) || !list || !vport_wwpn || !target_wwpn || |
5730 | !phba->cfg_EnableXLane) | 5758 | !phba->cfg_fof) |
5731 | return NULL; | 5759 | return NULL; |
5732 | 5760 | ||
5733 | /* Check to see if the lun is already enabled for OAS. */ | 5761 | /* Check to see if the lun is already enabled for OAS. */ |
@@ -5789,7 +5817,7 @@ lpfc_find_next_oas_lun(struct lpfc_hba *phba, struct lpfc_name *vport_wwpn, | |||
5789 | !starting_lun || !found_vport_wwpn || | 5817 | !starting_lun || !found_vport_wwpn || |
5790 | !found_target_wwpn || !found_lun || !found_lun_status || | 5818 | !found_target_wwpn || !found_lun || !found_lun_status || |
5791 | (*starting_lun == NO_MORE_OAS_LUN) || | 5819 | (*starting_lun == NO_MORE_OAS_LUN) || |
5792 | !phba->cfg_EnableXLane) | 5820 | !phba->cfg_fof) |
5793 | return false; | 5821 | return false; |
5794 | 5822 | ||
5795 | lun = *starting_lun; | 5823 | lun = *starting_lun; |
@@ -5873,7 +5901,7 @@ lpfc_enable_oas_lun(struct lpfc_hba *phba, struct lpfc_name *vport_wwpn, | |||
5873 | unsigned long flags; | 5901 | unsigned long flags; |
5874 | 5902 | ||
5875 | if (unlikely(!phba) || !vport_wwpn || !target_wwpn || | 5903 | if (unlikely(!phba) || !vport_wwpn || !target_wwpn || |
5876 | !phba->cfg_EnableXLane) | 5904 | !phba->cfg_fof) |
5877 | return false; | 5905 | return false; |
5878 | 5906 | ||
5879 | spin_lock_irqsave(&phba->devicelock, flags); | 5907 | spin_lock_irqsave(&phba->devicelock, flags); |
@@ -5930,7 +5958,7 @@ lpfc_disable_oas_lun(struct lpfc_hba *phba, struct lpfc_name *vport_wwpn, | |||
5930 | unsigned long flags; | 5958 | unsigned long flags; |
5931 | 5959 | ||
5932 | if (unlikely(!phba) || !vport_wwpn || !target_wwpn || | 5960 | if (unlikely(!phba) || !vport_wwpn || !target_wwpn || |
5933 | !phba->cfg_EnableXLane) | 5961 | !phba->cfg_fof) |
5934 | return false; | 5962 | return false; |
5935 | 5963 | ||
5936 | spin_lock_irqsave(&phba->devicelock, flags); | 5964 | spin_lock_irqsave(&phba->devicelock, flags); |