Commit 96b171d6 authored by Bart Van Assche's avatar Bart Van Assche Committed by Martin K. Petersen

scsi: core: Query the Block Limits Extension VPD page

Parse the Reduced Stream Control Supported (RSCS) bit from the block limits
extension VPD page. The RSCS bit is defined in SBC-5 r05
(https://www.t10.org/cgi-bin/ac.pl?t=f&f=sbc5r05.pdf).
Reviewed-by: default avatarAvri Altman <avri.altman@wdc.com>
Reviewed-by: default avatarDaejun Park <daejun7.park@samsung.com>
Cc: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
Link: https://lore.kernel.org/r/20240130214911.1863909-10-bvanassche@acm.orgSigned-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 44981351
...@@ -499,6 +499,8 @@ void scsi_attach_vpd(struct scsi_device *sdev) ...@@ -499,6 +499,8 @@ void scsi_attach_vpd(struct scsi_device *sdev)
scsi_update_vpd_page(sdev, 0xb1, &sdev->vpd_pgb1); scsi_update_vpd_page(sdev, 0xb1, &sdev->vpd_pgb1);
if (vpd_buf->data[i] == 0xb2) if (vpd_buf->data[i] == 0xb2)
scsi_update_vpd_page(sdev, 0xb2, &sdev->vpd_pgb2); scsi_update_vpd_page(sdev, 0xb2, &sdev->vpd_pgb2);
if (vpd_buf->data[i] == 0xb7)
scsi_update_vpd_page(sdev, 0xb7, &sdev->vpd_pgb7);
} }
kfree(vpd_buf); kfree(vpd_buf);
} }
......
...@@ -449,6 +449,7 @@ static void scsi_device_dev_release(struct device *dev) ...@@ -449,6 +449,7 @@ static void scsi_device_dev_release(struct device *dev)
struct scsi_vpd *vpd_pg80 = NULL, *vpd_pg83 = NULL; struct scsi_vpd *vpd_pg80 = NULL, *vpd_pg83 = NULL;
struct scsi_vpd *vpd_pg0 = NULL, *vpd_pg89 = NULL; struct scsi_vpd *vpd_pg0 = NULL, *vpd_pg89 = NULL;
struct scsi_vpd *vpd_pgb0 = NULL, *vpd_pgb1 = NULL, *vpd_pgb2 = NULL; struct scsi_vpd *vpd_pgb0 = NULL, *vpd_pgb1 = NULL, *vpd_pgb2 = NULL;
struct scsi_vpd *vpd_pgb7 = NULL;
unsigned long flags; unsigned long flags;
might_sleep(); might_sleep();
...@@ -494,6 +495,8 @@ static void scsi_device_dev_release(struct device *dev) ...@@ -494,6 +495,8 @@ static void scsi_device_dev_release(struct device *dev)
lockdep_is_held(&sdev->inquiry_mutex)); lockdep_is_held(&sdev->inquiry_mutex));
vpd_pgb2 = rcu_replace_pointer(sdev->vpd_pgb2, vpd_pgb2, vpd_pgb2 = rcu_replace_pointer(sdev->vpd_pgb2, vpd_pgb2,
lockdep_is_held(&sdev->inquiry_mutex)); lockdep_is_held(&sdev->inquiry_mutex));
vpd_pgb7 = rcu_replace_pointer(sdev->vpd_pgb7, vpd_pgb7,
lockdep_is_held(&sdev->inquiry_mutex));
mutex_unlock(&sdev->inquiry_mutex); mutex_unlock(&sdev->inquiry_mutex);
if (vpd_pg0) if (vpd_pg0)
...@@ -510,6 +513,8 @@ static void scsi_device_dev_release(struct device *dev) ...@@ -510,6 +513,8 @@ static void scsi_device_dev_release(struct device *dev)
kfree_rcu(vpd_pgb1, rcu); kfree_rcu(vpd_pgb1, rcu);
if (vpd_pgb2) if (vpd_pgb2)
kfree_rcu(vpd_pgb2, rcu); kfree_rcu(vpd_pgb2, rcu);
if (vpd_pgb7)
kfree_rcu(vpd_pgb7, rcu);
kfree(sdev->inquiry); kfree(sdev->inquiry);
kfree(sdev); kfree(sdev);
...@@ -921,6 +926,7 @@ sdev_vpd_pg_attr(pg89); ...@@ -921,6 +926,7 @@ sdev_vpd_pg_attr(pg89);
sdev_vpd_pg_attr(pgb0); sdev_vpd_pg_attr(pgb0);
sdev_vpd_pg_attr(pgb1); sdev_vpd_pg_attr(pgb1);
sdev_vpd_pg_attr(pgb2); sdev_vpd_pg_attr(pgb2);
sdev_vpd_pg_attr(pgb7);
sdev_vpd_pg_attr(pg0); sdev_vpd_pg_attr(pg0);
static ssize_t show_inquiry(struct file *filep, struct kobject *kobj, static ssize_t show_inquiry(struct file *filep, struct kobject *kobj,
...@@ -1295,6 +1301,9 @@ static umode_t scsi_sdev_bin_attr_is_visible(struct kobject *kobj, ...@@ -1295,6 +1301,9 @@ static umode_t scsi_sdev_bin_attr_is_visible(struct kobject *kobj,
if (attr == &dev_attr_vpd_pgb2 && !sdev->vpd_pgb2) if (attr == &dev_attr_vpd_pgb2 && !sdev->vpd_pgb2)
return 0; return 0;
if (attr == &dev_attr_vpd_pgb7 && !sdev->vpd_pgb7)
return 0;
return S_IRUGO; return S_IRUGO;
} }
...@@ -1347,6 +1356,7 @@ static struct bin_attribute *scsi_sdev_bin_attrs[] = { ...@@ -1347,6 +1356,7 @@ static struct bin_attribute *scsi_sdev_bin_attrs[] = {
&dev_attr_vpd_pgb0, &dev_attr_vpd_pgb0,
&dev_attr_vpd_pgb1, &dev_attr_vpd_pgb1,
&dev_attr_vpd_pgb2, &dev_attr_vpd_pgb2,
&dev_attr_vpd_pgb7,
&dev_attr_inquiry, &dev_attr_inquiry,
NULL NULL
}; };
......
...@@ -3108,6 +3108,18 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) ...@@ -3108,6 +3108,18 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
rcu_read_unlock(); rcu_read_unlock();
} }
/* Parse the Block Limits Extension VPD page (0xb7) */
static void sd_read_block_limits_ext(struct scsi_disk *sdkp)
{
struct scsi_vpd *vpd;
rcu_read_lock();
vpd = rcu_dereference(sdkp->device->vpd_pgb7);
if (vpd && vpd->len >= 2)
sdkp->rscs = vpd->data[5] & 1;
rcu_read_unlock();
}
/** /**
* sd_read_block_characteristics - Query block dev. characteristics * sd_read_block_characteristics - Query block dev. characteristics
* @sdkp: disk to query * @sdkp: disk to query
...@@ -3459,6 +3471,7 @@ static int sd_revalidate_disk(struct gendisk *disk) ...@@ -3459,6 +3471,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
if (scsi_device_supports_vpd(sdp)) { if (scsi_device_supports_vpd(sdp)) {
sd_read_block_provisioning(sdkp); sd_read_block_provisioning(sdkp);
sd_read_block_limits(sdkp); sd_read_block_limits(sdkp);
sd_read_block_limits_ext(sdkp);
sd_read_block_characteristics(sdkp); sd_read_block_characteristics(sdkp);
sd_zbc_read_zones(sdkp, buffer); sd_zbc_read_zones(sdkp, buffer);
sd_read_cpr(sdkp); sd_read_cpr(sdkp);
......
...@@ -151,6 +151,7 @@ struct scsi_disk { ...@@ -151,6 +151,7 @@ struct scsi_disk {
unsigned urswrz : 1; unsigned urswrz : 1;
unsigned security : 1; unsigned security : 1;
unsigned ignore_medium_access_errors : 1; unsigned ignore_medium_access_errors : 1;
bool rscs : 1; /* reduced stream control support */
}; };
#define to_scsi_disk(obj) container_of(obj, struct scsi_disk, disk_dev) #define to_scsi_disk(obj) container_of(obj, struct scsi_disk, disk_dev)
......
...@@ -153,6 +153,7 @@ struct scsi_device { ...@@ -153,6 +153,7 @@ struct scsi_device {
struct scsi_vpd __rcu *vpd_pgb0; struct scsi_vpd __rcu *vpd_pgb0;
struct scsi_vpd __rcu *vpd_pgb1; struct scsi_vpd __rcu *vpd_pgb1;
struct scsi_vpd __rcu *vpd_pgb2; struct scsi_vpd __rcu *vpd_pgb2;
struct scsi_vpd __rcu *vpd_pgb7;
struct scsi_target *sdev_target; struct scsi_target *sdev_target;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment