diff options
author | Adam Manzanares <adam.manzanares@wdc.com> | 2016-12-12 19:31:40 -0500 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-12-14 15:40:38 -0500 |
commit | 307d9075a02b696e817b775c565e45c4fa3c32f2 (patch) | |
tree | 4c5a1136a82e3248f85db962b2541cfbb44a75ec | |
parent | 093df73771bac8a37d607c0e705d157a8cef4c5c (diff) |
scsi: mpt3sas: Recognize and act on iopriority info
This patch adds support for request iopriority handling in the mpt3sas
layer. This works only when a ATA device is behind the SATL. The ATA
device also has to indicate that it supports command priorities in the
identify information that is pulled from the SATL.
Signed-off-by: Adam Manzanares <adam.manzanares@wdc.com>
Acked-by: Sreekanth Reddy <Sreekanth.Reddy@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_base.h | 6 | ||||
-rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_ctl.c | 43 | ||||
-rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_scsih.c | 34 |
3 files changed, 80 insertions, 3 deletions
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index 8de0eda8cd00..394fe1338d09 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h | |||
@@ -402,6 +402,9 @@ struct MPT3SAS_DEVICE { | |||
402 | u8 block; | 402 | u8 block; |
403 | u8 tlr_snoop_check; | 403 | u8 tlr_snoop_check; |
404 | u8 ignore_delay_remove; | 404 | u8 ignore_delay_remove; |
405 | /* Iopriority Command Handling */ | ||
406 | u8 ncq_prio_enable; | ||
407 | |||
405 | }; | 408 | }; |
406 | 409 | ||
407 | #define MPT3_CMD_NOT_USED 0x8000 /* free */ | 410 | #define MPT3_CMD_NOT_USED 0x8000 /* free */ |
@@ -1458,4 +1461,7 @@ mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
1458 | struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request, | 1461 | struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request, |
1459 | u16 smid); | 1462 | u16 smid); |
1460 | 1463 | ||
1464 | /* NCQ Prio Handling Check */ | ||
1465 | bool scsih_ncq_prio_supp(struct scsi_device *sdev); | ||
1466 | |||
1461 | #endif /* MPT3SAS_BASE_H_INCLUDED */ | 1467 | #endif /* MPT3SAS_BASE_H_INCLUDED */ |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 050bd788ad02..95f0f24bac05 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c | |||
@@ -3325,8 +3325,6 @@ static DEVICE_ATTR(diag_trigger_mpi, S_IRUGO | S_IWUSR, | |||
3325 | 3325 | ||
3326 | /*********** diagnostic trigger suppport *** END ****************************/ | 3326 | /*********** diagnostic trigger suppport *** END ****************************/ |
3327 | 3327 | ||
3328 | |||
3329 | |||
3330 | /*****************************************/ | 3328 | /*****************************************/ |
3331 | 3329 | ||
3332 | struct device_attribute *mpt3sas_host_attrs[] = { | 3330 | struct device_attribute *mpt3sas_host_attrs[] = { |
@@ -3402,9 +3400,50 @@ _ctl_device_handle_show(struct device *dev, struct device_attribute *attr, | |||
3402 | } | 3400 | } |
3403 | static DEVICE_ATTR(sas_device_handle, S_IRUGO, _ctl_device_handle_show, NULL); | 3401 | static DEVICE_ATTR(sas_device_handle, S_IRUGO, _ctl_device_handle_show, NULL); |
3404 | 3402 | ||
3403 | /** | ||
3404 | * _ctl_device_ncq_io_prio_show - send prioritized io commands to device | ||
3405 | * @dev - pointer to embedded device | ||
3406 | * @buf - the buffer returned | ||
3407 | * | ||
3408 | * A sysfs 'read/write' sdev attribute, only works with SATA | ||
3409 | */ | ||
3410 | static ssize_t | ||
3411 | _ctl_device_ncq_prio_enable_show(struct device *dev, | ||
3412 | struct device_attribute *attr, char *buf) | ||
3413 | { | ||
3414 | struct scsi_device *sdev = to_scsi_device(dev); | ||
3415 | struct MPT3SAS_DEVICE *sas_device_priv_data = sdev->hostdata; | ||
3416 | |||
3417 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
3418 | sas_device_priv_data->ncq_prio_enable); | ||
3419 | } | ||
3420 | |||
3421 | static ssize_t | ||
3422 | _ctl_device_ncq_prio_enable_store(struct device *dev, | ||
3423 | struct device_attribute *attr, | ||
3424 | const char *buf, size_t count) | ||
3425 | { | ||
3426 | struct scsi_device *sdev = to_scsi_device(dev); | ||
3427 | struct MPT3SAS_DEVICE *sas_device_priv_data = sdev->hostdata; | ||
3428 | bool ncq_prio_enable = 0; | ||
3429 | |||
3430 | if (kstrtobool(buf, &ncq_prio_enable)) | ||
3431 | return -EINVAL; | ||
3432 | |||
3433 | if (!scsih_ncq_prio_supp(sdev)) | ||
3434 | return -EINVAL; | ||
3435 | |||
3436 | sas_device_priv_data->ncq_prio_enable = ncq_prio_enable; | ||
3437 | return strlen(buf); | ||
3438 | } | ||
3439 | static DEVICE_ATTR(sas_ncq_prio_enable, S_IRUGO | S_IWUSR, | ||
3440 | _ctl_device_ncq_prio_enable_show, | ||
3441 | _ctl_device_ncq_prio_enable_store); | ||
3442 | |||
3405 | struct device_attribute *mpt3sas_dev_attrs[] = { | 3443 | struct device_attribute *mpt3sas_dev_attrs[] = { |
3406 | &dev_attr_sas_address, | 3444 | &dev_attr_sas_address, |
3407 | &dev_attr_sas_device_handle, | 3445 | &dev_attr_sas_device_handle, |
3446 | &dev_attr_sas_ncq_prio_enable, | ||
3408 | NULL, | 3447 | NULL, |
3409 | }; | 3448 | }; |
3410 | 3449 | ||
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 5c8f75247d73..b5c966e319d3 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c | |||
@@ -4053,6 +4053,8 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) | |||
4053 | struct MPT3SAS_DEVICE *sas_device_priv_data; | 4053 | struct MPT3SAS_DEVICE *sas_device_priv_data; |
4054 | struct MPT3SAS_TARGET *sas_target_priv_data; | 4054 | struct MPT3SAS_TARGET *sas_target_priv_data; |
4055 | struct _raid_device *raid_device; | 4055 | struct _raid_device *raid_device; |
4056 | struct request *rq = scmd->request; | ||
4057 | int class; | ||
4056 | Mpi2SCSIIORequest_t *mpi_request; | 4058 | Mpi2SCSIIORequest_t *mpi_request; |
4057 | u32 mpi_control; | 4059 | u32 mpi_control; |
4058 | u16 smid; | 4060 | u16 smid; |
@@ -4115,7 +4117,12 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) | |||
4115 | 4117 | ||
4116 | /* set tags */ | 4118 | /* set tags */ |
4117 | mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; | 4119 | mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; |
4118 | 4120 | /* NCQ Prio supported, make sure control indicated high priority */ | |
4121 | if (sas_device_priv_data->ncq_prio_enable) { | ||
4122 | class = IOPRIO_PRIO_CLASS(req_get_ioprio(rq)); | ||
4123 | if (class == IOPRIO_CLASS_RT) | ||
4124 | mpi_control |= 1 << MPI2_SCSIIO_CONTROL_CMDPRI_SHIFT; | ||
4125 | } | ||
4119 | /* Make sure Device is not raid volume. | 4126 | /* Make sure Device is not raid volume. |
4120 | * We do not expose raid functionality to upper layer for warpdrive. | 4127 | * We do not expose raid functionality to upper layer for warpdrive. |
4121 | */ | 4128 | */ |
@@ -9099,6 +9106,31 @@ scsih_pci_mmio_enabled(struct pci_dev *pdev) | |||
9099 | return PCI_ERS_RESULT_RECOVERED; | 9106 | return PCI_ERS_RESULT_RECOVERED; |
9100 | } | 9107 | } |
9101 | 9108 | ||
9109 | /** | ||
9110 | * scsih__ncq_prio_supp - Check for NCQ command priority support | ||
9111 | * @sdev: scsi device struct | ||
9112 | * | ||
9113 | * This is called when a user indicates they would like to enable | ||
9114 | * ncq command priorities. This works only on SATA devices. | ||
9115 | */ | ||
9116 | bool scsih_ncq_prio_supp(struct scsi_device *sdev) | ||
9117 | { | ||
9118 | unsigned char *buf; | ||
9119 | bool ncq_prio_supp = false; | ||
9120 | |||
9121 | if (!scsi_device_supports_vpd(sdev)) | ||
9122 | return ncq_prio_supp; | ||
9123 | |||
9124 | buf = kmalloc(SCSI_VPD_PG_LEN, GFP_KERNEL); | ||
9125 | if (!buf) | ||
9126 | return ncq_prio_supp; | ||
9127 | |||
9128 | if (!scsi_get_vpd_page(sdev, 0x89, buf, SCSI_VPD_PG_LEN)) | ||
9129 | ncq_prio_supp = (buf[213] >> 4) & 1; | ||
9130 | |||
9131 | kfree(buf); | ||
9132 | return ncq_prio_supp; | ||
9133 | } | ||
9102 | /* | 9134 | /* |
9103 | * The pci device ids are defined in mpi/mpi2_cnfg.h. | 9135 | * The pci device ids are defined in mpi/mpi2_cnfg.h. |
9104 | */ | 9136 | */ |