Skip to content

Commit 90e6f08

Browse files
damien-lemoalmartinkpetersen
authored andcommitted
scsi: mpi3mr: Fix ATA NCQ priority support
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 <scott.mccoy@wdc.com> Fixes: 023ab2a ("scsi: mpi3mr: Add support for queue command processing") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Link: https://lore.kernel.org/r/20240611083435.92961-1-dlemoal@kernel.org Reviewed-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 77691af commit 90e6f08

File tree

6 files changed

+89
-28
lines changed

6 files changed

+89
-28
lines changed

drivers/scsi/mpi3mr/mpi3mr_app.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2163,10 +2163,72 @@ persistent_id_show(struct device *dev, struct device_attribute *attr,
21632163
}
21642164
static DEVICE_ATTR_RO(persistent_id);
21652165

2166+
/**
2167+
* sas_ncq_prio_supported_show - Indicate if device supports NCQ priority
2168+
* @dev: pointer to embedded device
2169+
* @attr: sas_ncq_prio_supported attribute descriptor
2170+
* @buf: the buffer returned
2171+
*
2172+
* A sysfs 'read-only' sdev attribute, only works with SATA devices
2173+
*/
2174+
static ssize_t
2175+
sas_ncq_prio_supported_show(struct device *dev,
2176+
struct device_attribute *attr, char *buf)
2177+
{
2178+
struct scsi_device *sdev = to_scsi_device(dev);
2179+
2180+
return sysfs_emit(buf, "%d\n", sas_ata_ncq_prio_supported(sdev));
2181+
}
2182+
static DEVICE_ATTR_RO(sas_ncq_prio_supported);
2183+
2184+
/**
2185+
* sas_ncq_prio_enable_show - send prioritized io commands to device
2186+
* @dev: pointer to embedded device
2187+
* @attr: sas_ncq_prio_enable attribute descriptor
2188+
* @buf: the buffer returned
2189+
*
2190+
* A sysfs 'read/write' sdev attribute, only works with SATA devices
2191+
*/
2192+
static ssize_t
2193+
sas_ncq_prio_enable_show(struct device *dev,
2194+
struct device_attribute *attr, char *buf)
2195+
{
2196+
struct scsi_device *sdev = to_scsi_device(dev);
2197+
struct mpi3mr_sdev_priv_data *sdev_priv_data = sdev->hostdata;
2198+
2199+
if (!sdev_priv_data)
2200+
return 0;
2201+
2202+
return sysfs_emit(buf, "%d\n", sdev_priv_data->ncq_prio_enable);
2203+
}
2204+
2205+
static ssize_t
2206+
sas_ncq_prio_enable_store(struct device *dev,
2207+
struct device_attribute *attr,
2208+
const char *buf, size_t count)
2209+
{
2210+
struct scsi_device *sdev = to_scsi_device(dev);
2211+
struct mpi3mr_sdev_priv_data *sdev_priv_data = sdev->hostdata;
2212+
bool ncq_prio_enable = 0;
2213+
2214+
if (kstrtobool(buf, &ncq_prio_enable))
2215+
return -EINVAL;
2216+
2217+
if (!sas_ata_ncq_prio_supported(sdev))
2218+
return -EINVAL;
2219+
2220+
sdev_priv_data->ncq_prio_enable = ncq_prio_enable;
2221+
2222+
return strlen(buf);
2223+
}
2224+
static DEVICE_ATTR_RW(sas_ncq_prio_enable);
2225+
21662226
static struct attribute *mpi3mr_dev_attrs[] = {
21672227
&dev_attr_sas_address.attr,
21682228
&dev_attr_device_handle.attr,
21692229
&dev_attr_persistent_id.attr,
2230+
&dev_attr_sas_ncq_prio_supported.attr,
2231+
&dev_attr_sas_ncq_prio_enable.attr,
21702232
NULL,
21712233
};
21722234

drivers/scsi/mpt3sas/mpt3sas_base.h

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

2051-
/* NCQ Prio Handling Check */
2052-
bool scsih_ncq_prio_supp(struct scsi_device *sdev);
2053-
20542051
void mpt3sas_setup_debugfs(struct MPT3SAS_ADAPTER *ioc);
20552052
void mpt3sas_destroy_debugfs(struct MPT3SAS_ADAPTER *ioc);
20562053
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
@@ -4088,7 +4088,7 @@ sas_ncq_prio_supported_show(struct device *dev,
40884088
{
40894089
struct scsi_device *sdev = to_scsi_device(dev);
40904090

4091-
return sysfs_emit(buf, "%d\n", scsih_ncq_prio_supp(sdev));
4091+
return sysfs_emit(buf, "%d\n", sas_ata_ncq_prio_supported(sdev));
40924092
}
40934093
static DEVICE_ATTR_RO(sas_ncq_prio_supported);
40944094

@@ -4123,7 +4123,7 @@ sas_ncq_prio_enable_store(struct device *dev,
41234123
if (kstrtobool(buf, &ncq_prio_enable))
41244124
return -EINVAL;
41254125

4126-
if (!scsih_ncq_prio_supp(sdev))
4126+
if (!sas_ata_ncq_prio_supported(sdev))
41274127
return -EINVAL;
41284128

41294129
sas_device_priv_data->ncq_prio_enable = ncq_prio_enable;

drivers/scsi/mpt3sas/mpt3sas_scsih.c

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12571,29 +12571,6 @@ scsih_pci_mmio_enabled(struct pci_dev *pdev)
1257112571
return PCI_ERS_RESULT_RECOVERED;
1257212572
}
1257312573

12574-
/**
12575-
* scsih_ncq_prio_supp - Check for NCQ command priority support
12576-
* @sdev: scsi device struct
12577-
*
12578-
* This is called when a user indicates they would like to enable
12579-
* ncq command priorities. This works only on SATA devices.
12580-
*/
12581-
bool scsih_ncq_prio_supp(struct scsi_device *sdev)
12582-
{
12583-
struct scsi_vpd *vpd;
12584-
bool ncq_prio_supp = false;
12585-
12586-
rcu_read_lock();
12587-
vpd = rcu_dereference(sdev->vpd_pg89);
12588-
if (!vpd || vpd->len < 214)
12589-
goto out;
12590-
12591-
ncq_prio_supp = (vpd->data[213] >> 4) & 1;
12592-
out:
12593-
rcu_read_unlock();
12594-
12595-
return ncq_prio_supp;
12596-
}
1259712574
/*
1259812575
* The pci device ids are defined in mpi/mpi2_cnfg.h.
1259912576
*/

drivers/scsi/scsi_transport_sas.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,29 @@ unsigned int sas_is_tlr_enabled(struct scsi_device *sdev)
416416
}
417417
EXPORT_SYMBOL_GPL(sas_is_tlr_enabled);
418418

419+
/**
420+
* sas_ata_ncq_prio_supported - Check for ATA NCQ command priority support
421+
* @sdev: SCSI device
422+
*
423+
* Check if an ATA device supports NCQ priority using VPD page 89h (ATA
424+
* Information). Since this VPD page is implemented only for ATA devices,
425+
* this function always returns false for SCSI devices.
426+
*/
427+
bool sas_ata_ncq_prio_supported(struct scsi_device *sdev)
428+
{
429+
struct scsi_vpd *vpd;
430+
bool ncq_prio_supported = false;
431+
432+
rcu_read_lock();
433+
vpd = rcu_dereference(sdev->vpd_pg89);
434+
if (vpd && vpd->len >= 214)
435+
ncq_prio_supported = (vpd->data[213] >> 4) & 1;
436+
rcu_read_unlock();
437+
438+
return ncq_prio_supported;
439+
}
440+
EXPORT_SYMBOL_GPL(sas_ata_ncq_prio_supported);
441+
419442
/*
420443
* SAS Phy attributes
421444
*/

include/scsi/scsi_transport_sas.h

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

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

0 commit comments

Comments
 (0)