Skip to content

Commit 0b320c8

Browse files
committed
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley: "Three obvious driver fixes and two core fixes. The two core fixes are to disable Command Duration Limits by default to fix an inconsistency in SATA and some USB devices. The other is to change the default read size for block zero to follow the device preference (some USB bridges preferring 16 byte commands don't have a translation for READ(10) and thus don't scan properly)" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: mpi3mr: Fix ATA NCQ priority support scsi: ufs: core: Quiesce request queues before checking pending cmds scsi: core: Disable CDL by default scsi: mpt3sas: Avoid test/set_bit() operating in non-allocated memory scsi: sd: Use READ(16) when reading block zero on large capacity disks
2 parents 1110027 + 90e6f08 commit 0b320c8

File tree

10 files changed

+130
-36
lines changed

10 files changed

+130
-36
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.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8512,6 +8512,12 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
85128512
ioc->pd_handles_sz = (ioc->facts.MaxDevHandle / 8);
85138513
if (ioc->facts.MaxDevHandle % 8)
85148514
ioc->pd_handles_sz++;
8515+
/*
8516+
* pd_handles_sz should have, at least, the minimal room for
8517+
* set_bit()/test_bit(), otherwise out-of-memory touch may occur.
8518+
*/
8519+
ioc->pd_handles_sz = ALIGN(ioc->pd_handles_sz, sizeof(unsigned long));
8520+
85158521
ioc->pd_handles = kzalloc(ioc->pd_handles_sz,
85168522
GFP_KERNEL);
85178523
if (!ioc->pd_handles) {
@@ -8529,6 +8535,13 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
85298535
ioc->pend_os_device_add_sz = (ioc->facts.MaxDevHandle / 8);
85308536
if (ioc->facts.MaxDevHandle % 8)
85318537
ioc->pend_os_device_add_sz++;
8538+
8539+
/*
8540+
* pend_os_device_add_sz should have, at least, the minimal room for
8541+
* set_bit()/test_bit(), otherwise out-of-memory may occur.
8542+
*/
8543+
ioc->pend_os_device_add_sz = ALIGN(ioc->pend_os_device_add_sz,
8544+
sizeof(unsigned long));
85328545
ioc->pend_os_device_add = kzalloc(ioc->pend_os_device_add_sz,
85338546
GFP_KERNEL);
85348547
if (!ioc->pend_os_device_add) {
@@ -8820,6 +8833,12 @@ _base_check_ioc_facts_changes(struct MPT3SAS_ADAPTER *ioc)
88208833
if (ioc->facts.MaxDevHandle % 8)
88218834
pd_handles_sz++;
88228835

8836+
/*
8837+
* pd_handles should have, at least, the minimal room for
8838+
* set_bit()/test_bit(), otherwise out-of-memory touch may
8839+
* occur.
8840+
*/
8841+
pd_handles_sz = ALIGN(pd_handles_sz, sizeof(unsigned long));
88238842
pd_handles = krealloc(ioc->pd_handles, pd_handles_sz,
88248843
GFP_KERNEL);
88258844
if (!pd_handles) {

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.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,13 @@ void scsi_cdl_check(struct scsi_device *sdev)
673673
sdev->use_10_for_rw = 0;
674674

675675
sdev->cdl_supported = 1;
676+
677+
/*
678+
* If the device supports CDL, make sure that the current drive
679+
* feature status is consistent with the user controlled
680+
* cdl_enable state.
681+
*/
682+
scsi_cdl_enable(sdev, sdev->cdl_enable);
676683
} else {
677684
sdev->cdl_supported = 0;
678685
}

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

drivers/scsi/sd.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3565,16 +3565,23 @@ static bool sd_validate_opt_xfer_size(struct scsi_disk *sdkp,
35653565

35663566
static void sd_read_block_zero(struct scsi_disk *sdkp)
35673567
{
3568-
unsigned int buf_len = sdkp->device->sector_size;
3569-
char *buffer, cmd[10] = { };
3568+
struct scsi_device *sdev = sdkp->device;
3569+
unsigned int buf_len = sdev->sector_size;
3570+
u8 *buffer, cmd[16] = { };
35703571

35713572
buffer = kmalloc(buf_len, GFP_KERNEL);
35723573
if (!buffer)
35733574
return;
35743575

3575-
cmd[0] = READ_10;
3576-
put_unaligned_be32(0, &cmd[2]); /* Logical block address 0 */
3577-
put_unaligned_be16(1, &cmd[7]); /* Transfer 1 logical block */
3576+
if (sdev->use_16_for_rw) {
3577+
cmd[0] = READ_16;
3578+
put_unaligned_be64(0, &cmd[2]); /* Logical block address 0 */
3579+
put_unaligned_be32(1, &cmd[10]);/* Transfer 1 logical block */
3580+
} else {
3581+
cmd[0] = READ_10;
3582+
put_unaligned_be32(0, &cmd[2]); /* Logical block address 0 */
3583+
put_unaligned_be16(1, &cmd[7]); /* Transfer 1 logical block */
3584+
}
35783585

35793586
scsi_execute_cmd(sdkp->device, cmd, REQ_OP_DRV_IN, buffer, buf_len,
35803587
SD_TIMEOUT, sdkp->max_retries, NULL);

drivers/ufs/core/ufshcd.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,7 +1366,7 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba, u64 timeout_us)
13661366
* make sure that there are no outstanding requests when
13671367
* clock scaling is in progress
13681368
*/
1369-
ufshcd_scsi_block_requests(hba);
1369+
blk_mq_quiesce_tagset(&hba->host->tag_set);
13701370
mutex_lock(&hba->wb_mutex);
13711371
down_write(&hba->clk_scaling_lock);
13721372

@@ -1375,7 +1375,7 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba, u64 timeout_us)
13751375
ret = -EBUSY;
13761376
up_write(&hba->clk_scaling_lock);
13771377
mutex_unlock(&hba->wb_mutex);
1378-
ufshcd_scsi_unblock_requests(hba);
1378+
blk_mq_unquiesce_tagset(&hba->host->tag_set);
13791379
goto out;
13801380
}
13811381

@@ -1396,7 +1396,7 @@ static void ufshcd_clock_scaling_unprepare(struct ufs_hba *hba, int err, bool sc
13961396

13971397
mutex_unlock(&hba->wb_mutex);
13981398

1399-
ufshcd_scsi_unblock_requests(hba);
1399+
blk_mq_unquiesce_tagset(&hba->host->tag_set);
14001400
ufshcd_release(hba);
14011401
}
14021402

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)