109c434b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * sd.c Copyright (C) 1992 Drew Eckhardt
41da177e4SLinus Torvalds * Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale
51da177e4SLinus Torvalds *
61da177e4SLinus Torvalds * Linux scsi disk driver
71da177e4SLinus Torvalds * Initial versions: Drew Eckhardt
81da177e4SLinus Torvalds * Subsequent revisions: Eric Youngdale
91da177e4SLinus Torvalds * Modification history:
101da177e4SLinus Torvalds * - Drew Eckhardt <drew@colorado.edu> original
111da177e4SLinus Torvalds * - Eric Youngdale <eric@andante.org> add scatter-gather, multiple
121da177e4SLinus Torvalds * outstanding request, and other enhancements.
131da177e4SLinus Torvalds * Support loadable low-level scsi drivers.
141da177e4SLinus Torvalds * - Jirka Hanika <geo@ff.cuni.cz> support more scsi disks using
151da177e4SLinus Torvalds * eight major numbers.
161da177e4SLinus Torvalds * - Richard Gooch <rgooch@atnf.csiro.au> support devfs.
171da177e4SLinus Torvalds * - Torben Mathiasen <tmm@image.dk> Resource allocation fixes in
181da177e4SLinus Torvalds * sd_init and cleanups.
191da177e4SLinus Torvalds * - Alex Davis <letmein@erols.com> Fix problem where partition info
201da177e4SLinus Torvalds * not being read in sd_open. Fix problem where removable media
211da177e4SLinus Torvalds * could be ejected after sd_open.
221da177e4SLinus Torvalds * - Douglas Gilbert <dgilbert@interlog.com> cleanup for lk 2.5.x
231da177e4SLinus Torvalds * - Badari Pulavarty <pbadari@us.ibm.com>, Matthew Wilcox
241da177e4SLinus Torvalds * <willy@debian.org>, Kurt Garloff <garloff@suse.de>:
251da177e4SLinus Torvalds * Support 32k/1M disks.
261da177e4SLinus Torvalds *
271da177e4SLinus Torvalds * Logging policy (needs CONFIG_SCSI_LOGGING defined):
281da177e4SLinus Torvalds * - setting up transfer: SCSI_LOG_HLQUEUE levels 1 and 2
291da177e4SLinus Torvalds * - end of transfer (bh + scsi_lib): SCSI_LOG_HLCOMPLETE level 1
301da177e4SLinus Torvalds * - entering sd_ioctl: SCSI_LOG_IOCTL level 1
311da177e4SLinus Torvalds * - entering other commands: SCSI_LOG_HLQUEUE level 3
321da177e4SLinus Torvalds * Note: when the logging level is set by the user, it must be greater
331da177e4SLinus Torvalds * than the level indicated above to trigger output.
341da177e4SLinus Torvalds */
351da177e4SLinus Torvalds
361da177e4SLinus Torvalds #include <linux/module.h>
371da177e4SLinus Torvalds #include <linux/fs.h>
381da177e4SLinus Torvalds #include <linux/kernel.h>
391da177e4SLinus Torvalds #include <linux/mm.h>
401da177e4SLinus Torvalds #include <linux/bio.h>
411da177e4SLinus Torvalds #include <linux/hdreg.h>
421da177e4SLinus Torvalds #include <linux/errno.h>
431da177e4SLinus Torvalds #include <linux/idr.h>
441da177e4SLinus Torvalds #include <linux/interrupt.h>
451da177e4SLinus Torvalds #include <linux/init.h>
461da177e4SLinus Torvalds #include <linux/blkdev.h>
471da177e4SLinus Torvalds #include <linux/blkpg.h>
48bca6b067SBart Van Assche #include <linux/blk-pm.h>
491da177e4SLinus Torvalds #include <linux/delay.h>
50b81e0c23SChristoph Hellwig #include <linux/major.h>
510b950672SArjan van de Ven #include <linux/mutex.h>
527404ad3bSJames Bottomley #include <linux/string_helpers.h>
535a0e3ad6STejun Heo #include <linux/slab.h>
54d80210f2SChristoph Hellwig #include <linux/sed-opal.h>
5554f57588SLin Ming #include <linux/pm_runtime.h>
56924d55b0SChristoph Hellwig #include <linux/pr.h>
578475c811SChristoph Hellwig #include <linux/t10-pi.h>
587c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
598f76d151SDave Hansen #include <asm/unaligned.h>
601da177e4SLinus Torvalds
611da177e4SLinus Torvalds #include <scsi/scsi.h>
621da177e4SLinus Torvalds #include <scsi/scsi_cmnd.h>
631da177e4SLinus Torvalds #include <scsi/scsi_dbg.h>
641da177e4SLinus Torvalds #include <scsi/scsi_device.h>
651da177e4SLinus Torvalds #include <scsi/scsi_driver.h>
661da177e4SLinus Torvalds #include <scsi/scsi_eh.h>
671da177e4SLinus Torvalds #include <scsi/scsi_host.h>
681da177e4SLinus Torvalds #include <scsi/scsi_ioctl.h>
691da177e4SLinus Torvalds #include <scsi/scsicam.h>
700730b163SMike Christie #include <scsi/scsi_common.h>
711da177e4SLinus Torvalds
72aa91696eSMartin K. Petersen #include "sd.h"
73a7a20d10SDan Williams #include "scsi_priv.h"
741da177e4SLinus Torvalds #include "scsi_logging.h"
751da177e4SLinus Torvalds
76f018fa55SRene Herman MODULE_AUTHOR("Eric Youngdale");
77f018fa55SRene Herman MODULE_DESCRIPTION("SCSI disk (sd) driver");
78f018fa55SRene Herman MODULE_LICENSE("GPL");
79f018fa55SRene Herman
80f018fa55SRene Herman MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK0_MAJOR);
81f018fa55SRene Herman MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK1_MAJOR);
82f018fa55SRene Herman MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK2_MAJOR);
83f018fa55SRene Herman MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK3_MAJOR);
84f018fa55SRene Herman MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK4_MAJOR);
85f018fa55SRene Herman MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK5_MAJOR);
86f018fa55SRene Herman MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK6_MAJOR);
87f018fa55SRene Herman MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK7_MAJOR);
88f018fa55SRene Herman MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK8_MAJOR);
89f018fa55SRene Herman MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK9_MAJOR);
90f018fa55SRene Herman MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK10_MAJOR);
91f018fa55SRene Herman MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK11_MAJOR);
92f018fa55SRene Herman MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK12_MAJOR);
93f018fa55SRene Herman MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK13_MAJOR);
94f018fa55SRene Herman MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK14_MAJOR);
95f018fa55SRene Herman MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK15_MAJOR);
96d7b8bcb0SMichael Tokarev MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK);
97d7b8bcb0SMichael Tokarev MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD);
98d7b8bcb0SMichael Tokarev MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC);
9989d94756SHannes Reinecke MODULE_ALIAS_SCSI_DEVICE(TYPE_ZBC);
100f018fa55SRene Herman
101f615b48cSTejun Heo #define SD_MINORS 16
102870d6656STejun Heo
103c98a0eb0SMartin K. Petersen static void sd_config_discard(struct scsi_disk *, unsigned int);
1045db44863SMartin K. Petersen static void sd_config_write_same(struct scsi_disk *);
1057b3d9545SLinus Torvalds static int sd_revalidate_disk(struct gendisk *);
10672ec24bdSTejun Heo static void sd_unlock_native_capacity(struct gendisk *disk);
1077b3d9545SLinus Torvalds static void sd_shutdown(struct device *);
1087b3d9545SLinus Torvalds static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer);
109ee959b00STony Jones static void scsi_disk_release(struct device *cdev);
1107b3d9545SLinus Torvalds
111f27bac27STejun Heo static DEFINE_IDA(sd_index_ida);
1121da177e4SLinus Torvalds
11361cce6f6SJens Axboe static mempool_t *sd_page_pool;
1149c2b9dbaSChristoph Hellwig static struct lock_class_key sd_bio_compl_lkclass;
1154e7392ecSMartin K. Petersen
1166bdaa1f1SJames Bottomley static const char *sd_cache_types[] = {
1176bdaa1f1SJames Bottomley "write through", "none", "write back",
1186bdaa1f1SJames Bottomley "write back, no read (daft)"
1196bdaa1f1SJames Bottomley };
1206bdaa1f1SJames Bottomley
sd_set_flush_flag(struct scsi_disk * sdkp)121cb2fb68dSVaughan Cao static void sd_set_flush_flag(struct scsi_disk *sdkp)
122cb2fb68dSVaughan Cao {
123eb310e23SJens Axboe bool wc = false, fua = false;
124cb2fb68dSVaughan Cao
125cb2fb68dSVaughan Cao if (sdkp->WCE) {
126eb310e23SJens Axboe wc = true;
127cb2fb68dSVaughan Cao if (sdkp->DPOFUA)
128eb310e23SJens Axboe fua = true;
129cb2fb68dSVaughan Cao }
130cb2fb68dSVaughan Cao
131eb310e23SJens Axboe blk_queue_write_cache(sdkp->disk->queue, wc, fua);
132cb2fb68dSVaughan Cao }
133cb2fb68dSVaughan Cao
134ee959b00STony Jones static ssize_t
cache_type_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)135e1ea2351SGreg Kroah-Hartman cache_type_store(struct device *dev, struct device_attribute *attr,
136ee959b00STony Jones const char *buf, size_t count)
1376bdaa1f1SJames Bottomley {
1384c11712aSMartin K. Petersen int ct, rcd, wce, sp;
139ee959b00STony Jones struct scsi_disk *sdkp = to_scsi_disk(dev);
1406bdaa1f1SJames Bottomley struct scsi_device *sdp = sdkp->device;
1416bdaa1f1SJames Bottomley char buffer[64];
1426bdaa1f1SJames Bottomley char *buffer_data;
1436bdaa1f1SJames Bottomley struct scsi_mode_data data;
1446bdaa1f1SJames Bottomley struct scsi_sense_hdr sshdr;
1452ee3e26cSBen Hutchings static const char temp[] = "temporary ";
1466bdaa1f1SJames Bottomley int len;
1476bdaa1f1SJames Bottomley
14889d94756SHannes Reinecke if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
1496bdaa1f1SJames Bottomley /* no cache control on RBC devices; theoretically they
1506bdaa1f1SJames Bottomley * can do it, but there's probably so many exceptions
1516bdaa1f1SJames Bottomley * it's not worth the risk */
1526bdaa1f1SJames Bottomley return -EINVAL;
1536bdaa1f1SJames Bottomley
15439c60a09SJames Bottomley if (strncmp(buf, temp, sizeof(temp) - 1) == 0) {
15539c60a09SJames Bottomley buf += sizeof(temp) - 1;
15639c60a09SJames Bottomley sdkp->cache_override = 1;
15739c60a09SJames Bottomley } else {
15839c60a09SJames Bottomley sdkp->cache_override = 0;
15939c60a09SJames Bottomley }
16039c60a09SJames Bottomley
1614c11712aSMartin K. Petersen ct = sysfs_match_string(sd_cache_types, buf);
1626bdaa1f1SJames Bottomley if (ct < 0)
1636bdaa1f1SJames Bottomley return -EINVAL;
1644c11712aSMartin K. Petersen
1656bdaa1f1SJames Bottomley rcd = ct & 0x01 ? 1 : 0;
1662eefd57bSSujit Reddy Thumma wce = (ct & 0x02) && !sdkp->write_prot ? 1 : 0;
16739c60a09SJames Bottomley
16839c60a09SJames Bottomley if (sdkp->cache_override) {
16939c60a09SJames Bottomley sdkp->WCE = wce;
17039c60a09SJames Bottomley sdkp->RCD = rcd;
171cb2fb68dSVaughan Cao sd_set_flush_flag(sdkp);
17239c60a09SJames Bottomley return count;
17339c60a09SJames Bottomley }
17439c60a09SJames Bottomley
175a6cdc35fSDamien Le Moal if (scsi_mode_sense(sdp, 0x08, 8, 0, buffer, sizeof(buffer), SD_TIMEOUT,
1760610959fSMike Christie sdkp->max_retries, &data, NULL))
1776bdaa1f1SJames Bottomley return -EINVAL;
178a9312fb8SAndrew Morton len = min_t(size_t, sizeof(buffer), data.length - data.header_length -
1796bdaa1f1SJames Bottomley data.block_descriptor_length);
1806bdaa1f1SJames Bottomley buffer_data = buffer + data.header_length +
1816bdaa1f1SJames Bottomley data.block_descriptor_length;
1826bdaa1f1SJames Bottomley buffer_data[2] &= ~0x05;
1836bdaa1f1SJames Bottomley buffer_data[2] |= wce << 2 | rcd;
1846bdaa1f1SJames Bottomley sp = buffer_data[0] & 0x80 ? 1 : 0;
1852c5d16d6SGabriel Krisman Bertazi buffer_data[0] &= ~0x80;
1866bdaa1f1SJames Bottomley
18744759979SIvan Mironov /*
18844759979SIvan Mironov * Ensure WP, DPOFUA, and RESERVED fields are cleared in
18944759979SIvan Mironov * received mode parameter buffer before doing MODE SELECT.
19044759979SIvan Mironov */
19144759979SIvan Mironov data.device_specific = 0;
19244759979SIvan Mironov
19381d3f500SDamien Le Moal if (scsi_mode_select(sdp, 1, sp, buffer_data, len, SD_TIMEOUT,
1940610959fSMike Christie sdkp->max_retries, &data, &sshdr)) {
1956bdaa1f1SJames Bottomley if (scsi_sense_valid(&sshdr))
196e73aec82SMartin K. Petersen sd_print_sense_hdr(sdkp, &sshdr);
1976bdaa1f1SJames Bottomley return -EINVAL;
1986bdaa1f1SJames Bottomley }
199033a1b98SChristoph Hellwig sd_revalidate_disk(sdkp->disk);
2006bdaa1f1SJames Bottomley return count;
2016bdaa1f1SJames Bottomley }
2026bdaa1f1SJames Bottomley
203ee959b00STony Jones static ssize_t
manage_start_stop_show(struct device * dev,struct device_attribute * attr,char * buf)2043cc2ffe5SDamien Le Moal manage_start_stop_show(struct device *dev,
2053cc2ffe5SDamien Le Moal struct device_attribute *attr, char *buf)
206e1ea2351SGreg Kroah-Hartman {
207e1ea2351SGreg Kroah-Hartman struct scsi_disk *sdkp = to_scsi_disk(dev);
208e1ea2351SGreg Kroah-Hartman struct scsi_device *sdp = sdkp->device;
209e1ea2351SGreg Kroah-Hartman
2103cc2ffe5SDamien Le Moal return sysfs_emit(buf, "%u\n",
2113cc2ffe5SDamien Le Moal sdp->manage_system_start_stop &&
21224eca2dcSDamien Le Moal sdp->manage_runtime_start_stop &&
21324eca2dcSDamien Le Moal sdp->manage_shutdown);
2143cc2ffe5SDamien Le Moal }
2153cc2ffe5SDamien Le Moal static DEVICE_ATTR_RO(manage_start_stop);
2163cc2ffe5SDamien Le Moal
2173cc2ffe5SDamien Le Moal static ssize_t
manage_system_start_stop_show(struct device * dev,struct device_attribute * attr,char * buf)2183cc2ffe5SDamien Le Moal manage_system_start_stop_show(struct device *dev,
2193cc2ffe5SDamien Le Moal struct device_attribute *attr, char *buf)
2203cc2ffe5SDamien Le Moal {
2213cc2ffe5SDamien Le Moal struct scsi_disk *sdkp = to_scsi_disk(dev);
2223cc2ffe5SDamien Le Moal struct scsi_device *sdp = sdkp->device;
2233cc2ffe5SDamien Le Moal
2243cc2ffe5SDamien Le Moal return sysfs_emit(buf, "%u\n", sdp->manage_system_start_stop);
225e1ea2351SGreg Kroah-Hartman }
226e1ea2351SGreg Kroah-Hartman
227e1ea2351SGreg Kroah-Hartman static ssize_t
manage_system_start_stop_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)2283cc2ffe5SDamien Le Moal manage_system_start_stop_store(struct device *dev,
2293cc2ffe5SDamien Le Moal struct device_attribute *attr,
230c3c94c5aSTejun Heo const char *buf, size_t count)
231c3c94c5aSTejun Heo {
232ee959b00STony Jones struct scsi_disk *sdkp = to_scsi_disk(dev);
233c3c94c5aSTejun Heo struct scsi_device *sdp = sdkp->device;
234623401eeSweiping zhang bool v;
235c3c94c5aSTejun Heo
236c3c94c5aSTejun Heo if (!capable(CAP_SYS_ADMIN))
237c3c94c5aSTejun Heo return -EACCES;
238c3c94c5aSTejun Heo
239623401eeSweiping zhang if (kstrtobool(buf, &v))
240623401eeSweiping zhang return -EINVAL;
241623401eeSweiping zhang
2423cc2ffe5SDamien Le Moal sdp->manage_system_start_stop = v;
243c3c94c5aSTejun Heo
244c3c94c5aSTejun Heo return count;
245c3c94c5aSTejun Heo }
2463cc2ffe5SDamien Le Moal static DEVICE_ATTR_RW(manage_system_start_stop);
2473cc2ffe5SDamien Le Moal
2483cc2ffe5SDamien Le Moal static ssize_t
manage_runtime_start_stop_show(struct device * dev,struct device_attribute * attr,char * buf)2493cc2ffe5SDamien Le Moal manage_runtime_start_stop_show(struct device *dev,
2503cc2ffe5SDamien Le Moal struct device_attribute *attr, char *buf)
2513cc2ffe5SDamien Le Moal {
2523cc2ffe5SDamien Le Moal struct scsi_disk *sdkp = to_scsi_disk(dev);
2533cc2ffe5SDamien Le Moal struct scsi_device *sdp = sdkp->device;
2543cc2ffe5SDamien Le Moal
2553cc2ffe5SDamien Le Moal return sysfs_emit(buf, "%u\n", sdp->manage_runtime_start_stop);
2563cc2ffe5SDamien Le Moal }
2573cc2ffe5SDamien Le Moal
2583cc2ffe5SDamien Le Moal static ssize_t
manage_runtime_start_stop_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)2593cc2ffe5SDamien Le Moal manage_runtime_start_stop_store(struct device *dev,
2603cc2ffe5SDamien Le Moal struct device_attribute *attr,
2613cc2ffe5SDamien Le Moal const char *buf, size_t count)
2623cc2ffe5SDamien Le Moal {
2633cc2ffe5SDamien Le Moal struct scsi_disk *sdkp = to_scsi_disk(dev);
2643cc2ffe5SDamien Le Moal struct scsi_device *sdp = sdkp->device;
2653cc2ffe5SDamien Le Moal bool v;
2663cc2ffe5SDamien Le Moal
2673cc2ffe5SDamien Le Moal if (!capable(CAP_SYS_ADMIN))
2683cc2ffe5SDamien Le Moal return -EACCES;
2693cc2ffe5SDamien Le Moal
2703cc2ffe5SDamien Le Moal if (kstrtobool(buf, &v))
2713cc2ffe5SDamien Le Moal return -EINVAL;
2723cc2ffe5SDamien Le Moal
2733cc2ffe5SDamien Le Moal sdp->manage_runtime_start_stop = v;
2743cc2ffe5SDamien Le Moal
2753cc2ffe5SDamien Le Moal return count;
2763cc2ffe5SDamien Le Moal }
2773cc2ffe5SDamien Le Moal static DEVICE_ATTR_RW(manage_runtime_start_stop);
278c3c94c5aSTejun Heo
manage_shutdown_show(struct device * dev,struct device_attribute * attr,char * buf)27924eca2dcSDamien Le Moal static ssize_t manage_shutdown_show(struct device *dev,
28024eca2dcSDamien Le Moal struct device_attribute *attr, char *buf)
28124eca2dcSDamien Le Moal {
28224eca2dcSDamien Le Moal struct scsi_disk *sdkp = to_scsi_disk(dev);
28324eca2dcSDamien Le Moal struct scsi_device *sdp = sdkp->device;
28424eca2dcSDamien Le Moal
28524eca2dcSDamien Le Moal return sysfs_emit(buf, "%u\n", sdp->manage_shutdown);
28624eca2dcSDamien Le Moal }
28724eca2dcSDamien Le Moal
manage_shutdown_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)28824eca2dcSDamien Le Moal static ssize_t manage_shutdown_store(struct device *dev,
28924eca2dcSDamien Le Moal struct device_attribute *attr,
29024eca2dcSDamien Le Moal const char *buf, size_t count)
29124eca2dcSDamien Le Moal {
29224eca2dcSDamien Le Moal struct scsi_disk *sdkp = to_scsi_disk(dev);
29324eca2dcSDamien Le Moal struct scsi_device *sdp = sdkp->device;
29424eca2dcSDamien Le Moal bool v;
29524eca2dcSDamien Le Moal
29624eca2dcSDamien Le Moal if (!capable(CAP_SYS_ADMIN))
29724eca2dcSDamien Le Moal return -EACCES;
29824eca2dcSDamien Le Moal
29924eca2dcSDamien Le Moal if (kstrtobool(buf, &v))
30024eca2dcSDamien Le Moal return -EINVAL;
30124eca2dcSDamien Le Moal
30224eca2dcSDamien Le Moal sdp->manage_shutdown = v;
30324eca2dcSDamien Le Moal
30424eca2dcSDamien Le Moal return count;
30524eca2dcSDamien Le Moal }
30624eca2dcSDamien Le Moal static DEVICE_ATTR_RW(manage_shutdown);
30724eca2dcSDamien Le Moal
308ee959b00STony Jones static ssize_t
allow_restart_show(struct device * dev,struct device_attribute * attr,char * buf)309e1ea2351SGreg Kroah-Hartman allow_restart_show(struct device *dev, struct device_attribute *attr, char *buf)
310e1ea2351SGreg Kroah-Hartman {
311e1ea2351SGreg Kroah-Hartman struct scsi_disk *sdkp = to_scsi_disk(dev);
312e1ea2351SGreg Kroah-Hartman
3134c11712aSMartin K. Petersen return sprintf(buf, "%u\n", sdkp->device->allow_restart);
314e1ea2351SGreg Kroah-Hartman }
315e1ea2351SGreg Kroah-Hartman
316e1ea2351SGreg Kroah-Hartman static ssize_t
allow_restart_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)317e1ea2351SGreg Kroah-Hartman allow_restart_store(struct device *dev, struct device_attribute *attr,
318ee959b00STony Jones const char *buf, size_t count)
319a144c5aeSBrian King {
320658e9a6dSweiping zhang bool v;
321ee959b00STony Jones struct scsi_disk *sdkp = to_scsi_disk(dev);
322a144c5aeSBrian King struct scsi_device *sdp = sdkp->device;
323a144c5aeSBrian King
324a144c5aeSBrian King if (!capable(CAP_SYS_ADMIN))
325a144c5aeSBrian King return -EACCES;
326a144c5aeSBrian King
32789d94756SHannes Reinecke if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
328a144c5aeSBrian King return -EINVAL;
329a144c5aeSBrian King
330658e9a6dSweiping zhang if (kstrtobool(buf, &v))
331658e9a6dSweiping zhang return -EINVAL;
332658e9a6dSweiping zhang
333658e9a6dSweiping zhang sdp->allow_restart = v;
334a144c5aeSBrian King
335a144c5aeSBrian King return count;
336a144c5aeSBrian King }
337e1ea2351SGreg Kroah-Hartman static DEVICE_ATTR_RW(allow_restart);
338a144c5aeSBrian King
339ee959b00STony Jones static ssize_t
cache_type_show(struct device * dev,struct device_attribute * attr,char * buf)340e1ea2351SGreg Kroah-Hartman cache_type_show(struct device *dev, struct device_attribute *attr, char *buf)
3416bdaa1f1SJames Bottomley {
342ee959b00STony Jones struct scsi_disk *sdkp = to_scsi_disk(dev);
3436bdaa1f1SJames Bottomley int ct = sdkp->RCD + 2*sdkp->WCE;
3446bdaa1f1SJames Bottomley
3454c11712aSMartin K. Petersen return sprintf(buf, "%s\n", sd_cache_types[ct]);
3466bdaa1f1SJames Bottomley }
347e1ea2351SGreg Kroah-Hartman static DEVICE_ATTR_RW(cache_type);
3486bdaa1f1SJames Bottomley
349ee959b00STony Jones static ssize_t
FUA_show(struct device * dev,struct device_attribute * attr,char * buf)350e1ea2351SGreg Kroah-Hartman FUA_show(struct device *dev, struct device_attribute *attr, char *buf)
3516bdaa1f1SJames Bottomley {
352ee959b00STony Jones struct scsi_disk *sdkp = to_scsi_disk(dev);
3536bdaa1f1SJames Bottomley
3544c11712aSMartin K. Petersen return sprintf(buf, "%u\n", sdkp->DPOFUA);
3556bdaa1f1SJames Bottomley }
356e1ea2351SGreg Kroah-Hartman static DEVICE_ATTR_RO(FUA);
3576bdaa1f1SJames Bottomley
358ee959b00STony Jones static ssize_t
protection_type_show(struct device * dev,struct device_attribute * attr,char * buf)359e1ea2351SGreg Kroah-Hartman protection_type_show(struct device *dev, struct device_attribute *attr,
360e0597d70SMartin K. Petersen char *buf)
361e0597d70SMartin K. Petersen {
362e0597d70SMartin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev);
363e0597d70SMartin K. Petersen
3644c11712aSMartin K. Petersen return sprintf(buf, "%u\n", sdkp->protection_type);
365e0597d70SMartin K. Petersen }
366e0597d70SMartin K. Petersen
367e0597d70SMartin K. Petersen static ssize_t
protection_type_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)368e1ea2351SGreg Kroah-Hartman protection_type_store(struct device *dev, struct device_attribute *attr,
3698172499aSMartin K. Petersen const char *buf, size_t count)
3708172499aSMartin K. Petersen {
3718172499aSMartin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev);
3728172499aSMartin K. Petersen unsigned int val;
3738172499aSMartin K. Petersen int err;
3748172499aSMartin K. Petersen
3758172499aSMartin K. Petersen if (!capable(CAP_SYS_ADMIN))
3768172499aSMartin K. Petersen return -EACCES;
3778172499aSMartin K. Petersen
3788172499aSMartin K. Petersen err = kstrtouint(buf, 10, &val);
3798172499aSMartin K. Petersen
3808172499aSMartin K. Petersen if (err)
3818172499aSMartin K. Petersen return err;
3828172499aSMartin K. Petersen
383830cc351SBart Van Assche if (val <= T10_PI_TYPE3_PROTECTION)
3848172499aSMartin K. Petersen sdkp->protection_type = val;
3858172499aSMartin K. Petersen
3868172499aSMartin K. Petersen return count;
3878172499aSMartin K. Petersen }
388e1ea2351SGreg Kroah-Hartman static DEVICE_ATTR_RW(protection_type);
3898172499aSMartin K. Petersen
3908172499aSMartin K. Petersen static ssize_t
protection_mode_show(struct device * dev,struct device_attribute * attr,char * buf)391e1ea2351SGreg Kroah-Hartman protection_mode_show(struct device *dev, struct device_attribute *attr,
392518fa8e3SMartin K. Petersen char *buf)
393518fa8e3SMartin K. Petersen {
394518fa8e3SMartin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev);
395518fa8e3SMartin K. Petersen struct scsi_device *sdp = sdkp->device;
396518fa8e3SMartin K. Petersen unsigned int dif, dix;
397518fa8e3SMartin K. Petersen
398518fa8e3SMartin K. Petersen dif = scsi_host_dif_capable(sdp->host, sdkp->protection_type);
399518fa8e3SMartin K. Petersen dix = scsi_host_dix_capable(sdp->host, sdkp->protection_type);
400518fa8e3SMartin K. Petersen
4018475c811SChristoph Hellwig if (!dix && scsi_host_dix_capable(sdp->host, T10_PI_TYPE0_PROTECTION)) {
402518fa8e3SMartin K. Petersen dif = 0;
403518fa8e3SMartin K. Petersen dix = 1;
404518fa8e3SMartin K. Petersen }
405518fa8e3SMartin K. Petersen
406518fa8e3SMartin K. Petersen if (!dif && !dix)
4074c11712aSMartin K. Petersen return sprintf(buf, "none\n");
408518fa8e3SMartin K. Petersen
4094c11712aSMartin K. Petersen return sprintf(buf, "%s%u\n", dix ? "dix" : "dif", dif);
410518fa8e3SMartin K. Petersen }
411e1ea2351SGreg Kroah-Hartman static DEVICE_ATTR_RO(protection_mode);
412518fa8e3SMartin K. Petersen
413518fa8e3SMartin K. Petersen static ssize_t
app_tag_own_show(struct device * dev,struct device_attribute * attr,char * buf)414e1ea2351SGreg Kroah-Hartman app_tag_own_show(struct device *dev, struct device_attribute *attr, char *buf)
415e0597d70SMartin K. Petersen {
416e0597d70SMartin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev);
417e0597d70SMartin K. Petersen
4184c11712aSMartin K. Petersen return sprintf(buf, "%u\n", sdkp->ATO);
419e0597d70SMartin K. Petersen }
420e1ea2351SGreg Kroah-Hartman static DEVICE_ATTR_RO(app_tag_own);
421e0597d70SMartin K. Petersen
422e339c1a7SMartin K. Petersen static ssize_t
thin_provisioning_show(struct device * dev,struct device_attribute * attr,char * buf)423e1ea2351SGreg Kroah-Hartman thin_provisioning_show(struct device *dev, struct device_attribute *attr,
424e339c1a7SMartin K. Petersen char *buf)
425e339c1a7SMartin K. Petersen {
426e339c1a7SMartin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev);
427e339c1a7SMartin K. Petersen
4284c11712aSMartin K. Petersen return sprintf(buf, "%u\n", sdkp->lbpme);
429c98a0eb0SMartin K. Petersen }
430e1ea2351SGreg Kroah-Hartman static DEVICE_ATTR_RO(thin_provisioning);
431c98a0eb0SMartin K. Petersen
4324c11712aSMartin K. Petersen /* sysfs_match_string() requires dense arrays */
433c98a0eb0SMartin K. Petersen static const char *lbp_mode[] = {
434c98a0eb0SMartin K. Petersen [SD_LBP_FULL] = "full",
435c98a0eb0SMartin K. Petersen [SD_LBP_UNMAP] = "unmap",
436c98a0eb0SMartin K. Petersen [SD_LBP_WS16] = "writesame_16",
437c98a0eb0SMartin K. Petersen [SD_LBP_WS10] = "writesame_10",
438c98a0eb0SMartin K. Petersen [SD_LBP_ZERO] = "writesame_zero",
439c98a0eb0SMartin K. Petersen [SD_LBP_DISABLE] = "disabled",
440c98a0eb0SMartin K. Petersen };
441c98a0eb0SMartin K. Petersen
442c98a0eb0SMartin K. Petersen static ssize_t
provisioning_mode_show(struct device * dev,struct device_attribute * attr,char * buf)443e1ea2351SGreg Kroah-Hartman provisioning_mode_show(struct device *dev, struct device_attribute *attr,
444c98a0eb0SMartin K. Petersen char *buf)
445c98a0eb0SMartin K. Petersen {
446c98a0eb0SMartin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev);
447c98a0eb0SMartin K. Petersen
4484c11712aSMartin K. Petersen return sprintf(buf, "%s\n", lbp_mode[sdkp->provisioning_mode]);
449c98a0eb0SMartin K. Petersen }
450c98a0eb0SMartin K. Petersen
451c98a0eb0SMartin K. Petersen static ssize_t
provisioning_mode_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)452e1ea2351SGreg Kroah-Hartman provisioning_mode_store(struct device *dev, struct device_attribute *attr,
453c98a0eb0SMartin K. Petersen const char *buf, size_t count)
454c98a0eb0SMartin K. Petersen {
455c98a0eb0SMartin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev);
456c98a0eb0SMartin K. Petersen struct scsi_device *sdp = sdkp->device;
4574c11712aSMartin K. Petersen int mode;
458c98a0eb0SMartin K. Petersen
459c98a0eb0SMartin K. Petersen if (!capable(CAP_SYS_ADMIN))
460c98a0eb0SMartin K. Petersen return -EACCES;
461c98a0eb0SMartin K. Petersen
46289d94756SHannes Reinecke if (sd_is_zoned(sdkp)) {
46389d94756SHannes Reinecke sd_config_discard(sdkp, SD_LBP_DISABLE);
46489d94756SHannes Reinecke return count;
46589d94756SHannes Reinecke }
46689d94756SHannes Reinecke
467c98a0eb0SMartin K. Petersen if (sdp->type != TYPE_DISK)
468c98a0eb0SMartin K. Petersen return -EINVAL;
469c98a0eb0SMartin K. Petersen
4704c11712aSMartin K. Petersen mode = sysfs_match_string(lbp_mode, buf);
4714c11712aSMartin K. Petersen if (mode < 0)
472c98a0eb0SMartin K. Petersen return -EINVAL;
473c98a0eb0SMartin K. Petersen
4744c11712aSMartin K. Petersen sd_config_discard(sdkp, mode);
4754c11712aSMartin K. Petersen
476c98a0eb0SMartin K. Petersen return count;
477e339c1a7SMartin K. Petersen }
478e1ea2351SGreg Kroah-Hartman static DEVICE_ATTR_RW(provisioning_mode);
479e339c1a7SMartin K. Petersen
4804c11712aSMartin K. Petersen /* sysfs_match_string() requires dense arrays */
481e6bd9312SMartin K. Petersen static const char *zeroing_mode[] = {
482e6bd9312SMartin K. Petersen [SD_ZERO_WRITE] = "write",
483e6bd9312SMartin K. Petersen [SD_ZERO_WS] = "writesame",
484e6bd9312SMartin K. Petersen [SD_ZERO_WS16_UNMAP] = "writesame_16_unmap",
485e6bd9312SMartin K. Petersen [SD_ZERO_WS10_UNMAP] = "writesame_10_unmap",
486e6bd9312SMartin K. Petersen };
487e6bd9312SMartin K. Petersen
488e6bd9312SMartin K. Petersen static ssize_t
zeroing_mode_show(struct device * dev,struct device_attribute * attr,char * buf)489e6bd9312SMartin K. Petersen zeroing_mode_show(struct device *dev, struct device_attribute *attr,
490e6bd9312SMartin K. Petersen char *buf)
491e6bd9312SMartin K. Petersen {
492e6bd9312SMartin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev);
493e6bd9312SMartin K. Petersen
4944c11712aSMartin K. Petersen return sprintf(buf, "%s\n", zeroing_mode[sdkp->zeroing_mode]);
495e6bd9312SMartin K. Petersen }
496e6bd9312SMartin K. Petersen
497e6bd9312SMartin K. Petersen static ssize_t
zeroing_mode_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)498e6bd9312SMartin K. Petersen zeroing_mode_store(struct device *dev, struct device_attribute *attr,
499e6bd9312SMartin K. Petersen const char *buf, size_t count)
500e6bd9312SMartin K. Petersen {
501e6bd9312SMartin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev);
5024c11712aSMartin K. Petersen int mode;
503e6bd9312SMartin K. Petersen
504e6bd9312SMartin K. Petersen if (!capable(CAP_SYS_ADMIN))
505e6bd9312SMartin K. Petersen return -EACCES;
506e6bd9312SMartin K. Petersen
5074c11712aSMartin K. Petersen mode = sysfs_match_string(zeroing_mode, buf);
5084c11712aSMartin K. Petersen if (mode < 0)
509e6bd9312SMartin K. Petersen return -EINVAL;
510e6bd9312SMartin K. Petersen
5114c11712aSMartin K. Petersen sdkp->zeroing_mode = mode;
5124c11712aSMartin K. Petersen
513e6bd9312SMartin K. Petersen return count;
514e6bd9312SMartin K. Petersen }
515e6bd9312SMartin K. Petersen static DEVICE_ATTR_RW(zeroing_mode);
516e6bd9312SMartin K. Petersen
51718a4d0a2SMartin K. Petersen static ssize_t
max_medium_access_timeouts_show(struct device * dev,struct device_attribute * attr,char * buf)518e1ea2351SGreg Kroah-Hartman max_medium_access_timeouts_show(struct device *dev,
51918a4d0a2SMartin K. Petersen struct device_attribute *attr, char *buf)
52018a4d0a2SMartin K. Petersen {
52118a4d0a2SMartin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev);
52218a4d0a2SMartin K. Petersen
5234c11712aSMartin K. Petersen return sprintf(buf, "%u\n", sdkp->max_medium_access_timeouts);
52418a4d0a2SMartin K. Petersen }
52518a4d0a2SMartin K. Petersen
52618a4d0a2SMartin K. Petersen static ssize_t
max_medium_access_timeouts_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)527e1ea2351SGreg Kroah-Hartman max_medium_access_timeouts_store(struct device *dev,
528e1ea2351SGreg Kroah-Hartman struct device_attribute *attr, const char *buf,
529e1ea2351SGreg Kroah-Hartman size_t count)
53018a4d0a2SMartin K. Petersen {
53118a4d0a2SMartin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev);
53218a4d0a2SMartin K. Petersen int err;
53318a4d0a2SMartin K. Petersen
53418a4d0a2SMartin K. Petersen if (!capable(CAP_SYS_ADMIN))
53518a4d0a2SMartin K. Petersen return -EACCES;
53618a4d0a2SMartin K. Petersen
53718a4d0a2SMartin K. Petersen err = kstrtouint(buf, 10, &sdkp->max_medium_access_timeouts);
53818a4d0a2SMartin K. Petersen
53918a4d0a2SMartin K. Petersen return err ? err : count;
54018a4d0a2SMartin K. Petersen }
541e1ea2351SGreg Kroah-Hartman static DEVICE_ATTR_RW(max_medium_access_timeouts);
54218a4d0a2SMartin K. Petersen
5435db44863SMartin K. Petersen static ssize_t
max_write_same_blocks_show(struct device * dev,struct device_attribute * attr,char * buf)544e1ea2351SGreg Kroah-Hartman max_write_same_blocks_show(struct device *dev, struct device_attribute *attr,
5455db44863SMartin K. Petersen char *buf)
5465db44863SMartin K. Petersen {
5475db44863SMartin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev);
5485db44863SMartin K. Petersen
5494c11712aSMartin K. Petersen return sprintf(buf, "%u\n", sdkp->max_ws_blocks);
5505db44863SMartin K. Petersen }
5515db44863SMartin K. Petersen
5525db44863SMartin K. Petersen static ssize_t
max_write_same_blocks_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)553e1ea2351SGreg Kroah-Hartman max_write_same_blocks_store(struct device *dev, struct device_attribute *attr,
5545db44863SMartin K. Petersen const char *buf, size_t count)
5555db44863SMartin K. Petersen {
5565db44863SMartin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev);
5575db44863SMartin K. Petersen struct scsi_device *sdp = sdkp->device;
5585db44863SMartin K. Petersen unsigned long max;
5595db44863SMartin K. Petersen int err;
5605db44863SMartin K. Petersen
5615db44863SMartin K. Petersen if (!capable(CAP_SYS_ADMIN))
5625db44863SMartin K. Petersen return -EACCES;
5635db44863SMartin K. Petersen
56489d94756SHannes Reinecke if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
5655db44863SMartin K. Petersen return -EINVAL;
5665db44863SMartin K. Petersen
5675db44863SMartin K. Petersen err = kstrtoul(buf, 10, &max);
5685db44863SMartin K. Petersen
5695db44863SMartin K. Petersen if (err)
5705db44863SMartin K. Petersen return err;
5715db44863SMartin K. Petersen
5725db44863SMartin K. Petersen if (max == 0)
5735db44863SMartin K. Petersen sdp->no_write_same = 1;
57466c28f97SMartin K. Petersen else if (max <= SD_MAX_WS16_BLOCKS) {
57566c28f97SMartin K. Petersen sdp->no_write_same = 0;
5765db44863SMartin K. Petersen sdkp->max_ws_blocks = max;
57766c28f97SMartin K. Petersen }
5785db44863SMartin K. Petersen
5795db44863SMartin K. Petersen sd_config_write_same(sdkp);
5805db44863SMartin K. Petersen
5815db44863SMartin K. Petersen return count;
5825db44863SMartin K. Petersen }
583e1ea2351SGreg Kroah-Hartman static DEVICE_ATTR_RW(max_write_same_blocks);
5845db44863SMartin K. Petersen
585c5f88522SDamien Le Moal static ssize_t
zoned_cap_show(struct device * dev,struct device_attribute * attr,char * buf)586c5f88522SDamien Le Moal zoned_cap_show(struct device *dev, struct device_attribute *attr, char *buf)
587c5f88522SDamien Le Moal {
588c5f88522SDamien Le Moal struct scsi_disk *sdkp = to_scsi_disk(dev);
589c5f88522SDamien Le Moal
590c5f88522SDamien Le Moal if (sdkp->device->type == TYPE_ZBC)
591c5f88522SDamien Le Moal return sprintf(buf, "host-managed\n");
592c5f88522SDamien Le Moal if (sdkp->zoned == 1)
593c5f88522SDamien Le Moal return sprintf(buf, "host-aware\n");
594c5f88522SDamien Le Moal if (sdkp->zoned == 2)
595c5f88522SDamien Le Moal return sprintf(buf, "drive-managed\n");
596c5f88522SDamien Le Moal return sprintf(buf, "none\n");
597c5f88522SDamien Le Moal }
598c5f88522SDamien Le Moal static DEVICE_ATTR_RO(zoned_cap);
599c5f88522SDamien Le Moal
6000610959fSMike Christie static ssize_t
max_retries_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)6010610959fSMike Christie max_retries_store(struct device *dev, struct device_attribute *attr,
6020610959fSMike Christie const char *buf, size_t count)
6030610959fSMike Christie {
6040610959fSMike Christie struct scsi_disk *sdkp = to_scsi_disk(dev);
6050610959fSMike Christie struct scsi_device *sdev = sdkp->device;
6060610959fSMike Christie int retries, err;
6070610959fSMike Christie
6080610959fSMike Christie err = kstrtoint(buf, 10, &retries);
6090610959fSMike Christie if (err)
6100610959fSMike Christie return err;
6110610959fSMike Christie
6120610959fSMike Christie if (retries == SCSI_CMD_RETRIES_NO_LIMIT || retries <= SD_MAX_RETRIES) {
6130610959fSMike Christie sdkp->max_retries = retries;
6140610959fSMike Christie return count;
6150610959fSMike Christie }
6160610959fSMike Christie
6170610959fSMike Christie sdev_printk(KERN_ERR, sdev, "max_retries must be between -1 and %d\n",
6180610959fSMike Christie SD_MAX_RETRIES);
6190610959fSMike Christie return -EINVAL;
6200610959fSMike Christie }
6210610959fSMike Christie
6220610959fSMike Christie static ssize_t
max_retries_show(struct device * dev,struct device_attribute * attr,char * buf)6230610959fSMike Christie max_retries_show(struct device *dev, struct device_attribute *attr,
6240610959fSMike Christie char *buf)
6250610959fSMike Christie {
6260610959fSMike Christie struct scsi_disk *sdkp = to_scsi_disk(dev);
6270610959fSMike Christie
6280610959fSMike Christie return sprintf(buf, "%d\n", sdkp->max_retries);
6290610959fSMike Christie }
6300610959fSMike Christie
6310610959fSMike Christie static DEVICE_ATTR_RW(max_retries);
6320610959fSMike Christie
633e1ea2351SGreg Kroah-Hartman static struct attribute *sd_disk_attrs[] = {
634e1ea2351SGreg Kroah-Hartman &dev_attr_cache_type.attr,
635e1ea2351SGreg Kroah-Hartman &dev_attr_FUA.attr,
636e1ea2351SGreg Kroah-Hartman &dev_attr_allow_restart.attr,
637e1ea2351SGreg Kroah-Hartman &dev_attr_manage_start_stop.attr,
6383cc2ffe5SDamien Le Moal &dev_attr_manage_system_start_stop.attr,
6393cc2ffe5SDamien Le Moal &dev_attr_manage_runtime_start_stop.attr,
64024eca2dcSDamien Le Moal &dev_attr_manage_shutdown.attr,
641e1ea2351SGreg Kroah-Hartman &dev_attr_protection_type.attr,
642e1ea2351SGreg Kroah-Hartman &dev_attr_protection_mode.attr,
643e1ea2351SGreg Kroah-Hartman &dev_attr_app_tag_own.attr,
644e1ea2351SGreg Kroah-Hartman &dev_attr_thin_provisioning.attr,
645e1ea2351SGreg Kroah-Hartman &dev_attr_provisioning_mode.attr,
646e6bd9312SMartin K. Petersen &dev_attr_zeroing_mode.attr,
647e1ea2351SGreg Kroah-Hartman &dev_attr_max_write_same_blocks.attr,
648e1ea2351SGreg Kroah-Hartman &dev_attr_max_medium_access_timeouts.attr,
649c5f88522SDamien Le Moal &dev_attr_zoned_cap.attr,
6500610959fSMike Christie &dev_attr_max_retries.attr,
651e1ea2351SGreg Kroah-Hartman NULL,
6526bdaa1f1SJames Bottomley };
653e1ea2351SGreg Kroah-Hartman ATTRIBUTE_GROUPS(sd_disk);
6546bdaa1f1SJames Bottomley
6556bdaa1f1SJames Bottomley static struct class sd_disk_class = {
6566bdaa1f1SJames Bottomley .name = "scsi_disk",
657ee959b00STony Jones .dev_release = scsi_disk_release,
658e1ea2351SGreg Kroah-Hartman .dev_groups = sd_disk_groups,
6596bdaa1f1SJames Bottomley };
6601da177e4SLinus Torvalds
6611da177e4SLinus Torvalds /*
662996e509bSChristoph Hellwig * Don't request a new module, as that could deadlock in multipath
663996e509bSChristoph Hellwig * environment.
6640761df9cSHannes Reinecke */
sd_default_probe(dev_t devt)665996e509bSChristoph Hellwig static void sd_default_probe(dev_t devt)
6660761df9cSHannes Reinecke {
6670761df9cSHannes Reinecke }
6680761df9cSHannes Reinecke
6690761df9cSHannes Reinecke /*
6701da177e4SLinus Torvalds * Device no to disk mapping:
6711da177e4SLinus Torvalds *
6721da177e4SLinus Torvalds * major disc2 disc p1
6731da177e4SLinus Torvalds * |............|.............|....|....| <- dev_t
6741da177e4SLinus Torvalds * 31 20 19 8 7 4 3 0
6751da177e4SLinus Torvalds *
6761da177e4SLinus Torvalds * Inside a major, we have 16k disks, however mapped non-
6771da177e4SLinus Torvalds * contiguously. The first 16 disks are for major0, the next
6781da177e4SLinus Torvalds * ones with major1, ... Disk 256 is for major0 again, disk 272
6791da177e4SLinus Torvalds * for major1, ...
6801da177e4SLinus Torvalds * As we stay compatible with our numbering scheme, we can reuse
6811da177e4SLinus Torvalds * the well-know SCSI majors 8, 65--71, 136--143.
6821da177e4SLinus Torvalds */
sd_major(int major_idx)6831da177e4SLinus Torvalds static int sd_major(int major_idx)
6841da177e4SLinus Torvalds {
6851da177e4SLinus Torvalds switch (major_idx) {
6861da177e4SLinus Torvalds case 0:
6871da177e4SLinus Torvalds return SCSI_DISK0_MAJOR;
6881da177e4SLinus Torvalds case 1 ... 7:
6891da177e4SLinus Torvalds return SCSI_DISK1_MAJOR + major_idx - 1;
6901da177e4SLinus Torvalds case 8 ... 15:
6911da177e4SLinus Torvalds return SCSI_DISK8_MAJOR + major_idx - 8;
6921da177e4SLinus Torvalds default:
6931da177e4SLinus Torvalds BUG();
6941da177e4SLinus Torvalds return 0; /* shut up gcc */
6951da177e4SLinus Torvalds }
6961da177e4SLinus Torvalds }
6971da177e4SLinus Torvalds
698d80210f2SChristoph Hellwig #ifdef CONFIG_BLK_SED_OPAL
sd_sec_submit(void * data,u16 spsp,u8 secp,void * buffer,size_t len,bool send)699d80210f2SChristoph Hellwig static int sd_sec_submit(void *data, u16 spsp, u8 secp, void *buffer,
700d80210f2SChristoph Hellwig size_t len, bool send)
701d80210f2SChristoph Hellwig {
7020610959fSMike Christie struct scsi_disk *sdkp = data;
7030610959fSMike Christie struct scsi_device *sdev = sdkp->device;
704d80210f2SChristoph Hellwig u8 cdb[12] = { 0, };
705af16cd63SMike Christie const struct scsi_exec_args exec_args = {
706af16cd63SMike Christie .req_flags = BLK_MQ_REQ_PM,
707af16cd63SMike Christie };
708d80210f2SChristoph Hellwig int ret;
709d80210f2SChristoph Hellwig
710d80210f2SChristoph Hellwig cdb[0] = send ? SECURITY_PROTOCOL_OUT : SECURITY_PROTOCOL_IN;
711d80210f2SChristoph Hellwig cdb[1] = secp;
712d80210f2SChristoph Hellwig put_unaligned_be16(spsp, &cdb[2]);
713d80210f2SChristoph Hellwig put_unaligned_be32(len, &cdb[6]);
714d80210f2SChristoph Hellwig
715af16cd63SMike Christie ret = scsi_execute_cmd(sdev, cdb, send ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN,
716af16cd63SMike Christie buffer, len, SD_TIMEOUT, sdkp->max_retries,
717af16cd63SMike Christie &exec_args);
718d80210f2SChristoph Hellwig return ret <= 0 ? ret : -EIO;
719d80210f2SChristoph Hellwig }
720d80210f2SChristoph Hellwig #endif /* CONFIG_BLK_SED_OPAL */
721d80210f2SChristoph Hellwig
722082c2cd2SJohn Garry /*
723082c2cd2SJohn Garry * Look up the DIX operation based on whether the command is read or
724082c2cd2SJohn Garry * write and whether dix and dif are enabled.
725082c2cd2SJohn Garry */
sd_prot_op(bool write,bool dix,bool dif)726082c2cd2SJohn Garry static unsigned int sd_prot_op(bool write, bool dix, bool dif)
727082c2cd2SJohn Garry {
728082c2cd2SJohn Garry /* Lookup table: bit 2 (write), bit 1 (dix), bit 0 (dif) */
729082c2cd2SJohn Garry static const unsigned int ops[] = { /* wrt dix dif */
730082c2cd2SJohn Garry SCSI_PROT_NORMAL, /* 0 0 0 */
731082c2cd2SJohn Garry SCSI_PROT_READ_STRIP, /* 0 0 1 */
732082c2cd2SJohn Garry SCSI_PROT_READ_INSERT, /* 0 1 0 */
733082c2cd2SJohn Garry SCSI_PROT_READ_PASS, /* 0 1 1 */
734082c2cd2SJohn Garry SCSI_PROT_NORMAL, /* 1 0 0 */
735082c2cd2SJohn Garry SCSI_PROT_WRITE_INSERT, /* 1 0 1 */
736082c2cd2SJohn Garry SCSI_PROT_WRITE_STRIP, /* 1 1 0 */
737082c2cd2SJohn Garry SCSI_PROT_WRITE_PASS, /* 1 1 1 */
738082c2cd2SJohn Garry };
739082c2cd2SJohn Garry
740082c2cd2SJohn Garry return ops[write << 2 | dix << 1 | dif];
741082c2cd2SJohn Garry }
742082c2cd2SJohn Garry
743082c2cd2SJohn Garry /*
744082c2cd2SJohn Garry * Returns a mask of the protection flags that are valid for a given DIX
745082c2cd2SJohn Garry * operation.
746082c2cd2SJohn Garry */
sd_prot_flag_mask(unsigned int prot_op)747082c2cd2SJohn Garry static unsigned int sd_prot_flag_mask(unsigned int prot_op)
748082c2cd2SJohn Garry {
749082c2cd2SJohn Garry static const unsigned int flag_mask[] = {
750082c2cd2SJohn Garry [SCSI_PROT_NORMAL] = 0,
751082c2cd2SJohn Garry
752082c2cd2SJohn Garry [SCSI_PROT_READ_STRIP] = SCSI_PROT_TRANSFER_PI |
753082c2cd2SJohn Garry SCSI_PROT_GUARD_CHECK |
754082c2cd2SJohn Garry SCSI_PROT_REF_CHECK |
755082c2cd2SJohn Garry SCSI_PROT_REF_INCREMENT,
756082c2cd2SJohn Garry
757082c2cd2SJohn Garry [SCSI_PROT_READ_INSERT] = SCSI_PROT_REF_INCREMENT |
758082c2cd2SJohn Garry SCSI_PROT_IP_CHECKSUM,
759082c2cd2SJohn Garry
760082c2cd2SJohn Garry [SCSI_PROT_READ_PASS] = SCSI_PROT_TRANSFER_PI |
761082c2cd2SJohn Garry SCSI_PROT_GUARD_CHECK |
762082c2cd2SJohn Garry SCSI_PROT_REF_CHECK |
763082c2cd2SJohn Garry SCSI_PROT_REF_INCREMENT |
764082c2cd2SJohn Garry SCSI_PROT_IP_CHECKSUM,
765082c2cd2SJohn Garry
766082c2cd2SJohn Garry [SCSI_PROT_WRITE_INSERT] = SCSI_PROT_TRANSFER_PI |
767082c2cd2SJohn Garry SCSI_PROT_REF_INCREMENT,
768082c2cd2SJohn Garry
769082c2cd2SJohn Garry [SCSI_PROT_WRITE_STRIP] = SCSI_PROT_GUARD_CHECK |
770082c2cd2SJohn Garry SCSI_PROT_REF_CHECK |
771082c2cd2SJohn Garry SCSI_PROT_REF_INCREMENT |
772082c2cd2SJohn Garry SCSI_PROT_IP_CHECKSUM,
773082c2cd2SJohn Garry
774082c2cd2SJohn Garry [SCSI_PROT_WRITE_PASS] = SCSI_PROT_TRANSFER_PI |
775082c2cd2SJohn Garry SCSI_PROT_GUARD_CHECK |
776082c2cd2SJohn Garry SCSI_PROT_REF_CHECK |
777082c2cd2SJohn Garry SCSI_PROT_REF_INCREMENT |
778082c2cd2SJohn Garry SCSI_PROT_IP_CHECKSUM,
779082c2cd2SJohn Garry };
780082c2cd2SJohn Garry
781082c2cd2SJohn Garry return flag_mask[prot_op];
782082c2cd2SJohn Garry }
783082c2cd2SJohn Garry
sd_setup_protect_cmnd(struct scsi_cmnd * scmd,unsigned int dix,unsigned int dif)784c611529eSMartin K. Petersen static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd,
785c611529eSMartin K. Petersen unsigned int dix, unsigned int dif)
786c611529eSMartin K. Petersen {
7875999ccffSBart Van Assche struct request *rq = scsi_cmd_to_rq(scmd);
7885999ccffSBart Van Assche struct bio *bio = rq->bio;
7895999ccffSBart Van Assche unsigned int prot_op = sd_prot_op(rq_data_dir(rq), dix, dif);
790c611529eSMartin K. Petersen unsigned int protect = 0;
791c611529eSMartin K. Petersen
792c611529eSMartin K. Petersen if (dix) { /* DIX Type 0, 1, 2, 3 */
793c611529eSMartin K. Petersen if (bio_integrity_flagged(bio, BIP_IP_CHECKSUM))
794c611529eSMartin K. Petersen scmd->prot_flags |= SCSI_PROT_IP_CHECKSUM;
795c611529eSMartin K. Petersen
796c611529eSMartin K. Petersen if (bio_integrity_flagged(bio, BIP_CTRL_NOCHECK) == false)
797c611529eSMartin K. Petersen scmd->prot_flags |= SCSI_PROT_GUARD_CHECK;
798c611529eSMartin K. Petersen }
799c611529eSMartin K. Petersen
8008475c811SChristoph Hellwig if (dif != T10_PI_TYPE3_PROTECTION) { /* DIX/DIF Type 0, 1, 2 */
801c611529eSMartin K. Petersen scmd->prot_flags |= SCSI_PROT_REF_INCREMENT;
802c611529eSMartin K. Petersen
803c611529eSMartin K. Petersen if (bio_integrity_flagged(bio, BIP_CTRL_NOCHECK) == false)
804c611529eSMartin K. Petersen scmd->prot_flags |= SCSI_PROT_REF_CHECK;
805c611529eSMartin K. Petersen }
806c611529eSMartin K. Petersen
807c611529eSMartin K. Petersen if (dif) { /* DIX/DIF Type 1, 2, 3 */
808c611529eSMartin K. Petersen scmd->prot_flags |= SCSI_PROT_TRANSFER_PI;
809c611529eSMartin K. Petersen
810c611529eSMartin K. Petersen if (bio_integrity_flagged(bio, BIP_DISK_NOCHECK))
811c611529eSMartin K. Petersen protect = 3 << 5; /* Disable target PI checking */
812c611529eSMartin K. Petersen else
813c611529eSMartin K. Petersen protect = 1 << 5; /* Enable target PI checking */
81435e1a5d9SMartin K. Petersen }
81535e1a5d9SMartin K. Petersen
81635e1a5d9SMartin K. Petersen scsi_set_prot_op(scmd, prot_op);
81735e1a5d9SMartin K. Petersen scsi_set_prot_type(scmd, dif);
818c611529eSMartin K. Petersen scmd->prot_flags &= sd_prot_flag_mask(prot_op);
819c611529eSMartin K. Petersen
820c611529eSMartin K. Petersen return protect;
82135e1a5d9SMartin K. Petersen }
82235e1a5d9SMartin K. Petersen
sd_config_discard(struct scsi_disk * sdkp,unsigned int mode)823c98a0eb0SMartin K. Petersen static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
824c98a0eb0SMartin K. Petersen {
825c98a0eb0SMartin K. Petersen struct request_queue *q = sdkp->disk->queue;
826c98a0eb0SMartin K. Petersen unsigned int logical_block_size = sdkp->device->sector_size;
827c98a0eb0SMartin K. Petersen unsigned int max_blocks = 0;
828c98a0eb0SMartin K. Petersen
829bcd069bbSMartin K. Petersen q->limits.discard_alignment =
830bcd069bbSMartin K. Petersen sdkp->unmap_alignment * logical_block_size;
831c98a0eb0SMartin K. Petersen q->limits.discard_granularity =
832c98a0eb0SMartin K. Petersen max(sdkp->physical_block_size,
833c98a0eb0SMartin K. Petersen sdkp->unmap_granularity * logical_block_size);
83489730393SMartin K. Petersen sdkp->provisioning_mode = mode;
83589730393SMartin K. Petersen
836c98a0eb0SMartin K. Petersen switch (mode) {
837c98a0eb0SMartin K. Petersen
8384c11712aSMartin K. Petersen case SD_LBP_FULL:
839c98a0eb0SMartin K. Petersen case SD_LBP_DISABLE:
8402bb4cd5cSJens Axboe blk_queue_max_discard_sectors(q, 0);
841c98a0eb0SMartin K. Petersen return;
842c98a0eb0SMartin K. Petersen
843c98a0eb0SMartin K. Petersen case SD_LBP_UNMAP:
8445db44863SMartin K. Petersen max_blocks = min_not_zero(sdkp->max_unmap_blocks,
8455db44863SMartin K. Petersen (u32)SD_MAX_WS16_BLOCKS);
846c98a0eb0SMartin K. Petersen break;
847c98a0eb0SMartin K. Petersen
848c98a0eb0SMartin K. Petersen case SD_LBP_WS16:
84928a0bc41SMartin K. Petersen if (sdkp->device->unmap_limit_for_ws)
85028a0bc41SMartin K. Petersen max_blocks = sdkp->max_unmap_blocks;
85128a0bc41SMartin K. Petersen else
85228a0bc41SMartin K. Petersen max_blocks = sdkp->max_ws_blocks;
85328a0bc41SMartin K. Petersen
85428a0bc41SMartin K. Petersen max_blocks = min_not_zero(max_blocks, (u32)SD_MAX_WS16_BLOCKS);
855c98a0eb0SMartin K. Petersen break;
856c98a0eb0SMartin K. Petersen
857c98a0eb0SMartin K. Petersen case SD_LBP_WS10:
85828a0bc41SMartin K. Petersen if (sdkp->device->unmap_limit_for_ws)
85928a0bc41SMartin K. Petersen max_blocks = sdkp->max_unmap_blocks;
86028a0bc41SMartin K. Petersen else
86128a0bc41SMartin K. Petersen max_blocks = sdkp->max_ws_blocks;
86228a0bc41SMartin K. Petersen
86328a0bc41SMartin K. Petersen max_blocks = min_not_zero(max_blocks, (u32)SD_MAX_WS10_BLOCKS);
864c98a0eb0SMartin K. Petersen break;
865c98a0eb0SMartin K. Petersen
866c98a0eb0SMartin K. Petersen case SD_LBP_ZERO:
8675db44863SMartin K. Petersen max_blocks = min_not_zero(sdkp->max_ws_blocks,
8685db44863SMartin K. Petersen (u32)SD_MAX_WS10_BLOCKS);
869c98a0eb0SMartin K. Petersen break;
870c98a0eb0SMartin K. Petersen }
871c98a0eb0SMartin K. Petersen
8722bb4cd5cSJens Axboe blk_queue_max_discard_sectors(q, max_blocks * (logical_block_size >> 9));
873c98a0eb0SMartin K. Petersen }
874c98a0eb0SMartin K. Petersen
sd_set_special_bvec(struct request * rq,unsigned int data_len)875f1e117cbSChristoph Hellwig static void *sd_set_special_bvec(struct request *rq, unsigned int data_len)
876f1e117cbSChristoph Hellwig {
877f1e117cbSChristoph Hellwig struct page *page;
878f1e117cbSChristoph Hellwig
879f1e117cbSChristoph Hellwig page = mempool_alloc(sd_page_pool, GFP_ATOMIC);
880f1e117cbSChristoph Hellwig if (!page)
881f1e117cbSChristoph Hellwig return NULL;
882f1e117cbSChristoph Hellwig clear_highpage(page);
883f1e117cbSChristoph Hellwig bvec_set_page(&rq->special_vec, page, data_len, 0);
884f1e117cbSChristoph Hellwig rq->rq_flags |= RQF_SPECIAL_PAYLOAD;
885f1e117cbSChristoph Hellwig return bvec_virt(&rq->special_vec);
886f1e117cbSChristoph Hellwig }
887f1e117cbSChristoph Hellwig
sd_setup_unmap_cmnd(struct scsi_cmnd * cmd)888159b2cbfSChristoph Hellwig static blk_status_t sd_setup_unmap_cmnd(struct scsi_cmnd *cmd)
889e339c1a7SMartin K. Petersen {
8906a7b4398SChristoph Hellwig struct scsi_device *sdp = cmd->device;
8915999ccffSBart Van Assche struct request *rq = scsi_cmd_to_rq(cmd);
892f3fa33acSChristoph Hellwig struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
893c6c93fddSMartin K. Petersen u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
894c6c93fddSMartin K. Petersen u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
89581d926e8SChristoph Hellwig unsigned int data_len = 24;
896c98a0eb0SMartin K. Petersen char *buf;
897e339c1a7SMartin K. Petersen
898f1e117cbSChristoph Hellwig buf = sd_set_special_bvec(rq, data_len);
899f1e117cbSChristoph Hellwig if (!buf)
900159b2cbfSChristoph Hellwig return BLK_STS_RESOURCE;
90166ac0280SChristoph Hellwig
9026a7b4398SChristoph Hellwig cmd->cmd_len = 10;
9036a7b4398SChristoph Hellwig cmd->cmnd[0] = UNMAP;
9046a7b4398SChristoph Hellwig cmd->cmnd[8] = 24;
905e339c1a7SMartin K. Petersen
906e339c1a7SMartin K. Petersen put_unaligned_be16(6 + 16, &buf[0]);
907e339c1a7SMartin K. Petersen put_unaligned_be16(16, &buf[2]);
908c6c93fddSMartin K. Petersen put_unaligned_be64(lba, &buf[8]);
909c6c93fddSMartin K. Petersen put_unaligned_be32(nr_blocks, &buf[16]);
910e339c1a7SMartin K. Petersen
9110610959fSMike Christie cmd->allowed = sdkp->max_retries;
91281d926e8SChristoph Hellwig cmd->transfersize = data_len;
91381d926e8SChristoph Hellwig rq->timeout = SD_TIMEOUT;
914c98a0eb0SMartin K. Petersen
9157007e9ddSChristoph Hellwig return scsi_alloc_sgtables(cmd);
91681d926e8SChristoph Hellwig }
91781d926e8SChristoph Hellwig
sd_setup_write_same16_cmnd(struct scsi_cmnd * cmd,bool unmap)918159b2cbfSChristoph Hellwig static blk_status_t sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd,
919159b2cbfSChristoph Hellwig bool unmap)
92081d926e8SChristoph Hellwig {
92181d926e8SChristoph Hellwig struct scsi_device *sdp = cmd->device;
9225999ccffSBart Van Assche struct request *rq = scsi_cmd_to_rq(cmd);
923f3fa33acSChristoph Hellwig struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
924c6c93fddSMartin K. Petersen u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
925c6c93fddSMartin K. Petersen u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
92681d926e8SChristoph Hellwig u32 data_len = sdp->sector_size;
92781d926e8SChristoph Hellwig
928f1e117cbSChristoph Hellwig if (!sd_set_special_bvec(rq, data_len))
929159b2cbfSChristoph Hellwig return BLK_STS_RESOURCE;
93081d926e8SChristoph Hellwig
9316a7b4398SChristoph Hellwig cmd->cmd_len = 16;
9326a7b4398SChristoph Hellwig cmd->cmnd[0] = WRITE_SAME_16;
93302d26103SChristoph Hellwig if (unmap)
9346a7b4398SChristoph Hellwig cmd->cmnd[1] = 0x8; /* UNMAP */
935c6c93fddSMartin K. Petersen put_unaligned_be64(lba, &cmd->cmnd[2]);
936c6c93fddSMartin K. Petersen put_unaligned_be32(nr_blocks, &cmd->cmnd[10]);
93766ac0280SChristoph Hellwig
9380610959fSMike Christie cmd->allowed = sdkp->max_retries;
93981d926e8SChristoph Hellwig cmd->transfersize = data_len;
94002d26103SChristoph Hellwig rq->timeout = unmap ? SD_TIMEOUT : SD_WRITE_SAME_TIMEOUT;
941c98a0eb0SMartin K. Petersen
9427007e9ddSChristoph Hellwig return scsi_alloc_sgtables(cmd);
94381d926e8SChristoph Hellwig }
94481d926e8SChristoph Hellwig
sd_setup_write_same10_cmnd(struct scsi_cmnd * cmd,bool unmap)945159b2cbfSChristoph Hellwig static blk_status_t sd_setup_write_same10_cmnd(struct scsi_cmnd *cmd,
946159b2cbfSChristoph Hellwig bool unmap)
94781d926e8SChristoph Hellwig {
94881d926e8SChristoph Hellwig struct scsi_device *sdp = cmd->device;
9495999ccffSBart Van Assche struct request *rq = scsi_cmd_to_rq(cmd);
950f3fa33acSChristoph Hellwig struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
951c6c93fddSMartin K. Petersen u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
952c6c93fddSMartin K. Petersen u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
95381d926e8SChristoph Hellwig u32 data_len = sdp->sector_size;
95481d926e8SChristoph Hellwig
955f1e117cbSChristoph Hellwig if (!sd_set_special_bvec(rq, data_len))
956159b2cbfSChristoph Hellwig return BLK_STS_RESOURCE;
95781d926e8SChristoph Hellwig
9586a7b4398SChristoph Hellwig cmd->cmd_len = 10;
9596a7b4398SChristoph Hellwig cmd->cmnd[0] = WRITE_SAME;
96081d926e8SChristoph Hellwig if (unmap)
9616a7b4398SChristoph Hellwig cmd->cmnd[1] = 0x8; /* UNMAP */
962c6c93fddSMartin K. Petersen put_unaligned_be32(lba, &cmd->cmnd[2]);
963c6c93fddSMartin K. Petersen put_unaligned_be16(nr_blocks, &cmd->cmnd[7]);
964c98a0eb0SMartin K. Petersen
9650610959fSMike Christie cmd->allowed = sdkp->max_retries;
96681d926e8SChristoph Hellwig cmd->transfersize = data_len;
96702d26103SChristoph Hellwig rq->timeout = unmap ? SD_TIMEOUT : SD_WRITE_SAME_TIMEOUT;
968c98a0eb0SMartin K. Petersen
9697007e9ddSChristoph Hellwig return scsi_alloc_sgtables(cmd);
970e339c1a7SMartin K. Petersen }
971e339c1a7SMartin K. Petersen
sd_setup_write_zeroes_cmnd(struct scsi_cmnd * cmd)972159b2cbfSChristoph Hellwig static blk_status_t sd_setup_write_zeroes_cmnd(struct scsi_cmnd *cmd)
97302d26103SChristoph Hellwig {
9745999ccffSBart Van Assche struct request *rq = scsi_cmd_to_rq(cmd);
97502d26103SChristoph Hellwig struct scsi_device *sdp = cmd->device;
976f3fa33acSChristoph Hellwig struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
977c6c93fddSMartin K. Petersen u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
978c6c93fddSMartin K. Petersen u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
9796a7b4398SChristoph Hellwig
980e4b87837SChristoph Hellwig if (!(rq->cmd_flags & REQ_NOUNMAP)) {
981e6bd9312SMartin K. Petersen switch (sdkp->zeroing_mode) {
982e6bd9312SMartin K. Petersen case SD_ZERO_WS16_UNMAP:
98339051dd8SDamien Le Moal return sd_setup_write_same16_cmnd(cmd, true);
984e6bd9312SMartin K. Petersen case SD_ZERO_WS10_UNMAP:
98539051dd8SDamien Le Moal return sd_setup_write_same10_cmnd(cmd, true);
986e4b87837SChristoph Hellwig }
987e4b87837SChristoph Hellwig }
9886a7b4398SChristoph Hellwig
989e5cc9002SEwan D. Milne if (sdp->no_write_same) {
990e5cc9002SEwan D. Milne rq->rq_flags |= RQF_QUIET;
991159b2cbfSChristoph Hellwig return BLK_STS_TARGET;
992e5cc9002SEwan D. Milne }
993ed44fd7fSDamien Le Moal
994c6c93fddSMartin K. Petersen if (sdkp->ws16 || lba > 0xffffffff || nr_blocks > 0xffff)
99539051dd8SDamien Le Moal return sd_setup_write_same16_cmnd(cmd, false);
996ed44fd7fSDamien Le Moal
99739051dd8SDamien Le Moal return sd_setup_write_same10_cmnd(cmd, false);
998f1126e95SFUJITA Tomonori }
999f1126e95SFUJITA Tomonori
sd_config_write_same(struct scsi_disk * sdkp)10005db44863SMartin K. Petersen static void sd_config_write_same(struct scsi_disk *sdkp)
10015db44863SMartin K. Petersen {
10025db44863SMartin K. Petersen struct request_queue *q = sdkp->disk->queue;
10035db44863SMartin K. Petersen unsigned int logical_block_size = sdkp->device->sector_size;
10045db44863SMartin K. Petersen
10055db44863SMartin K. Petersen if (sdkp->device->no_write_same) {
10065db44863SMartin K. Petersen sdkp->max_ws_blocks = 0;
10075db44863SMartin K. Petersen goto out;
10085db44863SMartin K. Petersen }
10095db44863SMartin K. Petersen
10105db44863SMartin K. Petersen /* Some devices can not handle block counts above 0xffff despite
10115db44863SMartin K. Petersen * supporting WRITE SAME(16). Consequently we default to 64k
10125db44863SMartin K. Petersen * blocks per I/O unless the device explicitly advertises a
10135db44863SMartin K. Petersen * bigger limit.
10145db44863SMartin K. Petersen */
101566c28f97SMartin K. Petersen if (sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS)
101666c28f97SMartin K. Petersen sdkp->max_ws_blocks = min_not_zero(sdkp->max_ws_blocks,
10175db44863SMartin K. Petersen (u32)SD_MAX_WS16_BLOCKS);
101866c28f97SMartin K. Petersen else if (sdkp->ws16 || sdkp->ws10 || sdkp->device->no_report_opcodes)
101966c28f97SMartin K. Petersen sdkp->max_ws_blocks = min_not_zero(sdkp->max_ws_blocks,
10205db44863SMartin K. Petersen (u32)SD_MAX_WS10_BLOCKS);
102166c28f97SMartin K. Petersen else {
102266c28f97SMartin K. Petersen sdkp->device->no_write_same = 1;
102366c28f97SMartin K. Petersen sdkp->max_ws_blocks = 0;
102466c28f97SMartin K. Petersen }
10255db44863SMartin K. Petersen
1026e6bd9312SMartin K. Petersen if (sdkp->lbprz && sdkp->lbpws)
1027e6bd9312SMartin K. Petersen sdkp->zeroing_mode = SD_ZERO_WS16_UNMAP;
1028e6bd9312SMartin K. Petersen else if (sdkp->lbprz && sdkp->lbpws10)
1029e6bd9312SMartin K. Petersen sdkp->zeroing_mode = SD_ZERO_WS10_UNMAP;
1030e6bd9312SMartin K. Petersen else if (sdkp->max_ws_blocks)
1031e6bd9312SMartin K. Petersen sdkp->zeroing_mode = SD_ZERO_WS;
1032e6bd9312SMartin K. Petersen else
1033e6bd9312SMartin K. Petersen sdkp->zeroing_mode = SD_ZERO_WRITE;
1034e6bd9312SMartin K. Petersen
1035b7af62a9SDamien Le Moal if (sdkp->max_ws_blocks &&
1036b7af62a9SDamien Le Moal sdkp->physical_block_size > logical_block_size) {
1037b7af62a9SDamien Le Moal /*
1038b7af62a9SDamien Le Moal * Reporting a maximum number of blocks that is not aligned
1039b7af62a9SDamien Le Moal * on the device physical size would cause a large write same
1040b7af62a9SDamien Le Moal * request to be split into physically unaligned chunks by
1041e383e16eSChristoph Hellwig * __blkdev_issue_write_zeroes() even if the caller of this
1042e383e16eSChristoph Hellwig * functions took care to align the large request. So make sure
1043e383e16eSChristoph Hellwig * the maximum reported is aligned to the device physical block
1044e383e16eSChristoph Hellwig * size. This is only an optional optimization for regular
1045e383e16eSChristoph Hellwig * disks, but this is mandatory to avoid failure of large write
1046e383e16eSChristoph Hellwig * same requests directed at sequential write required zones of
1047e383e16eSChristoph Hellwig * host-managed ZBC disks.
1048b7af62a9SDamien Le Moal */
1049b7af62a9SDamien Le Moal sdkp->max_ws_blocks =
1050b7af62a9SDamien Le Moal round_down(sdkp->max_ws_blocks,
1051b7af62a9SDamien Le Moal bytes_to_logical(sdkp->device,
1052b7af62a9SDamien Le Moal sdkp->physical_block_size));
1053b7af62a9SDamien Le Moal }
1054b7af62a9SDamien Le Moal
10555db44863SMartin K. Petersen out:
105602d26103SChristoph Hellwig blk_queue_max_write_zeroes_sectors(q, sdkp->max_ws_blocks *
105702d26103SChristoph Hellwig (logical_block_size >> 9));
10585db44863SMartin K. Petersen }
10595db44863SMartin K. Petersen
sd_setup_flush_cmnd(struct scsi_cmnd * cmd)1060159b2cbfSChristoph Hellwig static blk_status_t sd_setup_flush_cmnd(struct scsi_cmnd *cmd)
106190467c29SFUJITA Tomonori {
10625999ccffSBart Van Assche struct request *rq = scsi_cmd_to_rq(cmd);
1063f3fa33acSChristoph Hellwig struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
106490467c29SFUJITA Tomonori
1065a118c6c1SChristoph Hellwig /* flush requests don't perform I/O, zero the S/G table */
1066a118c6c1SChristoph Hellwig memset(&cmd->sdb, 0, sizeof(cmd->sdb));
1067a118c6c1SChristoph Hellwig
106842c59077SShin'ichiro Kawasaki if (cmd->device->use_16_for_sync) {
106942c59077SShin'ichiro Kawasaki cmd->cmnd[0] = SYNCHRONIZE_CACHE_16;
107042c59077SShin'ichiro Kawasaki cmd->cmd_len = 16;
107142c59077SShin'ichiro Kawasaki } else {
1072a118c6c1SChristoph Hellwig cmd->cmnd[0] = SYNCHRONIZE_CACHE;
1073a118c6c1SChristoph Hellwig cmd->cmd_len = 10;
107442c59077SShin'ichiro Kawasaki }
1075a118c6c1SChristoph Hellwig cmd->transfersize = 0;
10760610959fSMike Christie cmd->allowed = sdkp->max_retries;
1077a118c6c1SChristoph Hellwig
107826b9fd8bSK. Y. Srinivasan rq->timeout = rq->q->rq_timeout * SD_FLUSH_TIMEOUT_MULTIPLIER;
1079159b2cbfSChristoph Hellwig return BLK_STS_OK;
108090467c29SFUJITA Tomonori }
108190467c29SFUJITA Tomonori
sd_setup_rw32_cmnd(struct scsi_cmnd * cmd,bool write,sector_t lba,unsigned int nr_blocks,unsigned char flags,unsigned int dld)108278a02f49SMartin K. Petersen static blk_status_t sd_setup_rw32_cmnd(struct scsi_cmnd *cmd, bool write,
108378a02f49SMartin K. Petersen sector_t lba, unsigned int nr_blocks,
1084e59e80cfSDamien Le Moal unsigned char flags, unsigned int dld)
10851da177e4SLinus Torvalds {
108678a02f49SMartin K. Petersen cmd->cmd_len = SD_EXT_CDB_SIZE;
108778a02f49SMartin K. Petersen cmd->cmnd[0] = VARIABLE_LENGTH_CMD;
108878a02f49SMartin K. Petersen cmd->cmnd[7] = 0x18; /* Additional CDB len */
108978a02f49SMartin K. Petersen cmd->cmnd[9] = write ? WRITE_32 : READ_32;
109078a02f49SMartin K. Petersen cmd->cmnd[10] = flags;
1091e59e80cfSDamien Le Moal cmd->cmnd[11] = dld & 0x07;
109278a02f49SMartin K. Petersen put_unaligned_be64(lba, &cmd->cmnd[12]);
109378a02f49SMartin K. Petersen put_unaligned_be32(lba, &cmd->cmnd[20]); /* Expected Indirect LBA */
109478a02f49SMartin K. Petersen put_unaligned_be32(nr_blocks, &cmd->cmnd[28]);
109578a02f49SMartin K. Petersen
109678a02f49SMartin K. Petersen return BLK_STS_OK;
109778a02f49SMartin K. Petersen }
109878a02f49SMartin K. Petersen
sd_setup_rw16_cmnd(struct scsi_cmnd * cmd,bool write,sector_t lba,unsigned int nr_blocks,unsigned char flags,unsigned int dld)109978a02f49SMartin K. Petersen static blk_status_t sd_setup_rw16_cmnd(struct scsi_cmnd *cmd, bool write,
110078a02f49SMartin K. Petersen sector_t lba, unsigned int nr_blocks,
1101e59e80cfSDamien Le Moal unsigned char flags, unsigned int dld)
110278a02f49SMartin K. Petersen {
110378a02f49SMartin K. Petersen cmd->cmd_len = 16;
110478a02f49SMartin K. Petersen cmd->cmnd[0] = write ? WRITE_16 : READ_16;
1105e59e80cfSDamien Le Moal cmd->cmnd[1] = flags | ((dld >> 2) & 0x01);
1106e59e80cfSDamien Le Moal cmd->cmnd[14] = (dld & 0x03) << 6;
110778a02f49SMartin K. Petersen cmd->cmnd[15] = 0;
110878a02f49SMartin K. Petersen put_unaligned_be64(lba, &cmd->cmnd[2]);
110978a02f49SMartin K. Petersen put_unaligned_be32(nr_blocks, &cmd->cmnd[10]);
111078a02f49SMartin K. Petersen
111178a02f49SMartin K. Petersen return BLK_STS_OK;
111278a02f49SMartin K. Petersen }
111378a02f49SMartin K. Petersen
sd_setup_rw10_cmnd(struct scsi_cmnd * cmd,bool write,sector_t lba,unsigned int nr_blocks,unsigned char flags)111478a02f49SMartin K. Petersen static blk_status_t sd_setup_rw10_cmnd(struct scsi_cmnd *cmd, bool write,
111578a02f49SMartin K. Petersen sector_t lba, unsigned int nr_blocks,
111678a02f49SMartin K. Petersen unsigned char flags)
111778a02f49SMartin K. Petersen {
111878a02f49SMartin K. Petersen cmd->cmd_len = 10;
111978a02f49SMartin K. Petersen cmd->cmnd[0] = write ? WRITE_10 : READ_10;
112078a02f49SMartin K. Petersen cmd->cmnd[1] = flags;
112178a02f49SMartin K. Petersen cmd->cmnd[6] = 0;
112278a02f49SMartin K. Petersen cmd->cmnd[9] = 0;
112378a02f49SMartin K. Petersen put_unaligned_be32(lba, &cmd->cmnd[2]);
112478a02f49SMartin K. Petersen put_unaligned_be16(nr_blocks, &cmd->cmnd[7]);
112578a02f49SMartin K. Petersen
112678a02f49SMartin K. Petersen return BLK_STS_OK;
112778a02f49SMartin K. Petersen }
112878a02f49SMartin K. Petersen
sd_setup_rw6_cmnd(struct scsi_cmnd * cmd,bool write,sector_t lba,unsigned int nr_blocks,unsigned char flags)112978a02f49SMartin K. Petersen static blk_status_t sd_setup_rw6_cmnd(struct scsi_cmnd *cmd, bool write,
113078a02f49SMartin K. Petersen sector_t lba, unsigned int nr_blocks,
113178a02f49SMartin K. Petersen unsigned char flags)
113278a02f49SMartin K. Petersen {
1133db5db4b9SBart Van Assche /* Avoid that 0 blocks gets translated into 256 blocks. */
1134db5db4b9SBart Van Assche if (WARN_ON_ONCE(nr_blocks == 0))
1135db5db4b9SBart Van Assche return BLK_STS_IOERR;
1136db5db4b9SBart Van Assche
113778a02f49SMartin K. Petersen if (unlikely(flags & 0x8)) {
113878a02f49SMartin K. Petersen /*
113978a02f49SMartin K. Petersen * This happens only if this drive failed 10byte rw
114078a02f49SMartin K. Petersen * command with ILLEGAL_REQUEST during operation and
114178a02f49SMartin K. Petersen * thus turned off use_10_for_rw.
114278a02f49SMartin K. Petersen */
114378a02f49SMartin K. Petersen scmd_printk(KERN_ERR, cmd, "FUA write on READ/WRITE(6) drive\n");
114478a02f49SMartin K. Petersen return BLK_STS_IOERR;
114578a02f49SMartin K. Petersen }
114678a02f49SMartin K. Petersen
114778a02f49SMartin K. Petersen cmd->cmd_len = 6;
114878a02f49SMartin K. Petersen cmd->cmnd[0] = write ? WRITE_6 : READ_6;
114978a02f49SMartin K. Petersen cmd->cmnd[1] = (lba >> 16) & 0x1f;
115078a02f49SMartin K. Petersen cmd->cmnd[2] = (lba >> 8) & 0xff;
115178a02f49SMartin K. Petersen cmd->cmnd[3] = lba & 0xff;
115278a02f49SMartin K. Petersen cmd->cmnd[4] = nr_blocks;
115378a02f49SMartin K. Petersen cmd->cmnd[5] = 0;
115478a02f49SMartin K. Petersen
115578a02f49SMartin K. Petersen return BLK_STS_OK;
115678a02f49SMartin K. Petersen }
115778a02f49SMartin K. Petersen
1158e59e80cfSDamien Le Moal /*
1159e59e80cfSDamien Le Moal * Check if a command has a duration limit set. If it does, and the target
1160e59e80cfSDamien Le Moal * device supports CDL and the feature is enabled, return the limit
1161e59e80cfSDamien Le Moal * descriptor index to use. Return 0 (no limit) otherwise.
1162e59e80cfSDamien Le Moal */
sd_cdl_dld(struct scsi_disk * sdkp,struct scsi_cmnd * scmd)1163e59e80cfSDamien Le Moal static int sd_cdl_dld(struct scsi_disk *sdkp, struct scsi_cmnd *scmd)
1164e59e80cfSDamien Le Moal {
1165e59e80cfSDamien Le Moal struct scsi_device *sdp = sdkp->device;
1166e59e80cfSDamien Le Moal int hint;
1167e59e80cfSDamien Le Moal
1168e59e80cfSDamien Le Moal if (!sdp->cdl_supported || !sdp->cdl_enable)
1169e59e80cfSDamien Le Moal return 0;
1170e59e80cfSDamien Le Moal
1171e59e80cfSDamien Le Moal /*
1172e59e80cfSDamien Le Moal * Use "no limit" if the request ioprio does not specify a duration
1173e59e80cfSDamien Le Moal * limit hint.
1174e59e80cfSDamien Le Moal */
1175e59e80cfSDamien Le Moal hint = IOPRIO_PRIO_HINT(req_get_ioprio(scsi_cmd_to_rq(scmd)));
1176e59e80cfSDamien Le Moal if (hint < IOPRIO_HINT_DEV_DURATION_LIMIT_1 ||
1177e59e80cfSDamien Le Moal hint > IOPRIO_HINT_DEV_DURATION_LIMIT_7)
1178e59e80cfSDamien Le Moal return 0;
1179e59e80cfSDamien Le Moal
1180e59e80cfSDamien Le Moal return (hint - IOPRIO_HINT_DEV_DURATION_LIMIT_1) + 1;
1181e59e80cfSDamien Le Moal }
1182e59e80cfSDamien Le Moal
sd_setup_read_write_cmnd(struct scsi_cmnd * cmd)1183cf64e5a5SBart Van Assche static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *cmd)
11841da177e4SLinus Torvalds {
11855999ccffSBart Van Assche struct request *rq = scsi_cmd_to_rq(cmd);
1186cf64e5a5SBart Van Assche struct scsi_device *sdp = cmd->device;
1187f3fa33acSChristoph Hellwig struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
1188ec029758SMartin K. Petersen sector_t lba = sectors_to_logical(sdp, blk_rq_pos(rq));
118918351070SLinus Torvalds sector_t threshold;
1190ec029758SMartin K. Petersen unsigned int nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
1191ec029758SMartin K. Petersen unsigned int mask = logical_to_sectors(sdp, 1) - 1;
119278a02f49SMartin K. Petersen bool write = rq_data_dir(rq) == WRITE;
119378a02f49SMartin K. Petersen unsigned char protect, fua;
1194e59e80cfSDamien Le Moal unsigned int dld;
1195159b2cbfSChristoph Hellwig blk_status_t ret;
11960cf9f4e5SXiang Chen unsigned int dif;
11970cf9f4e5SXiang Chen bool dix;
11987f9a6bc4SJames Bottomley
11997007e9ddSChristoph Hellwig ret = scsi_alloc_sgtables(cmd);
1200159b2cbfSChristoph Hellwig if (ret != BLK_STS_OK)
120139051dd8SDamien Le Moal return ret;
12027f9a6bc4SJames Bottomley
12037007e9ddSChristoph Hellwig ret = BLK_STS_IOERR;
1204e249e42dSMartin K. Petersen if (!scsi_device_online(sdp) || sdp->changed) {
1205cf64e5a5SBart Van Assche scmd_printk(KERN_ERR, cmd, "device offline or changed\n");
12067007e9ddSChristoph Hellwig goto fail;
12071da177e4SLinus Torvalds }
12081da177e4SLinus Torvalds
1209f3fa33acSChristoph Hellwig if (blk_rq_pos(rq) + blk_rq_sectors(rq) > get_capacity(rq->q->disk)) {
1210cf64e5a5SBart Van Assche scmd_printk(KERN_ERR, cmd, "access beyond end of device\n");
12117007e9ddSChristoph Hellwig goto fail;
1212e249e42dSMartin K. Petersen }
1213e249e42dSMartin K. Petersen
1214e249e42dSMartin K. Petersen if ((blk_rq_pos(rq) & mask) || (blk_rq_sectors(rq) & mask)) {
1215cf64e5a5SBart Van Assche scmd_printk(KERN_ERR, cmd, "request not aligned to the logical block size\n");
12167007e9ddSChristoph Hellwig goto fail;
12171da177e4SLinus Torvalds }
12187f9a6bc4SJames Bottomley
1219a0899d4dSHans de Goede /*
1220ec029758SMartin K. Petersen * Some SD card readers can't handle accesses which touch the
1221ec029758SMartin K. Petersen * last one or two logical blocks. Split accesses as needed.
1222a0899d4dSHans de Goede */
1223ec029758SMartin K. Petersen threshold = sdkp->capacity - SD_LAST_BUGGY_SECTORS;
122418351070SLinus Torvalds
1225c6c93fddSMartin K. Petersen if (unlikely(sdp->last_sector_bug && lba + nr_blocks > threshold)) {
1226c6c93fddSMartin K. Petersen if (lba < threshold) {
122718351070SLinus Torvalds /* Access up to the threshold but not beyond */
1228c6c93fddSMartin K. Petersen nr_blocks = threshold - lba;
122918351070SLinus Torvalds } else {
1230ec029758SMartin K. Petersen /* Access only a single logical block */
1231ec029758SMartin K. Petersen nr_blocks = 1;
123218351070SLinus Torvalds }
123318351070SLinus Torvalds }
1234a0899d4dSHans de Goede
12355795eb44SJohannes Thumshirn if (req_op(rq) == REQ_OP_ZONE_APPEND) {
12365795eb44SJohannes Thumshirn ret = sd_zbc_prepare_zone_append(cmd, &lba, nr_blocks);
12375795eb44SJohannes Thumshirn if (ret)
12387007e9ddSChristoph Hellwig goto fail;
12395795eb44SJohannes Thumshirn }
12405795eb44SJohannes Thumshirn
124178a02f49SMartin K. Petersen fua = rq->cmd_flags & REQ_FUA ? 0x8 : 0;
1242cf64e5a5SBart Van Assche dix = scsi_prot_sg_count(cmd);
1243cf64e5a5SBart Van Assche dif = scsi_host_dif_capable(cmd->device->host, sdkp->protection_type);
1244e59e80cfSDamien Le Moal dld = sd_cdl_dld(sdkp, cmd);
12451da177e4SLinus Torvalds
1246c611529eSMartin K. Petersen if (dif || dix)
1247cf64e5a5SBart Van Assche protect = sd_setup_protect_cmnd(cmd, dix, dif);
1248af55ff67SMartin K. Petersen else
12494e7392ecSMartin K. Petersen protect = 0;
12501da177e4SLinus Torvalds
12518475c811SChristoph Hellwig if (protect && sdkp->protection_type == T10_PI_TYPE2_PROTECTION) {
1252cf64e5a5SBart Van Assche ret = sd_setup_rw32_cmnd(cmd, write, lba, nr_blocks,
1253e59e80cfSDamien Le Moal protect | fua, dld);
1254c6c93fddSMartin K. Petersen } else if (sdp->use_16_for_rw || (nr_blocks > 0xffff)) {
1255cf64e5a5SBart Van Assche ret = sd_setup_rw16_cmnd(cmd, write, lba, nr_blocks,
1256e59e80cfSDamien Le Moal protect | fua, dld);
1257c6c93fddSMartin K. Petersen } else if ((nr_blocks > 0xff) || (lba > 0x1fffff) ||
1258e249e42dSMartin K. Petersen sdp->use_10_for_rw || protect) {
1259cf64e5a5SBart Van Assche ret = sd_setup_rw10_cmnd(cmd, write, lba, nr_blocks,
126078a02f49SMartin K. Petersen protect | fua);
12611da177e4SLinus Torvalds } else {
1262cf64e5a5SBart Van Assche ret = sd_setup_rw6_cmnd(cmd, write, lba, nr_blocks,
126378a02f49SMartin K. Petersen protect | fua);
1264007365adSTejun Heo }
1265007365adSTejun Heo
126678a02f49SMartin K. Petersen if (unlikely(ret != BLK_STS_OK))
12677007e9ddSChristoph Hellwig goto fail;
12681da177e4SLinus Torvalds
12691da177e4SLinus Torvalds /*
12701da177e4SLinus Torvalds * We shouldn't disconnect in the middle of a sector, so with a dumb
12711da177e4SLinus Torvalds * host adapter, it's safe to assume that we can at least transfer
12721da177e4SLinus Torvalds * this many bytes between each connect / disconnect.
12731da177e4SLinus Torvalds */
1274cf64e5a5SBart Van Assche cmd->transfersize = sdp->sector_size;
1275cf64e5a5SBart Van Assche cmd->underflow = nr_blocks << 9;
12760610959fSMike Christie cmd->allowed = sdkp->max_retries;
1277cf64e5a5SBart Van Assche cmd->sdb.length = nr_blocks * sdp->sector_size;
1278e249e42dSMartin K. Petersen
1279e249e42dSMartin K. Petersen SCSI_LOG_HLQUEUE(1,
1280cf64e5a5SBart Van Assche scmd_printk(KERN_INFO, cmd,
1281e249e42dSMartin K. Petersen "%s: block=%llu, count=%d\n", __func__,
1282e249e42dSMartin K. Petersen (unsigned long long)blk_rq_pos(rq),
1283e249e42dSMartin K. Petersen blk_rq_sectors(rq)));
1284e249e42dSMartin K. Petersen SCSI_LOG_HLQUEUE(2,
1285cf64e5a5SBart Van Assche scmd_printk(KERN_INFO, cmd,
1286e249e42dSMartin K. Petersen "%s %d/%u 512 byte blocks.\n",
1287e249e42dSMartin K. Petersen write ? "writing" : "reading", nr_blocks,
1288e249e42dSMartin K. Petersen blk_rq_sectors(rq)));
12891da177e4SLinus Torvalds
12901da177e4SLinus Torvalds /*
12917007e9ddSChristoph Hellwig * This indicates that the command is ready from our end to be queued.
12921da177e4SLinus Torvalds */
1293159b2cbfSChristoph Hellwig return BLK_STS_OK;
12947007e9ddSChristoph Hellwig fail:
12957007e9ddSChristoph Hellwig scsi_free_sgtables(cmd);
12967007e9ddSChristoph Hellwig return ret;
12971da177e4SLinus Torvalds }
12981da177e4SLinus Torvalds
sd_init_command(struct scsi_cmnd * cmd)1299159b2cbfSChristoph Hellwig static blk_status_t sd_init_command(struct scsi_cmnd *cmd)
130087949eeeSChristoph Hellwig {
13015999ccffSBart Van Assche struct request *rq = scsi_cmd_to_rq(cmd);
130287949eeeSChristoph Hellwig
1303c2df40dfSMike Christie switch (req_op(rq)) {
1304c2df40dfSMike Christie case REQ_OP_DISCARD:
1305f3fa33acSChristoph Hellwig switch (scsi_disk(rq->q->disk)->provisioning_mode) {
130681d926e8SChristoph Hellwig case SD_LBP_UNMAP:
130781d926e8SChristoph Hellwig return sd_setup_unmap_cmnd(cmd);
130881d926e8SChristoph Hellwig case SD_LBP_WS16:
130902d26103SChristoph Hellwig return sd_setup_write_same16_cmnd(cmd, true);
131081d926e8SChristoph Hellwig case SD_LBP_WS10:
131181d926e8SChristoph Hellwig return sd_setup_write_same10_cmnd(cmd, true);
131281d926e8SChristoph Hellwig case SD_LBP_ZERO:
131381d926e8SChristoph Hellwig return sd_setup_write_same10_cmnd(cmd, false);
131481d926e8SChristoph Hellwig default:
1315159b2cbfSChristoph Hellwig return BLK_STS_TARGET;
131681d926e8SChristoph Hellwig }
131702d26103SChristoph Hellwig case REQ_OP_WRITE_ZEROES:
131802d26103SChristoph Hellwig return sd_setup_write_zeroes_cmnd(cmd);
13193a5e02ceSMike Christie case REQ_OP_FLUSH:
132087949eeeSChristoph Hellwig return sd_setup_flush_cmnd(cmd);
1321c2df40dfSMike Christie case REQ_OP_READ:
1322c2df40dfSMike Christie case REQ_OP_WRITE:
13235795eb44SJohannes Thumshirn case REQ_OP_ZONE_APPEND:
132487949eeeSChristoph Hellwig return sd_setup_read_write_cmnd(cmd);
132589d94756SHannes Reinecke case REQ_OP_ZONE_RESET:
1326ad512f20SAjay Joshi return sd_zbc_setup_zone_mgmt_cmnd(cmd, ZO_RESET_WRITE_POINTER,
1327ad512f20SAjay Joshi false);
1328d81e9d49SChaitanya Kulkarni case REQ_OP_ZONE_RESET_ALL:
1329ad512f20SAjay Joshi return sd_zbc_setup_zone_mgmt_cmnd(cmd, ZO_RESET_WRITE_POINTER,
1330ad512f20SAjay Joshi true);
1331ad512f20SAjay Joshi case REQ_OP_ZONE_OPEN:
1332ad512f20SAjay Joshi return sd_zbc_setup_zone_mgmt_cmnd(cmd, ZO_OPEN_ZONE, false);
1333ad512f20SAjay Joshi case REQ_OP_ZONE_CLOSE:
1334ad512f20SAjay Joshi return sd_zbc_setup_zone_mgmt_cmnd(cmd, ZO_CLOSE_ZONE, false);
1335ad512f20SAjay Joshi case REQ_OP_ZONE_FINISH:
1336ad512f20SAjay Joshi return sd_zbc_setup_zone_mgmt_cmnd(cmd, ZO_FINISH_ZONE, false);
1337c2df40dfSMike Christie default:
1338f1f1fadaSJohannes Thumshirn WARN_ON_ONCE(1);
1339159b2cbfSChristoph Hellwig return BLK_STS_NOTSUPP;
1340c2df40dfSMike Christie }
134187949eeeSChristoph Hellwig }
134287949eeeSChristoph Hellwig
sd_uninit_command(struct scsi_cmnd * SCpnt)134387949eeeSChristoph Hellwig static void sd_uninit_command(struct scsi_cmnd *SCpnt)
134487949eeeSChristoph Hellwig {
13455999ccffSBart Van Assche struct request *rq = scsi_cmd_to_rq(SCpnt);
134687949eeeSChristoph Hellwig
1347f9d03f96SChristoph Hellwig if (rq->rq_flags & RQF_SPECIAL_PAYLOAD)
134861cce6f6SJens Axboe mempool_free(rq->special_vec.bv_page, sd_page_pool);
134987949eeeSChristoph Hellwig }
135087949eeeSChristoph Hellwig
sd_need_revalidate(struct gendisk * disk,struct scsi_disk * sdkp)1351444aa2c5SChristoph Hellwig static bool sd_need_revalidate(struct gendisk *disk, struct scsi_disk *sdkp)
1352d1b7f920SChristoph Hellwig {
1353d1b7f920SChristoph Hellwig if (sdkp->device->removable || sdkp->write_prot) {
1354444aa2c5SChristoph Hellwig if (disk_check_media_change(disk))
1355d1b7f920SChristoph Hellwig return true;
1356d1b7f920SChristoph Hellwig }
1357d1b7f920SChristoph Hellwig
1358d1b7f920SChristoph Hellwig /*
1359d1b7f920SChristoph Hellwig * Force a full rescan after ioctl(BLKRRPART). While the disk state has
1360d1b7f920SChristoph Hellwig * nothing to do with partitions, BLKRRPART is used to force a full
1361d1b7f920SChristoph Hellwig * revalidate after things like a format for historical reasons.
1362d1b7f920SChristoph Hellwig */
1363444aa2c5SChristoph Hellwig return test_bit(GD_NEED_PART_SCAN, &disk->state);
1364d1b7f920SChristoph Hellwig }
1365d1b7f920SChristoph Hellwig
13661da177e4SLinus Torvalds /**
13671da177e4SLinus Torvalds * sd_open - open a scsi disk device
1368d32e2bf8SChristoph Hellwig * @disk: disk to open
136905bdb996SChristoph Hellwig * @mode: open mode
13701da177e4SLinus Torvalds *
13711da177e4SLinus Torvalds * Returns 0 if successful. Returns a negated errno value in case
13721da177e4SLinus Torvalds * of error.
13731da177e4SLinus Torvalds *
13741da177e4SLinus Torvalds * Note: This can be called from a user context (e.g. fsck(1) )
13751da177e4SLinus Torvalds * or from within the kernel (e.g. as a result of a mount(1) ).
13761da177e4SLinus Torvalds * In the latter case @inode and @filp carry an abridged amount
13771da177e4SLinus Torvalds * of information as noted above.
1378409f3499SArnd Bergmann *
1379d32e2bf8SChristoph Hellwig * Locking: called with disk->open_mutex held.
13801da177e4SLinus Torvalds **/
sd_open(struct gendisk * disk,blk_mode_t mode)138105bdb996SChristoph Hellwig static int sd_open(struct gendisk *disk, blk_mode_t mode)
13821da177e4SLinus Torvalds {
1383d32e2bf8SChristoph Hellwig struct scsi_disk *sdkp = scsi_disk(disk);
13849c63f7f6SChristoph Hellwig struct scsi_device *sdev = sdkp->device;
13851da177e4SLinus Torvalds int retval;
13861da177e4SLinus Torvalds
13879c63f7f6SChristoph Hellwig if (scsi_device_get(sdev))
13881da177e4SLinus Torvalds return -ENXIO;
13891da177e4SLinus Torvalds
1390fa0d34beSMartin K. Petersen SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_open\n"));
13911da177e4SLinus Torvalds
13921da177e4SLinus Torvalds /*
13931da177e4SLinus Torvalds * If the device is in error recovery, wait until it is done.
13941da177e4SLinus Torvalds * If the device is offline, then disallow any access to it.
13951da177e4SLinus Torvalds */
13961da177e4SLinus Torvalds retval = -ENXIO;
13971da177e4SLinus Torvalds if (!scsi_block_when_processing_errors(sdev))
13981da177e4SLinus Torvalds goto error_out;
13991da177e4SLinus Torvalds
1400d32e2bf8SChristoph Hellwig if (sd_need_revalidate(disk, sdkp))
1401d32e2bf8SChristoph Hellwig sd_revalidate_disk(disk);
14021da177e4SLinus Torvalds
14031da177e4SLinus Torvalds /*
14041da177e4SLinus Torvalds * If the drive is empty, just let the open fail.
14051da177e4SLinus Torvalds */
14061da177e4SLinus Torvalds retval = -ENOMEDIUM;
140705bdb996SChristoph Hellwig if (sdev->removable && !sdkp->media_present &&
140805bdb996SChristoph Hellwig !(mode & BLK_OPEN_NDELAY))
14091da177e4SLinus Torvalds goto error_out;
14101da177e4SLinus Torvalds
14111da177e4SLinus Torvalds /*
14121da177e4SLinus Torvalds * If the device has the write protect tab set, have the open fail
14131da177e4SLinus Torvalds * if the user expects to be able to write to the thing.
14141da177e4SLinus Torvalds */
14151da177e4SLinus Torvalds retval = -EROFS;
141605bdb996SChristoph Hellwig if (sdkp->write_prot && (mode & BLK_OPEN_WRITE))
14171da177e4SLinus Torvalds goto error_out;
14181da177e4SLinus Torvalds
14191da177e4SLinus Torvalds /*
14201da177e4SLinus Torvalds * It is possible that the disk changing stuff resulted in
14211da177e4SLinus Torvalds * the device being taken offline. If this is the case,
14221da177e4SLinus Torvalds * report this to the user, and don't pretend that the
14231da177e4SLinus Torvalds * open actually succeeded.
14241da177e4SLinus Torvalds */
14251da177e4SLinus Torvalds retval = -ENXIO;
14261da177e4SLinus Torvalds if (!scsi_device_online(sdev))
14271da177e4SLinus Torvalds goto error_out;
14281da177e4SLinus Torvalds
1429409f3499SArnd Bergmann if ((atomic_inc_return(&sdkp->openers) == 1) && sdev->removable) {
14301da177e4SLinus Torvalds if (scsi_block_when_processing_errors(sdev))
14311da177e4SLinus Torvalds scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
14321da177e4SLinus Torvalds }
14331da177e4SLinus Torvalds
14341da177e4SLinus Torvalds return 0;
14351da177e4SLinus Torvalds
14361da177e4SLinus Torvalds error_out:
14379c63f7f6SChristoph Hellwig scsi_device_put(sdev);
14381da177e4SLinus Torvalds return retval;
14391da177e4SLinus Torvalds }
14401da177e4SLinus Torvalds
14411da177e4SLinus Torvalds /**
14421da177e4SLinus Torvalds * sd_release - invoked when the (last) close(2) is called on this
14431da177e4SLinus Torvalds * scsi disk.
14447529fbb0SDamien Le Moal * @disk: disk to release
14451da177e4SLinus Torvalds *
14461da177e4SLinus Torvalds * Returns 0.
14471da177e4SLinus Torvalds *
14481da177e4SLinus Torvalds * Note: may block (uninterruptible) if error recovery is underway
14491da177e4SLinus Torvalds * on this disk.
1450409f3499SArnd Bergmann *
145105bdb996SChristoph Hellwig * Locking: called with disk->open_mutex held.
14521da177e4SLinus Torvalds **/
sd_release(struct gendisk * disk)1453ae220766SChristoph Hellwig static void sd_release(struct gendisk *disk)
14541da177e4SLinus Torvalds {
14551da177e4SLinus Torvalds struct scsi_disk *sdkp = scsi_disk(disk);
14561da177e4SLinus Torvalds struct scsi_device *sdev = sdkp->device;
14571da177e4SLinus Torvalds
145856937f7bSJames Bottomley SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_release\n"));
14591da177e4SLinus Torvalds
14607e443312SAlan Stern if (atomic_dec_return(&sdkp->openers) == 0 && sdev->removable) {
14611da177e4SLinus Torvalds if (scsi_block_when_processing_errors(sdev))
14621da177e4SLinus Torvalds scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
14631da177e4SLinus Torvalds }
14641da177e4SLinus Torvalds
14659c63f7f6SChristoph Hellwig scsi_device_put(sdev);
14661da177e4SLinus Torvalds }
14671da177e4SLinus Torvalds
sd_getgeo(struct block_device * bdev,struct hd_geometry * geo)1468a885c8c4SChristoph Hellwig static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
14691da177e4SLinus Torvalds {
14701da177e4SLinus Torvalds struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
14711da177e4SLinus Torvalds struct scsi_device *sdp = sdkp->device;
14721da177e4SLinus Torvalds struct Scsi_Host *host = sdp->host;
1473f08bb1e0SMartin K. Petersen sector_t capacity = logical_to_sectors(sdp, sdkp->capacity);
14741da177e4SLinus Torvalds int diskinfo[4];
14751da177e4SLinus Torvalds
14761da177e4SLinus Torvalds /* default to most commonly used values */
14771da177e4SLinus Torvalds diskinfo[0] = 0x40; /* 1 << 6 */
14781da177e4SLinus Torvalds diskinfo[1] = 0x20; /* 1 << 5 */
1479f08bb1e0SMartin K. Petersen diskinfo[2] = capacity >> 11;
14801da177e4SLinus Torvalds
14811da177e4SLinus Torvalds /* override with calculated, extended default, or driver values */
14821da177e4SLinus Torvalds if (host->hostt->bios_param)
1483f08bb1e0SMartin K. Petersen host->hostt->bios_param(sdp, bdev, capacity, diskinfo);
14841da177e4SLinus Torvalds else
1485f08bb1e0SMartin K. Petersen scsicam_bios_param(bdev, capacity, diskinfo);
14861da177e4SLinus Torvalds
1487a885c8c4SChristoph Hellwig geo->heads = diskinfo[0];
1488a885c8c4SChristoph Hellwig geo->sectors = diskinfo[1];
1489a885c8c4SChristoph Hellwig geo->cylinders = diskinfo[2];
14901da177e4SLinus Torvalds return 0;
14911da177e4SLinus Torvalds }
14921da177e4SLinus Torvalds
14931da177e4SLinus Torvalds /**
149444328310SChristoph Hellwig * sd_ioctl - process an ioctl
14957529fbb0SDamien Le Moal * @bdev: target block device
149605bdb996SChristoph Hellwig * @mode: open mode
14971da177e4SLinus Torvalds * @cmd: ioctl command number
149844328310SChristoph Hellwig * @arg: this is third argument given to ioctl(2) system call.
14991da177e4SLinus Torvalds * Often contains a pointer.
15001da177e4SLinus Torvalds *
150125985edcSLucas De Marchi * Returns 0 if successful (some ioctls return positive numbers on
15021da177e4SLinus Torvalds * success as well). Returns a negated errno value in case of error.
15031da177e4SLinus Torvalds *
15041da177e4SLinus Torvalds * Note: most ioctls are forward onto the block subsystem or further
15053a4fa0a2SRobert P. J. Day * down in the scsi subsystem.
15061da177e4SLinus Torvalds **/
sd_ioctl(struct block_device * bdev,blk_mode_t mode,unsigned int cmd,unsigned long arg)150705bdb996SChristoph Hellwig static int sd_ioctl(struct block_device *bdev, blk_mode_t mode,
150844328310SChristoph Hellwig unsigned int cmd, unsigned long arg)
15091da177e4SLinus Torvalds {
15101da177e4SLinus Torvalds struct gendisk *disk = bdev->bd_disk;
1511fe2d1851SNao Nishijima struct scsi_disk *sdkp = scsi_disk(disk);
1512fe2d1851SNao Nishijima struct scsi_device *sdp = sdkp->device;
151344328310SChristoph Hellwig void __user *p = (void __user *)arg;
15141da177e4SLinus Torvalds int error;
15151da177e4SLinus Torvalds
1516fe2d1851SNao Nishijima SCSI_LOG_IOCTL(1, sd_printk(KERN_INFO, sdkp, "sd_ioctl: disk=%s, "
1517fe2d1851SNao Nishijima "cmd=0x%x\n", disk->disk_name, cmd));
15181da177e4SLinus Torvalds
15194f07bfc5SChristoph Hellwig if (bdev_is_partition(bdev) && !capable(CAP_SYS_RAWIO))
15204f07bfc5SChristoph Hellwig return -ENOIOCTLCMD;
15210bfc96cbSPaolo Bonzini
15221da177e4SLinus Torvalds /*
15231da177e4SLinus Torvalds * If we are in the middle of error recovery, don't let anyone
15241da177e4SLinus Torvalds * else try and use this device. Also, if error recovery fails, it
15251da177e4SLinus Torvalds * may try and take the device offline, in which case all further
15261da177e4SLinus Torvalds * access to the device is prohibited.
15271da177e4SLinus Torvalds */
1528906d15fbSChristoph Hellwig error = scsi_ioctl_block_when_processing_errors(sdp, cmd,
152905bdb996SChristoph Hellwig (mode & BLK_OPEN_NDELAY));
1530906d15fbSChristoph Hellwig if (error)
153144328310SChristoph Hellwig return error;
15321da177e4SLinus Torvalds
1533d80210f2SChristoph Hellwig if (is_sed_ioctl(cmd))
1534d80210f2SChristoph Hellwig return sed_ioctl(sdkp->opal_dev, cmd, p);
153505bdb996SChristoph Hellwig return scsi_ioctl(sdp, mode & BLK_OPEN_WRITE, cmd, p);
15361da177e4SLinus Torvalds }
15371da177e4SLinus Torvalds
set_media_not_present(struct scsi_disk * sdkp)15381da177e4SLinus Torvalds static void set_media_not_present(struct scsi_disk *sdkp)
15391da177e4SLinus Torvalds {
15402bae0093STejun Heo if (sdkp->media_present)
15412bae0093STejun Heo sdkp->device->changed = 1;
15422bae0093STejun Heo
15432bae0093STejun Heo if (sdkp->device->removable) {
15441da177e4SLinus Torvalds sdkp->media_present = 0;
15451da177e4SLinus Torvalds sdkp->capacity = 0;
15462bae0093STejun Heo }
15472bae0093STejun Heo }
15482bae0093STejun Heo
media_not_present(struct scsi_disk * sdkp,struct scsi_sense_hdr * sshdr)15492bae0093STejun Heo static int media_not_present(struct scsi_disk *sdkp,
15502bae0093STejun Heo struct scsi_sense_hdr *sshdr)
15512bae0093STejun Heo {
15522bae0093STejun Heo if (!scsi_sense_valid(sshdr))
15532bae0093STejun Heo return 0;
15542bae0093STejun Heo
15552bae0093STejun Heo /* not invoked for commands that could return deferred errors */
15562bae0093STejun Heo switch (sshdr->sense_key) {
15572bae0093STejun Heo case UNIT_ATTENTION:
15582bae0093STejun Heo case NOT_READY:
15592bae0093STejun Heo /* medium not present */
15602bae0093STejun Heo if (sshdr->asc == 0x3A) {
15612bae0093STejun Heo set_media_not_present(sdkp);
15622bae0093STejun Heo return 1;
15632bae0093STejun Heo }
15642bae0093STejun Heo }
15652bae0093STejun Heo return 0;
15661da177e4SLinus Torvalds }
15671da177e4SLinus Torvalds
15681da177e4SLinus Torvalds /**
15692bae0093STejun Heo * sd_check_events - check media events
15701da177e4SLinus Torvalds * @disk: kernel device descriptor
15712bae0093STejun Heo * @clearing: disk events currently being cleared
15721da177e4SLinus Torvalds *
15732bae0093STejun Heo * Returns mask of DISK_EVENT_*.
15741da177e4SLinus Torvalds *
15751da177e4SLinus Torvalds * Note: this function is invoked from the block subsystem.
15761da177e4SLinus Torvalds **/
sd_check_events(struct gendisk * disk,unsigned int clearing)15772bae0093STejun Heo static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)
15781da177e4SLinus Torvalds {
15799c63f7f6SChristoph Hellwig struct scsi_disk *sdkp = disk->private_data;
1580eb72d0bbSHannes Reinecke struct scsi_device *sdp;
15811da177e4SLinus Torvalds int retval;
158241e70e30SBart Van Assche bool disk_changed;
15831da177e4SLinus Torvalds
1584eb72d0bbSHannes Reinecke if (!sdkp)
1585eb72d0bbSHannes Reinecke return 0;
1586eb72d0bbSHannes Reinecke
1587eb72d0bbSHannes Reinecke sdp = sdkp->device;
15882bae0093STejun Heo SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_check_events\n"));
15891da177e4SLinus Torvalds
15901da177e4SLinus Torvalds /*
15911da177e4SLinus Torvalds * If the device is offline, don't send any commands - just pretend as
15921da177e4SLinus Torvalds * if the command failed. If the device ever comes back online, we
15931da177e4SLinus Torvalds * can deal with it then. It is only because of unrecoverable errors
15941da177e4SLinus Torvalds * that we would ever take a device offline in the first place.
15951da177e4SLinus Torvalds */
1596285e9670SKay Sievers if (!scsi_device_online(sdp)) {
1597285e9670SKay Sievers set_media_not_present(sdkp);
1598285e9670SKay Sievers goto out;
1599285e9670SKay Sievers }
16001da177e4SLinus Torvalds
16011da177e4SLinus Torvalds /*
16021da177e4SLinus Torvalds * Using TEST_UNIT_READY enables differentiation between drive with
16031da177e4SLinus Torvalds * no cartridge loaded - NOT READY, drive with changed cartridge -
16041da177e4SLinus Torvalds * UNIT ATTENTION, or with same cartridge - GOOD STATUS.
16051da177e4SLinus Torvalds *
16061da177e4SLinus Torvalds * Drives that auto spin down. eg iomega jaz 1G, will be started
16071da177e4SLinus Torvalds * by sd_spinup_disk() from sd_revalidate_disk(), which happens whenever
16081da177e4SLinus Torvalds * sd_revalidate() is called.
16091da177e4SLinus Torvalds */
1610001aac25SJames Bottomley if (scsi_block_when_processing_errors(sdp)) {
16116fa2b8f9SChristoph Hellwig struct scsi_sense_hdr sshdr = { 0, };
16126fa2b8f9SChristoph Hellwig
16130610959fSMike Christie retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, sdkp->max_retries,
16146fa2b8f9SChristoph Hellwig &sshdr);
16151da177e4SLinus Torvalds
16162bae0093STejun Heo /* failed to execute TUR, assume media not present */
1617ced202f7SHannes Reinecke if (retval < 0 || host_byte(retval)) {
1618285e9670SKay Sievers set_media_not_present(sdkp);
1619285e9670SKay Sievers goto out;
1620285e9670SKay Sievers }
16211da177e4SLinus Torvalds
16226fa2b8f9SChristoph Hellwig if (media_not_present(sdkp, &sshdr))
16232bae0093STejun Heo goto out;
16246fa2b8f9SChristoph Hellwig }
16252bae0093STejun Heo
16261da177e4SLinus Torvalds /*
16271da177e4SLinus Torvalds * For removable scsi disk we have to recognise the presence
16282bae0093STejun Heo * of a disk in the drive.
16291da177e4SLinus Torvalds */
16302bae0093STejun Heo if (!sdkp->media_present)
16312bae0093STejun Heo sdp->changed = 1;
16321da177e4SLinus Torvalds sdkp->media_present = 1;
1633285e9670SKay Sievers out:
16343ff5588dSAlan Stern /*
16352bae0093STejun Heo * sdp->changed is set under the following conditions:
16363ff5588dSAlan Stern *
16372bae0093STejun Heo * Medium present state has changed in either direction.
16382bae0093STejun Heo * Device has indicated UNIT_ATTENTION.
16393ff5588dSAlan Stern */
164041e70e30SBart Van Assche disk_changed = sdp->changed;
16412bae0093STejun Heo sdp->changed = 0;
164241e70e30SBart Van Assche return disk_changed ? DISK_EVENT_MEDIA_CHANGE : 0;
16431da177e4SLinus Torvalds }
16441da177e4SLinus Torvalds
sd_sync_cache(struct scsi_disk * sdkp)1645c94c4468SMike Christie static int sd_sync_cache(struct scsi_disk *sdkp)
16461da177e4SLinus Torvalds {
16471da177e4SLinus Torvalds int retries, res;
1648e73aec82SMartin K. Petersen struct scsi_device *sdp = sdkp->device;
16497e660100SJames Bottomley const int timeout = sdp->request_queue->rq_timeout
16507e660100SJames Bottomley * SD_FLUSH_TIMEOUT_MULTIPLIER;
1651c94c4468SMike Christie struct scsi_sense_hdr sshdr;
1652af16cd63SMike Christie const struct scsi_exec_args exec_args = {
1653af16cd63SMike Christie .req_flags = BLK_MQ_REQ_PM,
1654c94c4468SMike Christie .sshdr = &sshdr,
1655af16cd63SMike Christie };
16561da177e4SLinus Torvalds
16571da177e4SLinus Torvalds if (!scsi_device_online(sdp))
16581da177e4SLinus Torvalds return -ENODEV;
16591da177e4SLinus Torvalds
16601da177e4SLinus Torvalds for (retries = 3; retries > 0; --retries) {
166142c59077SShin'ichiro Kawasaki unsigned char cmd[16] = { 0 };
16621da177e4SLinus Torvalds
166342c59077SShin'ichiro Kawasaki if (sdp->use_16_for_sync)
166442c59077SShin'ichiro Kawasaki cmd[0] = SYNCHRONIZE_CACHE_16;
166542c59077SShin'ichiro Kawasaki else
16661da177e4SLinus Torvalds cmd[0] = SYNCHRONIZE_CACHE;
16671da177e4SLinus Torvalds /*
16681da177e4SLinus Torvalds * Leave the rest of the command zero to indicate
16691da177e4SLinus Torvalds * flush everything.
16701da177e4SLinus Torvalds */
1671af16cd63SMike Christie res = scsi_execute_cmd(sdp, cmd, REQ_OP_DRV_IN, NULL, 0,
1672af16cd63SMike Christie timeout, sdkp->max_retries, &exec_args);
1673ea73a9f2SJames Bottomley if (res == 0)
16741da177e4SLinus Torvalds break;
16751da177e4SLinus Torvalds }
16761da177e4SLinus Torvalds
1677e73aec82SMartin K. Petersen if (res) {
1678ef61329dSHannes Reinecke sd_print_result(sdkp, "Synchronize Cache(10) failed", res);
167995897910SOliver Neukum
1680ced202f7SHannes Reinecke if (res < 0)
1681ced202f7SHannes Reinecke return res;
1682ced202f7SHannes Reinecke
1683464a00c9SHannes Reinecke if (scsi_status_is_check_condition(res) &&
1684c94c4468SMike Christie scsi_sense_valid(&sshdr)) {
1685c94c4468SMike Christie sd_print_sense_hdr(sdkp, &sshdr);
16864fa83244SDerek Basehore
168795897910SOliver Neukum /* we need to evaluate the error return */
1688c94c4468SMike Christie if (sshdr.asc == 0x3a || /* medium not present */
1689c94c4468SMike Christie sshdr.asc == 0x20 || /* invalid command */
1690c94c4468SMike Christie (sshdr.asc == 0x74 && sshdr.ascq == 0x71)) /* drive is password locked */
169195897910SOliver Neukum /* this is no error here */
169295897910SOliver Neukum return 0;
169303e3156eSYihang Li
1694c94c4468SMike Christie /*
169503e3156eSYihang Li * If a format is in progress or if the drive does not
169603e3156eSYihang Li * support sync, there is not much we can do because
169703e3156eSYihang Li * this is called during shutdown or suspend so just
169803e3156eSYihang Li * return success so those operations can proceed.
1699c94c4468SMike Christie */
170003e3156eSYihang Li if ((sshdr.asc == 0x04 && sshdr.ascq == 0x04) ||
170103e3156eSYihang Li sshdr.sense_key == ILLEGAL_REQUEST)
1702c94c4468SMike Christie return 0;
1703464a00c9SHannes Reinecke }
17041da177e4SLinus Torvalds
170595897910SOliver Neukum switch (host_byte(res)) {
170695897910SOliver Neukum /* ignore errors due to racing a disconnection */
170795897910SOliver Neukum case DID_BAD_TARGET:
170895897910SOliver Neukum case DID_NO_CONNECT:
170995897910SOliver Neukum return 0;
171095897910SOliver Neukum /* signal the upper layer it might try again */
171195897910SOliver Neukum case DID_BUS_BUSY:
171295897910SOliver Neukum case DID_IMM_RETRY:
171395897910SOliver Neukum case DID_REQUEUE:
171495897910SOliver Neukum case DID_SOFT_ERROR:
171595897910SOliver Neukum return -EBUSY;
171695897910SOliver Neukum default:
17173721050aSTejun Heo return -EIO;
171895897910SOliver Neukum }
171995897910SOliver Neukum }
17203721050aSTejun Heo return 0;
17211da177e4SLinus Torvalds }
17221da177e4SLinus Torvalds
sd_rescan(struct device * dev)17231da177e4SLinus Torvalds static void sd_rescan(struct device *dev)
17241da177e4SLinus Torvalds {
17253d9a1f53SChristoph Hellwig struct scsi_disk *sdkp = dev_get_drvdata(dev);
172639b7f1e2SAlan Stern
1727b200e38cSChristoph Hellwig sd_revalidate_disk(sdkp->disk);
17281da177e4SLinus Torvalds }
17291da177e4SLinus Torvalds
sd_get_unique_id(struct gendisk * disk,u8 id[16],enum blk_unique_id type)1730b83ce214SChristoph Hellwig static int sd_get_unique_id(struct gendisk *disk, u8 id[16],
1731b83ce214SChristoph Hellwig enum blk_unique_id type)
1732b83ce214SChristoph Hellwig {
1733b83ce214SChristoph Hellwig struct scsi_device *sdev = scsi_disk(disk)->device;
1734b83ce214SChristoph Hellwig const struct scsi_vpd *vpd;
1735b83ce214SChristoph Hellwig const unsigned char *d;
1736b83ce214SChristoph Hellwig int ret = -ENXIO, len;
1737b83ce214SChristoph Hellwig
1738b83ce214SChristoph Hellwig rcu_read_lock();
1739b83ce214SChristoph Hellwig vpd = rcu_dereference(sdev->vpd_pg83);
1740b83ce214SChristoph Hellwig if (!vpd)
1741b83ce214SChristoph Hellwig goto out_unlock;
1742b83ce214SChristoph Hellwig
1743b83ce214SChristoph Hellwig ret = -EINVAL;
1744b83ce214SChristoph Hellwig for (d = vpd->data + 4; d < vpd->data + vpd->len; d += d[3] + 4) {
1745b83ce214SChristoph Hellwig /* we only care about designators with LU association */
1746b83ce214SChristoph Hellwig if (((d[1] >> 4) & 0x3) != 0x00)
1747b83ce214SChristoph Hellwig continue;
1748b83ce214SChristoph Hellwig if ((d[1] & 0xf) != type)
1749b83ce214SChristoph Hellwig continue;
1750b83ce214SChristoph Hellwig
1751b83ce214SChristoph Hellwig /*
1752b83ce214SChristoph Hellwig * Only exit early if a 16-byte descriptor was found. Otherwise
1753b83ce214SChristoph Hellwig * keep looking as one with more entropy might still show up.
1754b83ce214SChristoph Hellwig */
1755b83ce214SChristoph Hellwig len = d[3];
1756b83ce214SChristoph Hellwig if (len != 8 && len != 12 && len != 16)
1757b83ce214SChristoph Hellwig continue;
1758b83ce214SChristoph Hellwig ret = len;
1759b83ce214SChristoph Hellwig memcpy(id, d + 4, len);
1760b83ce214SChristoph Hellwig if (len == 16)
1761b83ce214SChristoph Hellwig break;
1762b83ce214SChristoph Hellwig }
1763b83ce214SChristoph Hellwig out_unlock:
1764b83ce214SChristoph Hellwig rcu_read_unlock();
1765b83ce214SChristoph Hellwig return ret;
1766b83ce214SChristoph Hellwig }
1767b83ce214SChristoph Hellwig
sd_scsi_to_pr_err(struct scsi_sense_hdr * sshdr,int result)176804b3c8c0SMike Christie static int sd_scsi_to_pr_err(struct scsi_sense_hdr *sshdr, int result)
176904b3c8c0SMike Christie {
177004b3c8c0SMike Christie switch (host_byte(result)) {
177104b3c8c0SMike Christie case DID_TRANSPORT_MARGINAL:
177204b3c8c0SMike Christie case DID_TRANSPORT_DISRUPTED:
177304b3c8c0SMike Christie case DID_BUS_BUSY:
177404b3c8c0SMike Christie return PR_STS_RETRY_PATH_FAILURE;
177504b3c8c0SMike Christie case DID_NO_CONNECT:
177604b3c8c0SMike Christie return PR_STS_PATH_FAILED;
177704b3c8c0SMike Christie case DID_TRANSPORT_FAILFAST:
177804b3c8c0SMike Christie return PR_STS_PATH_FAST_FAILED;
177904b3c8c0SMike Christie }
178004b3c8c0SMike Christie
178104b3c8c0SMike Christie switch (status_byte(result)) {
178204b3c8c0SMike Christie case SAM_STAT_RESERVATION_CONFLICT:
178304b3c8c0SMike Christie return PR_STS_RESERVATION_CONFLICT;
178404b3c8c0SMike Christie case SAM_STAT_CHECK_CONDITION:
178504b3c8c0SMike Christie if (!scsi_sense_valid(sshdr))
178604b3c8c0SMike Christie return PR_STS_IOERR;
178704b3c8c0SMike Christie
178804b3c8c0SMike Christie if (sshdr->sense_key == ILLEGAL_REQUEST &&
178904b3c8c0SMike Christie (sshdr->asc == 0x26 || sshdr->asc == 0x24))
179004b3c8c0SMike Christie return -EINVAL;
179104b3c8c0SMike Christie
179204b3c8c0SMike Christie fallthrough;
179304b3c8c0SMike Christie default:
179404b3c8c0SMike Christie return PR_STS_IOERR;
179504b3c8c0SMike Christie }
179604b3c8c0SMike Christie }
179704b3c8c0SMike Christie
sd_pr_in_command(struct block_device * bdev,u8 sa,unsigned char * data,int data_len)17980af7b5e2SMike Christie static int sd_pr_in_command(struct block_device *bdev, u8 sa,
17990af7b5e2SMike Christie unsigned char *data, int data_len)
18000af7b5e2SMike Christie {
18010af7b5e2SMike Christie struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
18020af7b5e2SMike Christie struct scsi_device *sdev = sdkp->device;
18030af7b5e2SMike Christie struct scsi_sense_hdr sshdr;
18040af7b5e2SMike Christie u8 cmd[10] = { PERSISTENT_RESERVE_IN, sa };
18050af7b5e2SMike Christie const struct scsi_exec_args exec_args = {
18060af7b5e2SMike Christie .sshdr = &sshdr,
18070af7b5e2SMike Christie };
18080af7b5e2SMike Christie int result;
18090af7b5e2SMike Christie
18100af7b5e2SMike Christie put_unaligned_be16(data_len, &cmd[7]);
18110af7b5e2SMike Christie
18120af7b5e2SMike Christie result = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_IN, data, data_len,
18130af7b5e2SMike Christie SD_TIMEOUT, sdkp->max_retries, &exec_args);
18140af7b5e2SMike Christie if (scsi_status_is_check_condition(result) &&
18150af7b5e2SMike Christie scsi_sense_valid(&sshdr)) {
18160af7b5e2SMike Christie sdev_printk(KERN_INFO, sdev, "PR command failed: %d\n", result);
18170af7b5e2SMike Christie scsi_print_sense_hdr(sdev, NULL, &sshdr);
18180af7b5e2SMike Christie }
18190af7b5e2SMike Christie
18200af7b5e2SMike Christie if (result <= 0)
18210af7b5e2SMike Christie return result;
18220af7b5e2SMike Christie
18230af7b5e2SMike Christie return sd_scsi_to_pr_err(&sshdr, result);
18240af7b5e2SMike Christie }
18250af7b5e2SMike Christie
sd_pr_read_keys(struct block_device * bdev,struct pr_keys * keys_info)18260af7b5e2SMike Christie static int sd_pr_read_keys(struct block_device *bdev, struct pr_keys *keys_info)
18270af7b5e2SMike Christie {
18280af7b5e2SMike Christie int result, i, data_offset, num_copy_keys;
18290af7b5e2SMike Christie u32 num_keys = keys_info->num_keys;
18300af7b5e2SMike Christie int data_len = num_keys * 8 + 8;
18310af7b5e2SMike Christie u8 *data;
18320af7b5e2SMike Christie
18330af7b5e2SMike Christie data = kzalloc(data_len, GFP_KERNEL);
18340af7b5e2SMike Christie if (!data)
18350af7b5e2SMike Christie return -ENOMEM;
18360af7b5e2SMike Christie
18370af7b5e2SMike Christie result = sd_pr_in_command(bdev, READ_KEYS, data, data_len);
18380af7b5e2SMike Christie if (result)
18390af7b5e2SMike Christie goto free_data;
18400af7b5e2SMike Christie
18410af7b5e2SMike Christie keys_info->generation = get_unaligned_be32(&data[0]);
18420af7b5e2SMike Christie keys_info->num_keys = get_unaligned_be32(&data[4]) / 8;
18430af7b5e2SMike Christie
18440af7b5e2SMike Christie data_offset = 8;
18450af7b5e2SMike Christie num_copy_keys = min(num_keys, keys_info->num_keys);
18460af7b5e2SMike Christie
18470af7b5e2SMike Christie for (i = 0; i < num_copy_keys; i++) {
18480af7b5e2SMike Christie keys_info->keys[i] = get_unaligned_be64(&data[data_offset]);
18490af7b5e2SMike Christie data_offset += 8;
18500af7b5e2SMike Christie }
18510af7b5e2SMike Christie
18520af7b5e2SMike Christie free_data:
18530af7b5e2SMike Christie kfree(data);
18540af7b5e2SMike Christie return result;
18550af7b5e2SMike Christie }
18560af7b5e2SMike Christie
sd_pr_read_reservation(struct block_device * bdev,struct pr_held_reservation * rsv)18570af7b5e2SMike Christie static int sd_pr_read_reservation(struct block_device *bdev,
18580af7b5e2SMike Christie struct pr_held_reservation *rsv)
18590af7b5e2SMike Christie {
18600af7b5e2SMike Christie struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
18610af7b5e2SMike Christie struct scsi_device *sdev = sdkp->device;
18620af7b5e2SMike Christie u8 data[24] = { };
18630af7b5e2SMike Christie int result, len;
18640af7b5e2SMike Christie
18650af7b5e2SMike Christie result = sd_pr_in_command(bdev, READ_RESERVATION, data, sizeof(data));
18660af7b5e2SMike Christie if (result)
18670af7b5e2SMike Christie return result;
18680af7b5e2SMike Christie
18690af7b5e2SMike Christie len = get_unaligned_be32(&data[4]);
18700af7b5e2SMike Christie if (!len)
18710af7b5e2SMike Christie return 0;
18720af7b5e2SMike Christie
18730af7b5e2SMike Christie /* Make sure we have at least the key and type */
18740af7b5e2SMike Christie if (len < 14) {
18750af7b5e2SMike Christie sdev_printk(KERN_INFO, sdev,
18760af7b5e2SMike Christie "READ RESERVATION failed due to short return buffer of %d bytes\n",
18770af7b5e2SMike Christie len);
18780af7b5e2SMike Christie return -EINVAL;
18790af7b5e2SMike Christie }
18800af7b5e2SMike Christie
18810af7b5e2SMike Christie rsv->generation = get_unaligned_be32(&data[0]);
18820af7b5e2SMike Christie rsv->key = get_unaligned_be64(&data[8]);
18830af7b5e2SMike Christie rsv->type = scsi_pr_type_to_block(data[21] & 0x0f);
18840af7b5e2SMike Christie return 0;
18850af7b5e2SMike Christie }
18860af7b5e2SMike Christie
sd_pr_out_command(struct block_device * bdev,u8 sa,u64 key,u64 sa_key,enum scsi_pr_type type,u8 flags)18870730b163SMike Christie static int sd_pr_out_command(struct block_device *bdev, u8 sa, u64 key,
18880730b163SMike Christie u64 sa_key, enum scsi_pr_type type, u8 flags)
1889924d55b0SChristoph Hellwig {
18900610959fSMike Christie struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
18910610959fSMike Christie struct scsi_device *sdev = sdkp->device;
1892924d55b0SChristoph Hellwig struct scsi_sense_hdr sshdr;
1893af16cd63SMike Christie const struct scsi_exec_args exec_args = {
1894af16cd63SMike Christie .sshdr = &sshdr,
1895af16cd63SMike Christie };
1896924d55b0SChristoph Hellwig int result;
1897924d55b0SChristoph Hellwig u8 cmd[16] = { 0, };
1898924d55b0SChristoph Hellwig u8 data[24] = { 0, };
1899924d55b0SChristoph Hellwig
1900924d55b0SChristoph Hellwig cmd[0] = PERSISTENT_RESERVE_OUT;
1901924d55b0SChristoph Hellwig cmd[1] = sa;
1902924d55b0SChristoph Hellwig cmd[2] = type;
1903924d55b0SChristoph Hellwig put_unaligned_be32(sizeof(data), &cmd[5]);
1904924d55b0SChristoph Hellwig
1905924d55b0SChristoph Hellwig put_unaligned_be64(key, &data[0]);
1906924d55b0SChristoph Hellwig put_unaligned_be64(sa_key, &data[8]);
1907924d55b0SChristoph Hellwig data[20] = flags;
1908924d55b0SChristoph Hellwig
1909af16cd63SMike Christie result = scsi_execute_cmd(sdev, cmd, REQ_OP_DRV_OUT, &data,
1910af16cd63SMike Christie sizeof(data), SD_TIMEOUT, sdkp->max_retries,
1911af16cd63SMike Christie &exec_args);
1912924d55b0SChristoph Hellwig
1913464a00c9SHannes Reinecke if (scsi_status_is_check_condition(result) &&
1914c65be1a6SJohannes Thumshirn scsi_sense_valid(&sshdr)) {
1915924d55b0SChristoph Hellwig sdev_printk(KERN_INFO, sdev, "PR command failed: %d\n", result);
1916924d55b0SChristoph Hellwig scsi_print_sense_hdr(sdev, NULL, &sshdr);
1917924d55b0SChristoph Hellwig }
1918924d55b0SChristoph Hellwig
191904b3c8c0SMike Christie if (result <= 0)
1920924d55b0SChristoph Hellwig return result;
192104b3c8c0SMike Christie
192204b3c8c0SMike Christie return sd_scsi_to_pr_err(&sshdr, result);
1923924d55b0SChristoph Hellwig }
1924924d55b0SChristoph Hellwig
sd_pr_register(struct block_device * bdev,u64 old_key,u64 new_key,u32 flags)1925924d55b0SChristoph Hellwig static int sd_pr_register(struct block_device *bdev, u64 old_key, u64 new_key,
1926924d55b0SChristoph Hellwig u32 flags)
1927924d55b0SChristoph Hellwig {
1928924d55b0SChristoph Hellwig if (flags & ~PR_FL_IGNORE_KEY)
1929924d55b0SChristoph Hellwig return -EOPNOTSUPP;
193020bebccbSMike Christie return sd_pr_out_command(bdev, (flags & PR_FL_IGNORE_KEY) ? 0x06 : 0x00,
1931924d55b0SChristoph Hellwig old_key, new_key, 0,
193201f90dd9SChristoph Hellwig (1 << 0) /* APTPL */);
1933924d55b0SChristoph Hellwig }
1934924d55b0SChristoph Hellwig
sd_pr_reserve(struct block_device * bdev,u64 key,enum pr_type type,u32 flags)1935924d55b0SChristoph Hellwig static int sd_pr_reserve(struct block_device *bdev, u64 key, enum pr_type type,
1936924d55b0SChristoph Hellwig u32 flags)
1937924d55b0SChristoph Hellwig {
1938924d55b0SChristoph Hellwig if (flags)
1939924d55b0SChristoph Hellwig return -EOPNOTSUPP;
19400730b163SMike Christie return sd_pr_out_command(bdev, 0x01, key, 0,
19410730b163SMike Christie block_pr_type_to_scsi(type), 0);
1942924d55b0SChristoph Hellwig }
1943924d55b0SChristoph Hellwig
sd_pr_release(struct block_device * bdev,u64 key,enum pr_type type)1944924d55b0SChristoph Hellwig static int sd_pr_release(struct block_device *bdev, u64 key, enum pr_type type)
1945924d55b0SChristoph Hellwig {
19460730b163SMike Christie return sd_pr_out_command(bdev, 0x02, key, 0,
19470730b163SMike Christie block_pr_type_to_scsi(type), 0);
1948924d55b0SChristoph Hellwig }
1949924d55b0SChristoph Hellwig
sd_pr_preempt(struct block_device * bdev,u64 old_key,u64 new_key,enum pr_type type,bool abort)1950924d55b0SChristoph Hellwig static int sd_pr_preempt(struct block_device *bdev, u64 old_key, u64 new_key,
1951924d55b0SChristoph Hellwig enum pr_type type, bool abort)
1952924d55b0SChristoph Hellwig {
195320bebccbSMike Christie return sd_pr_out_command(bdev, abort ? 0x05 : 0x04, old_key, new_key,
19540730b163SMike Christie block_pr_type_to_scsi(type), 0);
1955924d55b0SChristoph Hellwig }
1956924d55b0SChristoph Hellwig
sd_pr_clear(struct block_device * bdev,u64 key)1957924d55b0SChristoph Hellwig static int sd_pr_clear(struct block_device *bdev, u64 key)
1958924d55b0SChristoph Hellwig {
195920bebccbSMike Christie return sd_pr_out_command(bdev, 0x03, key, 0, 0, 0);
1960924d55b0SChristoph Hellwig }
1961924d55b0SChristoph Hellwig
1962924d55b0SChristoph Hellwig static const struct pr_ops sd_pr_ops = {
1963924d55b0SChristoph Hellwig .pr_register = sd_pr_register,
1964924d55b0SChristoph Hellwig .pr_reserve = sd_pr_reserve,
1965924d55b0SChristoph Hellwig .pr_release = sd_pr_release,
1966924d55b0SChristoph Hellwig .pr_preempt = sd_pr_preempt,
1967924d55b0SChristoph Hellwig .pr_clear = sd_pr_clear,
19680af7b5e2SMike Christie .pr_read_keys = sd_pr_read_keys,
19690af7b5e2SMike Christie .pr_read_reservation = sd_pr_read_reservation,
1970924d55b0SChristoph Hellwig };
1971924d55b0SChristoph Hellwig
scsi_disk_free_disk(struct gendisk * disk)19729c63f7f6SChristoph Hellwig static void scsi_disk_free_disk(struct gendisk *disk)
19739c63f7f6SChristoph Hellwig {
19749c63f7f6SChristoph Hellwig struct scsi_disk *sdkp = scsi_disk(disk);
19759c63f7f6SChristoph Hellwig
19769c63f7f6SChristoph Hellwig put_device(&sdkp->disk_dev);
19779c63f7f6SChristoph Hellwig }
19789c63f7f6SChristoph Hellwig
197983d5cde4SAlexey Dobriyan static const struct block_device_operations sd_fops = {
19801da177e4SLinus Torvalds .owner = THIS_MODULE,
19810338e291SAl Viro .open = sd_open,
19820338e291SAl Viro .release = sd_release,
19838a6cfeb6SArnd Bergmann .ioctl = sd_ioctl,
1984a885c8c4SChristoph Hellwig .getgeo = sd_getgeo,
198544328310SChristoph Hellwig .compat_ioctl = blkdev_compat_ptr_ioctl,
19862bae0093STejun Heo .check_events = sd_check_events,
198772ec24bdSTejun Heo .unlock_native_capacity = sd_unlock_native_capacity,
1988e76239a3SChristoph Hellwig .report_zones = sd_zbc_report_zones,
1989b83ce214SChristoph Hellwig .get_unique_id = sd_get_unique_id,
19909c63f7f6SChristoph Hellwig .free_disk = scsi_disk_free_disk,
1991924d55b0SChristoph Hellwig .pr_ops = &sd_pr_ops,
19921da177e4SLinus Torvalds };
19931da177e4SLinus Torvalds
199418a4d0a2SMartin K. Petersen /**
19957a38dc0bSHannes Reinecke * sd_eh_reset - reset error handling callback
19967a38dc0bSHannes Reinecke * @scmd: sd-issued command that has failed
19977a38dc0bSHannes Reinecke *
19987a38dc0bSHannes Reinecke * This function is called by the SCSI midlayer before starting
19997a38dc0bSHannes Reinecke * SCSI EH. When counting medium access failures we have to be
20007a38dc0bSHannes Reinecke * careful to register it only only once per device and SCSI EH run;
20017a38dc0bSHannes Reinecke * there might be several timed out commands which will cause the
20027a38dc0bSHannes Reinecke * 'max_medium_access_timeouts' counter to trigger after the first
20037a38dc0bSHannes Reinecke * SCSI EH run already and set the device to offline.
20047a38dc0bSHannes Reinecke * So this function resets the internal counter before starting SCSI EH.
20057a38dc0bSHannes Reinecke **/
sd_eh_reset(struct scsi_cmnd * scmd)20067a38dc0bSHannes Reinecke static void sd_eh_reset(struct scsi_cmnd *scmd)
20077a38dc0bSHannes Reinecke {
2008f3fa33acSChristoph Hellwig struct scsi_disk *sdkp = scsi_disk(scsi_cmd_to_rq(scmd)->q->disk);
20097a38dc0bSHannes Reinecke
20107a38dc0bSHannes Reinecke /* New SCSI EH run, reset gate variable */
20117a38dc0bSHannes Reinecke sdkp->ignore_medium_access_errors = false;
20127a38dc0bSHannes Reinecke }
20137a38dc0bSHannes Reinecke
20147a38dc0bSHannes Reinecke /**
201518a4d0a2SMartin K. Petersen * sd_eh_action - error handling callback
201618a4d0a2SMartin K. Petersen * @scmd: sd-issued command that has failed
201718a4d0a2SMartin K. Petersen * @eh_disp: The recovery disposition suggested by the midlayer
201818a4d0a2SMartin K. Petersen *
20192451079bSJames Bottomley * This function is called by the SCSI midlayer upon completion of an
20202451079bSJames Bottomley * error test command (currently TEST UNIT READY). The result of sending
20212451079bSJames Bottomley * the eh command is passed in eh_disp. We're looking for devices that
20222451079bSJames Bottomley * fail medium access commands but are OK with non access commands like
20232451079bSJames Bottomley * test unit ready (so wrongly see the device as having a successful
20242451079bSJames Bottomley * recovery)
202518a4d0a2SMartin K. Petersen **/
sd_eh_action(struct scsi_cmnd * scmd,int eh_disp)20262451079bSJames Bottomley static int sd_eh_action(struct scsi_cmnd *scmd, int eh_disp)
202718a4d0a2SMartin K. Petersen {
2028f3fa33acSChristoph Hellwig struct scsi_disk *sdkp = scsi_disk(scsi_cmd_to_rq(scmd)->q->disk);
20290db6ca8aSBart Van Assche struct scsi_device *sdev = scmd->device;
203018a4d0a2SMartin K. Petersen
20310db6ca8aSBart Van Assche if (!scsi_device_online(sdev) ||
20322451079bSJames Bottomley !scsi_medium_access_command(scmd) ||
20332451079bSJames Bottomley host_byte(scmd->result) != DID_TIME_OUT ||
20342451079bSJames Bottomley eh_disp != SUCCESS)
203518a4d0a2SMartin K. Petersen return eh_disp;
203618a4d0a2SMartin K. Petersen
203718a4d0a2SMartin K. Petersen /*
203818a4d0a2SMartin K. Petersen * The device has timed out executing a medium access command.
203918a4d0a2SMartin K. Petersen * However, the TEST UNIT READY command sent during error
204018a4d0a2SMartin K. Petersen * handling completed successfully. Either the device is in the
204118a4d0a2SMartin K. Petersen * process of recovering or has it suffered an internal failure
204218a4d0a2SMartin K. Petersen * that prevents access to the storage medium.
204318a4d0a2SMartin K. Petersen */
20447a38dc0bSHannes Reinecke if (!sdkp->ignore_medium_access_errors) {
204518a4d0a2SMartin K. Petersen sdkp->medium_access_timed_out++;
20467a38dc0bSHannes Reinecke sdkp->ignore_medium_access_errors = true;
20477a38dc0bSHannes Reinecke }
204818a4d0a2SMartin K. Petersen
204918a4d0a2SMartin K. Petersen /*
205018a4d0a2SMartin K. Petersen * If the device keeps failing read/write commands but TEST UNIT
205118a4d0a2SMartin K. Petersen * READY always completes successfully we assume that medium
205218a4d0a2SMartin K. Petersen * access is no longer possible and take the device offline.
205318a4d0a2SMartin K. Petersen */
205418a4d0a2SMartin K. Petersen if (sdkp->medium_access_timed_out >= sdkp->max_medium_access_timeouts) {
205518a4d0a2SMartin K. Petersen scmd_printk(KERN_ERR, scmd,
205618a4d0a2SMartin K. Petersen "Medium access timeout failure. Offlining disk!\n");
20570db6ca8aSBart Van Assche mutex_lock(&sdev->state_mutex);
20580db6ca8aSBart Van Assche scsi_device_set_state(sdev, SDEV_OFFLINE);
20590db6ca8aSBart Van Assche mutex_unlock(&sdev->state_mutex);
206018a4d0a2SMartin K. Petersen
2061e8f8d50eSHannes Reinecke return SUCCESS;
206218a4d0a2SMartin K. Petersen }
206318a4d0a2SMartin K. Petersen
206418a4d0a2SMartin K. Petersen return eh_disp;
206518a4d0a2SMartin K. Petersen }
206618a4d0a2SMartin K. Petersen
sd_completed_bytes(struct scsi_cmnd * scmd)2067af55ff67SMartin K. Petersen static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd)
2068af55ff67SMartin K. Petersen {
20695999ccffSBart Van Assche struct request *req = scsi_cmd_to_rq(scmd);
20706eadc612SDamien Le Moal struct scsi_device *sdev = scmd->device;
20716eadc612SDamien Le Moal unsigned int transferred, good_bytes;
20726eadc612SDamien Le Moal u64 start_lba, end_lba, bad_lba;
20736eadc612SDamien Le Moal
20746eadc612SDamien Le Moal /*
20756eadc612SDamien Le Moal * Some commands have a payload smaller than the device logical
20766eadc612SDamien Le Moal * block size (e.g. INQUIRY on a 4K disk).
20776eadc612SDamien Le Moal */
20786eadc612SDamien Le Moal if (scsi_bufflen(scmd) <= sdev->sector_size)
20796eadc612SDamien Le Moal return 0;
20806eadc612SDamien Le Moal
20816eadc612SDamien Le Moal /* Check if we have a 'bad_lba' information */
20826eadc612SDamien Le Moal if (!scsi_get_sense_info_fld(scmd->sense_buffer,
20836eadc612SDamien Le Moal SCSI_SENSE_BUFFERSIZE,
20846eadc612SDamien Le Moal &bad_lba))
20856eadc612SDamien Le Moal return 0;
20866eadc612SDamien Le Moal
20876eadc612SDamien Le Moal /*
20886eadc612SDamien Le Moal * If the bad lba was reported incorrectly, we have no idea where
20896eadc612SDamien Le Moal * the error is.
20906eadc612SDamien Le Moal */
20916eadc612SDamien Le Moal start_lba = sectors_to_logical(sdev, blk_rq_pos(req));
20926eadc612SDamien Le Moal end_lba = start_lba + bytes_to_logical(sdev, scsi_bufflen(scmd));
20936eadc612SDamien Le Moal if (bad_lba < start_lba || bad_lba >= end_lba)
20946eadc612SDamien Le Moal return 0;
20956eadc612SDamien Le Moal
2096a8733c7bSJames Bottomley /*
2097a8733c7bSJames Bottomley * resid is optional but mostly filled in. When it's unused,
2098a8733c7bSJames Bottomley * its value is zero, so we assume the whole buffer transferred
2099a8733c7bSJames Bottomley */
21006eadc612SDamien Le Moal transferred = scsi_bufflen(scmd) - scsi_get_resid(scmd);
2101af55ff67SMartin K. Petersen
21026eadc612SDamien Le Moal /* This computation should always be done in terms of the
21036eadc612SDamien Le Moal * resolution of the device's medium.
2104af55ff67SMartin K. Petersen */
21056eadc612SDamien Le Moal good_bytes = logical_to_bytes(sdev, bad_lba - start_lba);
2106af55ff67SMartin K. Petersen
2107a8733c7bSJames Bottomley return min(good_bytes, transferred);
2108af55ff67SMartin K. Petersen }
2109af55ff67SMartin K. Petersen
21101da177e4SLinus Torvalds /**
21117b3d9545SLinus Torvalds * sd_done - bottom half handler: called when the lower level
21121da177e4SLinus Torvalds * driver has completed (successfully or otherwise) a scsi command.
21131da177e4SLinus Torvalds * @SCpnt: mid-level's per command structure.
21141da177e4SLinus Torvalds *
21151da177e4SLinus Torvalds * Note: potentially run from within an ISR. Must not block.
21161da177e4SLinus Torvalds **/
sd_done(struct scsi_cmnd * SCpnt)21177b3d9545SLinus Torvalds static int sd_done(struct scsi_cmnd *SCpnt)
21181da177e4SLinus Torvalds {
21191da177e4SLinus Torvalds int result = SCpnt->result;
2120af55ff67SMartin K. Petersen unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt);
2121c46f0917SDamien Le Moal unsigned int sector_size = SCpnt->device->sector_size;
2122c46f0917SDamien Le Moal unsigned int resid;
21231da177e4SLinus Torvalds struct scsi_sense_hdr sshdr;
21245999ccffSBart Van Assche struct request *req = scsi_cmd_to_rq(SCpnt);
2125f3fa33acSChristoph Hellwig struct scsi_disk *sdkp = scsi_disk(req->q->disk);
21261da177e4SLinus Torvalds int sense_valid = 0;
21271da177e4SLinus Torvalds int sense_deferred = 0;
21281da177e4SLinus Torvalds
212989d94756SHannes Reinecke switch (req_op(req)) {
213089d94756SHannes Reinecke case REQ_OP_DISCARD:
213102d26103SChristoph Hellwig case REQ_OP_WRITE_ZEROES:
213289d94756SHannes Reinecke case REQ_OP_ZONE_RESET:
2133d81e9d49SChaitanya Kulkarni case REQ_OP_ZONE_RESET_ALL:
2134ad512f20SAjay Joshi case REQ_OP_ZONE_OPEN:
2135ad512f20SAjay Joshi case REQ_OP_ZONE_CLOSE:
2136ad512f20SAjay Joshi case REQ_OP_ZONE_FINISH:
213726e85fcdSMartin K. Petersen if (!result) {
213826e85fcdSMartin K. Petersen good_bytes = blk_rq_bytes(req);
21396a32a8aeSFUJITA Tomonori scsi_set_resid(SCpnt, 0);
214026e85fcdSMartin K. Petersen } else {
214126e85fcdSMartin K. Petersen good_bytes = 0;
214226e85fcdSMartin K. Petersen scsi_set_resid(SCpnt, blk_rq_bytes(req));
214326e85fcdSMartin K. Petersen }
214489d94756SHannes Reinecke break;
2145c46f0917SDamien Le Moal default:
2146c46f0917SDamien Le Moal /*
2147c46f0917SDamien Le Moal * In case of bogus fw or device, we could end up having
2148c46f0917SDamien Le Moal * an unaligned partial completion. Check this here and force
2149c46f0917SDamien Le Moal * alignment.
2150c46f0917SDamien Le Moal */
2151c46f0917SDamien Le Moal resid = scsi_get_resid(SCpnt);
2152c46f0917SDamien Le Moal if (resid & (sector_size - 1)) {
2153c46f0917SDamien Le Moal sd_printk(KERN_INFO, sdkp,
2154c46f0917SDamien Le Moal "Unaligned partial completion (resid=%u, sector_sz=%u)\n",
2155c46f0917SDamien Le Moal resid, sector_size);
2156670d8be2SDamien Le Moal scsi_print_command(SCpnt);
2157c46f0917SDamien Le Moal resid = min(scsi_bufflen(SCpnt),
2158c46f0917SDamien Le Moal round_up(resid, sector_size));
2159c46f0917SDamien Le Moal scsi_set_resid(SCpnt, resid);
2160c46f0917SDamien Le Moal }
216126e85fcdSMartin K. Petersen }
21626a32a8aeSFUJITA Tomonori
21631da177e4SLinus Torvalds if (result) {
21641da177e4SLinus Torvalds sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr);
21651da177e4SLinus Torvalds if (sense_valid)
21661da177e4SLinus Torvalds sense_deferred = scsi_sense_is_deferred(&sshdr);
21671da177e4SLinus Torvalds }
21682a863ba8SDavid Jeffery sdkp->medium_access_timed_out = 0;
21692a863ba8SDavid Jeffery
2170464a00c9SHannes Reinecke if (!scsi_status_is_check_condition(result) &&
217103aba2f7SLuben Tuikov (!sense_valid || sense_deferred))
217203aba2f7SLuben Tuikov goto out;
217303aba2f7SLuben Tuikov
21741da177e4SLinus Torvalds switch (sshdr.sense_key) {
217503aba2f7SLuben Tuikov case HARDWARE_ERROR:
21761da177e4SLinus Torvalds case MEDIUM_ERROR:
2177af55ff67SMartin K. Petersen good_bytes = sd_completed_bytes(SCpnt);
21781da177e4SLinus Torvalds break;
217903aba2f7SLuben Tuikov case RECOVERED_ERROR:
2180af55ff67SMartin K. Petersen good_bytes = scsi_bufflen(SCpnt);
2181af55ff67SMartin K. Petersen break;
218210dab226SJamie Wellnitz case NO_SENSE:
218310dab226SJamie Wellnitz /* This indicates a false check condition, so ignore it. An
218410dab226SJamie Wellnitz * unknown amount of data was transferred so treat it as an
218510dab226SJamie Wellnitz * error.
218610dab226SJamie Wellnitz */
218710dab226SJamie Wellnitz SCpnt->result = 0;
218810dab226SJamie Wellnitz memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
218910dab226SJamie Wellnitz break;
2190c98a0eb0SMartin K. Petersen case ABORTED_COMMAND:
2191c98a0eb0SMartin K. Petersen if (sshdr.asc == 0x10) /* DIF: Target detected corruption */
2192af55ff67SMartin K. Petersen good_bytes = sd_completed_bytes(SCpnt);
21931da177e4SLinus Torvalds break;
2194c98a0eb0SMartin K. Petersen case ILLEGAL_REQUEST:
2195d227ec26SChristoph Hellwig switch (sshdr.asc) {
2196d227ec26SChristoph Hellwig case 0x10: /* DIX: Host detected corruption */
2197c98a0eb0SMartin K. Petersen good_bytes = sd_completed_bytes(SCpnt);
2198d227ec26SChristoph Hellwig break;
2199d227ec26SChristoph Hellwig case 0x20: /* INVALID COMMAND OPCODE */
2200d227ec26SChristoph Hellwig case 0x24: /* INVALID FIELD IN CDB */
2201d227ec26SChristoph Hellwig switch (SCpnt->cmnd[0]) {
22025db44863SMartin K. Petersen case UNMAP:
2203c98a0eb0SMartin K. Petersen sd_config_discard(sdkp, SD_LBP_DISABLE);
2204c98a0eb0SMartin K. Petersen break;
22055db44863SMartin K. Petersen case WRITE_SAME_16:
22065db44863SMartin K. Petersen case WRITE_SAME:
2207d227ec26SChristoph Hellwig if (SCpnt->cmnd[1] & 8) { /* UNMAP */
22085db44863SMartin K. Petersen sd_config_discard(sdkp, SD_LBP_DISABLE);
2209d227ec26SChristoph Hellwig } else {
22105db44863SMartin K. Petersen sdkp->device->no_write_same = 1;
22115db44863SMartin K. Petersen sd_config_write_same(sdkp);
2212e8064021SChristoph Hellwig req->rq_flags |= RQF_QUIET;
22135db44863SMartin K. Petersen }
2214d227ec26SChristoph Hellwig break;
22155db44863SMartin K. Petersen }
22165db44863SMartin K. Petersen }
22175db44863SMartin K. Petersen break;
22181da177e4SLinus Torvalds default:
22191da177e4SLinus Torvalds break;
22201da177e4SLinus Torvalds }
222189d94756SHannes Reinecke
222203aba2f7SLuben Tuikov out:
222389d94756SHannes Reinecke if (sd_is_zoned(sdkp))
22245795eb44SJohannes Thumshirn good_bytes = sd_zbc_complete(SCpnt, good_bytes, &sshdr);
222589d94756SHannes Reinecke
2226ef61329dSHannes Reinecke SCSI_LOG_HLCOMPLETE(1, scmd_printk(KERN_INFO, SCpnt,
2227ef61329dSHannes Reinecke "sd_done: completed %d of %d bytes\n",
2228ef61329dSHannes Reinecke good_bytes, scsi_bufflen(SCpnt)));
2229ef61329dSHannes Reinecke
22307b3d9545SLinus Torvalds return good_bytes;
22311da177e4SLinus Torvalds }
22321da177e4SLinus Torvalds
22331da177e4SLinus Torvalds /*
22341da177e4SLinus Torvalds * spinup disk - called only in sd_revalidate_disk()
22351da177e4SLinus Torvalds */
22361da177e4SLinus Torvalds static void
sd_spinup_disk(struct scsi_disk * sdkp)2237e73aec82SMartin K. Petersen sd_spinup_disk(struct scsi_disk *sdkp)
2238ea73a9f2SJames Bottomley {
22391da177e4SLinus Torvalds unsigned char cmd[10];
22404451e472SAlan Stern unsigned long spintime_expire = 0;
22411da177e4SLinus Torvalds int retries, spintime;
22421da177e4SLinus Torvalds unsigned int the_result;
22431da177e4SLinus Torvalds struct scsi_sense_hdr sshdr;
2244af16cd63SMike Christie const struct scsi_exec_args exec_args = {
2245af16cd63SMike Christie .sshdr = &sshdr,
2246af16cd63SMike Christie };
22471da177e4SLinus Torvalds int sense_valid = 0;
22481da177e4SLinus Torvalds
22491da177e4SLinus Torvalds spintime = 0;
22501da177e4SLinus Torvalds
22511da177e4SLinus Torvalds /* Spin up drives, as required. Only do this at boot time */
22521da177e4SLinus Torvalds /* Spinup needs to be done for module loads too. */
22531da177e4SLinus Torvalds do {
22541da177e4SLinus Torvalds retries = 0;
22551da177e4SLinus Torvalds
22561da177e4SLinus Torvalds do {
22574521428cSHeiner Kallweit bool media_was_present = sdkp->media_present;
22584521428cSHeiner Kallweit
22591da177e4SLinus Torvalds cmd[0] = TEST_UNIT_READY;
22601da177e4SLinus Torvalds memset((void *) &cmd[1], 0, 9);
22611da177e4SLinus Torvalds
2262af16cd63SMike Christie the_result = scsi_execute_cmd(sdkp->device, cmd,
2263af16cd63SMike Christie REQ_OP_DRV_IN, NULL, 0,
2264af16cd63SMike Christie SD_TIMEOUT,
2265af16cd63SMike Christie sdkp->max_retries,
2266af16cd63SMike Christie &exec_args);
22671da177e4SLinus Torvalds
2268b4d38e38SAlan Stern /*
2269b4d38e38SAlan Stern * If the drive has indicated to us that it
2270b4d38e38SAlan Stern * doesn't have any media in it, don't bother
2271b4d38e38SAlan Stern * with any more polling.
2272b4d38e38SAlan Stern */
2273848ade90SChristian Loehle if (media_not_present(sdkp, &sshdr)) {
22744521428cSHeiner Kallweit if (media_was_present)
2275848ade90SChristian Loehle sd_printk(KERN_NOTICE, sdkp, "Media removed, stopped polling\n");
2276b4d38e38SAlan Stern return;
2277848ade90SChristian Loehle }
2278b4d38e38SAlan Stern
22791da177e4SLinus Torvalds if (the_result)
2280ea73a9f2SJames Bottomley sense_valid = scsi_sense_valid(&sshdr);
22811da177e4SLinus Torvalds retries++;
22821da177e4SLinus Torvalds } while (retries < 3 &&
22831da177e4SLinus Torvalds (!scsi_status_is_good(the_result) ||
2284464a00c9SHannes Reinecke (scsi_status_is_check_condition(the_result) &&
22851da177e4SLinus Torvalds sense_valid && sshdr.sense_key == UNIT_ATTENTION)));
22861da177e4SLinus Torvalds
2287464a00c9SHannes Reinecke if (!scsi_status_is_check_condition(the_result)) {
22881da177e4SLinus Torvalds /* no sense, TUR either succeeded or failed
22891da177e4SLinus Torvalds * with a status error */
2290e73aec82SMartin K. Petersen if(!spintime && !scsi_status_is_good(the_result)) {
2291ef61329dSHannes Reinecke sd_print_result(sdkp, "Test Unit Ready failed",
2292ef61329dSHannes Reinecke the_result);
2293e73aec82SMartin K. Petersen }
22941da177e4SLinus Torvalds break;
22951da177e4SLinus Torvalds }
22961da177e4SLinus Torvalds
22971da177e4SLinus Torvalds /*
22981da177e4SLinus Torvalds * The device does not want the automatic start to be issued.
22991da177e4SLinus Torvalds */
230033dd6f92SMatthew Wilcox if (sdkp->device->no_start_on_add)
23011da177e4SLinus Torvalds break;
23021da177e4SLinus Torvalds
230333dd6f92SMatthew Wilcox if (sense_valid && sshdr.sense_key == NOT_READY) {
230433dd6f92SMatthew Wilcox if (sshdr.asc == 4 && sshdr.ascq == 3)
23051da177e4SLinus Torvalds break; /* manual intervention required */
230633dd6f92SMatthew Wilcox if (sshdr.asc == 4 && sshdr.ascq == 0xb)
230733dd6f92SMatthew Wilcox break; /* standby */
230833dd6f92SMatthew Wilcox if (sshdr.asc == 4 && sshdr.ascq == 0xc)
230933dd6f92SMatthew Wilcox break; /* unavailable */
2310505aa4b6SMahesh Rajashekhara if (sshdr.asc == 4 && sshdr.ascq == 0x1b)
2311505aa4b6SMahesh Rajashekhara break; /* sanitize in progress */
2312*7f818ac0SDouglas Gilbert if (sshdr.asc == 4 && sshdr.ascq == 0x24)
2313*7f818ac0SDouglas Gilbert break; /* depopulation in progress */
2314*7f818ac0SDouglas Gilbert if (sshdr.asc == 4 && sshdr.ascq == 0x25)
2315*7f818ac0SDouglas Gilbert break; /* depopulation restoration in progress */
23161da177e4SLinus Torvalds /*
23171da177e4SLinus Torvalds * Issue command to spin up drive when not ready
23181da177e4SLinus Torvalds */
23191da177e4SLinus Torvalds if (!spintime) {
2320e73aec82SMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, "Spinning up disk...");
23211da177e4SLinus Torvalds cmd[0] = START_STOP;
23221da177e4SLinus Torvalds cmd[1] = 1; /* Return immediately */
23231da177e4SLinus Torvalds memset((void *) &cmd[2], 0, 8);
23241da177e4SLinus Torvalds cmd[4] = 1; /* Start spin cycle */
2325d2886ea3SStefan Richter if (sdkp->device->start_stop_pwr_cond)
2326d2886ea3SStefan Richter cmd[4] |= 1 << 4;
2327af16cd63SMike Christie scsi_execute_cmd(sdkp->device, cmd,
2328af16cd63SMike Christie REQ_OP_DRV_IN, NULL, 0,
23290610959fSMike Christie SD_TIMEOUT, sdkp->max_retries,
2330af16cd63SMike Christie &exec_args);
23314451e472SAlan Stern spintime_expire = jiffies + 100 * HZ;
23321da177e4SLinus Torvalds spintime = 1;
23334451e472SAlan Stern }
23341da177e4SLinus Torvalds /* Wait 1 second for next try */
23351da177e4SLinus Torvalds msleep(1000);
23363a1d0783SMichał Mirosław printk(KERN_CONT ".");
23374451e472SAlan Stern
23384451e472SAlan Stern /*
23394451e472SAlan Stern * Wait for USB flash devices with slow firmware.
23404451e472SAlan Stern * Yes, this sense key/ASC combination shouldn't
23414451e472SAlan Stern * occur here. It's characteristic of these devices.
23424451e472SAlan Stern */
23434451e472SAlan Stern } else if (sense_valid &&
23444451e472SAlan Stern sshdr.sense_key == UNIT_ATTENTION &&
23454451e472SAlan Stern sshdr.asc == 0x28) {
23464451e472SAlan Stern if (!spintime) {
23474451e472SAlan Stern spintime_expire = jiffies + 5 * HZ;
23484451e472SAlan Stern spintime = 1;
23494451e472SAlan Stern }
23504451e472SAlan Stern /* Wait 1 second for next try */
23514451e472SAlan Stern msleep(1000);
23521da177e4SLinus Torvalds } else {
23531da177e4SLinus Torvalds /* we don't understand the sense code, so it's
23541da177e4SLinus Torvalds * probably pointless to loop */
23551da177e4SLinus Torvalds if(!spintime) {
2356e73aec82SMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, "Unit Not Ready\n");
2357e73aec82SMartin K. Petersen sd_print_sense_hdr(sdkp, &sshdr);
23581da177e4SLinus Torvalds }
23591da177e4SLinus Torvalds break;
23601da177e4SLinus Torvalds }
23611da177e4SLinus Torvalds
23624451e472SAlan Stern } while (spintime && time_before_eq(jiffies, spintime_expire));
23631da177e4SLinus Torvalds
23641da177e4SLinus Torvalds if (spintime) {
23651da177e4SLinus Torvalds if (scsi_status_is_good(the_result))
23663a1d0783SMichał Mirosław printk(KERN_CONT "ready\n");
23671da177e4SLinus Torvalds else
23683a1d0783SMichał Mirosław printk(KERN_CONT "not responding...\n");
23691da177e4SLinus Torvalds }
23701da177e4SLinus Torvalds }
23711da177e4SLinus Torvalds
2372e0597d70SMartin K. Petersen /*
2373e0597d70SMartin K. Petersen * Determine whether disk supports Data Integrity Field.
2374e0597d70SMartin K. Petersen */
sd_read_protection_type(struct scsi_disk * sdkp,unsigned char * buffer)2375fe542396SMartin K. Petersen static int sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer)
2376e0597d70SMartin K. Petersen {
2377e0597d70SMartin K. Petersen struct scsi_device *sdp = sdkp->device;
2378e0597d70SMartin K. Petersen u8 type;
2379e0597d70SMartin K. Petersen
2380465f4edaSXiang Chen if (scsi_device_protection(sdp) == 0 || (buffer[12] & 1) == 0) {
2381465f4edaSXiang Chen sdkp->protection_type = 0;
23821e029397SMartin K. Petersen return 0;
2383465f4edaSXiang Chen }
238435e1a5d9SMartin K. Petersen
2385e0597d70SMartin K. Petersen type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */
2386e0597d70SMartin K. Petersen
23871e029397SMartin K. Petersen if (type > T10_PI_TYPE3_PROTECTION) {
2388fe542396SMartin K. Petersen sd_printk(KERN_ERR, sdkp, "formatted with unsupported" \
2389fe542396SMartin K. Petersen " protection type %u. Disabling disk!\n",
2390fe542396SMartin K. Petersen type);
23911e029397SMartin K. Petersen sdkp->protection_type = 0;
23921e029397SMartin K. Petersen return -ENODEV;
2393fe542396SMartin K. Petersen }
239435e1a5d9SMartin K. Petersen
2395be922f47SMartin K. Petersen sdkp->protection_type = type;
2396be922f47SMartin K. Petersen
23971e029397SMartin K. Petersen return 0;
23981e029397SMartin K. Petersen }
23991e029397SMartin K. Petersen
sd_config_protection(struct scsi_disk * sdkp)24001e029397SMartin K. Petersen static void sd_config_protection(struct scsi_disk *sdkp)
24011e029397SMartin K. Petersen {
24021e029397SMartin K. Petersen struct scsi_device *sdp = sdkp->device;
24031e029397SMartin K. Petersen
24041e029397SMartin K. Petersen sd_dif_config_host(sdkp);
24051e029397SMartin K. Petersen
24061e029397SMartin K. Petersen if (!sdkp->protection_type)
24071e029397SMartin K. Petersen return;
24081e029397SMartin K. Petersen
24091e029397SMartin K. Petersen if (!scsi_host_dif_capable(sdp->host, sdkp->protection_type)) {
241026a02d97SXingui Yang sd_first_printk(KERN_NOTICE, sdkp,
24111e029397SMartin K. Petersen "Disabling DIF Type %u protection\n",
24121e029397SMartin K. Petersen sdkp->protection_type);
24131e029397SMartin K. Petersen sdkp->protection_type = 0;
24141e029397SMartin K. Petersen }
24151e029397SMartin K. Petersen
241626a02d97SXingui Yang sd_first_printk(KERN_NOTICE, sdkp, "Enabling DIF Type %u protection\n",
24171e029397SMartin K. Petersen sdkp->protection_type);
2418e0597d70SMartin K. Petersen }
2419e0597d70SMartin K. Petersen
read_capacity_error(struct scsi_disk * sdkp,struct scsi_device * sdp,struct scsi_sense_hdr * sshdr,int sense_valid,int the_result)24200da205e0SMatthew Wilcox static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp,
24210da205e0SMatthew Wilcox struct scsi_sense_hdr *sshdr, int sense_valid,
24220da205e0SMatthew Wilcox int the_result)
2423ea73a9f2SJames Bottomley {
2424464a00c9SHannes Reinecke if (sense_valid)
24250da205e0SMatthew Wilcox sd_print_sense_hdr(sdkp, sshdr);
24260da205e0SMatthew Wilcox else
24270da205e0SMatthew Wilcox sd_printk(KERN_NOTICE, sdkp, "Sense not available.\n");
24281da177e4SLinus Torvalds
24290da205e0SMatthew Wilcox /*
24300da205e0SMatthew Wilcox * Set dirty bit for removable devices if not ready -
24310da205e0SMatthew Wilcox * sometimes drives will not report this properly.
24320da205e0SMatthew Wilcox */
24330da205e0SMatthew Wilcox if (sdp->removable &&
24340da205e0SMatthew Wilcox sense_valid && sshdr->sense_key == NOT_READY)
24352bae0093STejun Heo set_media_not_present(sdkp);
24360da205e0SMatthew Wilcox
24370da205e0SMatthew Wilcox /*
24380da205e0SMatthew Wilcox * We used to set media_present to 0 here to indicate no media
24390da205e0SMatthew Wilcox * in the drive, but some drives fail read capacity even with
24400da205e0SMatthew Wilcox * media present, so we can't do that.
24410da205e0SMatthew Wilcox */
24420da205e0SMatthew Wilcox sdkp->capacity = 0; /* unknown mapped to zero - as usual */
24431da177e4SLinus Torvalds }
24441da177e4SLinus Torvalds
24450da205e0SMatthew Wilcox #define RC16_LEN 32
24460da205e0SMatthew Wilcox #if RC16_LEN > SD_BUF_SIZE
24470da205e0SMatthew Wilcox #error RC16_LEN must not be more than SD_BUF_SIZE
24480da205e0SMatthew Wilcox #endif
24490da205e0SMatthew Wilcox
24503233ac19SJames Bottomley #define READ_CAPACITY_RETRIES_ON_RESET 10
24513233ac19SJames Bottomley
read_capacity_16(struct scsi_disk * sdkp,struct scsi_device * sdp,unsigned char * buffer)24520da205e0SMatthew Wilcox static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
24530da205e0SMatthew Wilcox unsigned char *buffer)
24540da205e0SMatthew Wilcox {
24550da205e0SMatthew Wilcox unsigned char cmd[16];
24560da205e0SMatthew Wilcox struct scsi_sense_hdr sshdr;
2457af16cd63SMike Christie const struct scsi_exec_args exec_args = {
2458af16cd63SMike Christie .sshdr = &sshdr,
2459af16cd63SMike Christie };
24600da205e0SMatthew Wilcox int sense_valid = 0;
24610da205e0SMatthew Wilcox int the_result;
24623233ac19SJames Bottomley int retries = 3, reset_retries = READ_CAPACITY_RETRIES_ON_RESET;
2463ea09bcc9SMartin K. Petersen unsigned int alignment;
24640da205e0SMatthew Wilcox unsigned long long lba;
24650da205e0SMatthew Wilcox unsigned sector_size;
24660da205e0SMatthew Wilcox
24675ce524bdSHans de Goede if (sdp->no_read_capacity_16)
24685ce524bdSHans de Goede return -EINVAL;
24695ce524bdSHans de Goede
24700da205e0SMatthew Wilcox do {
24710da205e0SMatthew Wilcox memset(cmd, 0, 16);
2472eb846d9fSHannes Reinecke cmd[0] = SERVICE_ACTION_IN_16;
24730da205e0SMatthew Wilcox cmd[1] = SAI_READ_CAPACITY_16;
24740da205e0SMatthew Wilcox cmd[13] = RC16_LEN;
24750da205e0SMatthew Wilcox memset(buffer, 0, RC16_LEN);
24760da205e0SMatthew Wilcox
2477af16cd63SMike Christie the_result = scsi_execute_cmd(sdp, cmd, REQ_OP_DRV_IN,
2478af16cd63SMike Christie buffer, RC16_LEN, SD_TIMEOUT,
2479af16cd63SMike Christie sdkp->max_retries, &exec_args);
24801da177e4SLinus Torvalds
2481ea73a9f2SJames Bottomley if (media_not_present(sdkp, &sshdr))
24820da205e0SMatthew Wilcox return -ENODEV;
24831da177e4SLinus Torvalds
2484ced202f7SHannes Reinecke if (the_result > 0) {
2485ea73a9f2SJames Bottomley sense_valid = scsi_sense_valid(&sshdr);
24862b301307SMatthew Wilcox if (sense_valid &&
24872b301307SMatthew Wilcox sshdr.sense_key == ILLEGAL_REQUEST &&
24882b301307SMatthew Wilcox (sshdr.asc == 0x20 || sshdr.asc == 0x24) &&
24892b301307SMatthew Wilcox sshdr.ascq == 0x00)
24902b301307SMatthew Wilcox /* Invalid Command Operation Code or
24912b301307SMatthew Wilcox * Invalid Field in CDB, just retry
24922b301307SMatthew Wilcox * silently with RC10 */
24932b301307SMatthew Wilcox return -EINVAL;
24943233ac19SJames Bottomley if (sense_valid &&
24953233ac19SJames Bottomley sshdr.sense_key == UNIT_ATTENTION &&
24963233ac19SJames Bottomley sshdr.asc == 0x29 && sshdr.ascq == 0x00)
24973233ac19SJames Bottomley /* Device reset might occur several times,
24983233ac19SJames Bottomley * give it one more chance */
24993233ac19SJames Bottomley if (--reset_retries > 0)
25003233ac19SJames Bottomley continue;
25012b301307SMatthew Wilcox }
25021da177e4SLinus Torvalds retries--;
25031da177e4SLinus Torvalds
25041da177e4SLinus Torvalds } while (the_result && retries);
25051da177e4SLinus Torvalds
25060da205e0SMatthew Wilcox if (the_result) {
2507ef61329dSHannes Reinecke sd_print_result(sdkp, "Read Capacity(16) failed", the_result);
25080da205e0SMatthew Wilcox read_capacity_error(sdkp, sdp, &sshdr, sense_valid, the_result);
25090da205e0SMatthew Wilcox return -EINVAL;
25101da177e4SLinus Torvalds }
25111da177e4SLinus Torvalds
25128f76d151SDave Hansen sector_size = get_unaligned_be32(&buffer[8]);
25138f76d151SDave Hansen lba = get_unaligned_be64(&buffer[0]);
2514e0597d70SMartin K. Petersen
2515fe542396SMartin K. Petersen if (sd_read_protection_type(sdkp, buffer) < 0) {
2516fe542396SMartin K. Petersen sdkp->capacity = 0;
2517fe542396SMartin K. Petersen return -ENODEV;
2518fe542396SMartin K. Petersen }
25190da205e0SMatthew Wilcox
2520ea09bcc9SMartin K. Petersen /* Logical blocks per physical block exponent */
2521526f7c79SMartin K. Petersen sdkp->physical_block_size = (1 << (buffer[13] & 0xf)) * sector_size;
2522ea09bcc9SMartin K. Petersen
252389d94756SHannes Reinecke /* RC basis */
252489d94756SHannes Reinecke sdkp->rc_basis = (buffer[12] >> 4) & 0x3;
252589d94756SHannes Reinecke
2526ea09bcc9SMartin K. Petersen /* Lowest aligned logical block */
2527ea09bcc9SMartin K. Petersen alignment = ((buffer[14] & 0x3f) << 8 | buffer[15]) * sector_size;
2528ea09bcc9SMartin K. Petersen blk_queue_alignment_offset(sdp->request_queue, alignment);
2529ea09bcc9SMartin K. Petersen if (alignment && sdkp->first_scan)
2530ea09bcc9SMartin K. Petersen sd_printk(KERN_NOTICE, sdkp,
2531ea09bcc9SMartin K. Petersen "physical block alignment offset: %u\n", alignment);
2532ea09bcc9SMartin K. Petersen
2533c98a0eb0SMartin K. Petersen if (buffer[14] & 0x80) { /* LBPME */
2534c98a0eb0SMartin K. Petersen sdkp->lbpme = 1;
2535e339c1a7SMartin K. Petersen
2536c98a0eb0SMartin K. Petersen if (buffer[14] & 0x40) /* LBPRZ */
2537c98a0eb0SMartin K. Petersen sdkp->lbprz = 1;
2538e339c1a7SMartin K. Petersen
2539c98a0eb0SMartin K. Petersen sd_config_discard(sdkp, SD_LBP_WS16);
2540e339c1a7SMartin K. Petersen }
2541e339c1a7SMartin K. Petersen
25420da205e0SMatthew Wilcox sdkp->capacity = lba + 1;
25430da205e0SMatthew Wilcox return sector_size;
25440da205e0SMatthew Wilcox }
25450da205e0SMatthew Wilcox
read_capacity_10(struct scsi_disk * sdkp,struct scsi_device * sdp,unsigned char * buffer)25460da205e0SMatthew Wilcox static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
25470da205e0SMatthew Wilcox unsigned char *buffer)
25480da205e0SMatthew Wilcox {
25490da205e0SMatthew Wilcox unsigned char cmd[16];
25500da205e0SMatthew Wilcox struct scsi_sense_hdr sshdr;
2551af16cd63SMike Christie const struct scsi_exec_args exec_args = {
2552af16cd63SMike Christie .sshdr = &sshdr,
2553af16cd63SMike Christie };
25540da205e0SMatthew Wilcox int sense_valid = 0;
25550da205e0SMatthew Wilcox int the_result;
25563233ac19SJames Bottomley int retries = 3, reset_retries = READ_CAPACITY_RETRIES_ON_RESET;
25570da205e0SMatthew Wilcox sector_t lba;
25580da205e0SMatthew Wilcox unsigned sector_size;
25590da205e0SMatthew Wilcox
25600da205e0SMatthew Wilcox do {
25610da205e0SMatthew Wilcox cmd[0] = READ_CAPACITY;
25620da205e0SMatthew Wilcox memset(&cmd[1], 0, 9);
25630da205e0SMatthew Wilcox memset(buffer, 0, 8);
25640da205e0SMatthew Wilcox
2565af16cd63SMike Christie the_result = scsi_execute_cmd(sdp, cmd, REQ_OP_DRV_IN, buffer,
2566af16cd63SMike Christie 8, SD_TIMEOUT, sdkp->max_retries,
2567af16cd63SMike Christie &exec_args);
25680da205e0SMatthew Wilcox
25690da205e0SMatthew Wilcox if (media_not_present(sdkp, &sshdr))
25700da205e0SMatthew Wilcox return -ENODEV;
25710da205e0SMatthew Wilcox
2572ced202f7SHannes Reinecke if (the_result > 0) {
25730da205e0SMatthew Wilcox sense_valid = scsi_sense_valid(&sshdr);
25743233ac19SJames Bottomley if (sense_valid &&
25753233ac19SJames Bottomley sshdr.sense_key == UNIT_ATTENTION &&
25763233ac19SJames Bottomley sshdr.asc == 0x29 && sshdr.ascq == 0x00)
25773233ac19SJames Bottomley /* Device reset might occur several times,
25783233ac19SJames Bottomley * give it one more chance */
25793233ac19SJames Bottomley if (--reset_retries > 0)
25803233ac19SJames Bottomley continue;
25813233ac19SJames Bottomley }
25820da205e0SMatthew Wilcox retries--;
25830da205e0SMatthew Wilcox
25840da205e0SMatthew Wilcox } while (the_result && retries);
25850da205e0SMatthew Wilcox
25860da205e0SMatthew Wilcox if (the_result) {
2587ef61329dSHannes Reinecke sd_print_result(sdkp, "Read Capacity(10) failed", the_result);
25880da205e0SMatthew Wilcox read_capacity_error(sdkp, sdp, &sshdr, sense_valid, the_result);
25890da205e0SMatthew Wilcox return -EINVAL;
25900da205e0SMatthew Wilcox }
25910da205e0SMatthew Wilcox
25928f76d151SDave Hansen sector_size = get_unaligned_be32(&buffer[4]);
25938f76d151SDave Hansen lba = get_unaligned_be32(&buffer[0]);
25940da205e0SMatthew Wilcox
25955ce524bdSHans de Goede if (sdp->no_read_capacity_16 && (lba == 0xffffffff)) {
25965ce524bdSHans de Goede /* Some buggy (usb cardreader) devices return an lba of
25975ce524bdSHans de Goede 0xffffffff when the want to report a size of 0 (with
25985ce524bdSHans de Goede which they really mean no media is present) */
25995ce524bdSHans de Goede sdkp->capacity = 0;
26005cc10350SLinus Torvalds sdkp->physical_block_size = sector_size;
26015ce524bdSHans de Goede return sector_size;
26025ce524bdSHans de Goede }
26035ce524bdSHans de Goede
26040da205e0SMatthew Wilcox sdkp->capacity = lba + 1;
2605526f7c79SMartin K. Petersen sdkp->physical_block_size = sector_size;
26060da205e0SMatthew Wilcox return sector_size;
26070da205e0SMatthew Wilcox }
26080da205e0SMatthew Wilcox
sd_try_rc16_first(struct scsi_device * sdp)26092b301307SMatthew Wilcox static int sd_try_rc16_first(struct scsi_device *sdp)
26102b301307SMatthew Wilcox {
2611f87146bbSHannes Reinecke if (sdp->host->max_cmd_len < 16)
2612f87146bbSHannes Reinecke return 0;
26136a0bdffaSAlan Stern if (sdp->try_rc_10_first)
26146a0bdffaSAlan Stern return 0;
26152b301307SMatthew Wilcox if (sdp->scsi_level > SCSI_SPC_2)
26162b301307SMatthew Wilcox return 1;
26172b301307SMatthew Wilcox if (scsi_device_protection(sdp))
26182b301307SMatthew Wilcox return 1;
26192b301307SMatthew Wilcox return 0;
26202b301307SMatthew Wilcox }
26212b301307SMatthew Wilcox
26220da205e0SMatthew Wilcox /*
26230da205e0SMatthew Wilcox * read disk capacity
26240da205e0SMatthew Wilcox */
26250da205e0SMatthew Wilcox static void
sd_read_capacity(struct scsi_disk * sdkp,unsigned char * buffer)26260da205e0SMatthew Wilcox sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer)
26270da205e0SMatthew Wilcox {
26280da205e0SMatthew Wilcox int sector_size;
26290da205e0SMatthew Wilcox struct scsi_device *sdp = sdkp->device;
26300da205e0SMatthew Wilcox
26312b301307SMatthew Wilcox if (sd_try_rc16_first(sdp)) {
26320da205e0SMatthew Wilcox sector_size = read_capacity_16(sdkp, sdp, buffer);
26330da205e0SMatthew Wilcox if (sector_size == -EOVERFLOW)
26340da205e0SMatthew Wilcox goto got_data;
26352b301307SMatthew Wilcox if (sector_size == -ENODEV)
26362b301307SMatthew Wilcox return;
26372b301307SMatthew Wilcox if (sector_size < 0)
26382b301307SMatthew Wilcox sector_size = read_capacity_10(sdkp, sdp, buffer);
26390da205e0SMatthew Wilcox if (sector_size < 0)
26400da205e0SMatthew Wilcox return;
26410da205e0SMatthew Wilcox } else {
26420da205e0SMatthew Wilcox sector_size = read_capacity_10(sdkp, sdp, buffer);
26430da205e0SMatthew Wilcox if (sector_size == -EOVERFLOW)
26440da205e0SMatthew Wilcox goto got_data;
26450da205e0SMatthew Wilcox if (sector_size < 0)
26460da205e0SMatthew Wilcox return;
26470da205e0SMatthew Wilcox if ((sizeof(sdkp->capacity) > 4) &&
26480da205e0SMatthew Wilcox (sdkp->capacity > 0xffffffffULL)) {
26490da205e0SMatthew Wilcox int old_sector_size = sector_size;
26500da205e0SMatthew Wilcox sd_printk(KERN_NOTICE, sdkp, "Very big device. "
26510da205e0SMatthew Wilcox "Trying to use READ CAPACITY(16).\n");
26520da205e0SMatthew Wilcox sector_size = read_capacity_16(sdkp, sdp, buffer);
26530da205e0SMatthew Wilcox if (sector_size < 0) {
26540da205e0SMatthew Wilcox sd_printk(KERN_NOTICE, sdkp,
26550da205e0SMatthew Wilcox "Using 0xffffffff as device size\n");
26560da205e0SMatthew Wilcox sdkp->capacity = 1 + (sector_t) 0xffffffff;
26570da205e0SMatthew Wilcox sector_size = old_sector_size;
26580da205e0SMatthew Wilcox goto got_data;
26590da205e0SMatthew Wilcox }
2660597d7400SMartin K. Petersen /* Remember that READ CAPACITY(16) succeeded */
2661597d7400SMartin K. Petersen sdp->try_rc_10_first = 0;
26620da205e0SMatthew Wilcox }
26631da177e4SLinus Torvalds }
26641da177e4SLinus Torvalds
26655c211caaSAlan Stern /* Some devices are known to return the total number of blocks,
26665c211caaSAlan Stern * not the highest block number. Some devices have versions
26675c211caaSAlan Stern * which do this and others which do not. Some devices we might
26685c211caaSAlan Stern * suspect of doing this but we don't know for certain.
26695c211caaSAlan Stern *
26705c211caaSAlan Stern * If we know the reported capacity is wrong, decrement it. If
26715c211caaSAlan Stern * we can only guess, then assume the number of blocks is even
26725c211caaSAlan Stern * (usually true but not always) and err on the side of lowering
26735c211caaSAlan Stern * the capacity.
26745c211caaSAlan Stern */
26755c211caaSAlan Stern if (sdp->fix_capacity ||
26765c211caaSAlan Stern (sdp->guess_capacity && (sdkp->capacity & 0x01))) {
26775c211caaSAlan Stern sd_printk(KERN_INFO, sdkp, "Adjusting the sector count "
26785c211caaSAlan Stern "from its reported value: %llu\n",
26795c211caaSAlan Stern (unsigned long long) sdkp->capacity);
268061bf54b7SOliver Neukum --sdkp->capacity;
268161bf54b7SOliver Neukum }
268261bf54b7SOliver Neukum
26831da177e4SLinus Torvalds got_data:
26841da177e4SLinus Torvalds if (sector_size == 0) {
26851da177e4SLinus Torvalds sector_size = 512;
2686e73aec82SMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, "Sector size 0 reported, "
2687e73aec82SMartin K. Petersen "assuming 512.\n");
26881da177e4SLinus Torvalds }
26891da177e4SLinus Torvalds
26901da177e4SLinus Torvalds if (sector_size != 512 &&
26911da177e4SLinus Torvalds sector_size != 1024 &&
26921da177e4SLinus Torvalds sector_size != 2048 &&
269374856fbfSMark Hounschell sector_size != 4096) {
2694e73aec82SMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, "Unsupported sector size %d.\n",
2695e73aec82SMartin K. Petersen sector_size);
26961da177e4SLinus Torvalds /*
26971da177e4SLinus Torvalds * The user might want to re-format the drive with
26981da177e4SLinus Torvalds * a supported sectorsize. Once this happens, it
26991da177e4SLinus Torvalds * would be relatively trivial to set the thing up.
27001da177e4SLinus Torvalds * For this reason, we leave the thing in the table.
27011da177e4SLinus Torvalds */
27021da177e4SLinus Torvalds sdkp->capacity = 0;
27031da177e4SLinus Torvalds /*
27041da177e4SLinus Torvalds * set a bogus sector size so the normal read/write
27051da177e4SLinus Torvalds * logic in the block layer will eventually refuse any
27061da177e4SLinus Torvalds * request on this device without tripping over power
27071da177e4SLinus Torvalds * of two sector size assumptions
27081da177e4SLinus Torvalds */
27091da177e4SLinus Torvalds sector_size = 512;
27101da177e4SLinus Torvalds }
2711e1defc4fSMartin K. Petersen blk_queue_logical_block_size(sdp->request_queue, sector_size);
271289d94756SHannes Reinecke blk_queue_physical_block_size(sdp->request_queue,
271389d94756SHannes Reinecke sdkp->physical_block_size);
271489d94756SHannes Reinecke sdkp->device->sector_size = sector_size;
27151da177e4SLinus Torvalds
271689d94756SHannes Reinecke if (sdkp->capacity > 0xffffffff)
271789d94756SHannes Reinecke sdp->use_16_for_rw = 1;
271889d94756SHannes Reinecke
271989d94756SHannes Reinecke }
272089d94756SHannes Reinecke
272189d94756SHannes Reinecke /*
272289d94756SHannes Reinecke * Print disk capacity
272389d94756SHannes Reinecke */
272489d94756SHannes Reinecke static void
sd_print_capacity(struct scsi_disk * sdkp,sector_t old_capacity)272589d94756SHannes Reinecke sd_print_capacity(struct scsi_disk *sdkp,
272689d94756SHannes Reinecke sector_t old_capacity)
27277404ad3bSJames Bottomley {
272889d94756SHannes Reinecke int sector_size = sdkp->device->sector_size;
27297404ad3bSJames Bottomley char cap_str_2[10], cap_str_10[10];
27307404ad3bSJames Bottomley
2731d7e6db20SDamien Le Moal if (!sdkp->first_scan && old_capacity == sdkp->capacity)
2732d7e6db20SDamien Le Moal return;
2733d7e6db20SDamien Le Moal
2734b9f28d86SJames Bottomley string_get_size(sdkp->capacity, sector_size,
2735b9f28d86SJames Bottomley STRING_UNITS_2, cap_str_2, sizeof(cap_str_2));
2736b9f28d86SJames Bottomley string_get_size(sdkp->capacity, sector_size,
2737d7e6db20SDamien Le Moal STRING_UNITS_10, cap_str_10, sizeof(cap_str_10));
27381da177e4SLinus Torvalds
2739e73aec82SMartin K. Petersen sd_printk(KERN_NOTICE, sdkp,
2740ea09bcc9SMartin K. Petersen "%llu %d-byte logical blocks: (%s/%s)\n",
2741e73aec82SMartin K. Petersen (unsigned long long)sdkp->capacity,
27427404ad3bSJames Bottomley sector_size, cap_str_10, cap_str_2);
2743ea09bcc9SMartin K. Petersen
2744526f7c79SMartin K. Petersen if (sdkp->physical_block_size != sector_size)
2745ea09bcc9SMartin K. Petersen sd_printk(KERN_NOTICE, sdkp,
2746ea09bcc9SMartin K. Petersen "%u-byte physical blocks\n",
2747526f7c79SMartin K. Petersen sdkp->physical_block_size);
274889d94756SHannes Reinecke }
27491da177e4SLinus Torvalds
27501da177e4SLinus Torvalds /* called with buffer of length 512 */
27511da177e4SLinus Torvalds static inline int
sd_do_mode_sense(struct scsi_disk * sdkp,int dbd,int modepage,unsigned char * buffer,int len,struct scsi_mode_data * data,struct scsi_sense_hdr * sshdr)27520610959fSMike Christie sd_do_mode_sense(struct scsi_disk *sdkp, int dbd, int modepage,
2753ea73a9f2SJames Bottomley unsigned char *buffer, int len, struct scsi_mode_data *data,
2754ea73a9f2SJames Bottomley struct scsi_sense_hdr *sshdr)
27551da177e4SLinus Torvalds {
2756c749301eSDamien Le Moal /*
2757c749301eSDamien Le Moal * If we must use MODE SENSE(10), make sure that the buffer length
2758c749301eSDamien Le Moal * is at least 8 bytes so that the mode sense header fits.
2759c749301eSDamien Le Moal */
2760c749301eSDamien Le Moal if (sdkp->device->use_10_for_ms && len < 8)
2761c749301eSDamien Le Moal len = 8;
2762c749301eSDamien Le Moal
2763a6cdc35fSDamien Le Moal return scsi_mode_sense(sdkp->device, dbd, modepage, 0, buffer, len,
2764a6cdc35fSDamien Le Moal SD_TIMEOUT, sdkp->max_retries, data, sshdr);
27651da177e4SLinus Torvalds }
27661da177e4SLinus Torvalds
27671da177e4SLinus Torvalds /*
27681da177e4SLinus Torvalds * read write protect setting, if possible - called only in sd_revalidate_disk()
276948970800SAl Viro * called with buffer of length SD_BUF_SIZE
27701da177e4SLinus Torvalds */
27711da177e4SLinus Torvalds static void
sd_read_write_protect_flag(struct scsi_disk * sdkp,unsigned char * buffer)2772e73aec82SMartin K. Petersen sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer)
2773ea73a9f2SJames Bottomley {
27741da177e4SLinus Torvalds int res;
2775ea73a9f2SJames Bottomley struct scsi_device *sdp = sdkp->device;
27761da177e4SLinus Torvalds struct scsi_mode_data data;
277770a9b873SMartin K. Petersen int old_wp = sdkp->write_prot;
27781da177e4SLinus Torvalds
27791da177e4SLinus Torvalds set_disk_ro(sdkp->disk, 0);
2780ea73a9f2SJames Bottomley if (sdp->skip_ms_page_3f) {
2781b2bff6ceSMartin K. Petersen sd_first_printk(KERN_NOTICE, sdkp, "Assuming Write Enabled\n");
27821da177e4SLinus Torvalds return;
27831da177e4SLinus Torvalds }
27841da177e4SLinus Torvalds
2785ea73a9f2SJames Bottomley if (sdp->use_192_bytes_for_3f) {
27860610959fSMike Christie res = sd_do_mode_sense(sdkp, 0, 0x3F, buffer, 192, &data, NULL);
27871da177e4SLinus Torvalds } else {
27881da177e4SLinus Torvalds /*
27891da177e4SLinus Torvalds * First attempt: ask for all pages (0x3F), but only 4 bytes.
27901da177e4SLinus Torvalds * We have to start carefully: some devices hang if we ask
27911da177e4SLinus Torvalds * for more than is available.
27921da177e4SLinus Torvalds */
27930610959fSMike Christie res = sd_do_mode_sense(sdkp, 0, 0x3F, buffer, 4, &data, NULL);
27941da177e4SLinus Torvalds
27951da177e4SLinus Torvalds /*
27961da177e4SLinus Torvalds * Second attempt: ask for page 0 When only page 0 is
27971da177e4SLinus Torvalds * implemented, a request for page 3F may return Sense Key
27981da177e4SLinus Torvalds * 5: Illegal Request, Sense Code 24: Invalid field in
27991da177e4SLinus Torvalds * CDB.
28001da177e4SLinus Torvalds */
28018793613dSHannes Reinecke if (res < 0)
28020610959fSMike Christie res = sd_do_mode_sense(sdkp, 0, 0, buffer, 4, &data, NULL);
28031da177e4SLinus Torvalds
28041da177e4SLinus Torvalds /*
28051da177e4SLinus Torvalds * Third attempt: ask 255 bytes, as we did earlier.
28061da177e4SLinus Torvalds */
28078793613dSHannes Reinecke if (res < 0)
28080610959fSMike Christie res = sd_do_mode_sense(sdkp, 0, 0x3F, buffer, 255,
2809ea73a9f2SJames Bottomley &data, NULL);
28101da177e4SLinus Torvalds }
28111da177e4SLinus Torvalds
28128793613dSHannes Reinecke if (res < 0) {
2813b2bff6ceSMartin K. Petersen sd_first_printk(KERN_WARNING, sdkp,
2814e73aec82SMartin K. Petersen "Test WP failed, assume Write Enabled\n");
28151da177e4SLinus Torvalds } else {
28161da177e4SLinus Torvalds sdkp->write_prot = ((data.device_specific & 0x80) != 0);
28178acf608eSMartin K. Petersen set_disk_ro(sdkp->disk, sdkp->write_prot);
281870a9b873SMartin K. Petersen if (sdkp->first_scan || old_wp != sdkp->write_prot) {
2819e73aec82SMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, "Write Protect is %s\n",
28201da177e4SLinus Torvalds sdkp->write_prot ? "on" : "off");
2821df441cc0SAndy Shevchenko sd_printk(KERN_DEBUG, sdkp, "Mode Sense: %4ph\n", buffer);
28221da177e4SLinus Torvalds }
28231da177e4SLinus Torvalds }
282470a9b873SMartin K. Petersen }
28251da177e4SLinus Torvalds
28261da177e4SLinus Torvalds /*
28271da177e4SLinus Torvalds * sd_read_cache_type - called only from sd_revalidate_disk()
282848970800SAl Viro * called with buffer of length SD_BUF_SIZE
28291da177e4SLinus Torvalds */
28301da177e4SLinus Torvalds static void
sd_read_cache_type(struct scsi_disk * sdkp,unsigned char * buffer)2831e73aec82SMartin K. Petersen sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
2832631e8a13SAl Viro {
28331da177e4SLinus Torvalds int len = 0, res;
2834ea73a9f2SJames Bottomley struct scsi_device *sdp = sdkp->device;
28351da177e4SLinus Torvalds
2836631e8a13SAl Viro int dbd;
2837631e8a13SAl Viro int modepage;
28380bcaa111SLuben Tuikov int first_len;
28391da177e4SLinus Torvalds struct scsi_mode_data data;
28401da177e4SLinus Torvalds struct scsi_sense_hdr sshdr;
284170a9b873SMartin K. Petersen int old_wce = sdkp->WCE;
284270a9b873SMartin K. Petersen int old_rcd = sdkp->RCD;
284370a9b873SMartin K. Petersen int old_dpofua = sdkp->DPOFUA;
28441da177e4SLinus Torvalds
284539c60a09SJames Bottomley
284639c60a09SJames Bottomley if (sdkp->cache_override)
284739c60a09SJames Bottomley return;
284839c60a09SJames Bottomley
28490bcaa111SLuben Tuikov first_len = 4;
28500bcaa111SLuben Tuikov if (sdp->skip_ms_page_8) {
28510bcaa111SLuben Tuikov if (sdp->type == TYPE_RBC)
28521da177e4SLinus Torvalds goto defaults;
28530bcaa111SLuben Tuikov else {
28540bcaa111SLuben Tuikov if (sdp->skip_ms_page_3f)
28550bcaa111SLuben Tuikov goto defaults;
28560bcaa111SLuben Tuikov modepage = 0x3F;
28570bcaa111SLuben Tuikov if (sdp->use_192_bytes_for_3f)
28580bcaa111SLuben Tuikov first_len = 192;
28590bcaa111SLuben Tuikov dbd = 0;
28600bcaa111SLuben Tuikov }
28610bcaa111SLuben Tuikov } else if (sdp->type == TYPE_RBC) {
2862631e8a13SAl Viro modepage = 6;
2863631e8a13SAl Viro dbd = 8;
2864631e8a13SAl Viro } else {
2865631e8a13SAl Viro modepage = 8;
2866631e8a13SAl Viro dbd = 0;
2867631e8a13SAl Viro }
2868631e8a13SAl Viro
28691da177e4SLinus Torvalds /* cautiously ask */
28700610959fSMike Christie res = sd_do_mode_sense(sdkp, dbd, modepage, buffer, first_len,
28710bcaa111SLuben Tuikov &data, &sshdr);
28721da177e4SLinus Torvalds
28738793613dSHannes Reinecke if (res < 0)
28741da177e4SLinus Torvalds goto bad_sense;
28751da177e4SLinus Torvalds
28766d73c851SAl Viro if (!data.header_length) {
28776d73c851SAl Viro modepage = 6;
28780bcaa111SLuben Tuikov first_len = 0;
2879b2bff6ceSMartin K. Petersen sd_first_printk(KERN_ERR, sdkp,
2880b2bff6ceSMartin K. Petersen "Missing header in MODE_SENSE response\n");
28816d73c851SAl Viro }
28826d73c851SAl Viro
28831da177e4SLinus Torvalds /* that went OK, now ask for the proper length */
28841da177e4SLinus Torvalds len = data.length;
28851da177e4SLinus Torvalds
28861da177e4SLinus Torvalds /*
28871da177e4SLinus Torvalds * We're only interested in the first three bytes, actually.
28881da177e4SLinus Torvalds * But the data cache page is defined for the first 20.
28891da177e4SLinus Torvalds */
28901da177e4SLinus Torvalds if (len < 3)
28911da177e4SLinus Torvalds goto bad_sense;
28920bcaa111SLuben Tuikov else if (len > SD_BUF_SIZE) {
2893b2bff6ceSMartin K. Petersen sd_first_printk(KERN_NOTICE, sdkp, "Truncating mode parameter "
28940bcaa111SLuben Tuikov "data from %d to %d bytes\n", len, SD_BUF_SIZE);
28950bcaa111SLuben Tuikov len = SD_BUF_SIZE;
28960bcaa111SLuben Tuikov }
28970bcaa111SLuben Tuikov if (modepage == 0x3F && sdp->use_192_bytes_for_3f)
28980bcaa111SLuben Tuikov len = 192;
28991da177e4SLinus Torvalds
29001da177e4SLinus Torvalds /* Get the data */
29010bcaa111SLuben Tuikov if (len > first_len)
29020610959fSMike Christie res = sd_do_mode_sense(sdkp, dbd, modepage, buffer, len,
29030bcaa111SLuben Tuikov &data, &sshdr);
29041da177e4SLinus Torvalds
29058793613dSHannes Reinecke if (!res) {
2906631e8a13SAl Viro int offset = data.header_length + data.block_descriptor_length;
29071da177e4SLinus Torvalds
29080bcaa111SLuben Tuikov while (offset < len) {
29090bcaa111SLuben Tuikov u8 page_code = buffer[offset] & 0x3F;
29100bcaa111SLuben Tuikov u8 spf = buffer[offset] & 0x40;
29110bcaa111SLuben Tuikov
29120bcaa111SLuben Tuikov if (page_code == 8 || page_code == 6) {
29130bcaa111SLuben Tuikov /* We're interested only in the first 3 bytes.
29140bcaa111SLuben Tuikov */
29150bcaa111SLuben Tuikov if (len - offset <= 2) {
2916b2bff6ceSMartin K. Petersen sd_first_printk(KERN_ERR, sdkp,
2917b2bff6ceSMartin K. Petersen "Incomplete mode parameter "
2918b2bff6ceSMartin K. Petersen "data\n");
29190bcaa111SLuben Tuikov goto defaults;
29200bcaa111SLuben Tuikov } else {
29210bcaa111SLuben Tuikov modepage = page_code;
29220bcaa111SLuben Tuikov goto Page_found;
29230bcaa111SLuben Tuikov }
29240bcaa111SLuben Tuikov } else {
29250bcaa111SLuben Tuikov /* Go to the next page */
29260bcaa111SLuben Tuikov if (spf && len - offset > 3)
29270bcaa111SLuben Tuikov offset += 4 + (buffer[offset+2] << 8) +
29280bcaa111SLuben Tuikov buffer[offset+3];
29290bcaa111SLuben Tuikov else if (!spf && len - offset > 1)
29300bcaa111SLuben Tuikov offset += 2 + buffer[offset+1];
29310bcaa111SLuben Tuikov else {
2932b2bff6ceSMartin K. Petersen sd_first_printk(KERN_ERR, sdkp,
2933b2bff6ceSMartin K. Petersen "Incomplete mode "
2934b2bff6ceSMartin K. Petersen "parameter data\n");
293524d720b7SLuben Tuikov goto defaults;
293624d720b7SLuben Tuikov }
29370bcaa111SLuben Tuikov }
29380bcaa111SLuben Tuikov }
293948970800SAl Viro
2940c4da1205SMartin Kepplinger sd_first_printk(KERN_WARNING, sdkp,
2941c4da1205SMartin Kepplinger "No Caching mode page found\n");
29420bcaa111SLuben Tuikov goto defaults;
2943984f1733SAlan Stern
29440bcaa111SLuben Tuikov Page_found:
2945631e8a13SAl Viro if (modepage == 8) {
2946631e8a13SAl Viro sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0);
2947631e8a13SAl Viro sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0);
2948631e8a13SAl Viro } else {
2949631e8a13SAl Viro sdkp->WCE = ((buffer[offset + 2] & 0x01) == 0);
2950631e8a13SAl Viro sdkp->RCD = 0;
2951631e8a13SAl Viro }
29521da177e4SLinus Torvalds
2953007365adSTejun Heo sdkp->DPOFUA = (data.device_specific & 0x10) != 0;
2954b14bf2d0SAlan Stern if (sdp->broken_fua) {
2955b14bf2d0SAlan Stern sd_first_printk(KERN_NOTICE, sdkp, "Disabling FUA\n");
2956b14bf2d0SAlan Stern sdkp->DPOFUA = 0;
295726f28197SDamien Le Moal } else if (sdkp->DPOFUA && !sdkp->device->use_10_for_rw &&
295826f28197SDamien Le Moal !sdkp->device->use_16_for_rw) {
2959b2bff6ceSMartin K. Petersen sd_first_printk(KERN_NOTICE, sdkp,
2960e73aec82SMartin K. Petersen "Uses READ/WRITE(6), disabling FUA\n");
2961007365adSTejun Heo sdkp->DPOFUA = 0;
2962007365adSTejun Heo }
2963007365adSTejun Heo
29642eefd57bSSujit Reddy Thumma /* No cache flush allowed for write protected devices */
29652eefd57bSSujit Reddy Thumma if (sdkp->WCE && sdkp->write_prot)
29662eefd57bSSujit Reddy Thumma sdkp->WCE = 0;
29672eefd57bSSujit Reddy Thumma
296870a9b873SMartin K. Petersen if (sdkp->first_scan || old_wce != sdkp->WCE ||
296970a9b873SMartin K. Petersen old_rcd != sdkp->RCD || old_dpofua != sdkp->DPOFUA)
2970e73aec82SMartin K. Petersen sd_printk(KERN_NOTICE, sdkp,
2971e73aec82SMartin K. Petersen "Write cache: %s, read cache: %s, %s\n",
2972fd44bab5SLuben Tuikov sdkp->WCE ? "enabled" : "disabled",
2973fd44bab5SLuben Tuikov sdkp->RCD ? "disabled" : "enabled",
2974fd44bab5SLuben Tuikov sdkp->DPOFUA ? "supports DPO and FUA"
2975fd44bab5SLuben Tuikov : "doesn't support DPO or FUA");
29761da177e4SLinus Torvalds
29771da177e4SLinus Torvalds return;
29781da177e4SLinus Torvalds }
29791da177e4SLinus Torvalds
29801da177e4SLinus Torvalds bad_sense:
2981ea73a9f2SJames Bottomley if (scsi_sense_valid(&sshdr) &&
29821da177e4SLinus Torvalds sshdr.sense_key == ILLEGAL_REQUEST &&
29831da177e4SLinus Torvalds sshdr.asc == 0x24 && sshdr.ascq == 0x0)
2984e73aec82SMartin K. Petersen /* Invalid field in CDB */
2985b2bff6ceSMartin K. Petersen sd_first_printk(KERN_NOTICE, sdkp, "Cache data unavailable\n");
29861da177e4SLinus Torvalds else
2987b2bff6ceSMartin K. Petersen sd_first_printk(KERN_ERR, sdkp,
2988b2bff6ceSMartin K. Petersen "Asking for cache data failed\n");
29891da177e4SLinus Torvalds
29901da177e4SLinus Torvalds defaults:
2991b81478d8SNamjae Jeon if (sdp->wce_default_on) {
2992b2bff6ceSMartin K. Petersen sd_first_printk(KERN_NOTICE, sdkp,
2993b2bff6ceSMartin K. Petersen "Assuming drive cache: write back\n");
2994b81478d8SNamjae Jeon sdkp->WCE = 1;
2995b81478d8SNamjae Jeon } else {
2996c4da1205SMartin Kepplinger sd_first_printk(KERN_WARNING, sdkp,
2997b2bff6ceSMartin K. Petersen "Assuming drive cache: write through\n");
29981da177e4SLinus Torvalds sdkp->WCE = 0;
2999b81478d8SNamjae Jeon }
30001da177e4SLinus Torvalds sdkp->RCD = 0;
300148970800SAl Viro sdkp->DPOFUA = 0;
30021da177e4SLinus Torvalds }
30031da177e4SLinus Torvalds
3004e0597d70SMartin K. Petersen /*
3005e0597d70SMartin K. Petersen * The ATO bit indicates whether the DIF application tag is available
3006e0597d70SMartin K. Petersen * for use by the operating system.
3007e0597d70SMartin K. Petersen */
sd_read_app_tag_own(struct scsi_disk * sdkp,unsigned char * buffer)3008439d77f7SH Hartley Sweeten static void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer)
3009e0597d70SMartin K. Petersen {
3010e0597d70SMartin K. Petersen int res, offset;
3011e0597d70SMartin K. Petersen struct scsi_device *sdp = sdkp->device;
3012e0597d70SMartin K. Petersen struct scsi_mode_data data;
3013e0597d70SMartin K. Petersen struct scsi_sense_hdr sshdr;
3014e0597d70SMartin K. Petersen
301589d94756SHannes Reinecke if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
3016e0597d70SMartin K. Petersen return;
3017e0597d70SMartin K. Petersen
3018e0597d70SMartin K. Petersen if (sdkp->protection_type == 0)
3019e0597d70SMartin K. Petersen return;
3020e0597d70SMartin K. Petersen
3021a6cdc35fSDamien Le Moal res = scsi_mode_sense(sdp, 1, 0x0a, 0, buffer, 36, SD_TIMEOUT,
30220610959fSMike Christie sdkp->max_retries, &data, &sshdr);
3023e0597d70SMartin K. Petersen
30248793613dSHannes Reinecke if (res < 0 || !data.header_length ||
3025e0597d70SMartin K. Petersen data.length < 6) {
3026b2bff6ceSMartin K. Petersen sd_first_printk(KERN_WARNING, sdkp,
3027e0597d70SMartin K. Petersen "getting Control mode page failed, assume no ATO\n");
3028e0597d70SMartin K. Petersen
3029e0597d70SMartin K. Petersen if (scsi_sense_valid(&sshdr))
3030e0597d70SMartin K. Petersen sd_print_sense_hdr(sdkp, &sshdr);
3031e0597d70SMartin K. Petersen
3032e0597d70SMartin K. Petersen return;
3033e0597d70SMartin K. Petersen }
3034e0597d70SMartin K. Petersen
3035e0597d70SMartin K. Petersen offset = data.header_length + data.block_descriptor_length;
3036e0597d70SMartin K. Petersen
3037e0597d70SMartin K. Petersen if ((buffer[offset] & 0x3f) != 0x0a) {
3038b2bff6ceSMartin K. Petersen sd_first_printk(KERN_ERR, sdkp, "ATO Got wrong page\n");
3039e0597d70SMartin K. Petersen return;
3040e0597d70SMartin K. Petersen }
3041e0597d70SMartin K. Petersen
3042e0597d70SMartin K. Petersen if ((buffer[offset + 5] & 0x80) == 0)
3043e0597d70SMartin K. Petersen return;
3044e0597d70SMartin K. Petersen
3045e0597d70SMartin K. Petersen sdkp->ATO = 1;
3046e0597d70SMartin K. Petersen
3047e0597d70SMartin K. Petersen return;
3048e0597d70SMartin K. Petersen }
3049e0597d70SMartin K. Petersen
30501da177e4SLinus Torvalds /**
3051d11b6916SMartin K. Petersen * sd_read_block_limits - Query disk device for preferred I/O sizes.
30527529fbb0SDamien Le Moal * @sdkp: disk to query
3053d11b6916SMartin K. Petersen */
sd_read_block_limits(struct scsi_disk * sdkp)3054d11b6916SMartin K. Petersen static void sd_read_block_limits(struct scsi_disk *sdkp)
3055d11b6916SMartin K. Petersen {
30567fb019c4SMartin K. Petersen struct scsi_vpd *vpd;
3057d11b6916SMartin K. Petersen
30587fb019c4SMartin K. Petersen rcu_read_lock();
30597fb019c4SMartin K. Petersen
30607fb019c4SMartin K. Petersen vpd = rcu_dereference(sdkp->device->vpd_pgb0);
30617fb019c4SMartin K. Petersen if (!vpd || vpd->len < 16)
3062e3deec09SJames Bottomley goto out;
3063d11b6916SMartin K. Petersen
3064631669a2SMartin K. Petersen sdkp->min_xfer_blocks = get_unaligned_be16(&vpd->data[6]);
30657fb019c4SMartin K. Petersen sdkp->max_xfer_blocks = get_unaligned_be32(&vpd->data[8]);
30667fb019c4SMartin K. Petersen sdkp->opt_xfer_blocks = get_unaligned_be32(&vpd->data[12]);
3067ca369d51SMartin K. Petersen
30687fb019c4SMartin K. Petersen if (vpd->len >= 64) {
3069c98a0eb0SMartin K. Petersen unsigned int lba_count, desc_count;
3070c98a0eb0SMartin K. Petersen
30717fb019c4SMartin K. Petersen sdkp->max_ws_blocks = (u32)get_unaligned_be64(&vpd->data[36]);
3072c98a0eb0SMartin K. Petersen
3073c98a0eb0SMartin K. Petersen if (!sdkp->lbpme)
3074c98a0eb0SMartin K. Petersen goto out;
3075e339c1a7SMartin K. Petersen
30767fb019c4SMartin K. Petersen lba_count = get_unaligned_be32(&vpd->data[20]);
30777fb019c4SMartin K. Petersen desc_count = get_unaligned_be32(&vpd->data[24]);
3078e339c1a7SMartin K. Petersen
3079c98a0eb0SMartin K. Petersen if (lba_count && desc_count)
3080c98a0eb0SMartin K. Petersen sdkp->max_unmap_blocks = lba_count;
3081e339c1a7SMartin K. Petersen
30827fb019c4SMartin K. Petersen sdkp->unmap_granularity = get_unaligned_be32(&vpd->data[28]);
3083e339c1a7SMartin K. Petersen
30847fb019c4SMartin K. Petersen if (vpd->data[32] & 0x80)
3085c98a0eb0SMartin K. Petersen sdkp->unmap_alignment =
30867fb019c4SMartin K. Petersen get_unaligned_be32(&vpd->data[32]) & ~(1 << 31);
3087c98a0eb0SMartin K. Petersen
3088c98a0eb0SMartin K. Petersen if (!sdkp->lbpvpd) { /* LBP VPD page not provided */
3089c98a0eb0SMartin K. Petersen
3090c98a0eb0SMartin K. Petersen if (sdkp->max_unmap_blocks)
3091c98a0eb0SMartin K. Petersen sd_config_discard(sdkp, SD_LBP_UNMAP);
3092c98a0eb0SMartin K. Petersen else
3093c98a0eb0SMartin K. Petersen sd_config_discard(sdkp, SD_LBP_WS16);
3094c98a0eb0SMartin K. Petersen
3095c98a0eb0SMartin K. Petersen } else { /* LBP VPD page tells us what to use */
3096bcd069bbSMartin K. Petersen if (sdkp->lbpu && sdkp->max_unmap_blocks)
3097e461338bSMartin K. Petersen sd_config_discard(sdkp, SD_LBP_UNMAP);
3098e461338bSMartin K. Petersen else if (sdkp->lbpws)
3099c98a0eb0SMartin K. Petersen sd_config_discard(sdkp, SD_LBP_WS16);
3100c98a0eb0SMartin K. Petersen else if (sdkp->lbpws10)
3101c98a0eb0SMartin K. Petersen sd_config_discard(sdkp, SD_LBP_WS10);
3102c98a0eb0SMartin K. Petersen else
3103c98a0eb0SMartin K. Petersen sd_config_discard(sdkp, SD_LBP_DISABLE);
3104c98a0eb0SMartin K. Petersen }
3105e339c1a7SMartin K. Petersen }
3106e339c1a7SMartin K. Petersen
3107e3deec09SJames Bottomley out:
31087fb019c4SMartin K. Petersen rcu_read_unlock();
3109d11b6916SMartin K. Petersen }
3110d11b6916SMartin K. Petersen
3111d11b6916SMartin K. Petersen /**
31123821d768SMartin K. Petersen * sd_read_block_characteristics - Query block dev. characteristics
31137529fbb0SDamien Le Moal * @sdkp: disk to query
31143821d768SMartin K. Petersen */
sd_read_block_characteristics(struct scsi_disk * sdkp)31153821d768SMartin K. Petersen static void sd_read_block_characteristics(struct scsi_disk *sdkp)
31163821d768SMartin K. Petersen {
311789d94756SHannes Reinecke struct request_queue *q = sdkp->disk->queue;
31187fb019c4SMartin K. Petersen struct scsi_vpd *vpd;
31193821d768SMartin K. Petersen u16 rot;
31207fb019c4SMartin K. Petersen u8 zoned;
31213821d768SMartin K. Petersen
31227fb019c4SMartin K. Petersen rcu_read_lock();
31237fb019c4SMartin K. Petersen vpd = rcu_dereference(sdkp->device->vpd_pgb1);
3124e3deec09SJames Bottomley
3125568c7c4cSMartin Wilck if (!vpd || vpd->len <= 8) {
31267fb019c4SMartin K. Petersen rcu_read_unlock();
31277fb019c4SMartin K. Petersen return;
31287fb019c4SMartin K. Petersen }
31293821d768SMartin K. Petersen
31307fb019c4SMartin K. Petersen rot = get_unaligned_be16(&vpd->data[4]);
31317fb019c4SMartin K. Petersen zoned = (vpd->data[8] >> 4) & 3;
31327fb019c4SMartin K. Petersen rcu_read_unlock();
31333821d768SMartin K. Petersen
3134b277da0aSMike Snitzer if (rot == 1) {
31358b904b5bSBart Van Assche blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
31368b904b5bSBart Van Assche blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, q);
3137b277da0aSMike Snitzer }
31383821d768SMartin K. Petersen
313968af412cSDamien Le Moal if (sdkp->device->type == TYPE_ZBC) {
3140288b3271SShin'ichiro Kawasaki /*
3141288b3271SShin'ichiro Kawasaki * Host-managed: Per ZBC and ZAC specifications, writes in
3142288b3271SShin'ichiro Kawasaki * sequential write required zones of host-managed devices must
3143288b3271SShin'ichiro Kawasaki * be aligned to the device physical block size.
3144288b3271SShin'ichiro Kawasaki */
31456b2bd274SChristoph Hellwig disk_set_zoned(sdkp->disk, BLK_ZONED_HM);
3146288b3271SShin'ichiro Kawasaki blk_queue_zone_write_granularity(q, sdkp->physical_block_size);
314768af412cSDamien Le Moal } else {
31487fb019c4SMartin K. Petersen sdkp->zoned = zoned;
314927ba3e8fSDamien Le Moal if (sdkp->zoned == 1) {
315068af412cSDamien Le Moal /* Host-aware */
31516b2bd274SChristoph Hellwig disk_set_zoned(sdkp->disk, BLK_ZONED_HA);
3152b7205307SChristoph Hellwig } else {
315327ba3e8fSDamien Le Moal /* Regular disk or drive managed disk */
31546b2bd274SChristoph Hellwig disk_set_zoned(sdkp->disk, BLK_ZONED_NONE);
315527ba3e8fSDamien Le Moal }
315627ba3e8fSDamien Le Moal }
315727ba3e8fSDamien Le Moal
315827ba3e8fSDamien Le Moal if (!sdkp->first_scan)
31597fb019c4SMartin K. Petersen return;
316027ba3e8fSDamien Le Moal
316127ba3e8fSDamien Le Moal if (blk_queue_is_zoned(q)) {
316227ba3e8fSDamien Le Moal sd_printk(KERN_NOTICE, sdkp, "Host-%s zoned block device\n",
316327ba3e8fSDamien Le Moal q->limits.zoned == BLK_ZONED_HM ? "managed" : "aware");
316427ba3e8fSDamien Le Moal } else {
316527ba3e8fSDamien Le Moal if (sdkp->zoned == 1)
316627ba3e8fSDamien Le Moal sd_printk(KERN_NOTICE, sdkp,
316727ba3e8fSDamien Le Moal "Host-aware SMR disk used as regular disk\n");
316827ba3e8fSDamien Le Moal else if (sdkp->zoned == 2)
31690bd735dfSDamien Le Moal sd_printk(KERN_NOTICE, sdkp,
31700bd735dfSDamien Le Moal "Drive-managed SMR disk\n");
317168af412cSDamien Le Moal }
31723821d768SMartin K. Petersen }
31733821d768SMartin K. Petersen
3174045d3fe7SMartin K. Petersen /**
3175c98a0eb0SMartin K. Petersen * sd_read_block_provisioning - Query provisioning VPD page
31767529fbb0SDamien Le Moal * @sdkp: disk to query
3177045d3fe7SMartin K. Petersen */
sd_read_block_provisioning(struct scsi_disk * sdkp)3178c98a0eb0SMartin K. Petersen static void sd_read_block_provisioning(struct scsi_disk *sdkp)
3179045d3fe7SMartin K. Petersen {
31807fb019c4SMartin K. Petersen struct scsi_vpd *vpd;
3181045d3fe7SMartin K. Petersen
3182c98a0eb0SMartin K. Petersen if (sdkp->lbpme == 0)
3183045d3fe7SMartin K. Petersen return;
3184045d3fe7SMartin K. Petersen
31857fb019c4SMartin K. Petersen rcu_read_lock();
31867fb019c4SMartin K. Petersen vpd = rcu_dereference(sdkp->device->vpd_pgb2);
3187045d3fe7SMartin K. Petersen
31887fb019c4SMartin K. Petersen if (!vpd || vpd->len < 8) {
31897fb019c4SMartin K. Petersen rcu_read_unlock();
31907fb019c4SMartin K. Petersen return;
31917fb019c4SMartin K. Petersen }
3192045d3fe7SMartin K. Petersen
3193c98a0eb0SMartin K. Petersen sdkp->lbpvpd = 1;
31947fb019c4SMartin K. Petersen sdkp->lbpu = (vpd->data[5] >> 7) & 1; /* UNMAP */
31957fb019c4SMartin K. Petersen sdkp->lbpws = (vpd->data[5] >> 6) & 1; /* WRITE SAME(16) w/ UNMAP */
31967fb019c4SMartin K. Petersen sdkp->lbpws10 = (vpd->data[5] >> 5) & 1; /* WRITE SAME(10) w/ UNMAP */
31977fb019c4SMartin K. Petersen rcu_read_unlock();
3198045d3fe7SMartin K. Petersen }
3199045d3fe7SMartin K. Petersen
sd_read_write_same(struct scsi_disk * sdkp,unsigned char * buffer)32005db44863SMartin K. Petersen static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer)
32015db44863SMartin K. Petersen {
320266c28f97SMartin K. Petersen struct scsi_device *sdev = sdkp->device;
320366c28f97SMartin K. Petersen
320454b2b50cSMartin K. Petersen if (sdev->host->no_write_same) {
320554b2b50cSMartin K. Petersen sdev->no_write_same = 1;
320654b2b50cSMartin K. Petersen
320754b2b50cSMartin K. Petersen return;
320854b2b50cSMartin K. Petersen }
320954b2b50cSMartin K. Petersen
3210152e52fbSDamien Le Moal if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, INQUIRY, 0) < 0) {
3211e38d9e83SMartin K. Petersen struct scsi_vpd *vpd;
3212af73623fSBernd Schubert
321366c28f97SMartin K. Petersen sdev->no_report_opcodes = 1;
321466c28f97SMartin K. Petersen
321566c28f97SMartin K. Petersen /* Disable WRITE SAME if REPORT SUPPORTED OPERATION
321666c28f97SMartin K. Petersen * CODES is unsupported and the device has an ATA
321766c28f97SMartin K. Petersen * Information VPD page (SAT).
321866c28f97SMartin K. Petersen */
3219e38d9e83SMartin K. Petersen rcu_read_lock();
3220e38d9e83SMartin K. Petersen vpd = rcu_dereference(sdev->vpd_pg89);
3221e38d9e83SMartin K. Petersen if (vpd)
322266c28f97SMartin K. Petersen sdev->no_write_same = 1;
3223e38d9e83SMartin K. Petersen rcu_read_unlock();
322466c28f97SMartin K. Petersen }
322566c28f97SMartin K. Petersen
3226152e52fbSDamien Le Moal if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, WRITE_SAME_16, 0) == 1)
32275db44863SMartin K. Petersen sdkp->ws16 = 1;
322866c28f97SMartin K. Petersen
3229152e52fbSDamien Le Moal if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, WRITE_SAME, 0) == 1)
323066c28f97SMartin K. Petersen sdkp->ws10 = 1;
32315db44863SMartin K. Petersen }
32325db44863SMartin K. Petersen
sd_read_security(struct scsi_disk * sdkp,unsigned char * buffer)3233d80210f2SChristoph Hellwig static void sd_read_security(struct scsi_disk *sdkp, unsigned char *buffer)
3234d80210f2SChristoph Hellwig {
3235d80210f2SChristoph Hellwig struct scsi_device *sdev = sdkp->device;
3236d80210f2SChristoph Hellwig
3237d80210f2SChristoph Hellwig if (!sdev->security_supported)
3238d80210f2SChristoph Hellwig return;
3239d80210f2SChristoph Hellwig
3240d80210f2SChristoph Hellwig if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE,
3241152e52fbSDamien Le Moal SECURITY_PROTOCOL_IN, 0) == 1 &&
3242d80210f2SChristoph Hellwig scsi_report_opcode(sdev, buffer, SD_BUF_SIZE,
3243152e52fbSDamien Le Moal SECURITY_PROTOCOL_OUT, 0) == 1)
3244d80210f2SChristoph Hellwig sdkp->security = 1;
3245d80210f2SChristoph Hellwig }
3246d80210f2SChristoph Hellwig
sd64_to_sectors(struct scsi_disk * sdkp,u8 * buf)3247e815d365SDamien Le Moal static inline sector_t sd64_to_sectors(struct scsi_disk *sdkp, u8 *buf)
3248e815d365SDamien Le Moal {
3249e815d365SDamien Le Moal return logical_to_sectors(sdkp->device, get_unaligned_be64(buf));
3250e815d365SDamien Le Moal }
3251e815d365SDamien Le Moal
3252e815d365SDamien Le Moal /**
3253e815d365SDamien Le Moal * sd_read_cpr - Query concurrent positioning ranges
3254e815d365SDamien Le Moal * @sdkp: disk to query
3255e815d365SDamien Le Moal */
sd_read_cpr(struct scsi_disk * sdkp)3256e815d365SDamien Le Moal static void sd_read_cpr(struct scsi_disk *sdkp)
3257e815d365SDamien Le Moal {
3258e815d365SDamien Le Moal struct blk_independent_access_ranges *iars = NULL;
3259e815d365SDamien Le Moal unsigned char *buffer = NULL;
3260e815d365SDamien Le Moal unsigned int nr_cpr = 0;
3261e815d365SDamien Le Moal int i, vpd_len, buf_len = SD_BUF_SIZE;
3262e815d365SDamien Le Moal u8 *desc;
3263e815d365SDamien Le Moal
3264e815d365SDamien Le Moal /*
3265e815d365SDamien Le Moal * We need to have the capacity set first for the block layer to be
3266e815d365SDamien Le Moal * able to check the ranges.
3267e815d365SDamien Le Moal */
3268e815d365SDamien Le Moal if (sdkp->first_scan)
3269e815d365SDamien Le Moal return;
3270e815d365SDamien Le Moal
3271e815d365SDamien Le Moal if (!sdkp->capacity)
3272e815d365SDamien Le Moal goto out;
3273e815d365SDamien Le Moal
3274e815d365SDamien Le Moal /*
3275e815d365SDamien Le Moal * Concurrent Positioning Ranges VPD: there can be at most 256 ranges,
3276e815d365SDamien Le Moal * leading to a maximum page size of 64 + 256*32 bytes.
3277e815d365SDamien Le Moal */
3278e815d365SDamien Le Moal buf_len = 64 + 256*32;
3279e815d365SDamien Le Moal buffer = kmalloc(buf_len, GFP_KERNEL);
3280e815d365SDamien Le Moal if (!buffer || scsi_get_vpd_page(sdkp->device, 0xb9, buffer, buf_len))
3281e815d365SDamien Le Moal goto out;
3282e815d365SDamien Le Moal
3283e815d365SDamien Le Moal /* We must have at least a 64B header and one 32B range descriptor */
3284f92de9d1STyler Erickson vpd_len = get_unaligned_be16(&buffer[2]) + 4;
3285e815d365SDamien Le Moal if (vpd_len > buf_len || vpd_len < 64 + 32 || (vpd_len & 31)) {
3286e815d365SDamien Le Moal sd_printk(KERN_ERR, sdkp,
3287e815d365SDamien Le Moal "Invalid Concurrent Positioning Ranges VPD page\n");
3288e815d365SDamien Le Moal goto out;
3289e815d365SDamien Le Moal }
3290e815d365SDamien Le Moal
3291e815d365SDamien Le Moal nr_cpr = (vpd_len - 64) / 32;
3292e815d365SDamien Le Moal if (nr_cpr == 1) {
3293e815d365SDamien Le Moal nr_cpr = 0;
3294e815d365SDamien Le Moal goto out;
3295e815d365SDamien Le Moal }
3296e815d365SDamien Le Moal
3297e815d365SDamien Le Moal iars = disk_alloc_independent_access_ranges(sdkp->disk, nr_cpr);
3298e815d365SDamien Le Moal if (!iars) {
3299e815d365SDamien Le Moal nr_cpr = 0;
3300e815d365SDamien Le Moal goto out;
3301e815d365SDamien Le Moal }
3302e815d365SDamien Le Moal
3303e815d365SDamien Le Moal desc = &buffer[64];
3304e815d365SDamien Le Moal for (i = 0; i < nr_cpr; i++, desc += 32) {
3305e815d365SDamien Le Moal if (desc[0] != i) {
3306e815d365SDamien Le Moal sd_printk(KERN_ERR, sdkp,
3307e815d365SDamien Le Moal "Invalid Concurrent Positioning Range number\n");
3308e815d365SDamien Le Moal nr_cpr = 0;
3309e815d365SDamien Le Moal break;
3310e815d365SDamien Le Moal }
3311e815d365SDamien Le Moal
3312e815d365SDamien Le Moal iars->ia_range[i].sector = sd64_to_sectors(sdkp, desc + 8);
3313e815d365SDamien Le Moal iars->ia_range[i].nr_sectors = sd64_to_sectors(sdkp, desc + 16);
3314e815d365SDamien Le Moal }
3315e815d365SDamien Le Moal
3316e815d365SDamien Le Moal out:
3317e815d365SDamien Le Moal disk_set_independent_access_ranges(sdkp->disk, iars);
3318e815d365SDamien Le Moal if (nr_cpr && sdkp->nr_actuators != nr_cpr) {
3319e815d365SDamien Le Moal sd_printk(KERN_NOTICE, sdkp,
3320e815d365SDamien Le Moal "%u concurrent positioning ranges\n", nr_cpr);
3321e815d365SDamien Le Moal sdkp->nr_actuators = nr_cpr;
3322e815d365SDamien Le Moal }
3323e815d365SDamien Le Moal
3324e815d365SDamien Le Moal kfree(buffer);
3325e815d365SDamien Le Moal }
3326e815d365SDamien Le Moal
sd_validate_min_xfer_size(struct scsi_disk * sdkp)3327631669a2SMartin K. Petersen static bool sd_validate_min_xfer_size(struct scsi_disk *sdkp)
3328631669a2SMartin K. Petersen {
3329631669a2SMartin K. Petersen struct scsi_device *sdp = sdkp->device;
3330631669a2SMartin K. Petersen unsigned int min_xfer_bytes =
3331631669a2SMartin K. Petersen logical_to_bytes(sdp, sdkp->min_xfer_blocks);
3332631669a2SMartin K. Petersen
3333631669a2SMartin K. Petersen if (sdkp->min_xfer_blocks == 0)
3334631669a2SMartin K. Petersen return false;
3335631669a2SMartin K. Petersen
3336631669a2SMartin K. Petersen if (min_xfer_bytes & (sdkp->physical_block_size - 1)) {
3337631669a2SMartin K. Petersen sd_first_printk(KERN_WARNING, sdkp,
3338631669a2SMartin K. Petersen "Preferred minimum I/O size %u bytes not a " \
3339631669a2SMartin K. Petersen "multiple of physical block size (%u bytes)\n",
3340631669a2SMartin K. Petersen min_xfer_bytes, sdkp->physical_block_size);
3341631669a2SMartin K. Petersen sdkp->min_xfer_blocks = 0;
3342631669a2SMartin K. Petersen return false;
3343631669a2SMartin K. Petersen }
3344631669a2SMartin K. Petersen
3345631669a2SMartin K. Petersen sd_first_printk(KERN_INFO, sdkp, "Preferred minimum I/O size %u bytes\n",
3346631669a2SMartin K. Petersen min_xfer_bytes);
3347631669a2SMartin K. Petersen return true;
3348631669a2SMartin K. Petersen }
3349631669a2SMartin K. Petersen
3350a83da8a4SMartin K. Petersen /*
3351a83da8a4SMartin K. Petersen * Determine the device's preferred I/O size for reads and writes
3352a83da8a4SMartin K. Petersen * unless the reported value is unreasonably small, large, not a
3353a83da8a4SMartin K. Petersen * multiple of the physical block size, or simply garbage.
3354a83da8a4SMartin K. Petersen */
sd_validate_opt_xfer_size(struct scsi_disk * sdkp,unsigned int dev_max)3355a83da8a4SMartin K. Petersen static bool sd_validate_opt_xfer_size(struct scsi_disk *sdkp,
3356a83da8a4SMartin K. Petersen unsigned int dev_max)
3357a83da8a4SMartin K. Petersen {
3358a83da8a4SMartin K. Petersen struct scsi_device *sdp = sdkp->device;
3359a83da8a4SMartin K. Petersen unsigned int opt_xfer_bytes =
3360a83da8a4SMartin K. Petersen logical_to_bytes(sdp, sdkp->opt_xfer_blocks);
3361631669a2SMartin K. Petersen unsigned int min_xfer_bytes =
3362631669a2SMartin K. Petersen logical_to_bytes(sdp, sdkp->min_xfer_blocks);
3363a83da8a4SMartin K. Petersen
33641d5de5bdSMartin K. Petersen if (sdkp->opt_xfer_blocks == 0)
33651d5de5bdSMartin K. Petersen return false;
33661d5de5bdSMartin K. Petersen
3367a83da8a4SMartin K. Petersen if (sdkp->opt_xfer_blocks > dev_max) {
3368a83da8a4SMartin K. Petersen sd_first_printk(KERN_WARNING, sdkp,
3369a83da8a4SMartin K. Petersen "Optimal transfer size %u logical blocks " \
3370a83da8a4SMartin K. Petersen "> dev_max (%u logical blocks)\n",
3371a83da8a4SMartin K. Petersen sdkp->opt_xfer_blocks, dev_max);
3372a83da8a4SMartin K. Petersen return false;
3373a83da8a4SMartin K. Petersen }
3374a83da8a4SMartin K. Petersen
3375a83da8a4SMartin K. Petersen if (sdkp->opt_xfer_blocks > SD_DEF_XFER_BLOCKS) {
3376a83da8a4SMartin K. Petersen sd_first_printk(KERN_WARNING, sdkp,
3377a83da8a4SMartin K. Petersen "Optimal transfer size %u logical blocks " \
3378a83da8a4SMartin K. Petersen "> sd driver limit (%u logical blocks)\n",
3379a83da8a4SMartin K. Petersen sdkp->opt_xfer_blocks, SD_DEF_XFER_BLOCKS);
3380a83da8a4SMartin K. Petersen return false;
3381a83da8a4SMartin K. Petersen }
3382a83da8a4SMartin K. Petersen
3383a83da8a4SMartin K. Petersen if (opt_xfer_bytes < PAGE_SIZE) {
3384a83da8a4SMartin K. Petersen sd_first_printk(KERN_WARNING, sdkp,
3385a83da8a4SMartin K. Petersen "Optimal transfer size %u bytes < " \
3386a83da8a4SMartin K. Petersen "PAGE_SIZE (%u bytes)\n",
3387a83da8a4SMartin K. Petersen opt_xfer_bytes, (unsigned int)PAGE_SIZE);
3388a83da8a4SMartin K. Petersen return false;
3389a83da8a4SMartin K. Petersen }
3390a83da8a4SMartin K. Petersen
3391631669a2SMartin K. Petersen if (min_xfer_bytes && opt_xfer_bytes % min_xfer_bytes) {
3392631669a2SMartin K. Petersen sd_first_printk(KERN_WARNING, sdkp,
3393631669a2SMartin K. Petersen "Optimal transfer size %u bytes not a " \
3394631669a2SMartin K. Petersen "multiple of preferred minimum block " \
3395631669a2SMartin K. Petersen "size (%u bytes)\n",
3396631669a2SMartin K. Petersen opt_xfer_bytes, min_xfer_bytes);
3397631669a2SMartin K. Petersen return false;
3398631669a2SMartin K. Petersen }
3399631669a2SMartin K. Petersen
3400a83da8a4SMartin K. Petersen if (opt_xfer_bytes & (sdkp->physical_block_size - 1)) {
3401a83da8a4SMartin K. Petersen sd_first_printk(KERN_WARNING, sdkp,
3402a83da8a4SMartin K. Petersen "Optimal transfer size %u bytes not a " \
3403a83da8a4SMartin K. Petersen "multiple of physical block size (%u bytes)\n",
3404a83da8a4SMartin K. Petersen opt_xfer_bytes, sdkp->physical_block_size);
3405a83da8a4SMartin K. Petersen return false;
3406a83da8a4SMartin K. Petersen }
3407a83da8a4SMartin K. Petersen
3408a83da8a4SMartin K. Petersen sd_first_printk(KERN_INFO, sdkp, "Optimal transfer size %u bytes\n",
3409a83da8a4SMartin K. Petersen opt_xfer_bytes);
3410a83da8a4SMartin K. Petersen return true;
3411a83da8a4SMartin K. Petersen }
3412a83da8a4SMartin K. Petersen
sd_read_block_zero(struct scsi_disk * sdkp)34139eb04addSMartin K. Petersen static void sd_read_block_zero(struct scsi_disk *sdkp)
34149eb04addSMartin K. Petersen {
3415323d2563SMartin K. Petersen struct scsi_device *sdev = sdkp->device;
3416323d2563SMartin K. Petersen unsigned int buf_len = sdev->sector_size;
3417323d2563SMartin K. Petersen u8 *buffer, cmd[16] = { };
34189eb04addSMartin K. Petersen
34199eb04addSMartin K. Petersen buffer = kmalloc(buf_len, GFP_KERNEL);
34209eb04addSMartin K. Petersen if (!buffer)
34219eb04addSMartin K. Petersen return;
34229eb04addSMartin K. Petersen
3423323d2563SMartin K. Petersen if (sdev->use_16_for_rw) {
3424323d2563SMartin K. Petersen cmd[0] = READ_16;
3425323d2563SMartin K. Petersen put_unaligned_be64(0, &cmd[2]); /* Logical block address 0 */
3426323d2563SMartin K. Petersen put_unaligned_be32(1, &cmd[10]);/* Transfer 1 logical block */
3427323d2563SMartin K. Petersen } else {
34289eb04addSMartin K. Petersen cmd[0] = READ_10;
34299eb04addSMartin K. Petersen put_unaligned_be32(0, &cmd[2]); /* Logical block address 0 */
34309eb04addSMartin K. Petersen put_unaligned_be16(1, &cmd[7]); /* Transfer 1 logical block */
3431323d2563SMartin K. Petersen }
34329eb04addSMartin K. Petersen
34339eb04addSMartin K. Petersen scsi_execute_cmd(sdkp->device, cmd, REQ_OP_DRV_IN, buffer, buf_len,
34349eb04addSMartin K. Petersen SD_TIMEOUT, sdkp->max_retries, NULL);
34359eb04addSMartin K. Petersen kfree(buffer);
34369eb04addSMartin K. Petersen }
34379eb04addSMartin K. Petersen
34383821d768SMartin K. Petersen /**
34391da177e4SLinus Torvalds * sd_revalidate_disk - called the first time a new disk is seen,
34401da177e4SLinus Torvalds * performs disk spin up, read_capacity, etc.
34411da177e4SLinus Torvalds * @disk: struct gendisk we care about
34421da177e4SLinus Torvalds **/
sd_revalidate_disk(struct gendisk * disk)34431da177e4SLinus Torvalds static int sd_revalidate_disk(struct gendisk *disk)
34441da177e4SLinus Torvalds {
34451da177e4SLinus Torvalds struct scsi_disk *sdkp = scsi_disk(disk);
34461da177e4SLinus Torvalds struct scsi_device *sdp = sdkp->device;
3447ca369d51SMartin K. Petersen struct request_queue *q = sdkp->disk->queue;
344889d94756SHannes Reinecke sector_t old_capacity = sdkp->capacity;
34491da177e4SLinus Torvalds unsigned char *buffer;
3450ca369d51SMartin K. Petersen unsigned int dev_max, rw_max;
34511da177e4SLinus Torvalds
3452fa0d34beSMartin K. Petersen SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp,
3453fa0d34beSMartin K. Petersen "sd_revalidate_disk\n"));
34541da177e4SLinus Torvalds
34551da177e4SLinus Torvalds /*
34561da177e4SLinus Torvalds * If the device is offline, don't try and read capacity or any
34571da177e4SLinus Torvalds * of the other niceties.
34581da177e4SLinus Torvalds */
34591da177e4SLinus Torvalds if (!scsi_device_online(sdp))
34601da177e4SLinus Torvalds goto out;
34611da177e4SLinus Torvalds
3462a6123f14SBernhard Walle buffer = kmalloc(SD_BUF_SIZE, GFP_KERNEL);
34631da177e4SLinus Torvalds if (!buffer) {
3464e73aec82SMartin K. Petersen sd_printk(KERN_WARNING, sdkp, "sd_revalidate_disk: Memory "
3465e73aec82SMartin K. Petersen "allocation failure.\n");
3466ea73a9f2SJames Bottomley goto out;
34671da177e4SLinus Torvalds }
34681da177e4SLinus Torvalds
3469e73aec82SMartin K. Petersen sd_spinup_disk(sdkp);
34701da177e4SLinus Torvalds
34711da177e4SLinus Torvalds /*
34721da177e4SLinus Torvalds * Without media there is no reason to ask; moreover, some devices
34731da177e4SLinus Torvalds * react badly if we do.
34741da177e4SLinus Torvalds */
34751da177e4SLinus Torvalds if (sdkp->media_present) {
3476e73aec82SMartin K. Petersen sd_read_capacity(sdkp, buffer);
34779eb04addSMartin K. Petersen /*
34789eb04addSMartin K. Petersen * Some USB/UAS devices return generic values for mode pages
34799eb04addSMartin K. Petersen * until the media has been accessed. Trigger a READ operation
34809eb04addSMartin K. Petersen * to force the device to populate mode pages.
34819eb04addSMartin K. Petersen */
34829eb04addSMartin K. Petersen if (sdp->read_before_ms)
34839eb04addSMartin K. Petersen sd_read_block_zero(sdkp);
3484e4a05698SJames Bottomley /*
3485e4a05698SJames Bottomley * set the default to rotational. All non-rotational devices
3486e4a05698SJames Bottomley * support the block characteristics VPD page, which will
3487e4a05698SJames Bottomley * cause this to be updated correctly and any device which
3488e4a05698SJames Bottomley * doesn't support it should be treated as rotational.
3489e4a05698SJames Bottomley */
3490e4a05698SJames Bottomley blk_queue_flag_clear(QUEUE_FLAG_NONROT, q);
3491e4a05698SJames Bottomley blk_queue_flag_set(QUEUE_FLAG_ADD_RANDOM, q);
3492e4a05698SJames Bottomley
34935ddfe085SHannes Reinecke if (scsi_device_supports_vpd(sdp)) {
3494c98a0eb0SMartin K. Petersen sd_read_block_provisioning(sdkp);
3495d11b6916SMartin K. Petersen sd_read_block_limits(sdkp);
34963821d768SMartin K. Petersen sd_read_block_characteristics(sdkp);
349789d94756SHannes Reinecke sd_zbc_read_zones(sdkp, buffer);
34981700714bSMartin K. Petersen sd_read_cpr(sdkp);
3499ffd4bc2aSMartin K. Petersen }
3500ffd4bc2aSMartin K. Petersen
350189d94756SHannes Reinecke sd_print_capacity(sdkp, old_capacity);
350289d94756SHannes Reinecke
3503e73aec82SMartin K. Petersen sd_read_write_protect_flag(sdkp, buffer);
3504e73aec82SMartin K. Petersen sd_read_cache_type(sdkp, buffer);
3505e0597d70SMartin K. Petersen sd_read_app_tag_own(sdkp, buffer);
35065db44863SMartin K. Petersen sd_read_write_same(sdkp, buffer);
3507d80210f2SChristoph Hellwig sd_read_security(sdkp, buffer);
35081e029397SMartin K. Petersen sd_config_protection(sdkp);
35091da177e4SLinus Torvalds }
35101da177e4SLinus Torvalds
3511461d4e90STejun Heo /*
3512461d4e90STejun Heo * We now have all cache related info, determine how we deal
35134913efe4STejun Heo * with flush requests.
3514461d4e90STejun Heo */
3515cb2fb68dSVaughan Cao sd_set_flush_flag(sdkp);
3516461d4e90STejun Heo
3517ca369d51SMartin K. Petersen /* Initial block count limit based on CDB TRANSFER LENGTH field size. */
3518ca369d51SMartin K. Petersen dev_max = sdp->use_16_for_rw ? SD_MAX_XFER_BLOCKS : SD_DEF_XFER_BLOCKS;
35193a9794d3SBrian King
3520ca369d51SMartin K. Petersen /* Some devices report a maximum block count for READ/WRITE requests. */
3521ca369d51SMartin K. Petersen dev_max = min_not_zero(dev_max, sdkp->max_xfer_blocks);
3522ca369d51SMartin K. Petersen q->limits.max_dev_sectors = logical_to_sectors(sdp, dev_max);
3523ca369d51SMartin K. Petersen
3524631669a2SMartin K. Petersen if (sd_validate_min_xfer_size(sdkp))
3525631669a2SMartin K. Petersen blk_queue_io_min(sdkp->disk->queue,
3526631669a2SMartin K. Petersen logical_to_bytes(sdp, sdkp->min_xfer_blocks));
3527631669a2SMartin K. Petersen else
3528631669a2SMartin K. Petersen blk_queue_io_min(sdkp->disk->queue, 0);
3529631669a2SMartin K. Petersen
3530a83da8a4SMartin K. Petersen if (sd_validate_opt_xfer_size(sdkp, dev_max)) {
35316b7e9cdeSMartin K. Petersen q->limits.io_opt = logical_to_bytes(sdp, sdkp->opt_xfer_blocks);
35326b7e9cdeSMartin K. Petersen rw_max = logical_to_sectors(sdp, sdkp->opt_xfer_blocks);
3533ea697a8bSMartin K. Petersen } else {
3534ea697a8bSMartin K. Petersen q->limits.io_opt = 0;
353567804145SFam Zheng rw_max = min_not_zero(logical_to_sectors(sdp, dev_max),
353667804145SFam Zheng (sector_t)BLK_DEF_MAX_SECTORS);
3537ea697a8bSMartin K. Petersen }
3538ca369d51SMartin K. Petersen
3539c9337ad4SJohn Garry /*
3540c9337ad4SJohn Garry * Limit default to SCSI host optimal sector limit if set. There may be
3541c9337ad4SJohn Garry * an impact on performance for when the size of a request exceeds this
3542c9337ad4SJohn Garry * host limit.
3543c9337ad4SJohn Garry */
3544608128d3SJohn Garry rw_max = min_not_zero(rw_max, sdp->host->opt_sectors);
3545608128d3SJohn Garry
354677082ca5SMartin K. Petersen /* Do not exceed controller limit */
354777082ca5SMartin K. Petersen rw_max = min(rw_max, queue_max_hw_sectors(q));
354877082ca5SMartin K. Petersen
354977082ca5SMartin K. Petersen /*
355077082ca5SMartin K. Petersen * Only update max_sectors if previously unset or if the current value
355177082ca5SMartin K. Petersen * exceeds the capabilities of the hardware.
355277082ca5SMartin K. Petersen */
355377082ca5SMartin K. Petersen if (sdkp->first_scan ||
355477082ca5SMartin K. Petersen q->limits.max_sectors > q->limits.max_dev_sectors ||
355577082ca5SMartin K. Petersen q->limits.max_sectors > q->limits.max_hw_sectors)
355677082ca5SMartin K. Petersen q->limits.max_sectors = rw_max;
355777082ca5SMartin K. Petersen
355877082ca5SMartin K. Petersen sdkp->first_scan = 0;
35594f258a46SMartin K. Petersen
3560449f4ec9SChristoph Hellwig set_capacity_and_notify(disk, logical_to_sectors(sdp, sdkp->capacity));
35615db44863SMartin K. Petersen sd_config_write_same(sdkp);
35621da177e4SLinus Torvalds kfree(buffer);
35631da177e4SLinus Torvalds
3564a3d8a257SDamien Le Moal /*
3565a3d8a257SDamien Le Moal * For a zoned drive, revalidating the zones can be done only once
3566a3d8a257SDamien Le Moal * the gendisk capacity is set. So if this fails, set back the gendisk
3567a3d8a257SDamien Le Moal * capacity to 0.
3568a3d8a257SDamien Le Moal */
3569a3d8a257SDamien Le Moal if (sd_zbc_revalidate_zones(sdkp))
3570449f4ec9SChristoph Hellwig set_capacity_and_notify(disk, 0);
3571a3d8a257SDamien Le Moal
35721da177e4SLinus Torvalds out:
35731da177e4SLinus Torvalds return 0;
35741da177e4SLinus Torvalds }
35751da177e4SLinus Torvalds
35761da177e4SLinus Torvalds /**
357772ec24bdSTejun Heo * sd_unlock_native_capacity - unlock native capacity
357872ec24bdSTejun Heo * @disk: struct gendisk to set capacity for
357972ec24bdSTejun Heo *
358072ec24bdSTejun Heo * Block layer calls this function if it detects that partitions
358172ec24bdSTejun Heo * on @disk reach beyond the end of the device. If the SCSI host
358272ec24bdSTejun Heo * implements ->unlock_native_capacity() method, it's invoked to
358372ec24bdSTejun Heo * give it a chance to adjust the device capacity.
358472ec24bdSTejun Heo *
358572ec24bdSTejun Heo * CONTEXT:
358672ec24bdSTejun Heo * Defined by block layer. Might sleep.
358772ec24bdSTejun Heo */
sd_unlock_native_capacity(struct gendisk * disk)358872ec24bdSTejun Heo static void sd_unlock_native_capacity(struct gendisk *disk)
358972ec24bdSTejun Heo {
359072ec24bdSTejun Heo struct scsi_device *sdev = scsi_disk(disk)->device;
359172ec24bdSTejun Heo
359272ec24bdSTejun Heo if (sdev->host->hostt->unlock_native_capacity)
359372ec24bdSTejun Heo sdev->host->hostt->unlock_native_capacity(sdev);
359472ec24bdSTejun Heo }
359572ec24bdSTejun Heo
359672ec24bdSTejun Heo /**
35973e1a7ff8STejun Heo * sd_format_disk_name - format disk name
35983e1a7ff8STejun Heo * @prefix: name prefix - ie. "sd" for SCSI disks
35993e1a7ff8STejun Heo * @index: index of the disk to format name for
36003e1a7ff8STejun Heo * @buf: output buffer
36013e1a7ff8STejun Heo * @buflen: length of the output buffer
36023e1a7ff8STejun Heo *
36033e1a7ff8STejun Heo * SCSI disk names starts at sda. The 26th device is sdz and the
36043e1a7ff8STejun Heo * 27th is sdaa. The last one for two lettered suffix is sdzz
36053e1a7ff8STejun Heo * which is followed by sdaaa.
36063e1a7ff8STejun Heo *
36073e1a7ff8STejun Heo * This is basically 26 base counting with one extra 'nil' entry
36083ad2f3fbSDaniel Mack * at the beginning from the second digit on and can be
36093e1a7ff8STejun Heo * determined using similar method as 26 base conversion with the
36103e1a7ff8STejun Heo * index shifted -1 after each digit is computed.
36113e1a7ff8STejun Heo *
36123e1a7ff8STejun Heo * CONTEXT:
36133e1a7ff8STejun Heo * Don't care.
36143e1a7ff8STejun Heo *
36153e1a7ff8STejun Heo * RETURNS:
36163e1a7ff8STejun Heo * 0 on success, -errno on failure.
36173e1a7ff8STejun Heo */
sd_format_disk_name(char * prefix,int index,char * buf,int buflen)36183e1a7ff8STejun Heo static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen)
36193e1a7ff8STejun Heo {
36203e1a7ff8STejun Heo const int base = 'z' - 'a' + 1;
36213e1a7ff8STejun Heo char *begin = buf + strlen(prefix);
36223e1a7ff8STejun Heo char *end = buf + buflen;
36233e1a7ff8STejun Heo char *p;
36243e1a7ff8STejun Heo int unit;
36253e1a7ff8STejun Heo
36263e1a7ff8STejun Heo p = end - 1;
36273e1a7ff8STejun Heo *p = '\0';
36283e1a7ff8STejun Heo unit = base;
36293e1a7ff8STejun Heo do {
36303e1a7ff8STejun Heo if (p == begin)
36313e1a7ff8STejun Heo return -EINVAL;
36323e1a7ff8STejun Heo *--p = 'a' + (index % unit);
36333e1a7ff8STejun Heo index = (index / unit) - 1;
36343e1a7ff8STejun Heo } while (index >= 0);
36353e1a7ff8STejun Heo
36363e1a7ff8STejun Heo memmove(begin, p, end - p);
36373e1a7ff8STejun Heo memcpy(buf, prefix, strlen(prefix));
36383e1a7ff8STejun Heo
36393e1a7ff8STejun Heo return 0;
36403e1a7ff8STejun Heo }
36413e1a7ff8STejun Heo
36423e1a7ff8STejun Heo /**
36431da177e4SLinus Torvalds * sd_probe - called during driver initialization and whenever a
36441da177e4SLinus Torvalds * new scsi device is attached to the system. It is called once
36451da177e4SLinus Torvalds * for each scsi device (not just disks) present.
36461da177e4SLinus Torvalds * @dev: pointer to device object
36471da177e4SLinus Torvalds *
36481da177e4SLinus Torvalds * Returns 0 if successful (or not interested in this scsi device
36491da177e4SLinus Torvalds * (e.g. scanner)); 1 when there is an error.
36501da177e4SLinus Torvalds *
36511da177e4SLinus Torvalds * Note: this function is invoked from the scsi mid-level.
36521da177e4SLinus Torvalds * This function sets up the mapping between a given
36531da177e4SLinus Torvalds * <host,channel,id,lun> (found in sdp) and new device name
36541da177e4SLinus Torvalds * (e.g. /dev/sda). More precisely it is the block device major
36551da177e4SLinus Torvalds * and minor number that is chosen here.
36561da177e4SLinus Torvalds *
36572db93ce8SPetr Uzel * Assume sd_probe is not re-entrant (for time being)
36582db93ce8SPetr Uzel * Also think about sd_probe() and sd_remove() running coincidentally.
36591da177e4SLinus Torvalds **/
sd_probe(struct device * dev)36601da177e4SLinus Torvalds static int sd_probe(struct device *dev)
36611da177e4SLinus Torvalds {
36621da177e4SLinus Torvalds struct scsi_device *sdp = to_scsi_device(dev);
36631da177e4SLinus Torvalds struct scsi_disk *sdkp;
36641da177e4SLinus Torvalds struct gendisk *gd;
3665439d77f7SH Hartley Sweeten int index;
36661da177e4SLinus Torvalds int error;
36671da177e4SLinus Torvalds
36686fe8c1dbSSubhash Jadavani scsi_autopm_get_device(sdp);
36691da177e4SLinus Torvalds error = -ENODEV;
367089d94756SHannes Reinecke if (sdp->type != TYPE_DISK &&
367189d94756SHannes Reinecke sdp->type != TYPE_ZBC &&
367289d94756SHannes Reinecke sdp->type != TYPE_MOD &&
367389d94756SHannes Reinecke sdp->type != TYPE_RBC)
36741da177e4SLinus Torvalds goto out;
36751da177e4SLinus Torvalds
3676bf1b4659SDamien Le Moal if (!IS_ENABLED(CONFIG_BLK_DEV_ZONED) && sdp->type == TYPE_ZBC) {
3677bf1b4659SDamien Le Moal sdev_printk(KERN_WARNING, sdp,
3678bf1b4659SDamien Le Moal "Unsupported ZBC host-managed device.\n");
367989d94756SHannes Reinecke goto out;
3680bf1b4659SDamien Le Moal }
3681bf1b4659SDamien Le Moal
36829ccfc756SJames Bottomley SCSI_LOG_HLQUEUE(3, sdev_printk(KERN_INFO, sdp,
36832db93ce8SPetr Uzel "sd_probe\n"));
36841da177e4SLinus Torvalds
36851da177e4SLinus Torvalds error = -ENOMEM;
368624669f75SJes Sorensen sdkp = kzalloc(sizeof(*sdkp), GFP_KERNEL);
36871da177e4SLinus Torvalds if (!sdkp)
36881da177e4SLinus Torvalds goto out;
36891da177e4SLinus Torvalds
36906f8191fdSChristoph Hellwig gd = blk_mq_alloc_disk_for_queue(sdp->request_queue,
36914a1fa41dSChristoph Hellwig &sd_bio_compl_lkclass);
36921da177e4SLinus Torvalds if (!gd)
3693c01228dbSJan Kara goto out_free;
36941da177e4SLinus Torvalds
369594015080SMatthew Wilcox index = ida_alloc(&sd_index_ida, GFP_KERNEL);
369694015080SMatthew Wilcox if (index < 0) {
369721208ae5SDave Kleikamp sdev_printk(KERN_WARNING, sdp, "sd_probe: memory exhausted.\n");
36981da177e4SLinus Torvalds goto out_put;
36991a03ae0fSMichael Reed }
37001a03ae0fSMichael Reed
37013e1a7ff8STejun Heo error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN);
370221208ae5SDave Kleikamp if (error) {
370321208ae5SDave Kleikamp sdev_printk(KERN_WARNING, sdp, "SCSI disk (sd) name length exceeded.\n");
3704f27bac27STejun Heo goto out_free_index;
370521208ae5SDave Kleikamp }
3706f27bac27STejun Heo
37071da177e4SLinus Torvalds sdkp->device = sdp;
37081da177e4SLinus Torvalds sdkp->disk = gd;
37091da177e4SLinus Torvalds sdkp->index = index;
37100610959fSMike Christie sdkp->max_retries = SD_MAX_RETRIES;
3711409f3499SArnd Bergmann atomic_set(&sdkp->openers, 0);
37129e1a1537SJosh Hunt atomic_set(&sdkp->device->ioerr_cnt, 0);
37131da177e4SLinus Torvalds
3714601e7638SJames Bottomley if (!sdp->request_queue->rq_timeout) {
3715601e7638SJames Bottomley if (sdp->type != TYPE_MOD)
3716601e7638SJames Bottomley blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT);
3717601e7638SJames Bottomley else
3718601e7638SJames Bottomley blk_queue_rq_timeout(sdp->request_queue,
3719601e7638SJames Bottomley SD_MOD_TIMEOUT);
3720601e7638SJames Bottomley }
3721601e7638SJames Bottomley
3722fad45c30SChristoph Hellwig device_initialize(&sdkp->disk_dev);
3723fad45c30SChristoph Hellwig sdkp->disk_dev.parent = get_device(dev);
3724fad45c30SChristoph Hellwig sdkp->disk_dev.class = &sd_disk_class;
3725fad45c30SChristoph Hellwig dev_set_name(&sdkp->disk_dev, "%s", dev_name(dev));
3726601e7638SJames Bottomley
3727fad45c30SChristoph Hellwig error = device_add(&sdkp->disk_dev);
3728265dfe8eSMing Lei if (error) {
3729fad45c30SChristoph Hellwig put_device(&sdkp->disk_dev);
3730265dfe8eSMing Lei goto out;
3731265dfe8eSMing Lei }
3732601e7638SJames Bottomley
3733478a8a05SAlan Stern dev_set_drvdata(dev, sdkp);
3734601e7638SJames Bottomley
373582a54da6SBart Van Assche gd->major = sd_major((index & 0xf0) >> 4);
373682a54da6SBart Van Assche gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
3737a58bd768SChristoph Hellwig gd->minors = SD_MINORS;
373882a54da6SBart Van Assche
373982a54da6SBart Van Assche gd->fops = &sd_fops;
3740e7f76552SChristoph Hellwig gd->private_data = sdkp;
374182a54da6SBart Van Assche
374282a54da6SBart Van Assche /* defaults, until the device tells us otherwise */
374382a54da6SBart Van Assche sdp->sector_size = 512;
374482a54da6SBart Van Assche sdkp->capacity = 0;
374582a54da6SBart Van Assche sdkp->media_present = 1;
374682a54da6SBart Van Assche sdkp->write_prot = 0;
374782a54da6SBart Van Assche sdkp->cache_override = 0;
374882a54da6SBart Van Assche sdkp->WCE = 0;
374982a54da6SBart Van Assche sdkp->RCD = 0;
375082a54da6SBart Van Assche sdkp->ATO = 0;
375182a54da6SBart Van Assche sdkp->first_scan = 1;
375282a54da6SBart Van Assche sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS;
375382a54da6SBart Van Assche
375482a54da6SBart Van Assche sd_revalidate_disk(gd);
375582a54da6SBart Van Assche
375682a54da6SBart Van Assche if (sdp->removable) {
375782a54da6SBart Van Assche gd->flags |= GENHD_FL_REMOVABLE;
375882a54da6SBart Van Assche gd->events |= DISK_EVENT_MEDIA_CHANGE;
375982a54da6SBart Van Assche gd->event_flags = DISK_EVENT_FLAG_POLL | DISK_EVENT_FLAG_UEVENT;
376082a54da6SBart Van Assche }
376182a54da6SBart Van Assche
376282a54da6SBart Van Assche blk_pm_runtime_init(sdp->request_queue, dev);
3763c74f8056SStanley Chu if (sdp->rpm_autosuspend) {
3764c74f8056SStanley Chu pm_runtime_set_autosuspend_delay(dev,
3765c74f8056SStanley Chu sdp->host->hostt->rpm_autosuspend_delay);
3766c74f8056SStanley Chu }
37672a7a891fSLuis Chamberlain
37682a7a891fSLuis Chamberlain error = device_add_disk(dev, gd, NULL);
37692a7a891fSLuis Chamberlain if (error) {
3770f3e692c8SLi Nan device_unregister(&sdkp->disk_dev);
37717274ce05SChristoph Hellwig put_disk(gd);
37722a7a891fSLuis Chamberlain goto out;
37732a7a891fSLuis Chamberlain }
37742a7a891fSLuis Chamberlain
377582a54da6SBart Van Assche if (sdkp->security) {
37760610959fSMike Christie sdkp->opal_dev = init_opal_dev(sdkp, &sd_sec_submit);
377782a54da6SBart Van Assche if (sdkp->opal_dev)
377882a54da6SBart Van Assche sd_printk(KERN_NOTICE, sdkp, "supports TCG Opal\n");
377982a54da6SBart Van Assche }
378082a54da6SBart Van Assche
378182a54da6SBart Van Assche sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
378282a54da6SBart Van Assche sdp->removable ? "removable " : "");
378382a54da6SBart Van Assche scsi_autopm_put_device(sdp);
37841da177e4SLinus Torvalds
37851da177e4SLinus Torvalds return 0;
37861da177e4SLinus Torvalds
3787f27bac27STejun Heo out_free_index:
378894015080SMatthew Wilcox ida_free(&sd_index_ida, index);
37891da177e4SLinus Torvalds out_put:
37901da177e4SLinus Torvalds put_disk(gd);
3791f170396cSColin Ian King out_free:
3792f170396cSColin Ian King kfree(sdkp);
37931da177e4SLinus Torvalds out:
37946fe8c1dbSSubhash Jadavani scsi_autopm_put_device(sdp);
37951da177e4SLinus Torvalds return error;
37961da177e4SLinus Torvalds }
37971da177e4SLinus Torvalds
37981da177e4SLinus Torvalds /**
37991da177e4SLinus Torvalds * sd_remove - called whenever a scsi disk (previously recognized by
38001da177e4SLinus Torvalds * sd_probe) is detached from the system. It is called (potentially
38011da177e4SLinus Torvalds * multiple times) during sd module unload.
3802f2a3313dSJohn Pittman * @dev: pointer to device object
38031da177e4SLinus Torvalds *
38041da177e4SLinus Torvalds * Note: this function is invoked from the scsi mid-level.
38051da177e4SLinus Torvalds * This function potentially frees up a device name (e.g. /dev/sdc)
38061da177e4SLinus Torvalds * that could be re-used by a subsequent sd_probe().
38071da177e4SLinus Torvalds * This function is not called when the built-in sd driver is "exit-ed".
38081da177e4SLinus Torvalds **/
sd_remove(struct device * dev)38091da177e4SLinus Torvalds static int sd_remove(struct device *dev)
38101da177e4SLinus Torvalds {
38119c63f7f6SChristoph Hellwig struct scsi_disk *sdkp = dev_get_drvdata(dev);
38121da177e4SLinus Torvalds
3813478a8a05SAlan Stern scsi_autopm_get_device(sdkp->device);
3814478a8a05SAlan Stern
3815fad45c30SChristoph Hellwig device_del(&sdkp->disk_dev);
38161da177e4SLinus Torvalds del_gendisk(sdkp->disk);
381799398d20SDamien Le Moal if (!sdkp->suspended)
38181da177e4SLinus Torvalds sd_shutdown(dev);
381939b7f1e2SAlan Stern
38209c63f7f6SChristoph Hellwig put_disk(sdkp->disk);
38211da177e4SLinus Torvalds return 0;
38221da177e4SLinus Torvalds }
38231da177e4SLinus Torvalds
scsi_disk_release(struct device * dev)3824ee959b00STony Jones static void scsi_disk_release(struct device *dev)
38251da177e4SLinus Torvalds {
3826ee959b00STony Jones struct scsi_disk *sdkp = to_scsi_disk(dev);
38271da177e4SLinus Torvalds
382894015080SMatthew Wilcox ida_free(&sd_index_ida, sdkp->index);
382930c4fdc3SDamien Le Moal sd_zbc_free_zone_info(sdkp);
3830c76c46faSChristoph Hellwig put_device(&sdkp->device->sdev_gendev);
3831534cf52aSChristoph Hellwig free_opal_dev(sdkp->opal_dev);
38325795eb44SJohannes Thumshirn
38331da177e4SLinus Torvalds kfree(sdkp);
38341da177e4SLinus Torvalds }
38351da177e4SLinus Torvalds
sd_start_stop_device(struct scsi_disk * sdkp,int start)3836cc5d2c8cSJames Bottomley static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
3837c3c94c5aSTejun Heo {
3838c3c94c5aSTejun Heo unsigned char cmd[6] = { START_STOP }; /* START_VALID */
3839785538bfSBart Van Assche struct scsi_sense_hdr sshdr;
3840af16cd63SMike Christie const struct scsi_exec_args exec_args = {
3841af16cd63SMike Christie .sshdr = &sshdr,
3842af16cd63SMike Christie .req_flags = BLK_MQ_REQ_PM,
3843af16cd63SMike Christie };
3844cc5d2c8cSJames Bottomley struct scsi_device *sdp = sdkp->device;
3845785538bfSBart Van Assche int res;
3846c3c94c5aSTejun Heo
3847c3c94c5aSTejun Heo if (start)
3848c3c94c5aSTejun Heo cmd[4] |= 1; /* START */
3849c3c94c5aSTejun Heo
3850d2886ea3SStefan Richter if (sdp->start_stop_pwr_cond)
3851d2886ea3SStefan Richter cmd[4] |= start ? 1 << 4 : 3 << 4; /* Active or Standby */
3852d2886ea3SStefan Richter
3853c3c94c5aSTejun Heo if (!scsi_device_online(sdp))
3854c3c94c5aSTejun Heo return -ENODEV;
3855c3c94c5aSTejun Heo
3856af16cd63SMike Christie res = scsi_execute_cmd(sdp, cmd, REQ_OP_DRV_IN, NULL, 0, SD_TIMEOUT,
3857af16cd63SMike Christie sdkp->max_retries, &exec_args);
3858785538bfSBart Van Assche if (res) {
3859785538bfSBart Van Assche sd_print_result(sdkp, "Start/Stop Unit failed", res);
3860785538bfSBart Van Assche if (res > 0 && scsi_sense_valid(&sshdr)) {
3861785538bfSBart Van Assche sd_print_sense_hdr(sdkp, &sshdr);
3862785538bfSBart Van Assche /* 0x3a is medium not present */
3863785538bfSBart Van Assche if (sshdr.asc == 0x3a)
3864785538bfSBart Van Assche res = 0;
3865785538bfSBart Van Assche }
3866785538bfSBart Van Assche }
3867c3c94c5aSTejun Heo
3868785538bfSBart Van Assche /* SCSI error codes must not go to the generic layer */
3869785538bfSBart Van Assche if (res)
3870785538bfSBart Van Assche return -EIO;
3871785538bfSBart Van Assche
3872785538bfSBart Van Assche return 0;
3873c3c94c5aSTejun Heo }
3874c3c94c5aSTejun Heo
38751da177e4SLinus Torvalds /*
38761da177e4SLinus Torvalds * Send a SYNCHRONIZE CACHE instruction down to the device through
38771da177e4SLinus Torvalds * the normal SCSI command structure. Wait for the command to
38781da177e4SLinus Torvalds * complete.
38791da177e4SLinus Torvalds */
sd_shutdown(struct device * dev)38801da177e4SLinus Torvalds static void sd_shutdown(struct device *dev)
38811da177e4SLinus Torvalds {
38823d9a1f53SChristoph Hellwig struct scsi_disk *sdkp = dev_get_drvdata(dev);
38831da177e4SLinus Torvalds
38841da177e4SLinus Torvalds if (!sdkp)
38851da177e4SLinus Torvalds return; /* this can happen */
38861da177e4SLinus Torvalds
388754f57588SLin Ming if (pm_runtime_suspended(dev))
38883d9a1f53SChristoph Hellwig return;
388954f57588SLin Ming
389095897910SOliver Neukum if (sdkp->WCE && sdkp->media_present) {
3891e73aec82SMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
3892c94c4468SMike Christie sd_sync_cache(sdkp);
38931da177e4SLinus Torvalds }
3894c3c94c5aSTejun Heo
389524eca2dcSDamien Le Moal if ((system_state != SYSTEM_RESTART &&
389624eca2dcSDamien Le Moal sdkp->device->manage_system_start_stop) ||
389724eca2dcSDamien Le Moal (system_state == SYSTEM_POWER_OFF &&
389824eca2dcSDamien Le Moal sdkp->device->manage_shutdown)) {
3899cc5d2c8cSJames Bottomley sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
3900cc5d2c8cSJames Bottomley sd_start_stop_device(sdkp, 0);
3901c3c94c5aSTejun Heo }
390239b7f1e2SAlan Stern }
39031da177e4SLinus Torvalds
sd_do_start_stop(struct scsi_device * sdev,bool runtime)39043cc2ffe5SDamien Le Moal static inline bool sd_do_start_stop(struct scsi_device *sdev, bool runtime)
39053cc2ffe5SDamien Le Moal {
39063cc2ffe5SDamien Le Moal return (sdev->manage_system_start_stop && !runtime) ||
39073cc2ffe5SDamien Le Moal (sdev->manage_runtime_start_stop && runtime);
39083cc2ffe5SDamien Le Moal }
39093cc2ffe5SDamien Le Moal
sd_suspend_common(struct device * dev,bool runtime)39103cc2ffe5SDamien Le Moal static int sd_suspend_common(struct device *dev, bool runtime)
3911c3c94c5aSTejun Heo {
39123d9a1f53SChristoph Hellwig struct scsi_disk *sdkp = dev_get_drvdata(dev);
391309ff92feSAlan Stern int ret = 0;
3914c3c94c5aSTejun Heo
391513b43891SAlan Stern if (!sdkp) /* E.g.: runtime suspend following sd_remove() */
391613b43891SAlan Stern return 0;
3917c3c94c5aSTejun Heo
391895897910SOliver Neukum if (sdkp->WCE && sdkp->media_present) {
3919af4edb1dSAdrian Hunter if (!sdkp->device->silence_suspend)
3920cc5d2c8cSJames Bottomley sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
3921c94c4468SMike Christie ret = sd_sync_cache(sdkp);
392295897910SOliver Neukum /* ignore OFFLINE device */
392395897910SOliver Neukum if (ret == -ENODEV)
39244fa83244SDerek Basehore return 0;
39254fa83244SDerek Basehore
3926c94c4468SMike Christie if (ret)
39274fa83244SDerek Basehore return ret;
392895897910SOliver Neukum }
3929c3c94c5aSTejun Heo
39303cc2ffe5SDamien Le Moal if (sd_do_start_stop(sdkp->device, runtime)) {
3931af4edb1dSAdrian Hunter if (!sdkp->device->silence_suspend)
3932cc5d2c8cSJames Bottomley sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
393395897910SOliver Neukum /* an error is not worth aborting a system sleep */
3934cc5d2c8cSJames Bottomley ret = sd_start_stop_device(sdkp, 0);
39353cc2ffe5SDamien Le Moal if (!runtime)
393695897910SOliver Neukum ret = 0;
3937c3c94c5aSTejun Heo }
3938c3c94c5aSTejun Heo
393999398d20SDamien Le Moal if (!ret)
394099398d20SDamien Le Moal sdkp->suspended = true;
394199398d20SDamien Le Moal
394209ff92feSAlan Stern return ret;
3943c3c94c5aSTejun Heo }
3944c3c94c5aSTejun Heo
sd_suspend_system(struct device * dev)394595897910SOliver Neukum static int sd_suspend_system(struct device *dev)
394695897910SOliver Neukum {
39479131bff6SBart Van Assche if (pm_runtime_suspended(dev))
39489131bff6SBart Van Assche return 0;
39499131bff6SBart Van Assche
39503cc2ffe5SDamien Le Moal return sd_suspend_common(dev, false);
395195897910SOliver Neukum }
395295897910SOliver Neukum
sd_suspend_runtime(struct device * dev)395395897910SOliver Neukum static int sd_suspend_runtime(struct device *dev)
395495897910SOliver Neukum {
39553cc2ffe5SDamien Le Moal return sd_suspend_common(dev, true);
395695897910SOliver Neukum }
395795897910SOliver Neukum
sd_resume(struct device * dev)3958a1f506afSDamien Le Moal static int sd_resume(struct device *dev)
3959a1f506afSDamien Le Moal {
3960a1f506afSDamien Le Moal struct scsi_disk *sdkp = dev_get_drvdata(dev);
3961a1f506afSDamien Le Moal
39628d5aebffSJohan Hovold sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
39638d5aebffSJohan Hovold
3964a1f506afSDamien Le Moal if (opal_unlock_from_suspend(sdkp->opal_dev)) {
3965a1f506afSDamien Le Moal sd_printk(KERN_NOTICE, sdkp, "OPAL unlock failed\n");
3966a1f506afSDamien Le Moal return -EIO;
3967a1f506afSDamien Le Moal }
3968a1f506afSDamien Le Moal
3969a1f506afSDamien Le Moal return 0;
3970a1f506afSDamien Le Moal }
3971a1f506afSDamien Le Moal
sd_resume_common(struct device * dev,bool runtime)3972a1f506afSDamien Le Moal static int sd_resume_common(struct device *dev, bool runtime)
3973c3c94c5aSTejun Heo {
39743d9a1f53SChristoph Hellwig struct scsi_disk *sdkp = dev_get_drvdata(dev);
39759e6075e1SDamien Le Moal int ret;
3976c3c94c5aSTejun Heo
397713b43891SAlan Stern if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */
397813b43891SAlan Stern return 0;
397913b43891SAlan Stern
398099398d20SDamien Le Moal if (!sd_do_start_stop(sdkp->device, runtime)) {
398199398d20SDamien Le Moal sdkp->suspended = false;
39823d9a1f53SChristoph Hellwig return 0;
398399398d20SDamien Le Moal }
3984c3c94c5aSTejun Heo
39858d5aebffSJohan Hovold sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
3986d80210f2SChristoph Hellwig ret = sd_start_stop_device(sdkp, 1);
398799398d20SDamien Le Moal if (!ret) {
3988a1f506afSDamien Le Moal sd_resume(dev);
398999398d20SDamien Le Moal sdkp->suspended = false;
399099398d20SDamien Le Moal }
399199398d20SDamien Le Moal
3992d80210f2SChristoph Hellwig return ret;
3993c3c94c5aSTejun Heo }
3994c3c94c5aSTejun Heo
sd_resume_system(struct device * dev)39951c957532SBart Van Assche static int sd_resume_system(struct device *dev)
39961c957532SBart Van Assche {
3997b32c0a7cSDamien Le Moal if (pm_runtime_suspended(dev)) {
3998b32c0a7cSDamien Le Moal struct scsi_disk *sdkp = dev_get_drvdata(dev);
3999b32c0a7cSDamien Le Moal struct scsi_device *sdp = sdkp ? sdkp->device : NULL;
4000b32c0a7cSDamien Le Moal
4001b32c0a7cSDamien Le Moal if (sdp && sdp->force_runtime_start_on_system_start)
4002b32c0a7cSDamien Le Moal pm_request_resume(dev);
4003b32c0a7cSDamien Le Moal
40049131bff6SBart Van Assche return 0;
4005b32c0a7cSDamien Le Moal }
40069131bff6SBart Van Assche
4007a1f506afSDamien Le Moal return sd_resume_common(dev, false);
40081c957532SBart Van Assche }
40091c957532SBart Van Assche
sd_resume_runtime(struct device * dev)4010ed4246d3SMartin Kepplinger static int sd_resume_runtime(struct device *dev)
4011ed4246d3SMartin Kepplinger {
4012ed4246d3SMartin Kepplinger struct scsi_disk *sdkp = dev_get_drvdata(dev);
401385374b63SMiles Chen struct scsi_device *sdp;
401485374b63SMiles Chen
401585374b63SMiles Chen if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */
401685374b63SMiles Chen return 0;
401785374b63SMiles Chen
401885374b63SMiles Chen sdp = sdkp->device;
4019ed4246d3SMartin Kepplinger
4020ed4246d3SMartin Kepplinger if (sdp->ignore_media_change) {
4021ed4246d3SMartin Kepplinger /* clear the device's sense data */
4022ed4246d3SMartin Kepplinger static const u8 cmd[10] = { REQUEST_SENSE };
4023af16cd63SMike Christie const struct scsi_exec_args exec_args = {
4024af16cd63SMike Christie .req_flags = BLK_MQ_REQ_PM,
4025af16cd63SMike Christie };
4026ed4246d3SMartin Kepplinger
4027af16cd63SMike Christie if (scsi_execute_cmd(sdp, cmd, REQ_OP_DRV_IN, NULL, 0,
4028af16cd63SMike Christie sdp->request_queue->rq_timeout, 1,
4029af16cd63SMike Christie &exec_args))
4030ed4246d3SMartin Kepplinger sd_printk(KERN_NOTICE, sdkp,
4031ed4246d3SMartin Kepplinger "Failed to clear sense data\n");
4032ed4246d3SMartin Kepplinger }
4033ed4246d3SMartin Kepplinger
4034a1f506afSDamien Le Moal return sd_resume_common(dev, true);
4035ed4246d3SMartin Kepplinger }
4036ed4246d3SMartin Kepplinger
4037efcf965aSBart Van Assche static const struct dev_pm_ops sd_pm_ops = {
4038efcf965aSBart Van Assche .suspend = sd_suspend_system,
4039efcf965aSBart Van Assche .resume = sd_resume_system,
4040efcf965aSBart Van Assche .poweroff = sd_suspend_system,
4041efcf965aSBart Van Assche .restore = sd_resume_system,
4042efcf965aSBart Van Assche .runtime_suspend = sd_suspend_runtime,
4043efcf965aSBart Van Assche .runtime_resume = sd_resume_runtime,
4044efcf965aSBart Van Assche };
4045efcf965aSBart Van Assche
4046efcf965aSBart Van Assche static struct scsi_driver sd_template = {
4047efcf965aSBart Van Assche .gendrv = {
4048efcf965aSBart Van Assche .name = "sd",
4049efcf965aSBart Van Assche .owner = THIS_MODULE,
4050efcf965aSBart Van Assche .probe = sd_probe,
4051efcf965aSBart Van Assche .probe_type = PROBE_PREFER_ASYNCHRONOUS,
4052efcf965aSBart Van Assche .remove = sd_remove,
4053efcf965aSBart Van Assche .shutdown = sd_shutdown,
4054efcf965aSBart Van Assche .pm = &sd_pm_ops,
4055efcf965aSBart Van Assche },
4056efcf965aSBart Van Assche .rescan = sd_rescan,
4057a1f506afSDamien Le Moal .resume = sd_resume,
4058efcf965aSBart Van Assche .init_command = sd_init_command,
4059efcf965aSBart Van Assche .uninit_command = sd_uninit_command,
4060efcf965aSBart Van Assche .done = sd_done,
4061efcf965aSBart Van Assche .eh_action = sd_eh_action,
4062efcf965aSBart Van Assche .eh_reset = sd_eh_reset,
4063efcf965aSBart Van Assche };
4064efcf965aSBart Van Assche
40651da177e4SLinus Torvalds /**
40661da177e4SLinus Torvalds * init_sd - entry point for this driver (both when built in or when
40671da177e4SLinus Torvalds * a module).
40681da177e4SLinus Torvalds *
40691da177e4SLinus Torvalds * Note: this function registers this driver with the scsi mid-level.
40701da177e4SLinus Torvalds **/
init_sd(void)40711da177e4SLinus Torvalds static int __init init_sd(void)
40721da177e4SLinus Torvalds {
40735e4009baSJeff Garzik int majors = 0, i, err;
40741da177e4SLinus Torvalds
40751da177e4SLinus Torvalds SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n"));
40761da177e4SLinus Torvalds
40770761df9cSHannes Reinecke for (i = 0; i < SD_MAJORS; i++) {
4078996e509bSChristoph Hellwig if (__register_blkdev(sd_major(i), "sd", sd_default_probe))
40790761df9cSHannes Reinecke continue;
40801da177e4SLinus Torvalds majors++;
40810761df9cSHannes Reinecke }
40821da177e4SLinus Torvalds
40831da177e4SLinus Torvalds if (!majors)
40841da177e4SLinus Torvalds return -ENODEV;
40851da177e4SLinus Torvalds
40865e4009baSJeff Garzik err = class_register(&sd_disk_class);
40875e4009baSJeff Garzik if (err)
40885e4009baSJeff Garzik goto err_out;
40896bdaa1f1SJames Bottomley
409061cce6f6SJens Axboe sd_page_pool = mempool_create_page_pool(SD_MEMPOOL_SIZE, 0);
409161cce6f6SJens Axboe if (!sd_page_pool) {
409261cce6f6SJens Axboe printk(KERN_ERR "sd: can't init discard page pool\n");
409361cce6f6SJens Axboe err = -ENOMEM;
40942b379516SFengnan Chang goto err_out_class;
409561cce6f6SJens Axboe }
409661cce6f6SJens Axboe
4097afd5e34bSJoel D. Diaz err = scsi_register_driver(&sd_template.gendrv);
4098afd5e34bSJoel D. Diaz if (err)
4099afd5e34bSJoel D. Diaz goto err_out_driver;
4100afd5e34bSJoel D. Diaz
41015e4009baSJeff Garzik return 0;
41025e4009baSJeff Garzik
4103afd5e34bSJoel D. Diaz err_out_driver:
410461cce6f6SJens Axboe mempool_destroy(sd_page_pool);
41055e4009baSJeff Garzik err_out_class:
41065e4009baSJeff Garzik class_unregister(&sd_disk_class);
41075e4009baSJeff Garzik err_out:
41085e4009baSJeff Garzik for (i = 0; i < SD_MAJORS; i++)
41095e4009baSJeff Garzik unregister_blkdev(sd_major(i), "sd");
41105e4009baSJeff Garzik return err;
41111da177e4SLinus Torvalds }
41121da177e4SLinus Torvalds
41131da177e4SLinus Torvalds /**
41141da177e4SLinus Torvalds * exit_sd - exit point for this driver (when it is a module).
41151da177e4SLinus Torvalds *
41161da177e4SLinus Torvalds * Note: this function unregisters this driver from the scsi mid-level.
41171da177e4SLinus Torvalds **/
exit_sd(void)41181da177e4SLinus Torvalds static void __exit exit_sd(void)
41191da177e4SLinus Torvalds {
41201da177e4SLinus Torvalds int i;
41211da177e4SLinus Torvalds
41221da177e4SLinus Torvalds SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n"));
41231da177e4SLinus Torvalds
4124afd5e34bSJoel D. Diaz scsi_unregister_driver(&sd_template.gendrv);
412561cce6f6SJens Axboe mempool_destroy(sd_page_pool);
41264e7392ecSMartin K. Petersen
41275e4009baSJeff Garzik class_unregister(&sd_disk_class);
41285e4009baSJeff Garzik
4129996e509bSChristoph Hellwig for (i = 0; i < SD_MAJORS; i++)
41301da177e4SLinus Torvalds unregister_blkdev(sd_major(i), "sd");
41311da177e4SLinus Torvalds }
41321da177e4SLinus Torvalds
41331da177e4SLinus Torvalds module_init(init_sd);
41341da177e4SLinus Torvalds module_exit(exit_sd);
4135e73aec82SMartin K. Petersen
sd_print_sense_hdr(struct scsi_disk * sdkp,struct scsi_sense_hdr * sshdr)4136a35989a0SDamien Le Moal void sd_print_sense_hdr(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr)
4137e73aec82SMartin K. Petersen {
413821045519SHannes Reinecke scsi_print_sense_hdr(sdkp->device,
4139d811b848SHannes Reinecke sdkp->disk ? sdkp->disk->disk_name : NULL, sshdr);
4140e73aec82SMartin K. Petersen }
4141e73aec82SMartin K. Petersen
sd_print_result(const struct scsi_disk * sdkp,const char * msg,int result)4142a35989a0SDamien Le Moal void sd_print_result(const struct scsi_disk *sdkp, const char *msg, int result)
4143e73aec82SMartin K. Petersen {
4144ef61329dSHannes Reinecke const char *hb_string = scsi_hostbyte_string(result);
4145ef61329dSHannes Reinecke
414654c29086SHannes Reinecke if (hb_string)
4147ef61329dSHannes Reinecke sd_printk(KERN_INFO, sdkp,
4148ef61329dSHannes Reinecke "%s: Result: hostbyte=%s driverbyte=%s\n", msg,
4149ef61329dSHannes Reinecke hb_string ? hb_string : "invalid",
415054c29086SHannes Reinecke "DRIVER_OK");
4151ef61329dSHannes Reinecke else
4152ef61329dSHannes Reinecke sd_printk(KERN_INFO, sdkp,
415354c29086SHannes Reinecke "%s: Result: hostbyte=0x%02x driverbyte=%s\n",
415454c29086SHannes Reinecke msg, host_byte(result), "DRIVER_OK");
4155e73aec82SMartin K. Petersen }
4156