aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Smart <james.smart@broadcom.com>2016-07-06 15:36:05 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2016-07-15 15:25:06 -0400
commitc92c841cc72ae7eb665fb9ea2a1c991e214c3807 (patch)
tree5d356f1aa32a1864e5cf16c679de36e1276e8a5c /drivers/scsi
parent5b1993dedfdc131ff095c0c079ef106aed3fe9ac (diff)
lpfc: Add support for XLane LUN priority
Add support for XLane LUN priority Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <james.smart@broadcom.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/lpfc/lpfc.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c89
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c9
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c21
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h1
7 files changed, 104 insertions, 20 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 69da16d63a01..40e069c76091 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -743,6 +743,7 @@ struct lpfc_hba {
743#define OAS_FIND_ANY_VPORT 0x01 743#define OAS_FIND_ANY_VPORT 0x01
744#define OAS_FIND_ANY_TARGET 0x02 744#define OAS_FIND_ANY_TARGET 0x02
745#define OAS_LUN_VALID 0x04 745#define OAS_LUN_VALID 0x04
746 uint32_t cfg_oas_priority;
746 uint32_t cfg_XLanePriority; 747 uint32_t cfg_XLanePriority;
747 uint32_t cfg_enable_bg; 748 uint32_t cfg_enable_bg;
748 uint32_t cfg_hostmem_hgp; 749 uint32_t cfg_hostmem_hgp;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index cde7da6af2ea..a75404ae4fc1 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -2401,6 +2401,69 @@ static DEVICE_ATTR(lpfc_xlane_tgt, S_IRUGO | S_IWUSR,
2401 lpfc_oas_tgt_show, lpfc_oas_tgt_store); 2401 lpfc_oas_tgt_show, lpfc_oas_tgt_store);
2402 2402
2403/** 2403/**
2404 * lpfc_oas_priority_show - Return wwpn of target whose luns maybe enabled for
2405 * Optimized Access Storage (OAS) operations.
2406 * @dev: class device that is converted into a Scsi_host.
2407 * @attr: device attribute, not used.
2408 * @buf: buffer for passing information.
2409 *
2410 * Returns:
2411 * value of count
2412 **/
2413static ssize_t
2414lpfc_oas_priority_show(struct device *dev, struct device_attribute *attr,
2415 char *buf)
2416{
2417 struct Scsi_Host *shost = class_to_shost(dev);
2418 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
2419
2420 return snprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_priority);
2421}
2422
2423/**
2424 * lpfc_oas_priority_store - Store wwpn of target whose luns maybe enabled for
2425 * Optimized Access Storage (OAS) operations.
2426 * @dev: class device that is converted into a Scsi_host.
2427 * @attr: device attribute, not used.
2428 * @buf: buffer for passing information.
2429 * @count: Size of the data buffer.
2430 *
2431 * Returns:
2432 * -EINVAL count is invalid, invalid wwpn byte invalid
2433 * -EPERM oas is not supported by hba
2434 * value of count on success
2435 **/
2436static ssize_t
2437lpfc_oas_priority_store(struct device *dev, struct device_attribute *attr,
2438 const char *buf, size_t count)
2439{
2440 struct Scsi_Host *shost = class_to_shost(dev);
2441 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
2442 unsigned int cnt = count;
2443 unsigned long val;
2444 int ret;
2445
2446 if (!phba->cfg_fof)
2447 return -EPERM;
2448
2449 /* count may include a LF at end of string */
2450 if (buf[cnt-1] == '\n')
2451 cnt--;
2452
2453 ret = kstrtoul(buf, 0, &val);
2454 if (ret || (val > 0x7f))
2455 return -EINVAL;
2456
2457 if (val)
2458 phba->cfg_oas_priority = (uint8_t)val;
2459 else
2460 phba->cfg_oas_priority = phba->cfg_XLanePriority;
2461 return count;
2462}
2463static DEVICE_ATTR(lpfc_xlane_priority, S_IRUGO | S_IWUSR,
2464 lpfc_oas_priority_show, lpfc_oas_priority_store);
2465
2466/**
2404 * lpfc_oas_vpt_show - Return wwpn of vport whose targets maybe enabled 2467 * lpfc_oas_vpt_show - Return wwpn of vport whose targets maybe enabled
2405 * for Optimized Access Storage (OAS) operations. 2468 * for Optimized Access Storage (OAS) operations.
2406 * @dev: class device that is converted into a Scsi_host. 2469 * @dev: class device that is converted into a Scsi_host.
@@ -2462,6 +2525,7 @@ lpfc_oas_vpt_store(struct device *dev, struct device_attribute *attr,
2462 else 2525 else
2463 phba->cfg_oas_flags &= ~OAS_FIND_ANY_VPORT; 2526 phba->cfg_oas_flags &= ~OAS_FIND_ANY_VPORT;
2464 phba->cfg_oas_flags &= ~OAS_LUN_VALID; 2527 phba->cfg_oas_flags &= ~OAS_LUN_VALID;
2528 phba->cfg_oas_priority = phba->cfg_XLanePriority;
2465 phba->sli4_hba.oas_next_lun = FIND_FIRST_OAS_LUN; 2529 phba->sli4_hba.oas_next_lun = FIND_FIRST_OAS_LUN;
2466 return count; 2530 return count;
2467} 2531}
@@ -2524,7 +2588,6 @@ lpfc_oas_lun_state_store(struct device *dev, struct device_attribute *attr,
2524 return -EINVAL; 2588 return -EINVAL;
2525 2589
2526 phba->cfg_oas_lun_state = val; 2590 phba->cfg_oas_lun_state = val;
2527
2528 return strlen(buf); 2591 return strlen(buf);
2529} 2592}
2530static DEVICE_ATTR(lpfc_xlane_lun_state, S_IRUGO | S_IWUSR, 2593static DEVICE_ATTR(lpfc_xlane_lun_state, S_IRUGO | S_IWUSR,
@@ -2572,7 +2635,8 @@ static DEVICE_ATTR(lpfc_xlane_lun_status, S_IRUGO,
2572 */ 2635 */
2573static size_t 2636static size_t
2574lpfc_oas_lun_state_set(struct lpfc_hba *phba, uint8_t vpt_wwpn[], 2637lpfc_oas_lun_state_set(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
2575 uint8_t tgt_wwpn[], uint64_t lun, uint32_t oas_state) 2638 uint8_t tgt_wwpn[], uint64_t lun,
2639 uint32_t oas_state, uint8_t pri)
2576{ 2640{
2577 2641
2578 int rc = 0; 2642 int rc = 0;
@@ -2582,7 +2646,8 @@ lpfc_oas_lun_state_set(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
2582 2646
2583 if (oas_state) { 2647 if (oas_state) {
2584 if (!lpfc_enable_oas_lun(phba, (struct lpfc_name *)vpt_wwpn, 2648 if (!lpfc_enable_oas_lun(phba, (struct lpfc_name *)vpt_wwpn,
2585 (struct lpfc_name *)tgt_wwpn, lun)) 2649 (struct lpfc_name *)tgt_wwpn,
2650 lun, pri))
2586 rc = -ENOMEM; 2651 rc = -ENOMEM;
2587 } else { 2652 } else {
2588 lpfc_disable_oas_lun(phba, (struct lpfc_name *)vpt_wwpn, 2653 lpfc_disable_oas_lun(phba, (struct lpfc_name *)vpt_wwpn,
@@ -2648,13 +2713,13 @@ lpfc_oas_lun_get_next(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
2648static ssize_t 2713static ssize_t
2649lpfc_oas_lun_state_change(struct lpfc_hba *phba, uint8_t vpt_wwpn[], 2714lpfc_oas_lun_state_change(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
2650 uint8_t tgt_wwpn[], uint64_t lun, 2715 uint8_t tgt_wwpn[], uint64_t lun,
2651 uint32_t oas_state) 2716 uint32_t oas_state, uint8_t pri)
2652{ 2717{
2653 2718
2654 int rc; 2719 int rc;
2655 2720
2656 rc = lpfc_oas_lun_state_set(phba, vpt_wwpn, tgt_wwpn, lun, 2721 rc = lpfc_oas_lun_state_set(phba, vpt_wwpn, tgt_wwpn, lun,
2657 oas_state); 2722 oas_state, pri);
2658 return rc; 2723 return rc;
2659} 2724}
2660 2725
@@ -2744,16 +2809,16 @@ lpfc_oas_lun_store(struct device *dev, struct device_attribute *attr,
2744 return -EINVAL; 2809 return -EINVAL;
2745 2810
2746 lpfc_printf_log(phba, KERN_INFO, LOG_INIT, 2811 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
2747 "3372 Try to set vport 0x%llx target 0x%llx lun:%lld " 2812 "3372 Try to set vport 0x%llx target 0x%llx lun:0x%llx "
2748 "with oas set to %d\n", 2813 "priority 0x%x with oas state %d\n",
2749 wwn_to_u64(phba->cfg_oas_vpt_wwpn), 2814 wwn_to_u64(phba->cfg_oas_vpt_wwpn),
2750 wwn_to_u64(phba->cfg_oas_tgt_wwpn), scsi_lun, 2815 wwn_to_u64(phba->cfg_oas_tgt_wwpn), scsi_lun,
2751 phba->cfg_oas_lun_state); 2816 phba->cfg_oas_priority, phba->cfg_oas_lun_state);
2752 2817
2753 rc = lpfc_oas_lun_state_change(phba, phba->cfg_oas_vpt_wwpn, 2818 rc = lpfc_oas_lun_state_change(phba, phba->cfg_oas_vpt_wwpn,
2754 phba->cfg_oas_tgt_wwpn, scsi_lun, 2819 phba->cfg_oas_tgt_wwpn, scsi_lun,
2755 phba->cfg_oas_lun_state); 2820 phba->cfg_oas_lun_state,
2756 2821 phba->cfg_oas_priority);
2757 if (rc) 2822 if (rc)
2758 return rc; 2823 return rc;
2759 2824
@@ -4865,6 +4930,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
4865 &dev_attr_lpfc_xlane_vpt, 4930 &dev_attr_lpfc_xlane_vpt,
4866 &dev_attr_lpfc_xlane_lun_state, 4931 &dev_attr_lpfc_xlane_lun_state,
4867 &dev_attr_lpfc_xlane_lun_status, 4932 &dev_attr_lpfc_xlane_lun_status,
4933 &dev_attr_lpfc_xlane_priority,
4868 &dev_attr_lpfc_sg_seg_cnt, 4934 &dev_attr_lpfc_sg_seg_cnt,
4869 &dev_attr_lpfc_max_scsicmpl_time, 4935 &dev_attr_lpfc_max_scsicmpl_time,
4870 &dev_attr_lpfc_stat_data_ctrl, 4936 &dev_attr_lpfc_stat_data_ctrl,
@@ -5858,6 +5924,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
5858 phba->cfg_oas_lun_state = 0; 5924 phba->cfg_oas_lun_state = 0;
5859 phba->cfg_oas_lun_status = 0; 5925 phba->cfg_oas_lun_status = 0;
5860 phba->cfg_oas_flags = 0; 5926 phba->cfg_oas_flags = 0;
5927 phba->cfg_oas_priority = 0;
5861 lpfc_enable_bg_init(phba, lpfc_enable_bg); 5928 lpfc_enable_bg_init(phba, lpfc_enable_bg);
5862 if (phba->sli_rev == LPFC_SLI_REV4) 5929 if (phba->sli_rev == LPFC_SLI_REV4)
5863 phba->cfg_poll = 0; 5930 phba->cfg_poll = 0;
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 4e55b35180a4..bc0e2f197ff5 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -492,7 +492,7 @@ struct lpfc_device_data *__lpfc_get_device_data(struct lpfc_hba *,
492 struct lpfc_name *, 492 struct lpfc_name *,
493 struct lpfc_name *, uint64_t); 493 struct lpfc_name *, uint64_t);
494bool lpfc_enable_oas_lun(struct lpfc_hba *, struct lpfc_name *, 494bool lpfc_enable_oas_lun(struct lpfc_hba *, struct lpfc_name *,
495 struct lpfc_name *, uint64_t); 495 struct lpfc_name *, uint64_t, uint8_t);
496bool lpfc_disable_oas_lun(struct lpfc_hba *, struct lpfc_name *, 496bool lpfc_disable_oas_lun(struct lpfc_hba *, struct lpfc_name *,
497 struct lpfc_name *, uint64_t); 497 struct lpfc_name *, uint64_t);
498bool lpfc_find_next_oas_lun(struct lpfc_hba *, struct lpfc_name *, 498bool lpfc_find_next_oas_lun(struct lpfc_hba *, struct lpfc_name *,
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 12b8e82529fd..3f33fd6b1b6f 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -3335,8 +3335,11 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
3335 * OAS, set the oas iocb related flags. 3335 * OAS, set the oas iocb related flags.
3336 */ 3336 */
3337 if ((phba->cfg_fof) && ((struct lpfc_device_data *) 3337 if ((phba->cfg_fof) && ((struct lpfc_device_data *)
3338 scsi_cmnd->device->hostdata)->oas_enabled) 3338 scsi_cmnd->device->hostdata)->oas_enabled) {
3339 lpfc_cmd->cur_iocbq.iocb_flag |= (LPFC_IO_OAS | LPFC_IO_FOF); 3339 lpfc_cmd->cur_iocbq.iocb_flag |= (LPFC_IO_OAS | LPFC_IO_FOF);
3340 lpfc_cmd->cur_iocbq.priority = ((struct lpfc_device_data *)
3341 scsi_cmnd->device->hostdata)->priority;
3342 }
3340 return 0; 3343 return 0;
3341} 3344}
3342 3345
@@ -5607,6 +5610,7 @@ lpfc_create_device_data(struct lpfc_hba *phba, struct lpfc_name *vport_wwpn,
5607 sizeof(struct lpfc_name)); 5610 sizeof(struct lpfc_name));
5608 lun_info->device_id.lun = lun; 5611 lun_info->device_id.lun = lun;
5609 lun_info->oas_enabled = false; 5612 lun_info->oas_enabled = false;
5613 lun_info->priority = phba->cfg_XLanePriority;
5610 lun_info->available = false; 5614 lun_info->available = false;
5611 return lun_info; 5615 return lun_info;
5612} 5616}
@@ -5798,7 +5802,7 @@ lpfc_find_next_oas_lun(struct lpfc_hba *phba, struct lpfc_name *vport_wwpn,
5798 **/ 5802 **/
5799bool 5803bool
5800lpfc_enable_oas_lun(struct lpfc_hba *phba, struct lpfc_name *vport_wwpn, 5804lpfc_enable_oas_lun(struct lpfc_hba *phba, struct lpfc_name *vport_wwpn,
5801 struct lpfc_name *target_wwpn, uint64_t lun) 5805 struct lpfc_name *target_wwpn, uint64_t lun, uint8_t pri)
5802{ 5806{
5803 5807
5804 struct lpfc_device_data *lun_info; 5808 struct lpfc_device_data *lun_info;
@@ -5825,6 +5829,7 @@ lpfc_enable_oas_lun(struct lpfc_hba *phba, struct lpfc_name *vport_wwpn,
5825 false); 5829 false);
5826 if (lun_info) { 5830 if (lun_info) {
5827 lun_info->oas_enabled = true; 5831 lun_info->oas_enabled = true;
5832 lun_info->priority = pri;
5828 lun_info->available = false; 5833 lun_info->available = false;
5829 list_add_tail(&lun_info->listentry, &phba->luns); 5834 list_add_tail(&lun_info->listentry, &phba->luns);
5830 spin_unlock_irqrestore(&phba->devicelock, flags); 5835 spin_unlock_irqrestore(&phba->devicelock, flags);
diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h
index 18b9260ccfac..46c090bd053b 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.h
+++ b/drivers/scsi/lpfc/lpfc_scsi.h
@@ -51,6 +51,7 @@ struct lpfc_device_data {
51 struct list_head listentry; 51 struct list_head listentry;
52 struct lpfc_rport_data *rport_data; 52 struct lpfc_rport_data *rport_data;
53 struct lpfc_device_id device_id; 53 struct lpfc_device_id device_id;
54 uint8_t priority;
54 bool oas_enabled; 55 bool oas_enabled;
55 bool available; 56 bool available;
56}; 57};
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index b1ddbaac1c79..53ed6c534f82 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -8441,8 +8441,11 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
8441 bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 1); 8441 bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 1);
8442 if (iocbq->iocb_flag & LPFC_IO_OAS) { 8442 if (iocbq->iocb_flag & LPFC_IO_OAS) {
8443 bf_set(wqe_oas, &wqe->fcp_iwrite.wqe_com, 1); 8443 bf_set(wqe_oas, &wqe->fcp_iwrite.wqe_com, 1);
8444 if (phba->cfg_XLanePriority) { 8444 bf_set(wqe_ccpe, &wqe->fcp_iwrite.wqe_com, 1);
8445 bf_set(wqe_ccpe, &wqe->fcp_iwrite.wqe_com, 1); 8445 if (iocbq->priority) {
8446 bf_set(wqe_ccp, &wqe->fcp_iwrite.wqe_com,
8447 (iocbq->priority << 1));
8448 } else {
8446 bf_set(wqe_ccp, &wqe->fcp_iwrite.wqe_com, 8449 bf_set(wqe_ccp, &wqe->fcp_iwrite.wqe_com,
8447 (phba->cfg_XLanePriority << 1)); 8450 (phba->cfg_XLanePriority << 1));
8448 } 8451 }
@@ -8497,8 +8500,11 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
8497 bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 1); 8500 bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 1);
8498 if (iocbq->iocb_flag & LPFC_IO_OAS) { 8501 if (iocbq->iocb_flag & LPFC_IO_OAS) {
8499 bf_set(wqe_oas, &wqe->fcp_iread.wqe_com, 1); 8502 bf_set(wqe_oas, &wqe->fcp_iread.wqe_com, 1);
8500 if (phba->cfg_XLanePriority) { 8503 bf_set(wqe_ccpe, &wqe->fcp_iread.wqe_com, 1);
8501 bf_set(wqe_ccpe, &wqe->fcp_iread.wqe_com, 1); 8504 if (iocbq->priority) {
8505 bf_set(wqe_ccp, &wqe->fcp_iread.wqe_com,
8506 (iocbq->priority << 1));
8507 } else {
8502 bf_set(wqe_ccp, &wqe->fcp_iread.wqe_com, 8508 bf_set(wqe_ccp, &wqe->fcp_iread.wqe_com,
8503 (phba->cfg_XLanePriority << 1)); 8509 (phba->cfg_XLanePriority << 1));
8504 } 8510 }
@@ -8552,8 +8558,11 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
8552 iocbq->iocb.ulpFCP2Rcvy); 8558 iocbq->iocb.ulpFCP2Rcvy);
8553 if (iocbq->iocb_flag & LPFC_IO_OAS) { 8559 if (iocbq->iocb_flag & LPFC_IO_OAS) {
8554 bf_set(wqe_oas, &wqe->fcp_icmd.wqe_com, 1); 8560 bf_set(wqe_oas, &wqe->fcp_icmd.wqe_com, 1);
8555 if (phba->cfg_XLanePriority) { 8561 bf_set(wqe_ccpe, &wqe->fcp_icmd.wqe_com, 1);
8556 bf_set(wqe_ccpe, &wqe->fcp_icmd.wqe_com, 1); 8562 if (iocbq->priority) {
8563 bf_set(wqe_ccp, &wqe->fcp_icmd.wqe_com,
8564 (iocbq->priority << 1));
8565 } else {
8557 bf_set(wqe_ccp, &wqe->fcp_icmd.wqe_com, 8566 bf_set(wqe_ccp, &wqe->fcp_icmd.wqe_com,
8558 (phba->cfg_XLanePriority << 1)); 8567 (phba->cfg_XLanePriority << 1));
8559 } 8568 }
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index 7fe99ff80846..b33dbd323694 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -57,6 +57,7 @@ struct lpfc_iocbq {
57 struct lpfc_cq_event cq_event; 57 struct lpfc_cq_event cq_event;
58 58
59 IOCB_t iocb; /* IOCB cmd */ 59 IOCB_t iocb; /* IOCB cmd */
60 uint8_t priority; /* OAS priority */
60 uint8_t retry; /* retry counter for IOCB cmd - if needed */ 61 uint8_t retry; /* retry counter for IOCB cmd - if needed */
61 uint32_t iocb_flag; 62 uint32_t iocb_flag;
62#define LPFC_IO_LIBDFC 1 /* libdfc iocb */ 63#define LPFC_IO_LIBDFC 1 /* libdfc iocb */