Skip to content

Commit b76ec77

Browse files
damien-lemoalroxanan1996
authored andcommitted
scsi: mpi3mr: Fix ATA NCQ priority support
BugLink: https://bugs.launchpad.net/bugs/2073765 commit 90e6f08 upstream. The function mpi3mr_qcmd() of the mpi3mr driver is able to indicate to the HBA if a read or write command directed at an ATA device should be translated to an NCQ read/write command with the high prioiryt bit set when the request uses the RT priority class and the user has enabled NCQ priority through sysfs. However, unlike the mpt3sas driver, the mpi3mr driver does not define the sas_ncq_prio_supported and sas_ncq_prio_enable sysfs attributes, so the ncq_prio_enable field of struct mpi3mr_sdev_priv_data is never actually set and NCQ Priority cannot ever be used. Fix this by defining these missing atributes to allow a user to check if an ATA device supports NCQ priority and to enable/disable the use of NCQ priority. To do this, lift the function scsih_ncq_prio_supp() out of the mpt3sas driver and make it the generic SCSI SAS transport function sas_ata_ncq_prio_supported(). Nothing in that function is hardware specific, so this function can be used in both the mpt3sas driver and the mpi3mr driver. Reported-by: Scott McCoy <[email protected]> Fixes: 023ab2a ("scsi: mpi3mr: Add support for queue command processing") Cc: [email protected] Signed-off-by: Damien Le Moal <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Niklas Cassel <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Portia Stephens <[email protected]> Signed-off-by: Roxana Nicolescu <[email protected]>
1 parent bc80416 commit b76ec77

File tree

7 files changed

+101
-30
lines changed

7 files changed

+101
-30
lines changed

drivers/scsi/mpi3mr/mpi3mr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <scsi/scsi_device.h>
3939
#include <scsi/scsi_host.h>
4040
#include <scsi/scsi_tcq.h>
41+
#include <scsi/scsi_transport_sas.h>
4142
#include <uapi/scsi/scsi_bsg_mpi3mr.h>
4243

4344
#include "mpi/mpi30_transport.h"

drivers/scsi/mpi3mr/mpi3mr_os.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4122,6 +4122,72 @@ static int mpi3mr_qcmd(struct Scsi_Host *shost,
41224122
return retval;
41234123
}
41244124

