On Tue, Dec 13, 2016 at 6:01 AM, Adam Manzanares <adam.manzana...@hgst.com> wrote: > From: Adam Manzanares <adam.manzana...@wdc.com> > > 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. > > This patch depends on block: Add iocontext priority to request > > v2: > - Get iopriority class only if sysfs variable is set. > > Signed-off-by: Adam Manzanares <adam.manzana...@wdc.com>
Acked-by: Sreekanth Reddy <sreekanth.re...@broadcom.com> > --- > drivers/scsi/mpt3sas/mpt3sas_base.h | 6 +++++ > drivers/scsi/mpt3sas/mpt3sas_ctl.c | 43 > ++++++++++++++++++++++++++++++++++-- > 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 3e71bc1..354cdc7 100644 > --- a/drivers/scsi/mpt3sas/mpt3sas_base.h > +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h > @@ -402,6 +402,9 @@ struct MPT3SAS_DEVICE { > u8 block; > u8 tlr_snoop_check; > u8 ignore_delay_remove; > + /* Iopriority Command Handling */ > + u8 ncq_prio_enable; > + > }; > > #define MPT3_CMD_NOT_USED 0x8000 /* free */ > @@ -1449,4 +1452,7 @@ mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, > struct scsi_cmnd *scmd, > struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request, > u16 smid); > > +/* NCQ Prio Handling Check */ > +bool scsih_ncq_prio_supp(struct scsi_device *sdev); > + > #endif /* MPT3SAS_BASE_H_INCLUDED */ > diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c > b/drivers/scsi/mpt3sas/mpt3sas_ctl.c > index 26cdc12..3ad8339 100644 > --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c > +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c > @@ -3290,8 +3290,6 @@ static DEVICE_ATTR(diag_trigger_mpi, S_IRUGO | S_IWUSR, > > /*********** diagnostic trigger suppport *** END > ****************************/ > > - > - > /*****************************************/ > > struct device_attribute *mpt3sas_host_attrs[] = { > @@ -3367,9 +3365,50 @@ _ctl_device_handle_show(struct device *dev, struct > device_attribute *attr, > } > static DEVICE_ATTR(sas_device_handle, S_IRUGO, _ctl_device_handle_show, > NULL); > > +/** > + * _ctl_device_ncq_io_prio_show - send prioritized io commands to device > + * @dev - pointer to embedded device > + * @buf - the buffer returned > + * > + * A sysfs 'read/write' sdev attribute, only works with SATA > + */ > +static ssize_t > +_ctl_device_ncq_prio_enable_show(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct scsi_device *sdev = to_scsi_device(dev); > + struct MPT3SAS_DEVICE *sas_device_priv_data = sdev->hostdata; > + > + return snprintf(buf, PAGE_SIZE, "%d\n", > + sas_device_priv_data->ncq_prio_enable); > +} > + > +static ssize_t > +_ctl_device_ncq_prio_enable_store(struct device *dev, > + struct device_attribute *attr, > + const char *buf, size_t count) > +{ > + struct scsi_device *sdev = to_scsi_device(dev); > + struct MPT3SAS_DEVICE *sas_device_priv_data = sdev->hostdata; > + bool ncq_prio_enable = 0; > + > + if (kstrtobool(buf, &ncq_prio_enable)) > + return -EINVAL; > + > + if (!scsih_ncq_prio_supp(sdev)) > + return -EINVAL; > + > + sas_device_priv_data->ncq_prio_enable = ncq_prio_enable; > + return strlen(buf); > +} > +static DEVICE_ATTR(sas_ncq_prio_enable, S_IRUGO | S_IWUSR, > + _ctl_device_ncq_prio_enable_show, > + _ctl_device_ncq_prio_enable_store); > + > struct device_attribute *mpt3sas_dev_attrs[] = { > &dev_attr_sas_address, > &dev_attr_sas_device_handle, > + &dev_attr_sas_ncq_prio_enable, > NULL, > }; > > diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c > b/drivers/scsi/mpt3sas/mpt3sas_scsih.c > index 209a969..a6d1045 100644 > --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c > +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c > @@ -4030,6 +4030,8 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd > *scmd) > struct MPT3SAS_DEVICE *sas_device_priv_data; > struct MPT3SAS_TARGET *sas_target_priv_data; > struct _raid_device *raid_device; > + struct request *rq = scmd->request; > + int class; > Mpi2SCSIIORequest_t *mpi_request; > u32 mpi_control; > u16 smid; > @@ -4085,7 +4087,12 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd > *scmd) > > /* set tags */ > mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; > - > + /* NCQ Prio supported, make sure control indicated high priority */ > + if (sas_device_priv_data->ncq_prio_enable) { > + class = IOPRIO_PRIO_CLASS(req_get_ioprio(rq)); > + if (class == IOPRIO_CLASS_RT) > + mpi_control |= 1 << MPI2_SCSIIO_CONTROL_CMDPRI_SHIFT; > + } > /* Make sure Device is not raid volume. > * We do not expose raid functionality to upper layer for warpdrive. > */ > @@ -9031,6 +9038,31 @@ scsih_pci_mmio_enabled(struct pci_dev *pdev) > return PCI_ERS_RESULT_RECOVERED; > } > > +/** > + * scsih__ncq_prio_supp - Check for NCQ command priority support > + * @sdev: scsi device struct > + * > + * This is called when a user indicates they would like to enable > + * ncq command priorities. This works only on SATA devices. > + */ > +bool scsih_ncq_prio_supp(struct scsi_device *sdev) > +{ > + unsigned char *buf; > + bool ncq_prio_supp = false; > + > + if (!scsi_device_supports_vpd(sdev)) > + return ncq_prio_supp; > + > + buf = kmalloc(SCSI_VPD_PG_LEN, GFP_KERNEL); > + if (!buf) > + return ncq_prio_supp; > + > + if (!scsi_get_vpd_page(sdev, 0x89, buf, SCSI_VPD_PG_LEN)) > + ncq_prio_supp = (buf[213] >> 4) & 1; > + > + kfree(buf); > + return ncq_prio_supp; > +} > /* > * The pci device ids are defined in mpi/mpi2_cnfg.h. > */ > -- > 2.7.4 >