// SPDX-License-Identifier: GPL-2.0-only
/*
* sd.c Copyright (C) 1992 Drew Eckhardt
* Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale
*
* Linux scsi disk driver
* Initial versions: Drew Eckhardt
* Subsequent revisions: Eric Youngdale
* Modification history:
* - Drew Eckhardt <drew@colorado.edu> original
* - Eric Youngdale <eric@andante.org> add scatter-gather, multiple
* outstanding request, and other enhancements.
* Support loadable low-level scsi drivers.
* - Jirka Hanika <geo@ff.cuni.cz> support more scsi disks using
* eight major numbers.
* - Richard Gooch <rgooch@atnf.csiro.au> support devfs.
* - Torben Mathiasen <tmm@image.dk> Resource allocation fixes in
* sd_init and cleanups.
* - Alex Davis <letmein@erols.com> Fix problem where partition info
* not being read in sd_open. Fix problem where removable media
* could be ejected after sd_open.
* - Douglas Gilbert <dgilbert@interlog.com> cleanup for lk 2.5.x
* - Badari Pulavarty <pbadari@us.ibm.com>, Matthew Wilcox
* <willy@debian.org>, Kurt Garloff <garloff@suse.de>:
* Support 32k/1M disks.
*
* Logging policy (needs CONFIG_SCSI_LOGGING defined):
* - setting up transfer: SCSI_LOG_HLQUEUE levels 1 and 2
* - end of transfer (bh + scsi_lib): SCSI_LOG_HLCOMPLETE level 1
* - entering sd_ioctl: SCSI_LOG_IOCTL level 1
* - entering other commands: SCSI_LOG_HLQUEUE level 3
* Note: when the logging level is set by the user, it must be greater
* than the level indicated above to trigger output.
*/
#include <linux/bio-integrity.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/hdreg.h>
#include <linux/errno.h>
#include <linux/idr.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/blk-pm.h>
#include <linux/delay.h>
#include <linux/rw_hint.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/string_helpers.h>
#include <linux/slab.h>
#include <linux/sed-opal.h>
#include <linux/pm_runtime.h>
#include <linux/pr.h>
#include <linux/t10-pi.h>
#include <linux/uaccess.h>
#include <linux/unaligned.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_dbg.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_devinfo.h>
#include <scsi/scsi_driver.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/scsicam.h>
#include <scsi/scsi_common.h>
#include "sd.h"
#include "scsi_priv.h"
#include "scsi_logging.h"
MODULE_AUTHOR(
"Eric Youngdale");
MODULE_DESCRIPTION(
"SCSI disk (sd) driver");
MODULE_LICENSE(
"GPL");
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK0_MAJOR);
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK1_MAJOR);
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK2_MAJOR);
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK3_MAJOR);
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK4_MAJOR);
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK5_MAJOR);
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK6_MAJOR);
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK7_MAJOR);
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK8_MAJOR);
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK9_MAJOR);
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK10_MAJOR);
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK11_MAJOR);
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK12_MAJOR);
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK13_MAJOR);
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK14_MAJOR);
MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK15_MAJOR);
MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK);
MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD);
MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC);
MODULE_ALIAS_SCSI_DEVICE(TYPE_ZBC);
#define SD_MINORS 16
static void sd_config_discard(
struct scsi_disk *sdkp,
struct queue_limits *lim,
unsigned int mode);
static void sd_config_write_same(
struct scsi_disk *sdkp,
struct queue_limits *lim);
static int sd_revalidate_disk(
struct gendisk *);
static void sd_unlock_native_capacity(
struct gendisk *disk);
static void sd_shutdown(
struct device *);
static void scsi_disk_release(
struct device *cdev);
static DEFINE_IDA(sd_index_ida);
static mempool_t *sd_page_pool;
static struct lock_class_key sd_bio_compl_lkclass;
static const char *sd_cache_types[] = {
"write through",
"none",
"write back",
"write back, no read (daft)"
};
static void sd_set_flush_flag(
struct scsi_disk *sdkp,
struct queue_limits *lim)
{
if (sdkp->WCE) {
lim->features |= BLK_FEAT_WRITE_CACHE;
if (sdkp->DPOFUA)
lim->features |= BLK_FEAT_FUA;
else
lim->features &= ~BLK_FEAT_FUA;
}
else {
lim->features &= ~(BLK_FEAT_WRITE_CACHE | BLK_FEAT_FUA);
}
}
static ssize_t
cache_type_store(
struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int ct, rcd, wce, sp;
struct scsi_disk *sdkp = to_scsi_disk(dev);
struct scsi_device *sdp = sdkp->device;
char buffer[64];
char *buffer_data;
struct scsi_mode_data data;
struct scsi_sense_hdr sshdr;
static const char temp[] =
"temporary ";
int len, ret;
if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
/* no cache control on RBC devices; theoretically they
* can do it, but there's probably so many exceptions
* it's not worth the risk */
return -EINVAL;
if (strncmp(buf, temp,
sizeof(temp) - 1) == 0) {
buf +=
sizeof(temp) - 1;
sdkp->cache_override = 1;
}
else {
sdkp->cache_override = 0;
}
ct = sysfs_match_string(sd_cache_types, buf);
if (ct < 0)
return -EINVAL;
rcd = ct & 0x01 ? 1 : 0;
wce = (ct & 0x02) && !sdkp->write_prot ? 1 : 0;
if (sdkp->cache_override) {
struct queue_limits lim;
sdkp->WCE = wce;
sdkp->RCD = rcd;
lim = queue_limits_start_update(sdkp->disk->queue);
sd_set_flush_flag(sdkp, &lim);
ret = queue_limits_commit_update_frozen(sdkp->disk->queue,
&lim);
if (ret)
return ret;
return count;
}
if (scsi_mode_sense(sdp, 0x08, 8, 0, buffer,
sizeof(buffer), SD_TIMEOUT,
sdkp->max_retries, &data, NULL))
return -EINVAL;
len = min_t(size_t,
sizeof(buffer), data.length - data.header_length -
data.block_descriptor_length);
buffer_data = buffer + data.header_length +
data.block_descriptor_length;
buffer_data[2] &= ~0x05;
buffer_data[2] |= wce << 2 | rcd;
sp = buffer_data[0] & 0x80 ? 1 : 0;
buffer_data[0] &= ~0x80;
/*
* Ensure WP, DPOFUA, and RESERVED fields are cleared in
* received mode parameter buffer before doing MODE SELECT.
*/
data.device_specific = 0;
ret = scsi_mode_select(sdp, 1, sp, buffer_data, len, SD_TIMEOUT,
sdkp->max_retries, &data, &sshdr);
if (ret) {
if (ret > 0 && scsi_sense_valid(&sshdr))
sd_print_sense_hdr(sdkp, &sshdr);
return -EINVAL;
}
sd_revalidate_disk(sdkp->disk);
return count;
}
static ssize_t
manage_start_stop_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
struct scsi_device *sdp = sdkp->device;
return sysfs_emit(buf,
"%u\n",
sdp->manage_system_start_stop &&
sdp->manage_runtime_start_stop &&
sdp->manage_shutdown);
}
static DEVICE_ATTR_RO(manage_start_stop);
static ssize_t
manage_system_start_stop_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
struct scsi_device *sdp = sdkp->device;
return sysfs_emit(buf,
"%u\n", sdp->manage_system_start_stop);
}
static ssize_t
manage_system_start_stop_store(
struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
struct scsi_device *sdp = sdkp->device;
bool v;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (kstrtobool(buf, &v))
return -EINVAL;
sdp->manage_system_start_stop = v;
return count;
}
static DEVICE_ATTR_RW(manage_system_start_stop);
static ssize_t
manage_runtime_start_stop_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
struct scsi_device *sdp = sdkp->device;
return sysfs_emit(buf,
"%u\n", sdp->manage_runtime_start_stop);
}
static ssize_t
manage_runtime_start_stop_store(
struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
struct scsi_device *sdp = sdkp->device;
bool v;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (kstrtobool(buf, &v))
return -EINVAL;
sdp->manage_runtime_start_stop = v;
return count;
}
static DEVICE_ATTR_RW(manage_runtime_start_stop);
static ssize_t manage_shutdown_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
struct scsi_device *sdp = sdkp->device;
return sysfs_emit(buf,
"%u\n", sdp->manage_shutdown);
}
static ssize_t manage_shutdown_store(
struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
struct scsi_device *sdp = sdkp->device;
bool v;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (kstrtobool(buf, &v))
return -EINVAL;
sdp->manage_shutdown = v;
return count;
}
static DEVICE_ATTR_RW(manage_shutdown);
static ssize_t
allow_restart_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
return sprintf(buf,
"%u\n", sdkp->device->allow_restart);
}
static ssize_t
allow_restart_store(
struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
bool v;
struct scsi_disk *sdkp = to_scsi_disk(dev);
struct scsi_device *sdp = sdkp->device;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
return -EINVAL;
if (kstrtobool(buf, &v))
return -EINVAL;
sdp->allow_restart = v;
return count;
}
static DEVICE_ATTR_RW(allow_restart);
static ssize_t
cache_type_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
int ct = sdkp->RCD + 2*sdkp->WCE;
return sprintf(buf,
"%s\n", sd_cache_types[ct]);
}
static DEVICE_ATTR_RW(cache_type);
static ssize_t
FUA_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
return sprintf(buf,
"%u\n", sdkp->DPOFUA);
}
static DEVICE_ATTR_RO(FUA);
static ssize_t
protection_type_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
return sprintf(buf,
"%u\n", sdkp->protection_type);
}
static ssize_t
protection_type_store(
struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
unsigned int val;
int err;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
err = kstrtouint(buf, 10, &val);
if (err)
return err;
if (val <= T10_PI_TYPE3_PROTECTION)
sdkp->protection_type = val;
return count;
}
static DEVICE_ATTR_RW(protection_type);
static ssize_t
protection_mode_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
struct scsi_device *sdp = sdkp->device;
unsigned int dif, dix;
dif = scsi_host_dif_capable(sdp->host, sdkp->protection_type);
dix = scsi_host_dix_capable(sdp->host, sdkp->protection_type);
if (!dix && scsi_host_dix_capable(sdp->host, T10_PI_TYPE0_PROTECTION)) {
dif = 0;
dix = 1;
}
if (!dif && !dix)
return sprintf(buf,
"none\n");
return sprintf(buf,
"%s%u\n", dix ?
"dix" :
"dif", dif);
}
static DEVICE_ATTR_RO(protection_mode);
static ssize_t
app_tag_own_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
return sprintf(buf,
"%u\n", sdkp->ATO);
}
static DEVICE_ATTR_RO(app_tag_own);
static ssize_t
thin_provisioning_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
return sprintf(buf,
"%u\n", sdkp->lbpme);
}
static DEVICE_ATTR_RO(thin_provisioning);
/* sysfs_match_string() requires dense arrays */
static const char *lbp_mode[] = {
[SD_LBP_FULL] =
"full",
[SD_LBP_UNMAP] =
"unmap",
[SD_LBP_WS16] =
"writesame_16",
[SD_LBP_WS10] =
"writesame_10",
[SD_LBP_ZERO] =
"writesame_zero",
[SD_LBP_DISABLE] =
"disabled",
};
static ssize_t
provisioning_mode_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
return sprintf(buf,
"%s\n", lbp_mode[sdkp->provisioning_mode]);
}
static ssize_t
provisioning_mode_store(
struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
struct scsi_device *sdp = sdkp->device;
struct queue_limits lim;
int mode, err;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (sdp->type != TYPE_DISK)
return -EINVAL;
mode = sysfs_match_string(lbp_mode, buf);
if (mode < 0)
return -EINVAL;
lim = queue_limits_start_update(sdkp->disk->queue);
sd_config_discard(sdkp, &lim, mode);
err = queue_limits_commit_update_frozen(sdkp->disk->queue, &lim);
if (err)
return err;
return count;
}
static DEVICE_ATTR_RW(provisioning_mode);
/* sysfs_match_string() requires dense arrays */
static const char *zeroing_mode[] = {
[SD_ZERO_WRITE] =
"write",
[SD_ZERO_WS] =
"writesame",
[SD_ZERO_WS16_UNMAP] =
"writesame_16_unmap",
[SD_ZERO_WS10_UNMAP] =
"writesame_10_unmap",
};
static ssize_t
zeroing_mode_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
return sprintf(buf,
"%s\n", zeroing_mode[sdkp->zeroing_mode]);
}
static ssize_t
zeroing_mode_store(
struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
int mode;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
mode = sysfs_match_string(zeroing_mode, buf);
if (mode < 0)
return -EINVAL;
sdkp->zeroing_mode = mode;
return count;
}
static DEVICE_ATTR_RW(zeroing_mode);
static ssize_t
max_medium_access_timeouts_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
return sprintf(buf,
"%u\n", sdkp->max_medium_access_timeouts);
}
static ssize_t
max_medium_access_timeouts_store(
struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t count)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
int err;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
err = kstrtouint(buf, 10, &sdkp->max_medium_access_timeouts);
return err ? err : count;
}
static DEVICE_ATTR_RW(max_medium_access_timeouts);
static ssize_t
max_write_same_blocks_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
return sprintf(buf,
"%u\n", sdkp->max_ws_blocks);
}
static ssize_t
max_write_same_blocks_store(
struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
struct scsi_device *sdp = sdkp->device;
struct queue_limits lim;
unsigned long max;
int err;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
return -EINVAL;
err = kstrtoul(buf, 10, &max);
if (err)
return err;
if (max == 0)
sdp->no_write_same = 1;
else if (max <= SD_MAX_WS16_BLOCKS) {
sdp->no_write_same = 0;
sdkp->max_ws_blocks = max;
}
lim = queue_limits_start_update(sdkp->disk->queue);
sd_config_write_same(sdkp, &lim);
err = queue_limits_commit_update_frozen(sdkp->disk->queue, &lim);
if (err)
return err;
return count;
}
static DEVICE_ATTR_RW(max_write_same_blocks);
static ssize_t
zoned_cap_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
if (sdkp->device->type == TYPE_ZBC)
return sprintf(buf,
"host-managed\n");
if (sdkp->zoned == 1)
return sprintf(buf,
"host-aware\n");
if (sdkp->zoned == 2)
return sprintf(buf,
"drive-managed\n");
return sprintf(buf,
"none\n");
}
static DEVICE_ATTR_RO(zoned_cap);
static ssize_t
max_retries_store(
struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
struct scsi_device *sdev = sdkp->device;
int retries, err;
err = kstrtoint(buf, 10, &retries);
if (err)
return err;
if (retries == SCSI_CMD_RETRIES_NO_LIMIT || retries <= SD_MAX_RETRIES) {
sdkp->max_retries = retries;
return count;
}
sdev_printk(KERN_ERR, sdev,
"max_retries must be between -1 and %d\n",
SD_MAX_RETRIES);
return -EINVAL;
}
static ssize_t
max_retries_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct scsi_disk *sdkp = to_scsi_disk(dev);
return sprintf(buf,
"%d\n", sdkp->max_retries);
}
static DEVICE_ATTR_RW(max_retries);
static struct attribute *sd_disk_attrs[] = {
&dev_attr_cache_type.attr,
&dev_attr_FUA.attr,
&dev_attr_allow_restart.attr,
&dev_attr_manage_start_stop.attr,
&dev_attr_manage_system_start_stop.attr,
&dev_attr_manage_runtime_start_stop.attr,
&dev_attr_manage_shutdown.attr,
&dev_attr_protection_type.attr,
&dev_attr_protection_mode.attr,
&dev_attr_app_tag_own.attr,
&dev_attr_thin_provisioning.attr,
&dev_attr_provisioning_mode.attr,
&dev_attr_zeroing_mode.attr,
&dev_attr_max_write_same_blocks.attr,
&dev_attr_max_medium_access_timeouts.attr,
&dev_attr_zoned_cap.attr,
&dev_attr_max_retries.attr,
NULL,
};
ATTRIBUTE_GROUPS(sd_disk);
static struct class sd_disk_class = {
.name =
"scsi_disk",
.dev_release = scsi_disk_release,
.dev_groups = sd_disk_groups,
};
/*
* Don't request a new module, as that could deadlock in multipath
* environment.
*/
static void sd_default_probe(dev_t devt)
{
}
/*
* Device no to disk mapping:
*
* major disc2 disc p1
* |............|.............|....|....| <- dev_t
* 31 20 19 8 7 4 3 0
*
* Inside a major, we have 16k disks, however mapped non-
* contiguously. The first 16 disks are for major0, the next
* ones with major1, ... Disk 256 is for major0 again, disk 272
* for major1, ...
* As we stay compatible with our numbering scheme, we can reuse
* the well-know SCSI majors 8, 65--71, 136--143.
*/
static int sd_major(
int major_idx)
{
switch (major_idx) {
case 0:
return SCSI_DISK0_MAJOR;
case 1 ... 7:
return SCSI_DISK1_MAJOR + major_idx - 1;
case 8 ... 15:
return SCSI_DISK8_MAJOR + major_idx - 8;
default:
BUG();
return 0;
/* shut up gcc */
}
}
#ifdef CONFIG_BLK_SED_OPAL
static int sd_sec_submit(
void *data, u16 spsp, u8 secp,
void *buffer,
size_t len,
bool send)
{
struct scsi_disk *sdkp = data;
struct scsi_device *sdev = sdkp->device;
u8 cdb[12] = { 0, };
const struct scsi_exec_args exec_args = {
.req_flags = BLK_MQ_REQ_PM,
};
int ret;
cdb[0] = send ? SECURITY_PROTOCOL_OUT : SECURITY_PROTOCOL_IN;
cdb[1] = secp;
put_unaligned_be16(spsp, &cdb[2]);
put_unaligned_be32(len, &cdb[6]);
ret = scsi_execute_cmd(sdev, cdb, send ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN,
buffer, len, SD_TIMEOUT, sdkp->max_retries,
&exec_args);
return ret <= 0 ? ret : -EIO;
}
#endif /* CONFIG_BLK_SED_OPAL */
/*
* Look up the DIX operation based on whether the command is read or
* write and whether dix and dif are enabled.
*/
static unsigned int sd_prot_op(
bool write,
bool dix,
bool dif)
{
/* Lookup table: bit 2 (write), bit 1 (dix), bit 0 (dif) */
static const unsigned int ops[] = {
/* wrt dix dif */
SCSI_PROT_NORMAL,
/* 0 0 0 */
SCSI_PROT_READ_STRIP,
/* 0 0 1 */
SCSI_PROT_READ_INSERT,
/* 0 1 0 */
SCSI_PROT_READ_PASS,
/* 0 1 1 */
SCSI_PROT_NORMAL,
/* 1 0 0 */
SCSI_PROT_WRITE_INSERT,
/* 1 0 1 */
SCSI_PROT_WRITE_STRIP,
/* 1 1 0 */
SCSI_PROT_WRITE_PASS,
/* 1 1 1 */
};
return ops[write << 2 | dix << 1 | dif];
}
/*
* Returns a mask of the protection flags that are valid for a given DIX
* operation.
*/
static unsigned int sd_prot_flag_mask(
unsigned int prot_op)
{
static const unsigned int flag_mask[] = {
[SCSI_PROT_NORMAL] = 0,
[SCSI_PROT_READ_STRIP] = SCSI_PROT_TRANSFER_PI |
SCSI_PROT_GUARD_CHECK |
SCSI_PROT_REF_CHECK |
SCSI_PROT_REF_INCREMENT,
[SCSI_PROT_READ_INSERT] = SCSI_PROT_REF_INCREMENT |
SCSI_PROT_IP_CHECKSUM,
[SCSI_PROT_READ_PASS] = SCSI_PROT_TRANSFER_PI |
SCSI_PROT_GUARD_CHECK |
SCSI_PROT_REF_CHECK |
SCSI_PROT_REF_INCREMENT |
SCSI_PROT_IP_CHECKSUM,
[SCSI_PROT_WRITE_INSERT] = SCSI_PROT_TRANSFER_PI |
SCSI_PROT_REF_INCREMENT,
[SCSI_PROT_WRITE_STRIP] = SCSI_PROT_GUARD_CHECK |
SCSI_PROT_REF_CHECK |
SCSI_PROT_REF_INCREMENT |
SCSI_PROT_IP_CHECKSUM,
[SCSI_PROT_WRITE_PASS] = SCSI_PROT_TRANSFER_PI |
SCSI_PROT_GUARD_CHECK |
SCSI_PROT_REF_CHECK |
SCSI_PROT_REF_INCREMENT |
SCSI_PROT_IP_CHECKSUM,
};
return flag_mask[prot_op];
}
static unsigned char sd_setup_protect_cmnd(
struct scsi_cmnd *scmd,
unsigned int dix,
unsigned int dif)
{
struct request *rq = scsi_cmd_to_rq(scmd);
struct bio *bio = rq->bio;
unsigned int prot_op = sd_prot_op(rq_data_dir(rq), dix, dif);
unsigned int protect = 0;
if (dix) {
/* DIX Type 0, 1, 2, 3 */
if (bio_integrity_flagged(bio, BIP_IP_CHECKSUM))
scmd->prot_flags |= SCSI_PROT_IP_CHECKSUM;
if (bio_integrity_flagged(bio, BIP_CHECK_GUARD))
scmd->prot_flags |= SCSI_PROT_GUARD_CHECK;
}
if (dif != T10_PI_TYPE3_PROTECTION) {
/* DIX/DIF Type 0, 1, 2 */
scmd->prot_flags |= SCSI_PROT_REF_INCREMENT;
if (bio_integrity_flagged(bio, BIP_CHECK_REFTAG))
scmd->prot_flags |= SCSI_PROT_REF_CHECK;
}
if (dif) {
/* DIX/DIF Type 1, 2, 3 */
scmd->prot_flags |= SCSI_PROT_TRANSFER_PI;
if (bio_integrity_flagged(bio, BIP_DISK_NOCHECK))
protect = 3 << 5;
/* Disable target PI checking */
else
protect = 1 << 5;
/* Enable target PI checking */
}
scsi_set_prot_op(scmd, prot_op);
scsi_set_prot_type(scmd, dif);
scmd->prot_flags &= sd_prot_flag_mask(prot_op);
return protect;
}
static void sd_disable_discard(
struct scsi_disk *sdkp)
{
sdkp->provisioning_mode = SD_LBP_DISABLE;
blk_queue_disable_discard(sdkp->disk->queue);
}
static void sd_config_discard(
struct scsi_disk *sdkp,
struct queue_limits *lim,
unsigned int mode)
{
unsigned int logical_block_size = sdkp->device->sector_size;
unsigned int max_blocks = 0;
lim->discard_alignment = sdkp->unmap_alignment * logical_block_size;
lim->discard_granularity = max(sdkp->physical_block_size,
sdkp->unmap_granularity * logical_block_size);
sdkp->provisioning_mode = mode;
switch (mode) {
case SD_LBP_FULL:
case SD_LBP_DISABLE:
break;
case SD_LBP_UNMAP:
max_blocks = min_not_zero(sdkp->max_unmap_blocks,
(u32)SD_MAX_WS16_BLOCKS);
break;
case SD_LBP_WS16:
if (sdkp->device->unmap_limit_for_ws)
max_blocks = sdkp->max_unmap_blocks;
else
max_blocks = sdkp->max_ws_blocks;
max_blocks = min_not_zero(max_blocks, (u32)SD_MAX_WS16_BLOCKS);
break;
case SD_LBP_WS10:
if (sdkp->device->unmap_limit_for_ws)
max_blocks = sdkp->max_unmap_blocks;
else
max_blocks = sdkp->max_ws_blocks;
max_blocks = min_not_zero(max_blocks, (u32)SD_MAX_WS10_BLOCKS);
break;
case SD_LBP_ZERO:
max_blocks = min_not_zero(sdkp->max_ws_blocks,
(u32)SD_MAX_WS10_BLOCKS);
break;
}
lim->max_hw_discard_sectors = max_blocks *
(logical_block_size >> SECTOR_SHIFT);
}
static void *sd_set_special_bvec(
struct request *rq,
unsigned int data_len)
{
struct page *page;
page = mempool_alloc(sd_page_pool, GFP_ATOMIC);
if (!page)
return NULL;
clear_highpage(page);
bvec_set_page(&rq->special_vec, page, data_len, 0);
rq->rq_flags |= RQF_SPECIAL_PAYLOAD;
return bvec_virt(&rq->special_vec);
}
static blk_status_t sd_setup_unmap_cmnd(
struct scsi_cmnd *cmd)
{
struct scsi_device *sdp = cmd->device;
struct request *rq = scsi_cmd_to_rq(cmd);
struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
unsigned int data_len = 24;
char *buf;
buf = sd_set_special_bvec(rq, data_len);
if (!buf)
return BLK_STS_RESOURCE;
cmd->cmd_len = 10;
cmd->cmnd[0] = UNMAP;
cmd->cmnd[8] = 24;
put_unaligned_be16(6 + 16, &buf[0]);
put_unaligned_be16(16, &buf[2]);
put_unaligned_be64(lba, &buf[8]);
put_unaligned_be32(nr_blocks, &buf[16]);
cmd->allowed = sdkp->max_retries;
cmd->transfersize = data_len;
rq->timeout = SD_TIMEOUT;
return scsi_alloc_sgtables(cmd);
}
static void sd_config_atomic(
struct scsi_disk *sdkp,
struct queue_limits *lim)
{
unsigned int logical_block_size = sdkp->device->sector_size,
physical_block_size_sectors, max_atomic, unit_min, unit_max;
if ((!sdkp->max_atomic && !sdkp->max_atomic_with_boundary) ||
sdkp->protection_type == T10_PI_TYPE2_PROTECTION)
return;
physical_block_size_sectors = sdkp->physical_block_size /
sdkp->device->sector_size;
unit_min = rounddown_pow_of_two(sdkp->atomic_granularity ?
sdkp->atomic_granularity :
physical_block_size_sectors);
/*
* Only use atomic boundary when we have the odd scenario of
* sdkp->max_atomic == 0, which the spec does permit.
*/
if (sdkp->max_atomic) {
max_atomic = sdkp->max_atomic;
unit_max = rounddown_pow_of_two(sdkp->max_atomic);
sdkp->use_atomic_write_boundary = 0;
}
else {
max_atomic = sdkp->max_atomic_with_boundary;
unit_max = rounddown_pow_of_two(sdkp->max_atomic_boundary);
sdkp->use_atomic_write_boundary = 1;
}
/*
* Ensure compliance with granularity and alignment. For now, keep it
* simple and just don't support atomic writes for values mismatched
* with max_{boundary}atomic, physical block size, and
* atomic_granularity itself.
*
* We're really being distrustful by checking unit_max also...
*/
if (sdkp->atomic_granularity > 1) {
if (unit_min > 1 && unit_min % sdkp->atomic_granularity)
return;
if (unit_max > 1 && unit_max % sdkp->atomic_granularity)
return;
}
if (sdkp->atomic_alignment > 1) {
if (unit_min > 1 && unit_min % sdkp->atomic_alignment)
return;
if (unit_max > 1 && unit_max % sdkp->atomic_alignment)
return;
}
lim->atomic_write_hw_max = max_atomic * logical_block_size;
lim->atomic_write_hw_boundary = 0;
lim->atomic_write_hw_unit_min = unit_min * logical_block_size;
lim->atomic_write_hw_unit_max = unit_max * logical_block_size;
lim->features |= BLK_FEAT_ATOMIC_WRITES;
}
static blk_status_t sd_setup_write_same16_cmnd(
struct scsi_cmnd *cmd,
bool unmap)
{
struct scsi_device *sdp = cmd->device;
struct request *rq = scsi_cmd_to_rq(cmd);
struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
u32 data_len = sdp->sector_size;
if (!sd_set_special_bvec(rq, data_len))
return BLK_STS_RESOURCE;
cmd->cmd_len = 16;
cmd->cmnd[0] = WRITE_SAME_16;
if (unmap)
cmd->cmnd[1] = 0x8;
/* UNMAP */
put_unaligned_be64(lba, &cmd->cmnd[2]);
put_unaligned_be32(nr_blocks, &cmd->cmnd[10]);
cmd->allowed = sdkp->max_retries;
cmd->transfersize = data_len;
rq->timeout = unmap ? SD_TIMEOUT : SD_WRITE_SAME_TIMEOUT;
return scsi_alloc_sgtables(cmd);
}
static blk_status_t sd_setup_write_same10_cmnd(
struct scsi_cmnd *cmd,
bool unmap)
{
struct scsi_device *sdp = cmd->device;
struct request *rq = scsi_cmd_to_rq(cmd);
struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
u32 data_len = sdp->sector_size;
if (!sd_set_special_bvec(rq, data_len))
return BLK_STS_RESOURCE;
cmd->cmd_len = 10;
cmd->cmnd[0] = WRITE_SAME;
if (unmap)
cmd->cmnd[1] = 0x8;
/* UNMAP */
put_unaligned_be32(lba, &cmd->cmnd[2]);
put_unaligned_be16(nr_blocks, &cmd->cmnd[7]);
cmd->allowed = sdkp->max_retries;
cmd->transfersize = data_len;
rq->timeout = unmap ? SD_TIMEOUT : SD_WRITE_SAME_TIMEOUT;
return scsi_alloc_sgtables(cmd);
}
static blk_status_t sd_setup_write_zeroes_cmnd(
struct scsi_cmnd *cmd)
{
struct request *rq = scsi_cmd_to_rq(cmd);
struct scsi_device *sdp = cmd->device;
struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
if (!(rq->cmd_flags & REQ_NOUNMAP)) {
switch (sdkp->zeroing_mode) {
case SD_ZERO_WS16_UNMAP:
return sd_setup_write_same16_cmnd(cmd,
true);
case SD_ZERO_WS10_UNMAP:
return sd_setup_write_same10_cmnd(cmd,
true);
}
}
if (sdp->no_write_same) {
rq->rq_flags |= RQF_QUIET;
return BLK_STS_TARGET;
}
if (sdkp->ws16 || lba > 0xffffffff || nr_blocks > 0xffff)
return sd_setup_write_same16_cmnd(cmd,
false);
return sd_setup_write_same10_cmnd(cmd,
false);
}
static void sd_disable_write_same(
struct scsi_disk *sdkp)
{
sdkp->device->no_write_same = 1;
sdkp->max_ws_blocks = 0;
blk_queue_disable_write_zeroes(sdkp->disk->queue);
}
static void sd_config_write_same(
struct scsi_disk *sdkp,
struct queue_limits *lim)
{
unsigned int logical_block_size = sdkp->device->sector_size;
if (sdkp->device->no_write_same) {
sdkp->max_ws_blocks = 0;
goto out;
}
/* Some devices can not handle block counts above 0xffff despite
* supporting WRITE SAME(16). Consequently we default to 64k
* blocks per I/O unless the device explicitly advertises a
* bigger limit.
*/
if (sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS)
sdkp->max_ws_blocks = min_not_zero(sdkp->max_ws_blocks,
(u32)SD_MAX_WS16_BLOCKS);
else if (sdkp->ws16 || sdkp->ws10 || sdkp->device->no_report_opcodes)
sdkp->max_ws_blocks = min_not_zero(sdkp->max_ws_blocks,
(u32)SD_MAX_WS10_BLOCKS);
else {
sdkp->device->no_write_same = 1;
sdkp->max_ws_blocks = 0;
}
if (sdkp->lbprz && sdkp->lbpws)
sdkp->zeroing_mode = SD_ZERO_WS16_UNMAP;
else if (sdkp->lbprz && sdkp->lbpws10)
sdkp->zeroing_mode = SD_ZERO_WS10_UNMAP;
else if (sdkp->max_ws_blocks)
sdkp->zeroing_mode = SD_ZERO_WS;
else
sdkp->zeroing_mode = SD_ZERO_WRITE;
if (sdkp->max_ws_blocks &&
sdkp->physical_block_size > logical_block_size) {
/*
* Reporting a maximum number of blocks that is not aligned
* on the device physical size would cause a large write same
* request to be split into physically unaligned chunks by
* __blkdev_issue_write_zeroes() even if the caller of this
* functions took care to align the large request. So make sure
* the maximum reported is aligned to the device physical block
* size. This is only an optional optimization for regular
* disks, but this is mandatory to avoid failure of large write
* same requests directed at sequential write required zones of
* host-managed ZBC disks.
*/
sdkp->max_ws_blocks =
round_down(sdkp->max_ws_blocks,
bytes_to_logical(sdkp->device,
sdkp->physical_block_size));
}
out:
lim->max_write_zeroes_sectors =
sdkp->max_ws_blocks * (logical_block_size >> SECTOR_SHIFT);
if (sdkp->zeroing_mode == SD_ZERO_WS16_UNMAP ||
sdkp->zeroing_mode == SD_ZERO_WS10_UNMAP)
lim->max_hw_wzeroes_unmap_sectors =
lim->max_write_zeroes_sectors;
}
static blk_status_t sd_setup_flush_cmnd(
struct scsi_cmnd *cmd)
{
struct request *rq = scsi_cmd_to_rq(cmd);
struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
/* flush requests don't perform I/O, zero the S/G table */
memset(&cmd->sdb, 0,
sizeof(cmd->sdb));
if (cmd->device->use_16_for_sync) {
cmd->cmnd[0] = SYNCHRONIZE_CACHE_16;
cmd->cmd_len = 16;
}
else {
cmd->cmnd[0] = SYNCHRONIZE_CACHE;
cmd->cmd_len = 10;
}
cmd->transfersize = 0;
cmd->allowed = sdkp->max_retries;
rq->timeout = rq->q->rq_timeout * SD_FLUSH_TIMEOUT_MULTIPLIER;
return BLK_STS_OK;
}
/**
* sd_group_number() - Compute the GROUP NUMBER field
* @cmd: SCSI command for which to compute the value of the six-bit GROUP NUMBER
* field.
*
* From SBC-5 r05 (https://www.t10.org/cgi-bin/ac.pl?t=f&f=sbc5r05.pdf):
* 0: no relative lifetime.
* 1: shortest relative lifetime.
* 2: second shortest relative lifetime.
* 3 - 0x3d: intermediate relative lifetimes.
* 0x3e: second longest relative lifetime.
* 0x3f: longest relative lifetime.
*/
static u8 sd_group_number(
struct scsi_cmnd *cmd)
{
const struct request *rq = scsi_cmd_to_rq(cmd);
struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
if (!sdkp->rscs)
return 0;
return min3((u32)rq->bio->bi_write_hint,
(u32)sdkp->permanent_stream_count, 0x3fu);
}
static blk_status_t sd_setup_rw32_cmnd(
struct scsi_cmnd *cmd,
bool write,
sector_t lba,
unsigned int nr_blocks,
unsigned char flags,
unsigned int dld)
{
cmd->cmd_len = SD_EXT_CDB_SIZE;
cmd->cmnd[0] = VARIABLE_LENGTH_CMD;
cmd->cmnd[6] = sd_group_number(cmd);
cmd->cmnd[7] = 0x18;
/* Additional CDB len */
cmd->cmnd[9] = write ? WRITE_32 : READ_32;
cmd->cmnd[10] = flags;
cmd->cmnd[11] = dld & 0x07;
put_unaligned_be64(lba, &cmd->cmnd[12]);
put_unaligned_be32(lba, &cmd->cmnd[20]);
/* Expected Indirect LBA */
put_unaligned_be32(nr_blocks, &cmd->cmnd[28]);
return BLK_STS_OK;
}
static blk_status_t sd_setup_rw16_cmnd(
struct scsi_cmnd *cmd,
bool write,
sector_t lba,
unsigned int nr_blocks,
unsigned char flags,
unsigned int dld)
{
cmd->cmd_len = 16;
cmd->cmnd[0] = write ? WRITE_16 : READ_16;
cmd->cmnd[1] = flags | ((dld >> 2) & 0x01);
cmd->cmnd[14] = ((dld & 0x03) << 6) | sd_group_number(cmd);
cmd->cmnd[15] = 0;
put_unaligned_be64(lba, &cmd->cmnd[2]);
put_unaligned_be32(nr_blocks, &cmd->cmnd[10]);
return BLK_STS_OK;
}
static blk_status_t sd_setup_rw10_cmnd(
struct scsi_cmnd *cmd,
bool write,
sector_t lba,
unsigned int nr_blocks,
unsigned char flags)
{
cmd->cmd_len = 10;
cmd->cmnd[0] = write ? WRITE_10 : READ_10;
cmd->cmnd[1] = flags;
cmd->cmnd[6] = sd_group_number(cmd);
cmd->cmnd[9] = 0;
put_unaligned_be32(lba, &cmd->cmnd[2]);
put_unaligned_be16(nr_blocks, &cmd->cmnd[7]);
return BLK_STS_OK;
}
static blk_status_t sd_setup_rw6_cmnd(
struct scsi_cmnd *cmd,
bool write,
sector_t lba,
unsigned int nr_blocks,
unsigned char flags)
{
/* Avoid that 0 blocks gets translated into 256 blocks. */
if (WARN_ON_ONCE(nr_blocks == 0))
return BLK_STS_IOERR;
if (unlikely(flags & 0x8)) {
/*
* This happens only if this drive failed 10byte rw
* command with ILLEGAL_REQUEST during operation and
* thus turned off use_10_for_rw.
*/
scmd_printk(KERN_ERR, cmd,
"FUA write on READ/WRITE(6) drive\n");
return BLK_STS_IOERR;
}
cmd->cmd_len = 6;
cmd->cmnd[0] = write ? WRITE_6 : READ_6;
cmd->cmnd[1] = (lba >> 16) & 0x1f;
cmd->cmnd[2] = (lba >> 8) & 0xff;
cmd->cmnd[3] = lba & 0xff;
cmd->cmnd[4] = nr_blocks;
cmd->cmnd[5] = 0;
return BLK_STS_OK;
}
/*
* Check if a command has a duration limit set. If it does, and the target
* device supports CDL and the feature is enabled, return the limit
* descriptor index to use. Return 0 (no limit) otherwise.
*/
static int sd_cdl_dld(
struct scsi_disk *sdkp,
struct scsi_cmnd *scmd)
{
struct scsi_device *sdp = sdkp->device;
int hint;
if (!sdp->cdl_supported || !sdp->cdl_enable)
return 0;
/*
* Use "no limit" if the request ioprio does not specify a duration
* limit hint.
*/
hint = IOPRIO_PRIO_HINT(req_get_ioprio(scsi_cmd_to_rq(scmd)));
if (hint < IOPRIO_HINT_DEV_DURATION_LIMIT_1 ||
hint > IOPRIO_HINT_DEV_DURATION_LIMIT_7)
return 0;
return (hint - IOPRIO_HINT_DEV_DURATION_LIMIT_1) + 1;
}
static blk_status_t sd_setup_atomic_cmnd(
struct scsi_cmnd *cmd,
sector_t lba,
unsigned int nr_blocks,
bool boundary,
unsigned char flags)
{
cmd->cmd_len = 16;
cmd->cmnd[0] = WRITE_ATOMIC_16;
cmd->cmnd[1] = flags;
put_unaligned_be64(lba, &cmd->cmnd[2]);
put_unaligned_be16(nr_blocks, &cmd->cmnd[12]);
if (boundary)
put_unaligned_be16(nr_blocks, &cmd->cmnd[10]);
else
put_unaligned_be16(0, &cmd->cmnd[10]);
put_unaligned_be16(nr_blocks, &cmd->cmnd[12]);
cmd->cmnd[14] = 0;
cmd->cmnd[15] = 0;
return BLK_STS_OK;
}
static blk_status_t sd_setup_read_write_cmnd(
struct scsi_cmnd *cmd)
{
struct request *rq = scsi_cmd_to_rq(cmd);
struct scsi_device *sdp = cmd->device;
struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
sector_t lba = sectors_to_logical(sdp, blk_rq_pos(rq));
sector_t threshold;
unsigned int nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
unsigned int mask = logical_to_sectors(sdp, 1) - 1;
bool write = rq_data_dir(rq) == WRITE;
unsigned char protect, fua;
unsigned int dld;
blk_status_t ret;
unsigned int dif;
bool dix;
ret = scsi_alloc_sgtables(cmd);
if (ret != BLK_STS_OK)
return ret;
ret = BLK_STS_IOERR;
if (!scsi_device_online(sdp) || sdp->changed) {
scmd_printk(KERN_ERR, cmd,
"device offline or changed\n");
goto fail;
}
if (blk_rq_pos(rq) + blk_rq_sectors(rq) > get_capacity(rq->q->disk)) {
scmd_printk(KERN_ERR, cmd,
"access beyond end of device\n");
goto fail;
}
if ((blk_rq_pos(rq) & mask) || (blk_rq_sectors(rq) & mask)) {
scmd_printk(KERN_ERR, cmd,
"request not aligned to the logical block size\n");
goto fail;
}
/*
* Some SD card readers can't handle accesses which touch the
* last one or two logical blocks. Split accesses as needed.
*/
threshold = sdkp->capacity - SD_LAST_BUGGY_SECTORS;
if (unlikely(sdp->last_sector_bug && lba + nr_blocks > threshold)) {
if (lba < threshold) {
/* Access up to the threshold but not beyond */
nr_blocks = threshold - lba;
}
else {
/* Access only a single logical block */
nr_blocks = 1;
}
}
fua = rq->cmd_flags & REQ_FUA ? 0x8 : 0;
dix = scsi_prot_sg_count(cmd);
dif = scsi_host_dif_capable(cmd->device->host, sdkp->protection_type);
dld = sd_cdl_dld(sdkp, cmd);
if (dif || dix)
protect = sd_setup_protect_cmnd(cmd, dix, dif);
else
protect = 0;
if (protect && sdkp->protection_type == T10_PI_TYPE2_PROTECTION) {
ret = sd_setup_rw32_cmnd(cmd, write, lba, nr_blocks,
protect | fua, dld);
}
else if (rq->cmd_flags & REQ_ATOMIC) {
ret = sd_setup_atomic_cmnd(cmd, lba, nr_blocks,
sdkp->use_atomic_write_boundary,
protect | fua);
}
else if (sdp->use_16_for_rw || (nr_blocks > 0xffff)) {
ret = sd_setup_rw16_cmnd(cmd, write, lba, nr_blocks,
protect | fua, dld);
}
else if ((nr_blocks > 0xff) || (lba > 0x1fffff) ||
sdp->use_10_for_rw || protect || rq->bio->bi_write_hint) {
ret = sd_setup_rw10_cmnd(cmd, write, lba, nr_blocks,
protect | fua);
}
else {
ret = sd_setup_rw6_cmnd(cmd, write, lba, nr_blocks,
protect | fua);
}
if (unlikely(ret != BLK_STS_OK))
goto fail;
/*
* We shouldn't disconnect in the middle of a sector, so with a dumb
* host adapter, it's safe to assume that we can at least transfer
* this many bytes between each connect / disconnect.
*/
cmd->transfersize = sdp->sector_size;
cmd->underflow = nr_blocks << 9;
cmd->allowed = sdkp->max_retries;
cmd->sdb.length = nr_blocks * sdp->sector_size;
SCSI_LOG_HLQUEUE(1,
scmd_printk(KERN_INFO, cmd,
"%s: block=%llu, count=%d\n", __func__,
(
unsigned long long)blk_rq_pos(rq),
blk_rq_sectors(rq)));
SCSI_LOG_HLQUEUE(2,
scmd_printk(KERN_INFO, cmd,
"%s %d/%u 512 byte blocks.\n",
write ?
"writing" :
"reading", nr_blocks,
blk_rq_sectors(rq)));
/*
* This indicates that the command is ready from our end to be queued.
*/
return BLK_STS_OK;
fail:
scsi_free_sgtables(cmd);
return ret;
}
static blk_status_t sd_init_command(
struct scsi_cmnd *cmd)
{
struct request *rq = scsi_cmd_to_rq(cmd);
switch (req_op(rq)) {
case REQ_OP_DISCARD:
switch (scsi_disk(rq->q->disk)->provisioning_mode) {
case SD_LBP_UNMAP:
return sd_setup_unmap_cmnd(cmd);
case SD_LBP_WS16:
return sd_setup_write_same16_cmnd(cmd,
true);
case SD_LBP_WS10:
return sd_setup_write_same10_cmnd(cmd,
true);
case SD_LBP_ZERO:
return sd_setup_write_same10_cmnd(cmd,
false);
default:
return BLK_STS_TARGET;
}
case REQ_OP_WRITE_ZEROES:
return sd_setup_write_zeroes_cmnd(cmd);
case REQ_OP_FLUSH:
return sd_setup_flush_cmnd(cmd);
case REQ_OP_READ:
case REQ_OP_WRITE:
return sd_setup_read_write_cmnd(cmd);
case REQ_OP_ZONE_RESET:
return sd_zbc_setup_zone_mgmt_cmnd(cmd, ZO_RESET_WRITE_POINTER,
false);
case REQ_OP_ZONE_RESET_ALL:
return sd_zbc_setup_zone_mgmt_cmnd(cmd, ZO_RESET_WRITE_POINTER,
true);
case REQ_OP_ZONE_OPEN:
return sd_zbc_setup_zone_mgmt_cmnd(cmd, ZO_OPEN_ZONE,
false);
case REQ_OP_ZONE_CLOSE:
return sd_zbc_setup_zone_mgmt_cmnd(cmd, ZO_CLOSE_ZONE,
false);
case REQ_OP_ZONE_FINISH:
return sd_zbc_setup_zone_mgmt_cmnd(cmd, ZO_FINISH_ZONE,
false);
default:
WARN_ON_ONCE(1);
return BLK_STS_NOTSUPP;
}
}
static void sd_uninit_command(
struct scsi_cmnd *SCpnt)
{
struct request *rq = scsi_cmd_to_rq(SCpnt);
if (rq->rq_flags & RQF_SPECIAL_PAYLOAD)
mempool_free(rq->special_vec.bv_page, sd_page_pool);
}
static bool sd_need_revalidate(
struct gendisk *disk,
struct scsi_disk *sdkp)
{
if (sdkp->device->removable || sdkp->write_prot) {
if (disk_check_media_change(disk))
return true;
}
/*
* Force a full rescan after ioctl(BLKRRPART). While the disk state has
* nothing to do with partitions, BLKRRPART is used to force a full
* revalidate after things like a format for historical reasons.
*/
return test_bit(GD_NEED_PART_SCAN, &disk->state);
}
/**
* sd_open - open a scsi disk device
* @disk: disk to open
* @mode: open mode
*
* Returns 0 if successful. Returns a negated errno value in case
* of error.
*
* Note: This can be called from a user context (e.g. fsck(1) )
* or from within the kernel (e.g. as a result of a mount(1) ).
* In the latter case @inode and @filp carry an abridged amount
* of information as noted above.
*
* Locking: called with disk->open_mutex held.
**/
static int sd_open(
struct gendisk *disk, blk_mode_t mode)
{
struct scsi_disk *sdkp = scsi_disk(disk);
struct scsi_device *sdev = sdkp->device;
int retval;
if (scsi_device_get(sdev))
return -ENXIO;
SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp,
"sd_open\n"));
/*
* If the device is in error recovery, wait until it is done.
* If the device is offline, then disallow any access to it.
*/
retval = -ENXIO;
if (!scsi_block_when_processing_errors(sdev))
goto error_out;
if (sd_need_revalidate(disk, sdkp))
sd_revalidate_disk(disk);
/*
* If the drive is empty, just let the open fail.
*/
retval = -ENOMEDIUM;
if (sdev->removable && !sdkp->media_present &&
!(mode & BLK_OPEN_NDELAY))
goto error_out;
/*
* If the device has the write protect tab set, have the open fail
* if the user expects to be able to write to the thing.
*/
retval = -EROFS;
if (sdkp->write_prot && (mode & BLK_OPEN_WRITE))
goto error_out;
/*
* It is possible that the disk changing stuff resulted in
* the device being taken offline. If this is the case,
* report this to the user, and don't pretend that the
* open actually succeeded.
*/
retval = -ENXIO;
if (!scsi_device_online(sdev))
goto error_out;
if ((atomic_inc_return(&sdkp->openers) == 1) && sdev->removable) {
if (scsi_block_when_processing_errors(sdev))
scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
}
return 0;
error_out:
scsi_device_put(sdev);
return retval;
}
/**
* sd_release - invoked when the (last) close(2) is called on this
* scsi disk.
* @disk: disk to release
*
* Returns 0.
*
* Note: may block (uninterruptible) if error recovery is underway
* on this disk.
*
* Locking: called with disk->open_mutex held.
**/
static void sd_release(
struct gendisk *disk)
{
struct scsi_disk *sdkp = scsi_disk(disk);
struct scsi_device *sdev = sdkp->device;
SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp,
"sd_release\n"));
if (atomic_dec_return(&sdkp->openers) == 0 && sdev->removable) {
if (scsi_block_when_processing_errors(sdev))
scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
}
scsi_device_put(sdev);
}
static int sd_getgeo(
struct block_device *bdev,
struct hd_geometry *geo)
{
struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
struct scsi_device *sdp = sdkp->device;
struct Scsi_Host *host = sdp->host;
sector_t capacity = logical_to_sectors(sdp, sdkp->capacity);
int diskinfo[4];
/* default to most commonly used values */
diskinfo[0] = 0x40;
/* 1 << 6 */
diskinfo[1] = 0x20;
/* 1 << 5 */
diskinfo[2] = capacity >> 11;
/* override with calculated, extended default, or driver values */
if (host->hostt->bios_param)
host->hostt->bios_param(sdp, bdev, capacity, diskinfo);
else
scsicam_bios_param(bdev, capacity, diskinfo);
geo->heads = diskinfo[0];
geo->sectors = diskinfo[1];
geo->cylinders = diskinfo[2];
return 0;
}
/**
* sd_ioctl - process an ioctl
* @bdev: target block device
* @mode: open mode
* @cmd: ioctl command number
* @arg: this is third argument given to ioctl(2) system call.
* Often contains a pointer.
*
* Returns 0 if successful (some ioctls return positive numbers on
* success as well). Returns a negated errno value in case of error.
*
* Note: most ioctls are forward onto the block subsystem or further
* down in the scsi subsystem.
**/
static int sd_ioctl(
struct block_device *bdev, blk_mode_t mode,
unsigned int cmd,
unsigned long arg)
{
struct gendisk *disk = bdev->bd_disk;
struct scsi_disk *sdkp = scsi_disk(disk);
struct scsi_device *sdp = sdkp->device;
void __user *p = (
void __user *)arg;
int error;
SCSI_LOG_IOCTL(1, sd_printk(KERN_INFO, sdkp,
"sd_ioctl: disk=%s, "
"cmd=0x%x\n", disk->disk_name, cmd));
if (bdev_is_partition(bdev) && !capable(CAP_SYS_RAWIO))
return -ENOIOCTLCMD;
/*
* If we are in the middle of error recovery, don't let anyone
* else try and use this device. Also, if error recovery fails, it
* may try and take the device offline, in which case all further
* access to the device is prohibited.
*/
error = scsi_ioctl_block_when_processing_errors(sdp, cmd,
(mode & BLK_OPEN_NDELAY));
if (error)
return error;
if (is_sed_ioctl(cmd))
return sed_ioctl(sdkp->opal_dev, cmd, p);
return scsi_ioctl(sdp, mode & BLK_OPEN_WRITE, cmd, p);
}
static void set_media_not_present(
struct scsi_disk *sdkp)
{
if (sdkp->media_present)
sdkp->device->changed = 1;
if (sdkp->device->removable) {
sdkp->media_present = 0;
sdkp->capacity = 0;
}
}
static int media_not_present(
struct scsi_disk *sdkp,
struct scsi_sense_hdr *sshdr)
{
if (!scsi_sense_valid(sshdr))
return 0;
/* not invoked for commands that could return deferred errors */
switch (sshdr->sense_key) {
case UNIT_ATTENTION:
case NOT_READY:
/* medium not present */
if (sshdr->asc == 0x3A) {
set_media_not_present(sdkp);
return 1;
}
}
return 0;
}
/**
* sd_check_events - check media events
* @disk: kernel device descriptor
* @clearing: disk events currently being cleared
*
* Returns mask of DISK_EVENT_*.
*
* Note: this function is invoked from the block subsystem.
**/
static unsigned int sd_check_events(
struct gendisk *disk,
unsigned int clearing)
{
struct scsi_disk *sdkp = disk->private_data;
struct scsi_device *sdp;
int retval;
bool disk_changed;
if (!sdkp)
return 0;
sdp = sdkp->device;
SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp,
"sd_check_events\n"));
/*
* If the device is offline, don't send any commands - just pretend as
* if the command failed. If the device ever comes back online, we
* can deal with it then. It is only because of unrecoverable errors
* that we would ever take a device offline in the first place.
*/
if (!scsi_device_online(sdp)) {
set_media_not_present(sdkp);
goto out;
}
/*
* Using TEST_UNIT_READY enables differentiation between drive with
* no cartridge loaded - NOT READY, drive with changed cartridge -
* UNIT ATTENTION, or with same cartridge - GOOD STATUS.
*
* Drives that auto spin down. eg iomega jaz 1G, will be started
* by sd_spinup_disk() from sd_revalidate_disk(), which happens whenever
* sd_revalidate() is called.
*/
if (scsi_block_when_processing_errors(sdp)) {
struct scsi_sense_hdr sshdr = { 0, };
retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, sdkp->max_retries,
&sshdr);
/* failed to execute TUR, assume media not present */
if (retval < 0 || host_byte(retval)) {
set_media_not_present(sdkp);
goto out;
}
if (media_not_present(sdkp, &sshdr))
goto out;
}
/*
* For removable scsi disk we have to recognise the presence
* of a disk in the drive.
*/
if (!sdkp->media_present)
sdp->changed = 1;
sdkp->media_present = 1;
out:
/*
* sdp->changed is set under the following conditions:
*
* Medium present state has changed in either direction.
* Device has indicated UNIT_ATTENTION.
*/
disk_changed = sdp->changed;
sdp->changed = 0;
return disk_changed ? DISK_EVENT_MEDIA_CHANGE : 0;
}
static int sd_sync_cache(
struct scsi_disk *sdkp)
{
int res;
struct scsi_device *sdp = sdkp->device;
const int timeout = sdp->request_queue->rq_timeout
* SD_FLUSH_TIMEOUT_MULTIPLIER;
/* Leave the rest of the command zero to indicate flush everything. */
const unsigned char cmd[16] = { sdp->use_16_for_sync ?
SYNCHRONIZE_CACHE_16 : SYNCHRONIZE_CACHE };
struct scsi_sense_hdr sshdr;
struct scsi_failure failure_defs[] = {
{
.allowed = 3,
.result = SCMD_FAILURE_RESULT_ANY,
},
{}
};
struct scsi_failures failures = {
.failure_definitions = failure_defs,
};
const struct scsi_exec_args exec_args = {
.req_flags = BLK_MQ_REQ_PM,
.sshdr = &sshdr,
.failures = &failures,
};
if (!scsi_device_online(sdp))
return -ENODEV;
res = scsi_execute_cmd(sdp, cmd, REQ_OP_DRV_IN, NULL, 0, timeout,
sdkp->max_retries, &exec_args);
if (res) {
sd_print_result(sdkp,
"Synchronize Cache(10) failed", res);
if (res < 0)
return res;
if (scsi_status_is_check_condition(res) &&
scsi_sense_valid(&sshdr)) {
sd_print_sense_hdr(sdkp, &sshdr);
/* we need to evaluate the error return */
if (sshdr.asc == 0x3a ||
/* medium not present */
sshdr.asc == 0x20 ||
/* invalid command */
(sshdr.asc == 0x74 && sshdr.ascq == 0x71))
/* drive is password locked */
/* this is no error here */
return 0;
/*
* If a format is in progress or if the drive does not
* support sync, there is not much we can do because
* this is called during shutdown or suspend so just
* return success so those operations can proceed.
*/
if ((sshdr.asc == 0x04 && sshdr.ascq == 0x04) ||
sshdr.sense_key == ILLEGAL_REQUEST)
return 0;
}
switch (host_byte(res)) {
/* ignore errors due to racing a disconnection */
case DID_BAD_TARGET:
case DID_NO_CONNECT:
return 0;
/* signal the upper layer it might try again */
case DID_BUS_BUSY:
case DID_IMM_RETRY:
case DID_REQUEUE:
case DID_SOFT_ERROR:
return -EBUSY;
default:
return -EIO;
}
}
return 0;
}
static void sd_rescan(
struct device *dev)
{
struct scsi_disk *sdkp = dev_get_drvdata(dev);
sd_revalidate_disk(sdkp->disk);
}
static int sd_get_unique_id(
struct gendisk *disk, u8 id[16],
enum blk_unique_id type)
{
struct scsi_device *sdev = scsi_disk(disk)->device;
const struct scsi_vpd *vpd;
const unsigned char *d;
int ret = -ENXIO, len;
rcu_read_lock();
vpd = rcu_dereference(sdev->vpd_pg83);
if (!vpd)
goto out_unlock;
ret = -EINVAL;
for (d = vpd->data + 4; d < vpd->data + vpd->len; d += d[3] + 4) {
/* we only care about designators with LU association */
if (((d[1] >> 4) & 0x3) != 0x00)
continue;
if ((d[1] & 0xf) != type)
continue;
/*
* Only exit early if a 16-byte descriptor was found. Otherwise
* keep looking as one with more entropy might still show up.
*/
len = d[3];
if (len != 8 && len != 12 && len != 16)
continue;
ret = len;
memcpy(id, d + 4, len);
if (len == 16)
break;
}
out_unlock:
rcu_read_unlock();
return ret;
}
static int sd_scsi_to_pr_err(
struct scsi_sense_hdr *sshdr,
int result)
{
switch (host_byte(result)) {
case DID_TRANSPORT_MARGINAL:
case DID_TRANSPORT_DISRUPTED:
case DID_BUS_BUSY:
return PR_STS_RETRY_PATH_FAILURE;
case DID_NO_CONNECT:
return PR_STS_PATH_FAILED;
case DID_TRANSPORT_FAILFAST:
return PR_STS_PATH_FAST_FAILED;
}
switch (status_byte(result)) {
case SAM_STAT_RESERVATION_CONFLICT:
return PR_STS_RESERVATION_CONFLICT;
case SAM_STAT_CHECK_CONDITION:
if (!scsi_sense_valid(sshdr))
return PR_STS_IOERR;
if (sshdr->sense_key == ILLEGAL_REQUEST &&
(sshdr->asc == 0x26 || sshdr->asc == 0x24))
return -EINVAL;
fallthrough;
default:
return PR_STS_IOERR;
}
}
static int sd_pr_in_command(
struct block_device *bdev, u8 sa,
unsigned char *data,
int data_len)
{
struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
struct scsi_device *sdev = sdkp->device;
struct scsi_sense_hdr sshdr;
u8 cmd[10] = { PERSISTENT_RESERVE_IN, sa };
struct scsi_failure failure_defs[] = {
{
.sense = UNIT_ATTENTION,
.asc = SCMD_FAILURE_ASC_ANY,
.ascq = SCMD_FAILURE_ASCQ_ANY,
.allowed = 5,
.result = SAM_STAT_CHECK_CONDITION,
},
{}
};
struct scsi_failures failures = {
.failure_definitions = failure_defs,
};
const struct scsi_exec_args exec_args = {
.sshdr = &sshdr,
.failures = &failures,
};
int result;
put_unaligned_be16(data_len, &cmd[7]);
result = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_IN, data, data_len,
SD_TIMEOUT, sdkp->max_retries, &exec_args);
if (scsi_status_is_check_condition(result) &&
scsi_sense_valid(&sshdr)) {
sdev_printk(KERN_INFO, sdev,
"PR command failed: %d\n", result);
scsi_print_sense_hdr(sdev, NULL, &sshdr);
}
if (result <= 0)
return result;
return sd_scsi_to_pr_err(&sshdr, result);
}
static int sd_pr_read_keys(
struct block_device *bdev,
struct pr_keys *keys_info)
{
int result, i, data_offset, num_copy_keys;
u32 num_keys = keys_info->num_keys;
int data_len = num_keys * 8 + 8;
u8 *data;
data = kzalloc(data_len, GFP_KERNEL);
if (!data)
return -ENOMEM;
result = sd_pr_in_command(bdev, READ_KEYS, data, data_len);
if (result)
goto free_data;
keys_info->generation = get_unaligned_be32(&data[0]);
keys_info->num_keys = get_unaligned_be32(&data[4]) / 8;
data_offset = 8;
num_copy_keys = min(num_keys, keys_info->num_keys);
for (i = 0; i < num_copy_keys; i++) {
keys_info->keys[i] = get_unaligned_be64(&data[data_offset]);
data_offset += 8;
}
free_data:
kfree(data);
return result;
}
static int sd_pr_read_reservation(
struct block_device *bdev,
struct pr_held_reservation *rsv)
{
struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
struct scsi_device *sdev = sdkp->device;
u8 data[24] = { };
int result, len;
result = sd_pr_in_command(bdev, READ_RESERVATION, data,
sizeof(data));
if (result)
return result;
len = get_unaligned_be32(&data[4]);
if (!len)
return 0;
/* Make sure we have at least the key and type */
if (len < 14) {
sdev_printk(KERN_INFO, sdev,
"READ RESERVATION failed due to short return buffer of %d bytes\n",
len);
return -EINVAL;
}
rsv->generation = get_unaligned_be32(&data[0]);
rsv->key = get_unaligned_be64(&data[8]);
rsv->type = scsi_pr_type_to_block(data[21] & 0x0f);
return 0;
}
static int sd_pr_out_command(
struct block_device *bdev, u8 sa, u64 key,
u64 sa_key,
enum scsi_pr_type type, u8 flags)
{
struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
struct scsi_device *sdev = sdkp->device;
struct scsi_sense_hdr sshdr;
struct scsi_failure failure_defs[] = {
{
.sense = UNIT_ATTENTION,
.asc = SCMD_FAILURE_ASC_ANY,
.ascq = SCMD_FAILURE_ASCQ_ANY,
.allowed = 5,
.result = SAM_STAT_CHECK_CONDITION,
},
{}
};
struct scsi_failures failures = {
.failure_definitions = failure_defs,
};
const struct scsi_exec_args exec_args = {
.sshdr = &sshdr,
.failures = &failures,
};
int result;
u8 cmd[16] = { 0, };
u8 data[24] = { 0, };
cmd[0] = PERSISTENT_RESERVE_OUT;
cmd[1] = sa;
cmd[2] = type;
put_unaligned_be32(
sizeof(data), &cmd[5]);
put_unaligned_be64(key, &data[0]);
put_unaligned_be64(sa_key, &data[8]);
data[20] = flags;
result = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_OUT, &data,
sizeof(data), SD_TIMEOUT, sdkp->max_retries,
&exec_args);
if (scsi_status_is_check_condition(result) &&
scsi_sense_valid(&sshdr)) {
sdev_printk(KERN_INFO, sdev,
"PR command failed: %d\n", result);
scsi_print_sense_hdr(sdev, NULL, &sshdr);
}
if (result <= 0)
return result;
return sd_scsi_to_pr_err(&sshdr, result);
}
static int sd_pr_register(
struct block_device *bdev, u64 old_key, u64 new_key,
u32 flags)
{
if (flags & ~PR_FL_IGNORE_KEY)
return -EOPNOTSUPP;
return sd_pr_out_command(bdev, (flags & PR_FL_IGNORE_KEY) ? 0x06 : 0x00,
old_key, new_key, 0,
(1 << 0)
/* APTPL */);
}
static int sd_pr_reserve(
struct block_device *bdev, u64 key,
enum pr_type type,
u32 flags)
{
if (flags)
return -EOPNOTSUPP;
return sd_pr_out_command(bdev, 0x01, key, 0,
block_pr_type_to_scsi(type), 0);
}
static int sd_pr_release(
struct block_device *bdev, u64 key,
enum pr_type type)
{
return sd_pr_out_command(bdev, 0x02, key, 0,
block_pr_type_to_scsi(type), 0);
}
static int sd_pr_preempt(
struct block_device *bdev, u64 old_key, u64 new_key,
enum pr_type type,
bool abort)
{
return sd_pr_out_command(bdev, abort ? 0x05 : 0x04, old_key, new_key,
block_pr_type_to_scsi(type), 0);
}
static int sd_pr_clear(
struct block_device *bdev, u64 key)
{
return sd_pr_out_command(bdev, 0x03, key, 0, 0, 0);
}
static const struct pr_ops sd_pr_ops = {
.pr_register = sd_pr_register,
.pr_reserve = sd_pr_reserve,
.pr_release = sd_pr_release,
.pr_preempt = sd_pr_preempt,
.pr_clear = sd_pr_clear,
.pr_read_keys = sd_pr_read_keys,
.pr_read_reservation = sd_pr_read_reservation,
};
static void scsi_disk_free_disk(
struct gendisk *disk)
{
struct scsi_disk *sdkp = scsi_disk(disk);
put_device(&sdkp->disk_dev);
}
static const struct block_device_operations sd_fops = {
.owner = THIS_MODULE,
.open = sd_open,
.release = sd_release,
.ioctl = sd_ioctl,
.getgeo = sd_getgeo,
.compat_ioctl = blkdev_compat_ptr_ioctl,
.check_events = sd_check_events,
.unlock_native_capacity = sd_unlock_native_capacity,
.report_zones = sd_zbc_report_zones,
.get_unique_id = sd_get_unique_id,
.free_disk = scsi_disk_free_disk,
.pr_ops = &sd_pr_ops,
};
/**
* sd_eh_reset - reset error handling callback
* @scmd: sd-issued command that has failed
*
* This function is called by the SCSI midlayer before starting
* SCSI EH. When counting medium access failures we have to be
* careful to register it only only once per device and SCSI EH run;
* there might be several timed out commands which will cause the
* 'max_medium_access_timeouts' counter to trigger after the first
* SCSI EH run already and set the device to offline.
* So this function resets the internal counter before starting SCSI EH.
**/
static void sd_eh_reset(
struct scsi_cmnd *scmd)
{
struct scsi_disk *sdkp = scsi_disk(scsi_cmd_to_rq(scmd)->q->disk);
/* New SCSI EH run, reset gate variable */
sdkp->ignore_medium_access_errors =
false;
}
/**
* sd_eh_action - error handling callback
* @scmd: sd-issued command that has failed
* @eh_disp: The recovery disposition suggested by the midlayer
*
* This function is called by the SCSI midlayer upon completion of an
* error test command (currently TEST UNIT READY). The result of sending
* the eh command is passed in eh_disp. We're looking for devices that
* fail medium access commands but are OK with non access commands like
* test unit ready (so wrongly see the device as having a successful
* recovery)
**/
static int sd_eh_action(
struct scsi_cmnd *scmd,
int eh_disp)
{
struct scsi_disk *sdkp = scsi_disk(scsi_cmd_to_rq(scmd)->q->disk);
struct scsi_device *sdev = scmd->device;
if (!scsi_device_online(sdev) ||
!scsi_medium_access_command(scmd) ||
host_byte(scmd->result) != DID_TIME_OUT ||
eh_disp != SUCCESS)
return eh_disp;
/*
* The device has timed out executing a medium access command.
* However, the TEST UNIT READY command sent during error
* handling completed successfully. Either the device is in the
* process of recovering or has it suffered an internal failure
* that prevents access to the storage medium.
*/
if (!sdkp->ignore_medium_access_errors) {
sdkp->medium_access_timed_out++;
sdkp->ignore_medium_access_errors =
true;
}
/*
* If the device keeps failing read/write commands but TEST UNIT
* READY always completes successfully we assume that medium
* access is no longer possible and take the device offline.
*/
if (sdkp->medium_access_timed_out >= sdkp->max_medium_access_timeouts) {
scmd_printk(KERN_ERR, scmd,
"Medium access timeout failure. Offlining disk!\n");
mutex_lock(&sdev->state_mutex);
scsi_device_set_state(sdev, SDEV_OFFLINE);
mutex_unlock(&sdev->state_mutex);
return SUCCESS;
}
return eh_disp;
}
static unsigned int sd_completed_bytes(
struct scsi_cmnd *scmd)
{
struct request *req = scsi_cmd_to_rq(scmd);
struct scsi_device *sdev = scmd->device;
unsigned int transferred, good_bytes;
u64 start_lba, end_lba, bad_lba;
/*
* Some commands have a payload smaller than the device logical
* block size (e.g. INQUIRY on a 4K disk).
*/
if (scsi_bufflen(scmd) <= sdev->sector_size)
return 0;
/* Check if we have a 'bad_lba' information */
if (!scsi_get_sense_info_fld(scmd->sense_buffer,
SCSI_SENSE_BUFFERSIZE,
&bad_lba))
return 0;
/*
* If the bad lba was reported incorrectly, we have no idea where
* the error is.
*/
start_lba = sectors_to_logical(sdev, blk_rq_pos(req));
end_lba = start_lba + bytes_to_logical(sdev, scsi_bufflen(scmd));
if (bad_lba < start_lba || bad_lba >= end_lba)
return 0;
/*
* resid is optional but mostly filled in. When it's unused,
* its value is zero, so we assume the whole buffer transferred
*/
transferred = scsi_bufflen(scmd) - scsi_get_resid(scmd);
/* This computation should always be done in terms of the
* resolution of the device's medium.
*/
good_bytes = logical_to_bytes(sdev, bad_lba - start_lba);
return min(good_bytes, transferred);
}
/**
* sd_done - bottom half handler: called when the lower level
* driver has completed (successfully or otherwise) a scsi command.
* @SCpnt: mid-level's per command structure.
*
* Note: potentially run from within an ISR. Must not block.
**/
static int sd_done(
struct scsi_cmnd *SCpnt)
{
int result = SCpnt->result;
unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt);
unsigned int sector_size = SCpnt->device->sector_size;
unsigned int resid;
struct scsi_sense_hdr sshdr;
struct request *req = scsi_cmd_to_rq(SCpnt);
struct scsi_disk *sdkp = scsi_disk(req->q->disk);
int sense_valid = 0;
int sense_deferred = 0;
switch (req_op(req)) {
case REQ_OP_DISCARD:
case REQ_OP_WRITE_ZEROES:
case REQ_OP_ZONE_RESET:
case REQ_OP_ZONE_RESET_ALL:
case REQ_OP_ZONE_OPEN:
case REQ_OP_ZONE_CLOSE:
case REQ_OP_ZONE_FINISH:
if (!result) {
good_bytes = blk_rq_bytes(req);
scsi_set_resid(SCpnt, 0);
}
else {
good_bytes = 0;
scsi_set_resid(SCpnt, blk_rq_bytes(req));
}
break;
default:
/*
* In case of bogus fw or device, we could end up having
* an unaligned partial completion. Check this here and force
* alignment.
*/
resid = scsi_get_resid(SCpnt);
if (resid & (sector_size - 1)) {
sd_printk(KERN_INFO, sdkp,
"Unaligned partial completion (resid=%u, sector_sz=%u)\n",
resid, sector_size);
scsi_print_command(SCpnt);
resid = min(scsi_bufflen(SCpnt),
round_up(resid, sector_size));
scsi_set_resid(SCpnt, resid);
}
}
if (result) {
sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr);
if (sense_valid)
sense_deferred = scsi_sense_is_deferred(&sshdr);
}
sdkp->medium_access_timed_out = 0;
if (!scsi_status_is_check_condition(result) &&
(!sense_valid || sense_deferred))
goto out;
switch (sshdr.sense_key) {
case HARDWARE_ERROR:
case MEDIUM_ERROR:
good_bytes = sd_completed_bytes(SCpnt);
break;
case RECOVERED_ERROR:
good_bytes = scsi_bufflen(SCpnt);
break;
case NO_SENSE:
/* This indicates a false check condition, so ignore it. An
* unknown amount of data was transferred so treat it as an
* error.
*/
SCpnt->result = 0;
memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
break;
case ABORTED_COMMAND:
if (sshdr.asc == 0x10)
/* DIF: Target detected corruption */
good_bytes = sd_completed_bytes(SCpnt);
break;
case ILLEGAL_REQUEST:
switch (sshdr.asc) {
case 0x10:
/* DIX: Host detected corruption */
good_bytes = sd_completed_bytes(SCpnt);
break;
case 0x20:
/* INVALID COMMAND OPCODE */
case 0x24:
/* INVALID FIELD IN CDB */
switch (SCpnt->cmnd[0]) {
case UNMAP:
sd_disable_discard(sdkp);
break;
case WRITE_SAME_16:
case WRITE_SAME:
if (SCpnt->cmnd[1] & 8) {
/* UNMAP */
sd_disable_discard(sdkp);
}
else {
sd_disable_write_same(sdkp);
req->rq_flags |= RQF_QUIET;
}
break;
}
}
break;
default:
break;
}
out:
if (sdkp->device->type == TYPE_ZBC)
good_bytes = sd_zbc_complete(SCpnt, good_bytes, &sshdr);
SCSI_LOG_HLCOMPLETE(1, scmd_printk(KERN_INFO, SCpnt,
"sd_done: completed %d of %d bytes\n",
--> --------------------
--> maximum size reached
--> --------------------