diff options
| -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 | */ |