4125+
/**
4126+
* sas_ncq_prio_supported_show - Indicate if device supports NCQ priority
4127+
* @dev: pointer to embedded device
4128+
* @attr: sas_ncq_prio_supported attribute descriptor
4129+
* @buf: the buffer returned
4130+
*
4131+
* A sysfs 'read-only' sdev attribute, only works with SATA devices
4132+
*/
4133+
static ssize_t
4134+
sas_ncq_prio_supported_show(struct device *dev,
4135+
struct device_attribute *attr, char *buf)
4136+
{
4137+
struct scsi_device *sdev = to_scsi_device(dev);
4138+
4139+
return sysfs_emit(buf, "%d\n", sas_ata_ncq_prio_supported(sdev));
4140+
}
4141+
static DEVICE_ATTR_RO(sas_ncq_prio_supported);
4142+
4143+
/**
4144+
* sas_ncq_prio_enable_show - send prioritized io commands to device
4145+
* @dev: pointer to embedded device
4146+
* @attr: sas_ncq_prio_enable attribute descriptor
4147+
* @buf: the buffer returned
4148+
*
4149+
* A sysfs 'read/write' sdev attribute, only works with SATA devices
4150+
*/
4151+
static ssize_t
4152+
sas_ncq_prio_enable_show(struct device *dev,
4153+
struct device_attribute *attr, char *buf)
4154+
{
4155+
struct scsi_device *sdev = to_scsi_device(dev);
4156+
struct mpi3mr_sdev_priv_data *sdev_priv_data = sdev->hostdata;
4157+
4158+
if (!sdev_priv_data)
4159+
return 0;
4160+
4161+
return sysfs_emit(buf, "%d\n", sdev_priv_data->ncq_prio_enable);
4162+
}
4163+
4164+
static ssize_t
4165+
sas_ncq_prio_enable_store(struct device *dev,
4166+
struct device_attribute *attr,
4167+
const char *buf, size_t count)
4168+
{
4169+
struct scsi_device *sdev = to_scsi_device(dev);
4170+
struct mpi3mr_sdev_priv_data *sdev_priv_data = sdev->hostdata;
4171+
bool ncq_prio_enable = 0;
4172+
4173+
if (kstrtobool(buf, &ncq_prio_enable))
4174+
return -EINVAL;
4175+
4176+
if (!sas_ata_ncq_prio_supported(sdev))
4177+
return -EINVAL;
4178+
4179+
sdev_priv_data->ncq_prio_enable = ncq_prio_enable;
4180+
4181+
return strlen(buf);
4182+
}
4183+
static DEVICE_ATTR_RW(sas_ncq_prio_enable);
4184+
4185+
static struct device_attribute *mpi3mr_dev_attrs[] = {
4186+
&dev_attr_sas_ncq_prio_supported,
4187+
&dev_attr_sas_ncq_prio_enable,
4188+
NULL,
4189+
};
4190+
41254191
static struct scsi_host_template mpi3mr_driver_template = {
41264192
.module = THIS_MODULE,
41274193
.name = "MPI3 Storage Controller",
@@ -4153,6 +4219,7 @@ static struct scsi_host_template mpi3mr_driver_template = {
41534219
.track_queue_depth = 1,
41544220
.cmd_size = sizeof(struct scmd_priv),
41554221
.sdev_groups = mpi3mr_dev_groups,
4222+
.sdev_attrs = mpi3mr_dev_attrs,
41564223
};
41574224

41584225
/**

drivers/scsi/mpt3sas/mpt3sas_base.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2010,9 +2010,6 @@ void
20102010
mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
20112011
struct _raid_device *raid_device, Mpi25SCSIIORequest_t *mpi_request);
20122012

2013-
/* NCQ Prio Handling Check */
2014-
bool scsih_ncq_prio_supp(struct scsi_device *sdev);
2015-
20162013
void mpt3sas_setup_debugfs(struct MPT3SAS_ADAPTER *ioc);
20172014
void mpt3sas_destroy_debugfs(struct MPT3SAS_ADAPTER *ioc);
20182015
void mpt3sas_init_debugfs(void);

drivers/scsi/mpt3sas/mpt3sas_ctl.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4012,7 +4012,7 @@ sas_ncq_prio_supported_show(struct device *dev,
40124012
{
40134013
struct scsi_device *sdev = to_scsi_device(dev);
40144014

4015-
return sysfs_emit(buf, "%d\n", scsih_ncq_prio_supp(sdev));
4015+
return sysfs_emit(buf, "%d\n", sas_ata_ncq_prio_supported(sdev));
40164016
}
40174017
static DEVICE_ATTR_RO(sas_ncq_prio_supported);
40184018

@@ -4047,7 +4047,7 @@ sas_ncq_prio_enable_store(struct device *dev,
40474047
if (kstrtobool(buf, &ncq_prio_enable))
40484048
return -EINVAL;
40494049

4050-
if (!scsih_ncq_prio_supp(sdev))
4050+
if (!sas_ata_ncq_prio_supported(sdev))
40514051
return -EINVAL;
40524052

40534053
sas_device_priv_data->ncq_prio_enable = ncq_prio_enable;

drivers/scsi/mpt3sas/mpt3sas_scsih.c

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12580,31 +12580,6 @@ scsih_pci_mmio_enabled(struct pci_dev *pdev)
1258012580
return PCI_ERS_RESULT_RECOVERED;
1258112581
}
1258212582

12583-
/**
12584-
* scsih_ncq_prio_supp - Check for NCQ command priority support
12585-
* @sdev: scsi device struct
12586-
*
12587-
* This is called when a user indicates they would like to enable
12588-
* ncq command priorities. This works only on SATA devices.
12589-
*/
12590-
bool scsih_ncq_prio_supp(struct scsi_device *sdev)
12591-
{
12592-
unsigned char *buf;
12593-
bool ncq_prio_supp = false;
12594-
12595-
if (!scsi_device_supports_vpd(sdev))
12596-
return ncq_prio_supp;
12597-
12598-
buf = kmalloc(SCSI_VPD_PG_LEN, GFP_KERNEL);
12599-
if (!buf)
12600-
return ncq_prio_supp;
12601-
12602-
if (!scsi_get_vpd_page(sdev, 0x89, buf, SCSI_VPD_PG_LEN))
12603-
ncq_prio_supp = (buf[213] >> 4) & 1;
12604-
12605-
kfree(buf);
12606-
return ncq_prio_supp;
12607-
}
1260812583
/*
1260912584
* The pci device ids are defined in mpi/mpi2_cnfg.h.
1261012585
*/

drivers/scsi/scsi_transport_sas.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,35 @@ unsigned int sas_is_tlr_enabled(struct scsi_device *sdev)
410410
}
411411
EXPORT_SYMBOL_GPL(sas_is_tlr_enabled);
412412

413+
/**
414+
* sas_ata_ncq_prio_supported - Check for ATA NCQ command priority support
415+
* @sdev: SCSI device
416+
*
417+
* Check if an ATA device supports NCQ priority using VPD page 89h (ATA
418+
* Information). Since this VPD page is implemented only for ATA devices,
419+
* this function always returns false for SCSI devices.
420+
*/
421+
bool sas_ata_ncq_prio_supported(struct scsi_device *sdev)
422+
{
423+
unsigned char *buf;
424+
bool ncq_prio_supported = false;
425+
426+
if (!scsi_device_supports_vpd(sdev))
427+
return false;
428+
429+
buf = kmalloc(SCSI_VPD_PG_LEN, GFP_KERNEL);
430+
if (!buf)
431+
return false;
432+
433+
if (!scsi_get_vpd_page(sdev, 0x89, buf, SCSI_VPD_PG_LEN))
434+
ncq_prio_supported = (buf[213] >> 4) & 1;
435+
436+
kfree(buf);
437+
438+
return ncq_prio_supported;
439+
}
440+
EXPORT_SYMBOL_GPL(sas_ata_ncq_prio_supported);
441+
413442
/*
414443
* SAS Phy attributes
415444
*/

include/scsi/scsi_transport_sas.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ unsigned int sas_is_tlr_enabled(struct scsi_device *);
199199
void sas_disable_tlr(struct scsi_device *);
200200
void sas_enable_tlr(struct scsi_device *);
201201

202+
bool sas_ata_ncq_prio_supported(struct scsi_device *sdev);
203+
202204
extern struct sas_rphy *sas_end_device_alloc(struct sas_port *);
203205
extern struct sas_rphy *sas_expander_alloc(struct sas_port *, enum sas_device_type);
204206
void sas_rphy_free(struct sas_rphy *);

0 commit comments

Comments
 (0)