11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sd.c Copyright (C) 1992 Drew Eckhardt 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Linux scsi disk driver 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Initial versions: Drew Eckhardt 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Subsequent revisions: Eric Youngdale 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Modification history: 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Drew Eckhardt <drew@colorado.edu> original 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Eric Youngdale <eric@andante.org> add scatter-gather, multiple 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * outstanding request, and other enhancements. 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Support loadable low-level scsi drivers. 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Jirka Hanika <geo@ff.cuni.cz> support more scsi disks using 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * eight major numbers. 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Richard Gooch <rgooch@atnf.csiro.au> support devfs. 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Torben Mathiasen <tmm@image.dk> Resource allocation fixes in 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sd_init and cleanups. 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Alex Davis <letmein@erols.com> Fix problem where partition info 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * not being read in sd_open. Fix problem where removable media 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * could be ejected after sd_open. 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Douglas Gilbert <dgilbert@interlog.com> cleanup for lk 2.5.x 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Badari Pulavarty <pbadari@us.ibm.com>, Matthew Wilcox 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * <willy@debian.org>, Kurt Garloff <garloff@suse.de>: 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Support 32k/1M disks. 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Logging policy (needs CONFIG_SCSI_LOGGING defined): 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - setting up transfer: SCSI_LOG_HLQUEUE levels 1 and 2 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - end of transfer (bh + scsi_lib): SCSI_LOG_HLCOMPLETE level 1 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - entering sd_ioctl: SCSI_LOG_IOCTL level 1 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - entering other commands: SCSI_LOG_HLQUEUE level 3 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Note: when the logging level is set by the user, it must be greater 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * than the level indicated above to trigger output. 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fs.h> 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h> 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/bio.h> 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/genhd.h> 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/hdreg.h> 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h> 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/idr.h> 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h> 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/blkdev.h> 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/blkpg.h> 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 490b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven#include <linux/mutex.h> 507404ad3b6d04efbd918e9e2e776bf560fbedf47dJames Bottomley#include <linux/string_helpers.h> 514ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven#include <linux/async.h> 525a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 5354f57588463db1105f4a93b2902a6f95cb8f796aLin Ming#include <linux/pm_runtime.h> 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h> 558f76d151b010980d137bfdc736d1d8f64b489165Dave Hansen#include <asm/unaligned.h> 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi.h> 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi_cmnd.h> 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi_dbg.h> 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi_device.h> 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi_driver.h> 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi_eh.h> 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi_host.h> 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi_ioctl.h> 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsicam.h> 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 67aa91696e56a0870db5754610e9f9b937e77507e0Martin K. Petersen#include "sd.h" 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "scsi_logging.h" 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 70f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_AUTHOR("Eric Youngdale"); 71f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_DESCRIPTION("SCSI disk (sd) driver"); 72f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_LICENSE("GPL"); 73f018fa552c52642a6b9db2bda90477762e42163fRene Herman 74f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK0_MAJOR); 75f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK1_MAJOR); 76f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK2_MAJOR); 77f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK3_MAJOR); 78f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK4_MAJOR); 79f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK5_MAJOR); 80f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK6_MAJOR); 81f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK7_MAJOR); 82f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK8_MAJOR); 83f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK9_MAJOR); 84f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK10_MAJOR); 85f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK11_MAJOR); 86f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK12_MAJOR); 87f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK13_MAJOR); 88f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK14_MAJOR); 89f018fa552c52642a6b9db2bda90477762e42163fRene HermanMODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK15_MAJOR); 90d7b8bcb0a0819315a51cae620ff7ae0c1704c069Michael TokarevMODULE_ALIAS_SCSI_DEVICE(TYPE_DISK); 91d7b8bcb0a0819315a51cae620ff7ae0c1704c069Michael TokarevMODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); 92d7b8bcb0a0819315a51cae620ff7ae0c1704c069Michael TokarevMODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); 93f018fa552c52642a6b9db2bda90477762e42163fRene Herman 94870d6656126add8e383645732b03df2b7ccd4f94Tejun Heo#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) 95f615b48cc7df7cac3865ec76ac1a5bb04d3e07f4Tejun Heo#define SD_MINORS 16 96870d6656126add8e383645732b03df2b7ccd4f94Tejun Heo#else 973e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo#define SD_MINORS 0 98870d6656126add8e383645732b03df2b7ccd4f94Tejun Heo#endif 99870d6656126add8e383645732b03df2b7ccd4f94Tejun Heo 100c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersenstatic void sd_config_discard(struct scsi_disk *, unsigned int); 1017b3d9545f9ac8b31528dd2d6d8ec8d19922917b8Linus Torvaldsstatic int sd_revalidate_disk(struct gendisk *); 10272ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heostatic void sd_unlock_native_capacity(struct gendisk *disk); 1037b3d9545f9ac8b31528dd2d6d8ec8d19922917b8Linus Torvaldsstatic int sd_probe(struct device *); 1047b3d9545f9ac8b31528dd2d6d8ec8d19922917b8Linus Torvaldsstatic int sd_remove(struct device *); 1057b3d9545f9ac8b31528dd2d6d8ec8d19922917b8Linus Torvaldsstatic void sd_shutdown(struct device *); 1067b3d9545f9ac8b31528dd2d6d8ec8d19922917b8Linus Torvaldsstatic int sd_suspend(struct device *, pm_message_t state); 1077b3d9545f9ac8b31528dd2d6d8ec8d19922917b8Linus Torvaldsstatic int sd_resume(struct device *); 1087b3d9545f9ac8b31528dd2d6d8ec8d19922917b8Linus Torvaldsstatic void sd_rescan(struct device *); 1097b3d9545f9ac8b31528dd2d6d8ec8d19922917b8Linus Torvaldsstatic int sd_done(struct scsi_cmnd *); 11018a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersenstatic int sd_eh_action(struct scsi_cmnd *, unsigned char *, int, int); 1117b3d9545f9ac8b31528dd2d6d8ec8d19922917b8Linus Torvaldsstatic void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer); 112ee959b00c335d7780136c5abda37809191fe52c3Tony Jonesstatic void scsi_disk_release(struct device *cdev); 1137b3d9545f9ac8b31528dd2d6d8ec8d19922917b8Linus Torvaldsstatic void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); 1147b3d9545f9ac8b31528dd2d6d8ec8d19922917b8Linus Torvaldsstatic void sd_print_result(struct scsi_disk *, int); 1157b3d9545f9ac8b31528dd2d6d8ec8d19922917b8Linus Torvalds 1164034cc68157bfa0b6622efe368488d3d3e20f4e6Tejun Heostatic DEFINE_SPINLOCK(sd_index_lock); 117f27bac2761cab5a2e212dea602d22457a9aa6943Tejun Heostatic DEFINE_IDA(sd_index_ida); 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* This semaphore is used to mediate the 0->1 reference get in the 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * face of object destruction (i.e. we can't allow a get on an 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * object after last put) */ 1220b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Venstatic DEFINE_MUTEX(sd_ref_mutex); 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 124439d77f70f18ebe2b28757b141e67a25575fe363H Hartley Sweetenstatic struct kmem_cache *sd_cdb_cache; 125439d77f70f18ebe2b28757b141e67a25575fe363H Hartley Sweetenstatic mempool_t *sd_cdb_pool; 1264e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen 1276bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomleystatic const char *sd_cache_types[] = { 1286bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley "write through", "none", "write back", 1296bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley "write back, no read (daft)" 1306bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley}; 1316bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley 132ee959b00c335d7780136c5abda37809191fe52c3Tony Jonesstatic ssize_t 133ee959b00c335d7780136c5abda37809191fe52c3Tony Jonessd_store_cache_type(struct device *dev, struct device_attribute *attr, 134ee959b00c335d7780136c5abda37809191fe52c3Tony Jones const char *buf, size_t count) 1356bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley{ 1366bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley int i, ct = -1, rcd, wce, sp; 137ee959b00c335d7780136c5abda37809191fe52c3Tony Jones struct scsi_disk *sdkp = to_scsi_disk(dev); 1386bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley struct scsi_device *sdp = sdkp->device; 1396bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley char buffer[64]; 1406bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley char *buffer_data; 1416bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley struct scsi_mode_data data; 1426bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley struct scsi_sense_hdr sshdr; 1436bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley int len; 1446bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley 1456bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley if (sdp->type != TYPE_DISK) 1466bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley /* no cache control on RBC devices; theoretically they 1476bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley * can do it, but there's probably so many exceptions 1486bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley * it's not worth the risk */ 1496bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley return -EINVAL; 1506bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley 1516391a11375de5e2bb1eb8481e54619761dc65d9fTobias Klauser for (i = 0; i < ARRAY_SIZE(sd_cache_types); i++) { 152439d77f70f18ebe2b28757b141e67a25575fe363H Hartley Sweeten len = strlen(sd_cache_types[i]); 1536bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley if (strncmp(sd_cache_types[i], buf, len) == 0 && 1546bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley buf[len] == '\n') { 1556bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley ct = i; 1566bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley break; 1576bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley } 1586bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley } 1596bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley if (ct < 0) 1606bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley return -EINVAL; 1616bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley rcd = ct & 0x01 ? 1 : 0; 1626bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley wce = ct & 0x02 ? 1 : 0; 1636bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), SD_TIMEOUT, 1646bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley SD_MAX_RETRIES, &data, NULL)) 1656bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley return -EINVAL; 166a9312fb839e90668d05a90024f3a7e7ff646a4a3Andrew Morton len = min_t(size_t, sizeof(buffer), data.length - data.header_length - 1676bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley data.block_descriptor_length); 1686bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley buffer_data = buffer + data.header_length + 1696bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley data.block_descriptor_length; 1706bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley buffer_data[2] &= ~0x05; 1716bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley buffer_data[2] |= wce << 2 | rcd; 1726bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley sp = buffer_data[0] & 0x80 ? 1 : 0; 1736bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley 1746bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley if (scsi_mode_select(sdp, 1, sp, 8, buffer_data, len, SD_TIMEOUT, 1756bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley SD_MAX_RETRIES, &data, &sshdr)) { 1766bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley if (scsi_sense_valid(&sshdr)) 177e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_print_sense_hdr(sdkp, &sshdr); 1786bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley return -EINVAL; 1796bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley } 180f98a8cae12f2b2a8f9bfd7a53c990a1a405e880eAndrew Patterson revalidate_disk(sdkp->disk); 1816bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley return count; 1826bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley} 1836bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley 184ee959b00c335d7780136c5abda37809191fe52c3Tony Jonesstatic ssize_t 185ee959b00c335d7780136c5abda37809191fe52c3Tony Jonessd_store_manage_start_stop(struct device *dev, struct device_attribute *attr, 186ee959b00c335d7780136c5abda37809191fe52c3Tony Jones const char *buf, size_t count) 187c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo{ 188ee959b00c335d7780136c5abda37809191fe52c3Tony Jones struct scsi_disk *sdkp = to_scsi_disk(dev); 189c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo struct scsi_device *sdp = sdkp->device; 190c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 191c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo if (!capable(CAP_SYS_ADMIN)) 192c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo return -EACCES; 193c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 194c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo sdp->manage_start_stop = simple_strtoul(buf, NULL, 10); 195c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 196c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo return count; 197c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo} 198c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 199ee959b00c335d7780136c5abda37809191fe52c3Tony Jonesstatic ssize_t 200ee959b00c335d7780136c5abda37809191fe52c3Tony Jonessd_store_allow_restart(struct device *dev, struct device_attribute *attr, 201ee959b00c335d7780136c5abda37809191fe52c3Tony Jones const char *buf, size_t count) 202a144c5ae0956fb262e6c82624c82b1110a451437Brian King{ 203ee959b00c335d7780136c5abda37809191fe52c3Tony Jones struct scsi_disk *sdkp = to_scsi_disk(dev); 204a144c5ae0956fb262e6c82624c82b1110a451437Brian King struct scsi_device *sdp = sdkp->device; 205a144c5ae0956fb262e6c82624c82b1110a451437Brian King 206a144c5ae0956fb262e6c82624c82b1110a451437Brian King if (!capable(CAP_SYS_ADMIN)) 207a144c5ae0956fb262e6c82624c82b1110a451437Brian King return -EACCES; 208a144c5ae0956fb262e6c82624c82b1110a451437Brian King 209a144c5ae0956fb262e6c82624c82b1110a451437Brian King if (sdp->type != TYPE_DISK) 210a144c5ae0956fb262e6c82624c82b1110a451437Brian King return -EINVAL; 211a144c5ae0956fb262e6c82624c82b1110a451437Brian King 212a144c5ae0956fb262e6c82624c82b1110a451437Brian King sdp->allow_restart = simple_strtoul(buf, NULL, 10); 213a144c5ae0956fb262e6c82624c82b1110a451437Brian King 214a144c5ae0956fb262e6c82624c82b1110a451437Brian King return count; 215a144c5ae0956fb262e6c82624c82b1110a451437Brian King} 216a144c5ae0956fb262e6c82624c82b1110a451437Brian King 217ee959b00c335d7780136c5abda37809191fe52c3Tony Jonesstatic ssize_t 218ee959b00c335d7780136c5abda37809191fe52c3Tony Jonessd_show_cache_type(struct device *dev, struct device_attribute *attr, 219ee959b00c335d7780136c5abda37809191fe52c3Tony Jones char *buf) 2206bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley{ 221ee959b00c335d7780136c5abda37809191fe52c3Tony Jones struct scsi_disk *sdkp = to_scsi_disk(dev); 2226bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley int ct = sdkp->RCD + 2*sdkp->WCE; 2236bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley 2246bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley return snprintf(buf, 40, "%s\n", sd_cache_types[ct]); 2256bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley} 2266bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley 227ee959b00c335d7780136c5abda37809191fe52c3Tony Jonesstatic ssize_t 228ee959b00c335d7780136c5abda37809191fe52c3Tony Jonessd_show_fua(struct device *dev, struct device_attribute *attr, char *buf) 2296bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley{ 230ee959b00c335d7780136c5abda37809191fe52c3Tony Jones struct scsi_disk *sdkp = to_scsi_disk(dev); 2316bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley 2326bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley return snprintf(buf, 20, "%u\n", sdkp->DPOFUA); 2336bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley} 2346bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley 235ee959b00c335d7780136c5abda37809191fe52c3Tony Jonesstatic ssize_t 236ee959b00c335d7780136c5abda37809191fe52c3Tony Jonessd_show_manage_start_stop(struct device *dev, struct device_attribute *attr, 237ee959b00c335d7780136c5abda37809191fe52c3Tony Jones char *buf) 238c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo{ 239ee959b00c335d7780136c5abda37809191fe52c3Tony Jones struct scsi_disk *sdkp = to_scsi_disk(dev); 240c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo struct scsi_device *sdp = sdkp->device; 241c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 242c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo return snprintf(buf, 20, "%u\n", sdp->manage_start_stop); 243c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo} 244c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 245ee959b00c335d7780136c5abda37809191fe52c3Tony Jonesstatic ssize_t 246ee959b00c335d7780136c5abda37809191fe52c3Tony Jonessd_show_allow_restart(struct device *dev, struct device_attribute *attr, 247ee959b00c335d7780136c5abda37809191fe52c3Tony Jones char *buf) 248a144c5ae0956fb262e6c82624c82b1110a451437Brian King{ 249ee959b00c335d7780136c5abda37809191fe52c3Tony Jones struct scsi_disk *sdkp = to_scsi_disk(dev); 250a144c5ae0956fb262e6c82624c82b1110a451437Brian King 251a144c5ae0956fb262e6c82624c82b1110a451437Brian King return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart); 252a144c5ae0956fb262e6c82624c82b1110a451437Brian King} 253a144c5ae0956fb262e6c82624c82b1110a451437Brian King 254e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersenstatic ssize_t 255e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersensd_show_protection_type(struct device *dev, struct device_attribute *attr, 256e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen char *buf) 257e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen{ 258e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev); 259e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 260e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen return snprintf(buf, 20, "%u\n", sdkp->protection_type); 261e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen} 262e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 263e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersenstatic ssize_t 264518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersensd_show_protection_mode(struct device *dev, struct device_attribute *attr, 265518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen char *buf) 266518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen{ 267518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev); 268518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen struct scsi_device *sdp = sdkp->device; 269518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen unsigned int dif, dix; 270518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen 271518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen dif = scsi_host_dif_capable(sdp->host, sdkp->protection_type); 272518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen dix = scsi_host_dix_capable(sdp->host, sdkp->protection_type); 273518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen 274518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen if (!dix && scsi_host_dix_capable(sdp->host, SD_DIF_TYPE0_PROTECTION)) { 275518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen dif = 0; 276518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen dix = 1; 277518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen } 278518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen 279518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen if (!dif && !dix) 280518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen return snprintf(buf, 20, "none\n"); 281518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen 282518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen return snprintf(buf, 20, "%s%u\n", dix ? "dix" : "dif", dif); 283518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen} 284518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen 285518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersenstatic ssize_t 286e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersensd_show_app_tag_own(struct device *dev, struct device_attribute *attr, 287e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen char *buf) 288e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen{ 289e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev); 290e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 291e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen return snprintf(buf, 20, "%u\n", sdkp->ATO); 292e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen} 293e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 294e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersenstatic ssize_t 295e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersensd_show_thin_provisioning(struct device *dev, struct device_attribute *attr, 296e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen char *buf) 297e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen{ 298e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev); 299e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 300c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen return snprintf(buf, 20, "%u\n", sdkp->lbpme); 301c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen} 302c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 303c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersenstatic const char *lbp_mode[] = { 304c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen [SD_LBP_FULL] = "full", 305c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen [SD_LBP_UNMAP] = "unmap", 306c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen [SD_LBP_WS16] = "writesame_16", 307c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen [SD_LBP_WS10] = "writesame_10", 308c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen [SD_LBP_ZERO] = "writesame_zero", 309c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen [SD_LBP_DISABLE] = "disabled", 310c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen}; 311c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 312c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersenstatic ssize_t 313c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersensd_show_provisioning_mode(struct device *dev, struct device_attribute *attr, 314c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen char *buf) 315c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen{ 316c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev); 317c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 318c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen return snprintf(buf, 20, "%s\n", lbp_mode[sdkp->provisioning_mode]); 319c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen} 320c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 321c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersenstatic ssize_t 322c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersensd_store_provisioning_mode(struct device *dev, struct device_attribute *attr, 323c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen const char *buf, size_t count) 324c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen{ 325c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev); 326c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen struct scsi_device *sdp = sdkp->device; 327c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 328c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen if (!capable(CAP_SYS_ADMIN)) 329c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen return -EACCES; 330c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 331c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen if (sdp->type != TYPE_DISK) 332c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen return -EINVAL; 333c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 334c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen if (!strncmp(buf, lbp_mode[SD_LBP_UNMAP], 20)) 335c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sd_config_discard(sdkp, SD_LBP_UNMAP); 336c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen else if (!strncmp(buf, lbp_mode[SD_LBP_WS16], 20)) 337c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sd_config_discard(sdkp, SD_LBP_WS16); 338c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen else if (!strncmp(buf, lbp_mode[SD_LBP_WS10], 20)) 339c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sd_config_discard(sdkp, SD_LBP_WS10); 340c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen else if (!strncmp(buf, lbp_mode[SD_LBP_ZERO], 20)) 341c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sd_config_discard(sdkp, SD_LBP_ZERO); 342c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen else if (!strncmp(buf, lbp_mode[SD_LBP_DISABLE], 20)) 343c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sd_config_discard(sdkp, SD_LBP_DISABLE); 344c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen else 345c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen return -EINVAL; 346c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 347c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen return count; 348e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen} 349e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 35018a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersenstatic ssize_t 35118a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersensd_show_max_medium_access_timeouts(struct device *dev, 35218a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen struct device_attribute *attr, char *buf) 35318a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen{ 35418a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev); 35518a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen 35618a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen return snprintf(buf, 20, "%u\n", sdkp->max_medium_access_timeouts); 35718a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen} 35818a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen 35918a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersenstatic ssize_t 36018a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersensd_store_max_medium_access_timeouts(struct device *dev, 36118a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen struct device_attribute *attr, 36218a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen const char *buf, size_t count) 36318a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen{ 36418a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen struct scsi_disk *sdkp = to_scsi_disk(dev); 36518a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen int err; 36618a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen 36718a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen if (!capable(CAP_SYS_ADMIN)) 36818a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen return -EACCES; 36918a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen 37018a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen err = kstrtouint(buf, 10, &sdkp->max_medium_access_timeouts); 37118a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen 37218a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen return err ? err : count; 37318a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen} 37418a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen 375ee959b00c335d7780136c5abda37809191fe52c3Tony Jonesstatic struct device_attribute sd_disk_attrs[] = { 3766bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, 3776bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley sd_store_cache_type), 3786bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley __ATTR(FUA, S_IRUGO, sd_show_fua, NULL), 379a144c5ae0956fb262e6c82624c82b1110a451437Brian King __ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_allow_restart, 380a144c5ae0956fb262e6c82624c82b1110a451437Brian King sd_store_allow_restart), 381c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo __ATTR(manage_start_stop, S_IRUGO|S_IWUSR, sd_show_manage_start_stop, 382c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo sd_store_manage_start_stop), 383e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen __ATTR(protection_type, S_IRUGO, sd_show_protection_type, NULL), 384518fa8e39bafd2431c28adb8822bb6c3e4d1a390Martin K. Petersen __ATTR(protection_mode, S_IRUGO, sd_show_protection_mode, NULL), 385e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen __ATTR(app_tag_own, S_IRUGO, sd_show_app_tag_own, NULL), 386e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), 387c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen __ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode, 388c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sd_store_provisioning_mode), 38918a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen __ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR, 39018a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen sd_show_max_medium_access_timeouts, 39118a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen sd_store_max_medium_access_timeouts), 3926bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley __ATTR_NULL, 3936bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley}; 3946bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley 3956bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomleystatic struct class sd_disk_class = { 3966bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley .name = "scsi_disk", 3976bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley .owner = THIS_MODULE, 398ee959b00c335d7780136c5abda37809191fe52c3Tony Jones .dev_release = scsi_disk_release, 399ee959b00c335d7780136c5abda37809191fe52c3Tony Jones .dev_attrs = sd_disk_attrs, 4006bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley}; 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct scsi_driver sd_template = { 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .gendrv = { 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "sd", 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .probe = sd_probe, 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .remove = sd_remove, 408c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo .suspend = sd_suspend, 409c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo .resume = sd_resume, 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .shutdown = sd_shutdown, 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .rescan = sd_rescan, 4137b3d9545f9ac8b31528dd2d6d8ec8d19922917b8Linus Torvalds .done = sd_done, 41418a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen .eh_action = sd_eh_action, 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Device no to disk mapping: 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * major disc2 disc p1 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * |............|.............|....|....| <- dev_t 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 31 20 19 8 7 4 3 0 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inside a major, we have 16k disks, however mapped non- 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * contiguously. The first 16 disks are for major0, the next 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ones with major1, ... Disk 256 is for major0 again, disk 272 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for major1, ... 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * As we stay compatible with our numbering scheme, we can reuse 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the well-know SCSI majors 8, 65--71, 136--143. 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int sd_major(int major_idx) 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (major_idx) { 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SCSI_DISK0_MAJOR; 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1 ... 7: 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SCSI_DISK1_MAJOR + major_idx - 1; 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 8 ... 15: 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SCSI_DISK8_MAJOR + major_idx - 8; 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BUG(); 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; /* shut up gcc */ 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44639b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Sternstatic struct scsi_disk *__scsi_disk_get(struct gendisk *disk) 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_disk *sdkp = NULL; 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45039b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern if (disk->private_data) { 45139b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern sdkp = scsi_disk(disk); 45239b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern if (scsi_device_get(sdkp->device) == 0) 453ee959b00c335d7780136c5abda37809191fe52c3Tony Jones get_device(&sdkp->dev); 45439b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern else 45539b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern sdkp = NULL; 45639b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern } 45739b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern return sdkp; 45839b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern} 45939b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern 46039b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Sternstatic struct scsi_disk *scsi_disk_get(struct gendisk *disk) 46139b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern{ 46239b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern struct scsi_disk *sdkp; 46339b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern 4640b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven mutex_lock(&sd_ref_mutex); 46539b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern sdkp = __scsi_disk_get(disk); 4660b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven mutex_unlock(&sd_ref_mutex); 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sdkp; 46839b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern} 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47039b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Sternstatic struct scsi_disk *scsi_disk_get_from_dev(struct device *dev) 47139b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern{ 47239b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern struct scsi_disk *sdkp; 47339b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern 4740b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven mutex_lock(&sd_ref_mutex); 47539b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern sdkp = dev_get_drvdata(dev); 47639b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern if (sdkp) 47739b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern sdkp = __scsi_disk_get(sdkp->disk); 4780b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven mutex_unlock(&sd_ref_mutex); 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sdkp; 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void scsi_disk_put(struct scsi_disk *sdkp) 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_device *sdev = sdkp->device; 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4860b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven mutex_lock(&sd_ref_mutex); 487ee959b00c335d7780136c5abda37809191fe52c3Tony Jones put_device(&sdkp->dev); 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scsi_device_put(sdev); 4890b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven mutex_unlock(&sd_ref_mutex); 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49235e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersenstatic void sd_prot_op(struct scsi_cmnd *scmd, unsigned int dif) 49335e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen{ 49435e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen unsigned int prot_op = SCSI_PROT_NORMAL; 49535e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen unsigned int dix = scsi_prot_sg_count(scmd); 49635e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen 49735e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen if (scmd->sc_data_direction == DMA_FROM_DEVICE) { 49835e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen if (dif && dix) 49935e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen prot_op = SCSI_PROT_READ_PASS; 50035e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen else if (dif && !dix) 50135e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen prot_op = SCSI_PROT_READ_STRIP; 50235e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen else if (!dif && dix) 50335e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen prot_op = SCSI_PROT_READ_INSERT; 50435e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen } else { 50535e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen if (dif && dix) 50635e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen prot_op = SCSI_PROT_WRITE_PASS; 50735e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen else if (dif && !dix) 50835e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen prot_op = SCSI_PROT_WRITE_INSERT; 50935e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen else if (!dif && dix) 51035e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen prot_op = SCSI_PROT_WRITE_STRIP; 51135e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen } 51235e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen 51335e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen scsi_set_prot_op(scmd, prot_op); 51435e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen scsi_set_prot_type(scmd, dif); 51535e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen} 51635e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen 517c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersenstatic void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) 518c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen{ 519c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen struct request_queue *q = sdkp->disk->queue; 520c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen unsigned int logical_block_size = sdkp->device->sector_size; 521c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen unsigned int max_blocks = 0; 522c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 523c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen q->limits.discard_zeroes_data = sdkp->lbprz; 5242a8cfad06ebbb68e8c113a39bdd653297fb9369cMartin K. Petersen q->limits.discard_alignment = sdkp->unmap_alignment * 5252a8cfad06ebbb68e8c113a39bdd653297fb9369cMartin K. Petersen logical_block_size; 526c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen q->limits.discard_granularity = 527c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen max(sdkp->physical_block_size, 528c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sdkp->unmap_granularity * logical_block_size); 529c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 53089730393f260aef7fce9f6fd475da148517a4c5cMartin K. Petersen sdkp->provisioning_mode = mode; 53189730393f260aef7fce9f6fd475da148517a4c5cMartin K. Petersen 532c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen switch (mode) { 533c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 534c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen case SD_LBP_DISABLE: 535c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen q->limits.max_discard_sectors = 0; 536c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q); 537c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen return; 538c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 539c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen case SD_LBP_UNMAP: 540c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen max_blocks = min_not_zero(sdkp->max_unmap_blocks, 0xffffffff); 541c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen break; 542c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 543c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen case SD_LBP_WS16: 544c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen max_blocks = min_not_zero(sdkp->max_ws_blocks, 0xffffffff); 545c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen break; 546c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 547c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen case SD_LBP_WS10: 548c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); 549c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen break; 550c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 551c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen case SD_LBP_ZERO: 552c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); 553c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen q->limits.discard_zeroes_data = 1; 554c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen break; 555c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen } 556c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 557c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen q->limits.max_discard_sectors = max_blocks * (logical_block_size >> 9); 558c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); 559c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen} 560c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 56266ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig * scsi_setup_discard_cmnd - unmap blocks on thinly provisioned device 56366ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig * @sdp: scsi device to operate one 564e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen * @rq: Request to prepare 565e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen * 566e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen * Will issue either UNMAP or WRITE SAME(16) depending on preference 567e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen * indicated by target device. 568e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen **/ 56966ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwigstatic int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) 570e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen{ 571e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); 572e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen struct bio *bio = rq->bio; 573e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen sector_t sector = bio->bi_sector; 57466ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig unsigned int nr_sectors = bio_sectors(bio); 57566ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig unsigned int len; 576f1126e950d28ff875d96ed6a04a9ff96c7bfc357FUJITA Tomonori int ret; 577c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen char *buf; 57866ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig struct page *page; 579e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 580e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen if (sdkp->device->sector_size == 4096) { 581e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen sector >>= 3; 58266ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig nr_sectors >>= 3; 583e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen } 584e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 585e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen rq->timeout = SD_TIMEOUT; 586e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 587e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen memset(rq->cmd, 0, rq->cmd_len); 588e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 58966ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig page = alloc_page(GFP_ATOMIC | __GFP_ZERO); 59066ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig if (!page) 59166ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig return BLKPREP_DEFER; 59266ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig 593c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen switch (sdkp->provisioning_mode) { 594c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen case SD_LBP_UNMAP: 595c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen buf = page_address(page); 596e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 59766ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig rq->cmd_len = 10; 598e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen rq->cmd[0] = UNMAP; 599e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen rq->cmd[8] = 24; 600e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 601e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen put_unaligned_be16(6 + 16, &buf[0]); 602e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen put_unaligned_be16(16, &buf[2]); 603e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen put_unaligned_be64(sector, &buf[8]); 60466ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig put_unaligned_be32(nr_sectors, &buf[16]); 605e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 60666ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig len = 24; 607c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen break; 608c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 609c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen case SD_LBP_WS16: 61066ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig rq->cmd_len = 16; 611e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen rq->cmd[0] = WRITE_SAME_16; 612e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen rq->cmd[1] = 0x8; /* UNMAP */ 613e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen put_unaligned_be64(sector, &rq->cmd[2]); 61466ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig put_unaligned_be32(nr_sectors, &rq->cmd[10]); 61566ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig 61666ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig len = sdkp->device->sector_size; 617c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen break; 618c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 619c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen case SD_LBP_WS10: 620c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen case SD_LBP_ZERO: 621c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen rq->cmd_len = 10; 622c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen rq->cmd[0] = WRITE_SAME; 623c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen if (sdkp->provisioning_mode == SD_LBP_WS10) 624c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen rq->cmd[1] = 0x8; /* UNMAP */ 625c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen put_unaligned_be32(sector, &rq->cmd[2]); 626c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen put_unaligned_be16(nr_sectors, &rq->cmd[7]); 627c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 628c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen len = sdkp->device->sector_size; 629c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen break; 630c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 631c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen default: 63209b9cc44c942256026bf7a63fec2155b8f488899Martin K. Petersen ret = BLKPREP_KILL; 633c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen goto out; 634e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen } 635e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 63666ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig blk_add_request_payload(rq, page, len); 637f1126e950d28ff875d96ed6a04a9ff96c7bfc357FUJITA Tomonori ret = scsi_setup_blk_pc_cmnd(sdp, rq); 638f1126e950d28ff875d96ed6a04a9ff96c7bfc357FUJITA Tomonori rq->buffer = page_address(page); 639c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 640c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersenout: 641610a63498f7f366031a6327eaaa9963ffa110b2bFUJITA Tomonori if (ret != BLKPREP_OK) { 642610a63498f7f366031a6327eaaa9963ffa110b2bFUJITA Tomonori __free_page(page); 643610a63498f7f366031a6327eaaa9963ffa110b2bFUJITA Tomonori rq->buffer = NULL; 644610a63498f7f366031a6327eaaa9963ffa110b2bFUJITA Tomonori } 645f1126e950d28ff875d96ed6a04a9ff96c7bfc357FUJITA Tomonori return ret; 646f1126e950d28ff875d96ed6a04a9ff96c7bfc357FUJITA Tomonori} 647f1126e950d28ff875d96ed6a04a9ff96c7bfc357FUJITA Tomonori 64890467c294aba7f911bdae72ed86995cf1de4d364FUJITA Tomonoristatic int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq) 64990467c294aba7f911bdae72ed86995cf1de4d364FUJITA Tomonori{ 650e3b3e6246726cd05950677ed843010b8e8c5884cMike Christie rq->timeout = SD_FLUSH_TIMEOUT; 65190467c294aba7f911bdae72ed86995cf1de4d364FUJITA Tomonori rq->retries = SD_MAX_RETRIES; 65290467c294aba7f911bdae72ed86995cf1de4d364FUJITA Tomonori rq->cmd[0] = SYNCHRONIZE_CACHE; 65390467c294aba7f911bdae72ed86995cf1de4d364FUJITA Tomonori rq->cmd_len = 10; 65490467c294aba7f911bdae72ed86995cf1de4d364FUJITA Tomonori 65590467c294aba7f911bdae72ed86995cf1de4d364FUJITA Tomonori return scsi_setup_blk_pc_cmnd(sdp, rq); 65690467c294aba7f911bdae72ed86995cf1de4d364FUJITA Tomonori} 65790467c294aba7f911bdae72ed86995cf1de4d364FUJITA Tomonori 658f1126e950d28ff875d96ed6a04a9ff96c7bfc357FUJITA Tomonoristatic void sd_unprep_fn(struct request_queue *q, struct request *rq) 659f1126e950d28ff875d96ed6a04a9ff96c7bfc357FUJITA Tomonori{ 660610a63498f7f366031a6327eaaa9963ffa110b2bFUJITA Tomonori if (rq->cmd_flags & REQ_DISCARD) { 661610a63498f7f366031a6327eaaa9963ffa110b2bFUJITA Tomonori free_page((unsigned long)rq->buffer); 662610a63498f7f366031a6327eaaa9963ffa110b2bFUJITA Tomonori rq->buffer = NULL; 663610a63498f7f366031a6327eaaa9963ffa110b2bFUJITA Tomonori } 664e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen} 665e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 666e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen/** 6672db93ce8cc1801ccb32a2f19062d110e5a9d4282Petr Uzel * sd_prep_fn - build a scsi (read or write) command from 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * information in the request structure. 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @SCpnt: pointer to mid-level's per scsi command structure that 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * contains request and into which the scsi command is written 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns 1 if successful and 0 if error (or cannot be done now). 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/ 6747f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomleystatic int sd_prep_fn(struct request_queue *q, struct request *rq) 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6767f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley struct scsi_cmnd *SCpnt; 6777f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley struct scsi_device *sdp = q->queuedata; 678776b23a0363d99ca402edc1aba1db8099b747b33Christoph Hellwig struct gendisk *disk = rq->rq_disk; 679af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen struct scsi_disk *sdkp; 68083096ebf1263b2c1ee5e653ba37d993d02e3eb7bTejun Heo sector_t block = blk_rq_pos(rq); 68118351070b86d155713cf790b26af4f21b1fd0b29Linus Torvalds sector_t threshold; 68283096ebf1263b2c1ee5e653ba37d993d02e3eb7bTejun Heo unsigned int this_count = blk_rq_sectors(rq); 683bd623e79fb6bca7ab685bb1f7376476a81ce10bbMartin K. Petersen int ret, host_dif; 6844e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen unsigned char protect; 6857f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley 686e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen /* 687e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen * Discard request come in as REQ_TYPE_FS but we turn them into 688e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen * block PC requests to make life easier. 689e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen */ 69066ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig if (rq->cmd_flags & REQ_DISCARD) { 69166ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig ret = scsi_setup_discard_cmnd(sdp, rq); 69266ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig goto out; 69390467c294aba7f911bdae72ed86995cf1de4d364FUJITA Tomonori } else if (rq->cmd_flags & REQ_FLUSH) { 69490467c294aba7f911bdae72ed86995cf1de4d364FUJITA Tomonori ret = scsi_setup_flush_cmnd(sdp, rq); 69590467c294aba7f911bdae72ed86995cf1de4d364FUJITA Tomonori goto out; 69666ac0280197981f88774e74b60c8e5f9f07c1dbaChristoph Hellwig } else if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { 6977f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley ret = scsi_setup_blk_pc_cmnd(sdp, rq); 6987f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley goto out; 6997f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley } else if (rq->cmd_type != REQ_TYPE_FS) { 7007f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley ret = BLKPREP_KILL; 7017f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley goto out; 7027f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley } 7037f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley ret = scsi_setup_fs_cmnd(sdp, rq); 7047f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley if (ret != BLKPREP_OK) 7057f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley goto out; 7067f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley SCpnt = rq->special; 707af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen sdkp = scsi_disk(disk); 7087f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley 7097f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley /* from here on until we're complete, any goto out 7107f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley * is used for a killable error condition */ 7117f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley ret = BLKPREP_KILL; 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 713fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt, 7142db93ce8cc1801ccb32a2f19062d110e5a9d4282Petr Uzel "sd_prep_fn: block=%llu, " 715fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen "count=%d\n", 716fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen (unsigned long long)block, 717fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen this_count)); 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!sdp || !scsi_device_online(sdp) || 72083096ebf1263b2c1ee5e653ba37d993d02e3eb7bTejun Heo block + blk_rq_sectors(rq) > get_capacity(disk)) { 721fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, 72283096ebf1263b2c1ee5e653ba37d993d02e3eb7bTejun Heo "Finishing %u sectors\n", 72383096ebf1263b2c1ee5e653ba37d993d02e3eb7bTejun Heo blk_rq_sectors(rq))); 724fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, 725fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen "Retry with 0x%p\n", SCpnt)); 7267f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley goto out; 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sdp->changed) { 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * quietly refuse to do anything to a changed disc until 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the changed bit has been reset 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7343ff5588d3f8afad65ded52ac0e4191462fe034cbAlan Stern /* printk("SCSI disk has been changed or is not present. Prohibiting further I/O.\n"); */ 7357f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley goto out; 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7377f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley 738a0899d4df534d2bcf671b0f647b809842309a9aeHans de Goede /* 73918351070b86d155713cf790b26af4f21b1fd0b29Linus Torvalds * Some SD card readers can't handle multi-sector accesses which touch 74018351070b86d155713cf790b26af4f21b1fd0b29Linus Torvalds * the last one or two hardware sectors. Split accesses as needed. 741a0899d4df534d2bcf671b0f647b809842309a9aeHans de Goede */ 74218351070b86d155713cf790b26af4f21b1fd0b29Linus Torvalds threshold = get_capacity(disk) - SD_LAST_BUGGY_SECTORS * 74318351070b86d155713cf790b26af4f21b1fd0b29Linus Torvalds (sdp->sector_size / 512); 74418351070b86d155713cf790b26af4f21b1fd0b29Linus Torvalds 74518351070b86d155713cf790b26af4f21b1fd0b29Linus Torvalds if (unlikely(sdp->last_sector_bug && block + this_count > threshold)) { 74618351070b86d155713cf790b26af4f21b1fd0b29Linus Torvalds if (block < threshold) { 74718351070b86d155713cf790b26af4f21b1fd0b29Linus Torvalds /* Access up to the threshold but not beyond */ 74818351070b86d155713cf790b26af4f21b1fd0b29Linus Torvalds this_count = threshold - block; 74918351070b86d155713cf790b26af4f21b1fd0b29Linus Torvalds } else { 75018351070b86d155713cf790b26af4f21b1fd0b29Linus Torvalds /* Access only a single hardware sector */ 75118351070b86d155713cf790b26af4f21b1fd0b29Linus Torvalds this_count = sdp->sector_size / 512; 75218351070b86d155713cf790b26af4f21b1fd0b29Linus Torvalds } 75318351070b86d155713cf790b26af4f21b1fd0b29Linus Torvalds } 754a0899d4df534d2bcf671b0f647b809842309a9aeHans de Goede 755fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", 756fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen (unsigned long long)block)); 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If we have a 1K hardware sectorsize, prevent access to single 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 512 byte sectors. In theory we could handle this - in fact 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the scsi cdrom driver must be able to handle this because 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * we typically use 1K blocksizes, and cdroms typically have 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2K hardware sectorsizes. Of course, things are simpler 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * with the cdrom, since it is read-only. For performance 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * reasons, the filesystems should be able to handle this 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and not force the scsi disk driver to use bounce buffers 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for this. 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sdp->sector_size == 1024) { 77083096ebf1263b2c1ee5e653ba37d993d02e3eb7bTejun Heo if ((block & 1) || (blk_rq_sectors(rq) & 1)) { 771e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen scmd_printk(KERN_ERR, SCpnt, 772e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen "Bad block number requested\n"); 7737f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley goto out; 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds block = block >> 1; 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds this_count = this_count >> 1; 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sdp->sector_size == 2048) { 78083096ebf1263b2c1ee5e653ba37d993d02e3eb7bTejun Heo if ((block & 3) || (blk_rq_sectors(rq) & 3)) { 781e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen scmd_printk(KERN_ERR, SCpnt, 782e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen "Bad block number requested\n"); 7837f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley goto out; 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds block = block >> 2; 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds this_count = this_count >> 2; 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sdp->sector_size == 4096) { 79083096ebf1263b2c1ee5e653ba37d993d02e3eb7bTejun Heo if ((block & 7) || (blk_rq_sectors(rq) & 7)) { 791e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen scmd_printk(KERN_ERR, SCpnt, 792e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen "Bad block number requested\n"); 7937f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley goto out; 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds block = block >> 3; 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds this_count = this_count >> 3; 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rq_data_dir(rq) == WRITE) { 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!sdp->writeable) { 8017f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley goto out; 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[0] = WRITE_6; 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->sc_data_direction = DMA_TO_DEVICE; 805af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen 806af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen if (blk_integrity_rq(rq) && 807af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen sd_dif_prepare(rq, block, sdp->sector_size) == -EIO) 808af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen goto out; 809af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (rq_data_dir(rq) == READ) { 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[0] = READ_6; 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->sc_data_direction = DMA_FROM_DEVICE; 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 814e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen scmd_printk(KERN_ERR, SCpnt, "Unknown command %x\n", rq->cmd_flags); 8157f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley goto out; 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 818fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, 81983096ebf1263b2c1ee5e653ba37d993d02e3eb7bTejun Heo "%s %d/%u 512 byte blocks.\n", 820fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen (rq_data_dir(rq) == WRITE) ? 821fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen "writing" : "reading", this_count, 82283096ebf1263b2c1ee5e653ba37d993d02e3eb7bTejun Heo blk_rq_sectors(rq))); 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 824af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen /* Set RDPROTECT/WRPROTECT if disk is formatted with DIF */ 825bd623e79fb6bca7ab685bb1f7376476a81ce10bbMartin K. Petersen host_dif = scsi_host_dif_capable(sdp->host, sdkp->protection_type); 826bd623e79fb6bca7ab685bb1f7376476a81ce10bbMartin K. Petersen if (host_dif) 8274e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen protect = 1 << 5; 828af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen else 8294e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen protect = 0; 8304e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen 8314e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen if (host_dif == SD_DIF_TYPE2_PROTECTION) { 8324e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd = mempool_alloc(sd_cdb_pool, GFP_ATOMIC); 8334e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen 8344e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen if (unlikely(SCpnt->cmnd == NULL)) { 8354e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen ret = BLKPREP_DEFER; 8364e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen goto out; 8374e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen } 838af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen 8394e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmd_len = SD_EXT_CDB_SIZE; 8404e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen memset(SCpnt->cmnd, 0, SCpnt->cmd_len); 8414e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[0] = VARIABLE_LENGTH_CMD; 8424e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[7] = 0x18; 8434e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[9] = (rq_data_dir(rq) == READ) ? READ_32 : WRITE_32; 84433659ebbae262228eef4e0fe990f393d1f0ed941Christoph Hellwig SCpnt->cmnd[10] = protect | ((rq->cmd_flags & REQ_FUA) ? 0x8 : 0); 8454e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen 8464e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen /* LBA */ 8474e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[12] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0; 8484e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[13] = sizeof(block) > 4 ? (unsigned char) (block >> 48) & 0xff : 0; 8494e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[14] = sizeof(block) > 4 ? (unsigned char) (block >> 40) & 0xff : 0; 8504e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[15] = sizeof(block) > 4 ? (unsigned char) (block >> 32) & 0xff : 0; 8514e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[16] = (unsigned char) (block >> 24) & 0xff; 8524e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[17] = (unsigned char) (block >> 16) & 0xff; 8534e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[18] = (unsigned char) (block >> 8) & 0xff; 8544e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[19] = (unsigned char) block & 0xff; 8554e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen 8564e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen /* Expected Indirect LBA */ 8574e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[20] = (unsigned char) (block >> 24) & 0xff; 8584e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[21] = (unsigned char) (block >> 16) & 0xff; 8594e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[22] = (unsigned char) (block >> 8) & 0xff; 8604e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[23] = (unsigned char) block & 0xff; 8614e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen 8624e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen /* Transfer length */ 8634e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[28] = (unsigned char) (this_count >> 24) & 0xff; 8644e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[29] = (unsigned char) (this_count >> 16) & 0xff; 8654e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[30] = (unsigned char) (this_count >> 8) & 0xff; 8664e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen SCpnt->cmnd[31] = (unsigned char) this_count & 0xff; 8674e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen } else if (block > 0xffffffff) { 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[0] += READ_16 - READ_6; 86933659ebbae262228eef4e0fe990f393d1f0ed941Christoph Hellwig SCpnt->cmnd[1] = protect | ((rq->cmd_flags & REQ_FUA) ? 0x8 : 0); 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[2] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0; 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[3] = sizeof(block) > 4 ? (unsigned char) (block >> 48) & 0xff : 0; 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[4] = sizeof(block) > 4 ? (unsigned char) (block >> 40) & 0xff : 0; 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[5] = sizeof(block) > 4 ? (unsigned char) (block >> 32) & 0xff : 0; 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[6] = (unsigned char) (block >> 24) & 0xff; 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[7] = (unsigned char) (block >> 16) & 0xff; 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[8] = (unsigned char) (block >> 8) & 0xff; 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[9] = (unsigned char) block & 0xff; 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[10] = (unsigned char) (this_count >> 24) & 0xff; 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[11] = (unsigned char) (this_count >> 16) & 0xff; 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[12] = (unsigned char) (this_count >> 8) & 0xff; 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[13] = (unsigned char) this_count & 0xff; 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[14] = SCpnt->cmnd[15] = 0; 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if ((this_count > 0xff) || (block > 0x1fffff) || 884af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen scsi_device_protection(SCpnt->device) || 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->device->use_10_for_rw) { 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (this_count > 0xffff) 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds this_count = 0xffff; 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[0] += READ_10 - READ_6; 89033659ebbae262228eef4e0fe990f393d1f0ed941Christoph Hellwig SCpnt->cmnd[1] = protect | ((rq->cmd_flags & REQ_FUA) ? 0x8 : 0); 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff; 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff; 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[5] = (unsigned char) block & 0xff; 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[6] = SCpnt->cmnd[9] = 0; 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[7] = (unsigned char) (this_count >> 8) & 0xff; 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[8] = (unsigned char) this_count & 0xff; 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 89933659ebbae262228eef4e0fe990f393d1f0ed941Christoph Hellwig if (unlikely(rq->cmd_flags & REQ_FUA)) { 900007365ad60387df30f02f01fdc2b6e6432f6c265Tejun Heo /* 901007365ad60387df30f02f01fdc2b6e6432f6c265Tejun Heo * This happens only if this drive failed 902007365ad60387df30f02f01fdc2b6e6432f6c265Tejun Heo * 10byte rw command with ILLEGAL_REQUEST 903007365ad60387df30f02f01fdc2b6e6432f6c265Tejun Heo * during operation and thus turned off 904007365ad60387df30f02f01fdc2b6e6432f6c265Tejun Heo * use_10_for_rw. 905007365ad60387df30f02f01fdc2b6e6432f6c265Tejun Heo */ 906e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen scmd_printk(KERN_ERR, SCpnt, 907e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen "FUA write on READ/WRITE(6) drive\n"); 9087f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley goto out; 909007365ad60387df30f02f01fdc2b6e6432f6c265Tejun Heo } 910007365ad60387df30f02f01fdc2b6e6432f6c265Tejun Heo 9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f); 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[2] = (unsigned char) ((block >> 8) & 0xff); 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[3] = (unsigned char) block & 0xff; 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[4] = (unsigned char) this_count; 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->cmnd[5] = 0; 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 91730b0c37b27485a9cb897bfe3824f6f517b8c80d6Boaz Harrosh SCpnt->sdb.length = this_count * sdp->sector_size; 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 919af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen /* If DIF or DIX is enabled, tell HBA how to handle request */ 920bd623e79fb6bca7ab685bb1f7376476a81ce10bbMartin K. Petersen if (host_dif || scsi_prot_sg_count(SCpnt)) 92135e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen sd_prot_op(SCpnt, host_dif); 922af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We shouldn't disconnect in the middle of a sector, so with a dumb 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * host adapter, it's safe to assume that we can at least transfer 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * this many bytes between each connect / disconnect. 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->transfersize = sdp->sector_size; 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->underflow = this_count << 9; 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCpnt->allowed = SD_MAX_RETRIES; 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This indicates that the command is ready from our end to be 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * queued. 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9367f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley ret = BLKPREP_OK; 9377f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley out: 9387f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65James Bottomley return scsi_prep_return(q, rq, ret); 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sd_open - open a scsi disk device 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @inode: only i_rdev member may be used 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @filp: only f_mode and f_flags may be used 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns 0 if successful. Returns a negated errno value in case 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of error. 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Note: This can be called from a user context (e.g. fsck(1) ) 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * or from within the kernel (e.g. as a result of a mount(1) ). 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * In the latter case @inode and @filp carry an abridged amount 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of information as noted above. 953409f3499a2cfcd1e9c2857c53af7fcce069f027fArnd Bergmann * 954409f3499a2cfcd1e9c2857c53af7fcce069f027fArnd Bergmann * Locking: called with bdev->bd_mutex held. 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/ 9560338e29178795f0df0e1f3705b5d3effe9c95ff7Al Virostatic int sd_open(struct block_device *bdev, fmode_t mode) 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9580338e29178795f0df0e1f3705b5d3effe9c95ff7Al Viro struct scsi_disk *sdkp = scsi_disk_get(bdev->bd_disk); 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_device *sdev; 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retval; 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9620338e29178795f0df0e1f3705b5d3effe9c95ff7Al Viro if (!sdkp) 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENXIO; 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 965fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_open\n")); 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sdev = sdkp->device; 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 969478a8a0543021172220feeb0b39bb1b3e43c988fAlan Stern retval = scsi_autopm_get_device(sdev); 970478a8a0543021172220feeb0b39bb1b3e43c988fAlan Stern if (retval) 971478a8a0543021172220feeb0b39bb1b3e43c988fAlan Stern goto error_autopm; 972478a8a0543021172220feeb0b39bb1b3e43c988fAlan Stern 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If the device is in error recovery, wait until it is done. 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If the device is offline, then disallow any access to it. 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -ENXIO; 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!scsi_block_when_processing_errors(sdev)) 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto error_out; 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sdev->removable || sdkp->write_prot) 9820338e29178795f0df0e1f3705b5d3effe9c95ff7Al Viro check_disk_change(bdev); 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If the drive is empty, just let the open fail. 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -ENOMEDIUM; 9880338e29178795f0df0e1f3705b5d3effe9c95ff7Al Viro if (sdev->removable && !sdkp->media_present && !(mode & FMODE_NDELAY)) 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto error_out; 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If the device has the write protect tab set, have the open fail 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * if the user expects to be able to write to the thing. 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -EROFS; 9960338e29178795f0df0e1f3705b5d3effe9c95ff7Al Viro if (sdkp->write_prot && (mode & FMODE_WRITE)) 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto error_out; 9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * It is possible that the disk changing stuff resulted in 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the device being taken offline. If this is the case, 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * report this to the user, and don't pretend that the 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * open actually succeeded. 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -ENXIO; 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!scsi_device_online(sdev)) 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto error_out; 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1009409f3499a2cfcd1e9c2857c53af7fcce069f027fArnd Bergmann if ((atomic_inc_return(&sdkp->openers) == 1) && sdev->removable) { 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (scsi_block_when_processing_errors(sdev)) 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT); 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldserror_out: 1017478a8a0543021172220feeb0b39bb1b3e43c988fAlan Stern scsi_autopm_put_device(sdev); 1018478a8a0543021172220feeb0b39bb1b3e43c988fAlan Sternerror_autopm: 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scsi_disk_put(sdkp); 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return retval; 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sd_release - invoked when the (last) close(2) is called on this 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * scsi disk. 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @inode: only i_rdev member may be used 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @filp: only f_mode and f_flags may be used 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns 0. 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Note: may block (uninterruptible) if error recovery is underway 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * on this disk. 1033409f3499a2cfcd1e9c2857c53af7fcce069f027fArnd Bergmann * 1034409f3499a2cfcd1e9c2857c53af7fcce069f027fArnd Bergmann * Locking: called with bdev->bd_mutex held. 10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/ 10360338e29178795f0df0e1f3705b5d3effe9c95ff7Al Virostatic int sd_release(struct gendisk *disk, fmode_t mode) 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_disk *sdkp = scsi_disk(disk); 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_device *sdev = sdkp->device; 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 104156937f7b78d3e495a9f557775f3c3ea1d50ca7b3James Bottomley SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_release\n")); 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10437e443312403ad1ff40ef3177590e96d1fe747c79Alan Stern if (atomic_dec_return(&sdkp->openers) == 0 && sdev->removable) { 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (scsi_block_when_processing_errors(sdev)) 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW); 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * XXX and what if there are packets in flight and this close() 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * XXX is followed by a "rmmod sd_mod"? 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1052478a8a0543021172220feeb0b39bb1b3e43c988fAlan Stern 1053478a8a0543021172220feeb0b39bb1b3e43c988fAlan Stern scsi_autopm_put_device(sdev); 10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scsi_disk_put(sdkp); 10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1058a885c8c4316e1c1d2d2c8755da3f3d14f852528dChristoph Hellwigstatic int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo) 10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk); 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_device *sdp = sdkp->device; 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Scsi_Host *host = sdp->host; 10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int diskinfo[4]; 10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* default to most commonly used values */ 10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diskinfo[0] = 0x40; /* 1 << 6 */ 10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diskinfo[1] = 0x20; /* 1 << 5 */ 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diskinfo[2] = sdkp->capacity >> 11; 10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* override with calculated, extended default, or driver values */ 10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (host->hostt->bios_param) 10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds host->hostt->bios_param(sdp, bdev, sdkp->capacity, diskinfo); 10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scsicam_bios_param(bdev, sdkp->capacity, diskinfo); 10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1076a885c8c4316e1c1d2d2c8755da3f3d14f852528dChristoph Hellwig geo->heads = diskinfo[0]; 1077a885c8c4316e1c1d2d2c8755da3f3d14f852528dChristoph Hellwig geo->sectors = diskinfo[1]; 1078a885c8c4316e1c1d2d2c8755da3f3d14f852528dChristoph Hellwig geo->cylinders = diskinfo[2]; 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sd_ioctl - process an ioctl 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @inode: only i_rdev/i_bdev members may be used 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @filp: only f_mode and f_flags may be used 10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @cmd: ioctl command number 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @arg: this is third argument given to ioctl(2) system call. 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Often contains a pointer. 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 109025985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * Returns 0 if successful (some ioctls return positive numbers on 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * success as well). Returns a negated errno value in case of error. 10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Note: most ioctls are forward onto the block subsystem or further 10943a4fa0a25da81600ea0bcd75692ae8ca6050d165Robert P. J. Day * down in the scsi subsystem. 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/ 10960338e29178795f0df0e1f3705b5d3effe9c95ff7Al Virostatic int sd_ioctl(struct block_device *bdev, fmode_t mode, 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int cmd, unsigned long arg) 10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct gendisk *disk = bdev->bd_disk; 1100fe2d1851e9dc69da8de5dfe3fc748d041c31e25aNao Nishijima struct scsi_disk *sdkp = scsi_disk(disk); 1101fe2d1851e9dc69da8de5dfe3fc748d041c31e25aNao Nishijima struct scsi_device *sdp = sdkp->device; 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __user *p = (void __user *)arg; 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int error; 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1105fe2d1851e9dc69da8de5dfe3fc748d041c31e25aNao Nishijima SCSI_LOG_IOCTL(1, sd_printk(KERN_INFO, sdkp, "sd_ioctl: disk=%s, " 1106fe2d1851e9dc69da8de5dfe3fc748d041c31e25aNao Nishijima "cmd=0x%x\n", disk->disk_name, cmd)); 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11080bfc96cb77224736dfa35c3c555d37b3646ef35ePaolo Bonzini error = scsi_verify_blk_ioctl(bdev, cmd); 11090bfc96cb77224736dfa35c3c555d37b3646ef35ePaolo Bonzini if (error < 0) 11100bfc96cb77224736dfa35c3c555d37b3646ef35ePaolo Bonzini return error; 11110bfc96cb77224736dfa35c3c555d37b3646ef35ePaolo Bonzini 11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If we are in the middle of error recovery, don't let anyone 11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * else try and use this device. Also, if error recovery fails, it 11151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * may try and take the device offline, in which case all further 11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * access to the device is prohibited. 11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 111883ff6fe8580a7c834dba4389d742332fff9b9929Al Viro error = scsi_nonblockable_ioctl(sdp, cmd, p, 1119fd4ce1acd0f8558033b1a6968001552bd7671e6dChristoph Hellwig (mode & FMODE_NDELAY) != 0); 11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!scsi_block_when_processing_errors(sdp) || !error) 11218a6cfeb6deca3a8fefd639d898b0d163c0b5d368Arnd Bergmann goto out; 11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Send SCSI addressing ioctls directly to mid level, send other 11251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ioctls to block level and then onto mid level if they can't be 11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * resolved. 11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SCSI_IOCTL_GET_IDLUN: 11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SCSI_IOCTL_GET_BUS_NUMBER: 11318a6cfeb6deca3a8fefd639d898b0d163c0b5d368Arnd Bergmann error = scsi_ioctl(sdp, cmd, p); 11328a6cfeb6deca3a8fefd639d898b0d163c0b5d368Arnd Bergmann break; 11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1134577ebb374c78314ac4617242f509e2f5e7156649Paolo Bonzini error = scsi_cmd_blk_ioctl(bdev, mode, cmd, p); 11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (error != -ENOTTY) 11368a6cfeb6deca3a8fefd639d898b0d163c0b5d368Arnd Bergmann break; 11378a6cfeb6deca3a8fefd639d898b0d163c0b5d368Arnd Bergmann error = scsi_ioctl(sdp, cmd, p); 11388a6cfeb6deca3a8fefd639d898b0d163c0b5d368Arnd Bergmann break; 11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11408a6cfeb6deca3a8fefd639d898b0d163c0b5d368Arnd Bergmannout: 11418a6cfeb6deca3a8fefd639d898b0d163c0b5d368Arnd Bergmann return error; 11421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void set_media_not_present(struct scsi_disk *sdkp) 11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11462bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo if (sdkp->media_present) 11472bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo sdkp->device->changed = 1; 11482bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo 11492bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo if (sdkp->device->removable) { 11502bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo sdkp->media_present = 0; 11512bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo sdkp->capacity = 0; 11522bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo } 11532bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo} 11542bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo 11552bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heostatic int media_not_present(struct scsi_disk *sdkp, 11562bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo struct scsi_sense_hdr *sshdr) 11572bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo{ 11582bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo if (!scsi_sense_valid(sshdr)) 11592bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo return 0; 11602bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo 11612bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo /* not invoked for commands that could return deferred errors */ 11622bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo switch (sshdr->sense_key) { 11632bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo case UNIT_ATTENTION: 11642bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo case NOT_READY: 11652bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo /* medium not present */ 11662bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo if (sshdr->asc == 0x3A) { 11672bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo set_media_not_present(sdkp); 11682bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo return 1; 11692bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo } 11702bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo } 11712bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo return 0; 11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 11752bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo * sd_check_events - check media events 11762bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo * @disk: kernel device descriptor 11772bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo * @clearing: disk events currently being cleared 11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 11792bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo * Returns mask of DISK_EVENT_*. 11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Note: this function is invoked from the block subsystem. 11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/ 11832bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heostatic unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing) 11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_disk *sdkp = scsi_disk(disk); 11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_device *sdp = sdkp->device; 1187001aac257cf8adbe90cdcba6e07f8d12dfc8fa6bJames Bottomley struct scsi_sense_hdr *sshdr = NULL; 11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retval; 11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11902bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_check_events\n")); 11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If the device is offline, don't send any commands - just pretend as 11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * if the command failed. If the device ever comes back online, we 11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * can deal with it then. It is only because of unrecoverable errors 11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that we would ever take a device offline in the first place. 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1198285e9670d91cdeb6b6693729950339cb45410fdcKay Sievers if (!scsi_device_online(sdp)) { 1199285e9670d91cdeb6b6693729950339cb45410fdcKay Sievers set_media_not_present(sdkp); 1200285e9670d91cdeb6b6693729950339cb45410fdcKay Sievers goto out; 1201285e9670d91cdeb6b6693729950339cb45410fdcKay Sievers } 12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Using TEST_UNIT_READY enables differentiation between drive with 12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * no cartridge loaded - NOT READY, drive with changed cartridge - 12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * UNIT ATTENTION, or with same cartridge - GOOD STATUS. 12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Drives that auto spin down. eg iomega jaz 1G, will be started 12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * by sd_spinup_disk() from sd_revalidate_disk(), which happens whenever 12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sd_revalidate() is called. 12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -ENODEV; 1213285e9670d91cdeb6b6693729950339cb45410fdcKay Sievers 1214001aac257cf8adbe90cdcba6e07f8d12dfc8fa6bJames Bottomley if (scsi_block_when_processing_errors(sdp)) { 12154e2247b2bd289f079349d6c69755f8cff4e31f2bLan Tianyu retval = scsi_autopm_get_device(sdp); 12164e2247b2bd289f079349d6c69755f8cff4e31f2bLan Tianyu if (retval) 12174e2247b2bd289f079349d6c69755f8cff4e31f2bLan Tianyu goto out; 12184e2247b2bd289f079349d6c69755f8cff4e31f2bLan Tianyu 1219001aac257cf8adbe90cdcba6e07f8d12dfc8fa6bJames Bottomley sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL); 1220001aac257cf8adbe90cdcba6e07f8d12dfc8fa6bJames Bottomley retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES, 1221001aac257cf8adbe90cdcba6e07f8d12dfc8fa6bJames Bottomley sshdr); 12224e2247b2bd289f079349d6c69755f8cff4e31f2bLan Tianyu scsi_autopm_put_device(sdp); 1223001aac257cf8adbe90cdcba6e07f8d12dfc8fa6bJames Bottomley } 12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12252bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo /* failed to execute TUR, assume media not present */ 12262bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo if (host_byte(retval)) { 1227285e9670d91cdeb6b6693729950339cb45410fdcKay Sievers set_media_not_present(sdkp); 1228285e9670d91cdeb6b6693729950339cb45410fdcKay Sievers goto out; 1229285e9670d91cdeb6b6693729950339cb45410fdcKay Sievers } 12301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12312bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo if (media_not_present(sdkp, sshdr)) 12322bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo goto out; 12332bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo 12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * For removable scsi disk we have to recognise the presence 12362bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo * of a disk in the drive. 12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 12382bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo if (!sdkp->media_present) 12392bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo sdp->changed = 1; 12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sdkp->media_present = 1; 1241285e9670d91cdeb6b6693729950339cb45410fdcKay Sieversout: 12423ff5588d3f8afad65ded52ac0e4191462fe034cbAlan Stern /* 12432bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo * sdp->changed is set under the following conditions: 12443ff5588d3f8afad65ded52ac0e4191462fe034cbAlan Stern * 12452bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo * Medium present state has changed in either direction. 12462bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo * Device has indicated UNIT_ATTENTION. 12473ff5588d3f8afad65ded52ac0e4191462fe034cbAlan Stern */ 1248001aac257cf8adbe90cdcba6e07f8d12dfc8fa6bJames Bottomley kfree(sshdr); 12492bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo retval = sdp->changed ? DISK_EVENT_MEDIA_CHANGE : 0; 12502bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo sdp->changed = 0; 12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return retval; 12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1254e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersenstatic int sd_sync_cache(struct scsi_disk *sdkp) 12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retries, res; 1257e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen struct scsi_device *sdp = sdkp->device; 1258ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley struct scsi_sense_hdr sshdr; 12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!scsi_device_online(sdp)) 12611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENODEV; 12621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (retries = 3; retries > 0; --retries) { 12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char cmd[10] = { 0 }; 12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd[0] = SYNCHRONIZE_CACHE; 12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Leave the rest of the command zero to indicate 12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * flush everything. 12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1272ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr, 1273e3b3e6246726cd05950677ed843010b8e8c5884cMike Christie SD_FLUSH_TIMEOUT, SD_MAX_RETRIES, NULL); 1274ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley if (res == 0) 12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1278e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen if (res) { 1279e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_print_result(sdkp, res); 1280e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen if (driver_byte(res) & DRIVER_SENSE) 1281e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_print_sense_hdr(sdkp, &sshdr); 12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12843721050afc6cb6ddf6de0f782e2054ebcc225e9bTejun Heo if (res) 12853721050afc6cb6ddf6de0f782e2054ebcc225e9bTejun Heo return -EIO; 12863721050afc6cb6ddf6de0f782e2054ebcc225e9bTejun Heo return 0; 12871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void sd_rescan(struct device *dev) 12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 129139b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); 129239b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern 129339b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern if (sdkp) { 1294f98a8cae12f2b2a8f9bfd7a53c990a1a405e880eAndrew Patterson revalidate_disk(sdkp->disk); 129539b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern scsi_disk_put(sdkp); 129639b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern } 12971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_COMPAT 13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 13021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This gets directly called from VFS. When the ioctl 13031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is not recognized we go back to the other translation paths. 13041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 13050338e29178795f0df0e1f3705b5d3effe9c95ff7Al Virostatic int sd_compat_ioctl(struct block_device *bdev, fmode_t mode, 13060338e29178795f0df0e1f3705b5d3effe9c95ff7Al Viro unsigned int cmd, unsigned long arg) 13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13080338e29178795f0df0e1f3705b5d3effe9c95ff7Al Viro struct scsi_device *sdev = scsi_disk(bdev->bd_disk)->device; 13090bfc96cb77224736dfa35c3c555d37b3646ef35ePaolo Bonzini int ret; 13100bfc96cb77224736dfa35c3c555d37b3646ef35ePaolo Bonzini 13110bfc96cb77224736dfa35c3c555d37b3646ef35ePaolo Bonzini ret = scsi_verify_blk_ioctl(bdev, cmd); 13120bfc96cb77224736dfa35c3c555d37b3646ef35ePaolo Bonzini if (ret < 0) 13130bfc96cb77224736dfa35c3c555d37b3646ef35ePaolo Bonzini return ret; 13141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If we are in the middle of error recovery, don't let anyone 13171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * else try and use this device. Also, if error recovery fails, it 13181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * may try and take the device offline, in which case all further 13191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * access to the device is prohibited. 13201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!scsi_block_when_processing_errors(sdev)) 13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENODEV; 13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sdev->host->hostt->compat_ioctl) { 13251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg); 13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 13281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 13311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Let the static ioctl translation table take care of it. 13321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 13331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOIOCTLCMD; 13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 133783d5cde47dedf01b6a4a4331882cbc0a7eea3c2eAlexey Dobriyanstatic const struct block_device_operations sd_fops = { 13381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 13390338e29178795f0df0e1f3705b5d3effe9c95ff7Al Viro .open = sd_open, 13400338e29178795f0df0e1f3705b5d3effe9c95ff7Al Viro .release = sd_release, 13418a6cfeb6deca3a8fefd639d898b0d163c0b5d368Arnd Bergmann .ioctl = sd_ioctl, 1342a885c8c4316e1c1d2d2c8755da3f3d14f852528dChristoph Hellwig .getgeo = sd_getgeo, 13431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_COMPAT 13440338e29178795f0df0e1f3705b5d3effe9c95ff7Al Viro .compat_ioctl = sd_compat_ioctl, 13451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 13462bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo .check_events = sd_check_events, 13471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .revalidate_disk = sd_revalidate_disk, 134872ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo .unlock_native_capacity = sd_unlock_native_capacity, 13491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 13501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 135118a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen/** 135218a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * sd_eh_action - error handling callback 135318a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * @scmd: sd-issued command that has failed 135418a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * @eh_cmnd: The command that was sent during error handling 135518a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * @eh_cmnd_len: Length of eh_cmnd in bytes 135618a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * @eh_disp: The recovery disposition suggested by the midlayer 135718a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * 135818a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * This function is called by the SCSI midlayer upon completion of 135918a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * an error handling command (TEST UNIT READY, START STOP UNIT, 136018a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * etc.) The command sent to the device by the error handler is 136118a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * stored in eh_cmnd. The result of sending the eh command is 136218a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * passed in eh_disp. 136318a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen **/ 136418a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersenstatic int sd_eh_action(struct scsi_cmnd *scmd, unsigned char *eh_cmnd, 136518a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen int eh_cmnd_len, int eh_disp) 136618a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen{ 136718a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen struct scsi_disk *sdkp = scsi_disk(scmd->request->rq_disk); 136818a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen 136918a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen if (!scsi_device_online(scmd->device) || 137018a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen !scsi_medium_access_command(scmd)) 137118a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen return eh_disp; 137218a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen 137318a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen /* 137418a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * The device has timed out executing a medium access command. 137518a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * However, the TEST UNIT READY command sent during error 137618a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * handling completed successfully. Either the device is in the 137718a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * process of recovering or has it suffered an internal failure 137818a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * that prevents access to the storage medium. 137918a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen */ 138018a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen if (host_byte(scmd->result) == DID_TIME_OUT && eh_disp == SUCCESS && 138118a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen eh_cmnd_len && eh_cmnd[0] == TEST_UNIT_READY) 138218a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen sdkp->medium_access_timed_out++; 138318a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen 138418a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen /* 138518a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * If the device keeps failing read/write commands but TEST UNIT 138618a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * READY always completes successfully we assume that medium 138718a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen * access is no longer possible and take the device offline. 138818a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen */ 138918a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen if (sdkp->medium_access_timed_out >= sdkp->max_medium_access_timeouts) { 139018a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen scmd_printk(KERN_ERR, scmd, 139118a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen "Medium access timeout failure. Offlining disk!\n"); 139218a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen scsi_device_set_state(scmd->device, SDEV_OFFLINE); 139318a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen 139418a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen return FAILED; 139518a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen } 139618a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen 139718a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen return eh_disp; 139818a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen} 139918a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen 1400af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersenstatic unsigned int sd_completed_bytes(struct scsi_cmnd *scmd) 1401af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen{ 140283096ebf1263b2c1ee5e653ba37d993d02e3eb7bTejun Heo u64 start_lba = blk_rq_pos(scmd->request); 140383096ebf1263b2c1ee5e653ba37d993d02e3eb7bTejun Heo u64 end_lba = blk_rq_pos(scmd->request) + (scsi_bufflen(scmd) / 512); 1404af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen u64 bad_lba; 1405af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen int info_valid; 1406a8733c7baf457b071528e385a0b7d4aaec79287cJames Bottomley /* 1407a8733c7baf457b071528e385a0b7d4aaec79287cJames Bottomley * resid is optional but mostly filled in. When it's unused, 1408a8733c7baf457b071528e385a0b7d4aaec79287cJames Bottomley * its value is zero, so we assume the whole buffer transferred 1409a8733c7baf457b071528e385a0b7d4aaec79287cJames Bottomley */ 1410a8733c7baf457b071528e385a0b7d4aaec79287cJames Bottomley unsigned int transferred = scsi_bufflen(scmd) - scsi_get_resid(scmd); 1411a8733c7baf457b071528e385a0b7d4aaec79287cJames Bottomley unsigned int good_bytes; 1412af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen 141333659ebbae262228eef4e0fe990f393d1f0ed941Christoph Hellwig if (scmd->request->cmd_type != REQ_TYPE_FS) 1414af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen return 0; 1415af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen 1416af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen info_valid = scsi_get_sense_info_fld(scmd->sense_buffer, 1417af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen SCSI_SENSE_BUFFERSIZE, 1418af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen &bad_lba); 1419af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen if (!info_valid) 1420af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen return 0; 1421af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen 1422af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen if (scsi_bufflen(scmd) <= scmd->device->sector_size) 1423af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen return 0; 1424af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen 1425af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen if (scmd->device->sector_size < 512) { 1426af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen /* only legitimate sector_size here is 256 */ 1427af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen start_lba <<= 1; 1428af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen end_lba <<= 1; 1429af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen } else { 1430af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen /* be careful ... don't want any overflows */ 1431af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen u64 factor = scmd->device->sector_size / 512; 1432af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen do_div(start_lba, factor); 1433af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen do_div(end_lba, factor); 1434af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen } 1435af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen 1436af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen /* The bad lba was reported incorrectly, we have no idea where 1437af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen * the error is. 1438af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen */ 1439af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen if (bad_lba < start_lba || bad_lba >= end_lba) 1440af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen return 0; 1441af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen 1442af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen /* This computation should always be done in terms of 1443af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen * the resolution of the device's medium. 1444af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen */ 1445a8733c7baf457b071528e385a0b7d4aaec79287cJames Bottomley good_bytes = (bad_lba - start_lba) * scmd->device->sector_size; 1446a8733c7baf457b071528e385a0b7d4aaec79287cJames Bottomley return min(good_bytes, transferred); 1447af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen} 1448af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen 14491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 14507b3d9545f9ac8b31528dd2d6d8ec8d19922917b8Linus Torvalds * sd_done - bottom half handler: called when the lower level 14511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * driver has completed (successfully or otherwise) a scsi command. 14521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @SCpnt: mid-level's per command structure. 14531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 14541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Note: potentially run from within an ISR. Must not block. 14551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/ 14567b3d9545f9ac8b31528dd2d6d8ec8d19922917b8Linus Torvaldsstatic int sd_done(struct scsi_cmnd *SCpnt) 14571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result = SCpnt->result; 1459af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); 14601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_sense_hdr sshdr; 14614e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); 14621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int sense_valid = 0; 14631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int sense_deferred = 0; 1464c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen unsigned char op = SCpnt->cmnd[0]; 14651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1466c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen if ((SCpnt->request->cmd_flags & REQ_DISCARD) && !result) 1467c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen scsi_set_resid(SCpnt, 0); 14686a32a8aed509e71137043d464db4a7fcd88c903eFUJITA Tomonori 14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result) { 14701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr); 14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sense_valid) 14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sense_deferred = scsi_sense_is_deferred(&sshdr); 14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SCSI_LOGGING 1475fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen SCSI_LOG_HLCOMPLETE(1, scsi_print_result(SCpnt)); 14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sense_valid) { 1477fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen SCSI_LOG_HLCOMPLETE(1, scmd_printk(KERN_INFO, SCpnt, 14787b3d9545f9ac8b31528dd2d6d8ec8d19922917b8Linus Torvalds "sd_done: sb[respc,sk,asc," 1479fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen "ascq]=%x,%x,%x,%x\n", 1480fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen sshdr.response_code, 1481fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen sshdr.sense_key, sshdr.asc, 1482fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen sshdr.ascq)); 14831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 148503aba2f79594ca94d159c8bab454de9bcc385b76Luben Tuikov if (driver_byte(result) != DRIVER_SENSE && 148603aba2f79594ca94d159c8bab454de9bcc385b76Luben Tuikov (!sense_valid || sense_deferred)) 148703aba2f79594ca94d159c8bab454de9bcc385b76Luben Tuikov goto out; 148803aba2f79594ca94d159c8bab454de9bcc385b76Luben Tuikov 148918a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen sdkp->medium_access_timed_out = 0; 149018a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen 149103aba2f79594ca94d159c8bab454de9bcc385b76Luben Tuikov switch (sshdr.sense_key) { 149203aba2f79594ca94d159c8bab454de9bcc385b76Luben Tuikov case HARDWARE_ERROR: 149303aba2f79594ca94d159c8bab454de9bcc385b76Luben Tuikov case MEDIUM_ERROR: 1494af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen good_bytes = sd_completed_bytes(SCpnt); 149503aba2f79594ca94d159c8bab454de9bcc385b76Luben Tuikov break; 149603aba2f79594ca94d159c8bab454de9bcc385b76Luben Tuikov case RECOVERED_ERROR: 1497af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen good_bytes = scsi_bufflen(SCpnt); 1498af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen break; 149910dab22664914505dcb804d9ad09cad6bc94d349Jamie Wellnitz case NO_SENSE: 150010dab22664914505dcb804d9ad09cad6bc94d349Jamie Wellnitz /* This indicates a false check condition, so ignore it. An 150110dab22664914505dcb804d9ad09cad6bc94d349Jamie Wellnitz * unknown amount of data was transferred so treat it as an 150210dab22664914505dcb804d9ad09cad6bc94d349Jamie Wellnitz * error. 150310dab22664914505dcb804d9ad09cad6bc94d349Jamie Wellnitz */ 150410dab22664914505dcb804d9ad09cad6bc94d349Jamie Wellnitz scsi_print_sense("sd", SCpnt); 150510dab22664914505dcb804d9ad09cad6bc94d349Jamie Wellnitz SCpnt->result = 0; 150610dab22664914505dcb804d9ad09cad6bc94d349Jamie Wellnitz memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); 150710dab22664914505dcb804d9ad09cad6bc94d349Jamie Wellnitz break; 1508c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen case ABORTED_COMMAND: 1509c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen if (sshdr.asc == 0x10) /* DIF: Target detected corruption */ 1510c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen good_bytes = sd_completed_bytes(SCpnt); 1511c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen break; 1512c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen case ILLEGAL_REQUEST: 1513c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen if (sshdr.asc == 0x10) /* DIX: Host detected corruption */ 1514af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen good_bytes = sd_completed_bytes(SCpnt); 1515c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ 1516c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) && 1517c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen (op == UNMAP || op == WRITE_SAME_16 || op == WRITE_SAME)) 1518c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sd_config_discard(sdkp, SD_LBP_DISABLE); 151903aba2f79594ca94d159c8bab454de9bcc385b76Luben Tuikov break; 152003aba2f79594ca94d159c8bab454de9bcc385b76Luben Tuikov default: 152103aba2f79594ca94d159c8bab454de9bcc385b76Luben Tuikov break; 15221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 152303aba2f79594ca94d159c8bab454de9bcc385b76Luben Tuikov out: 1524af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen if (rq_data_dir(SCpnt->request) == READ && scsi_prot_sg_count(SCpnt)) 1525af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen sd_dif_complete(SCpnt, good_bytes); 1526af55ff675a8461da6a632320710b050af4366e0cMartin K. Petersen 15274e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen if (scsi_host_dif_capable(sdkp->device->host, sdkp->protection_type) 152877c9cfc51b0d732b2524799810fb30018074fd60Martin K. Petersen == SD_DIF_TYPE2_PROTECTION && SCpnt->cmnd != SCpnt->request->cmd) { 152977c9cfc51b0d732b2524799810fb30018074fd60Martin K. Petersen 153077c9cfc51b0d732b2524799810fb30018074fd60Martin K. Petersen /* We have to print a failed command here as the 153177c9cfc51b0d732b2524799810fb30018074fd60Martin K. Petersen * extended CDB gets freed before scsi_io_completion() 153277c9cfc51b0d732b2524799810fb30018074fd60Martin K. Petersen * is called. 153377c9cfc51b0d732b2524799810fb30018074fd60Martin K. Petersen */ 153477c9cfc51b0d732b2524799810fb30018074fd60Martin K. Petersen if (result) 153577c9cfc51b0d732b2524799810fb30018074fd60Martin K. Petersen scsi_print_command(SCpnt); 153677c9cfc51b0d732b2524799810fb30018074fd60Martin K. Petersen 15374e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen mempool_free(SCpnt->cmnd, sd_cdb_pool); 153877c9cfc51b0d732b2524799810fb30018074fd60Martin K. Petersen SCpnt->cmnd = NULL; 153977c9cfc51b0d732b2524799810fb30018074fd60Martin K. Petersen SCpnt->cmd_len = 0; 154077c9cfc51b0d732b2524799810fb30018074fd60Martin K. Petersen } 15414e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen 15427b3d9545f9ac8b31528dd2d6d8ec8d19922917b8Linus Torvalds return good_bytes; 15431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 15461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * spinup disk - called only in sd_revalidate_disk() 15471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 15481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1549e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersensd_spinup_disk(struct scsi_disk *sdkp) 1550ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley{ 15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char cmd[10]; 15524451e472627881e3e2240b224f127c99be500f91Alan Stern unsigned long spintime_expire = 0; 15531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retries, spintime; 15541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int the_result; 15551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_sense_hdr sshdr; 15561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int sense_valid = 0; 15571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spintime = 0; 15591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Spin up drives, as required. Only do this at boot time */ 15611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Spinup needs to be done for module loads too. */ 15621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do { 15631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retries = 0; 15641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do { 15661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd[0] = TEST_UNIT_READY; 15671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset((void *) &cmd[1], 0, 9); 15681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1569ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley the_result = scsi_execute_req(sdkp->device, cmd, 1570ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley DMA_NONE, NULL, 0, 1571ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley &sshdr, SD_TIMEOUT, 1572f4f4e47e4af6b02dd1c425b931c65d0165356e33FUJITA Tomonori SD_MAX_RETRIES, NULL); 15731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1574b4d38e38e66f8e1b32a1b1c00e533175314c8d56Alan Stern /* 1575b4d38e38e66f8e1b32a1b1c00e533175314c8d56Alan Stern * If the drive has indicated to us that it 1576b4d38e38e66f8e1b32a1b1c00e533175314c8d56Alan Stern * doesn't have any media in it, don't bother 1577b4d38e38e66f8e1b32a1b1c00e533175314c8d56Alan Stern * with any more polling. 1578b4d38e38e66f8e1b32a1b1c00e533175314c8d56Alan Stern */ 1579b4d38e38e66f8e1b32a1b1c00e533175314c8d56Alan Stern if (media_not_present(sdkp, &sshdr)) 1580b4d38e38e66f8e1b32a1b1c00e533175314c8d56Alan Stern return; 1581b4d38e38e66f8e1b32a1b1c00e533175314c8d56Alan Stern 15821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (the_result) 1583ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley sense_valid = scsi_sense_valid(&sshdr); 15841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retries++; 15851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } while (retries < 3 && 15861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (!scsi_status_is_good(the_result) || 15871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((driver_byte(the_result) & DRIVER_SENSE) && 15881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sense_valid && sshdr.sense_key == UNIT_ATTENTION))); 15891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((driver_byte(the_result) & DRIVER_SENSE) == 0) { 15911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* no sense, TUR either succeeded or failed 15921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * with a status error */ 1593e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen if(!spintime && !scsi_status_is_good(the_result)) { 1594e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, "Unit Not Ready\n"); 1595e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_print_result(sdkp, the_result); 1596e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen } 15971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 15981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 16011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The device does not want the automatic start to be issued. 16021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 160333dd6f92a1a7ad85c54d47fd9d73371a32c0bde4Matthew Wilcox if (sdkp->device->no_start_on_add) 16041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 16051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 160633dd6f92a1a7ad85c54d47fd9d73371a32c0bde4Matthew Wilcox if (sense_valid && sshdr.sense_key == NOT_READY) { 160733dd6f92a1a7ad85c54d47fd9d73371a32c0bde4Matthew Wilcox if (sshdr.asc == 4 && sshdr.ascq == 3) 160833dd6f92a1a7ad85c54d47fd9d73371a32c0bde4Matthew Wilcox break; /* manual intervention required */ 160933dd6f92a1a7ad85c54d47fd9d73371a32c0bde4Matthew Wilcox if (sshdr.asc == 4 && sshdr.ascq == 0xb) 161033dd6f92a1a7ad85c54d47fd9d73371a32c0bde4Matthew Wilcox break; /* standby */ 161133dd6f92a1a7ad85c54d47fd9d73371a32c0bde4Matthew Wilcox if (sshdr.asc == 4 && sshdr.ascq == 0xc) 161233dd6f92a1a7ad85c54d47fd9d73371a32c0bde4Matthew Wilcox break; /* unavailable */ 161333dd6f92a1a7ad85c54d47fd9d73371a32c0bde4Matthew Wilcox /* 161433dd6f92a1a7ad85c54d47fd9d73371a32c0bde4Matthew Wilcox * Issue command to spin up drive when not ready 161533dd6f92a1a7ad85c54d47fd9d73371a32c0bde4Matthew Wilcox */ 16161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!spintime) { 1617e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, "Spinning up disk..."); 16181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd[0] = START_STOP; 16191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd[1] = 1; /* Return immediately */ 16201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset((void *) &cmd[2], 0, 8); 16211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd[4] = 1; /* Start spin cycle */ 1622d2886ea368a67704ecc13e69075f18a9d74cb12bStefan Richter if (sdkp->device->start_stop_pwr_cond) 1623d2886ea368a67704ecc13e69075f18a9d74cb12bStefan Richter cmd[4] |= 1 << 4; 1624ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley scsi_execute_req(sdkp->device, cmd, DMA_NONE, 1625ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley NULL, 0, &sshdr, 1626f4f4e47e4af6b02dd1c425b931c65d0165356e33FUJITA Tomonori SD_TIMEOUT, SD_MAX_RETRIES, 1627f4f4e47e4af6b02dd1c425b931c65d0165356e33FUJITA Tomonori NULL); 16284451e472627881e3e2240b224f127c99be500f91Alan Stern spintime_expire = jiffies + 100 * HZ; 16294451e472627881e3e2240b224f127c99be500f91Alan Stern spintime = 1; 16301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Wait 1 second for next try */ 16321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msleep(1000); 16331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("."); 16344451e472627881e3e2240b224f127c99be500f91Alan Stern 16354451e472627881e3e2240b224f127c99be500f91Alan Stern /* 16364451e472627881e3e2240b224f127c99be500f91Alan Stern * Wait for USB flash devices with slow firmware. 16374451e472627881e3e2240b224f127c99be500f91Alan Stern * Yes, this sense key/ASC combination shouldn't 16384451e472627881e3e2240b224f127c99be500f91Alan Stern * occur here. It's characteristic of these devices. 16394451e472627881e3e2240b224f127c99be500f91Alan Stern */ 16404451e472627881e3e2240b224f127c99be500f91Alan Stern } else if (sense_valid && 16414451e472627881e3e2240b224f127c99be500f91Alan Stern sshdr.sense_key == UNIT_ATTENTION && 16424451e472627881e3e2240b224f127c99be500f91Alan Stern sshdr.asc == 0x28) { 16434451e472627881e3e2240b224f127c99be500f91Alan Stern if (!spintime) { 16444451e472627881e3e2240b224f127c99be500f91Alan Stern spintime_expire = jiffies + 5 * HZ; 16454451e472627881e3e2240b224f127c99be500f91Alan Stern spintime = 1; 16464451e472627881e3e2240b224f127c99be500f91Alan Stern } 16474451e472627881e3e2240b224f127c99be500f91Alan Stern /* Wait 1 second for next try */ 16484451e472627881e3e2240b224f127c99be500f91Alan Stern msleep(1000); 16491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 16501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* we don't understand the sense code, so it's 16511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * probably pointless to loop */ 16521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!spintime) { 1653e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, "Unit Not Ready\n"); 1654e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_print_sense_hdr(sdkp, &sshdr); 16551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 16571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16594451e472627881e3e2240b224f127c99be500f91Alan Stern } while (spintime && time_before_eq(jiffies, spintime_expire)); 16601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (spintime) { 16621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (scsi_status_is_good(the_result)) 16631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("ready\n"); 16641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 16651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("not responding...\n"); 16661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1669e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 1670e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen/* 1671e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen * Determine whether disk supports Data Integrity Field. 1672e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen */ 1673439d77f70f18ebe2b28757b141e67a25575fe363H Hartley Sweetenstatic void sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer) 1674e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen{ 1675e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen struct scsi_device *sdp = sdkp->device; 1676e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen u8 type; 1677e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 1678e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen if (scsi_device_protection(sdp) == 0 || (buffer[12] & 1) == 0) 167935e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen return; 168035e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen 168135e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */ 168235e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen 168335e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen if (type == sdkp->protection_type || !sdkp->first_scan) 168435e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen return; 1685e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 1686be922f478f430f8fab4db952ffc20c86f23de397Martin K. Petersen sdkp->protection_type = type; 1687be922f478f430f8fab4db952ffc20c86f23de397Martin K. Petersen 16884e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen if (type > SD_DIF_TYPE3_PROTECTION) { 168935e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen sd_printk(KERN_ERR, sdkp, "formatted with unsupported " \ 169035e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen "protection type %u. Disabling disk!\n", type); 169135e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen sdkp->capacity = 0; 169235e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen return; 1693e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen } 1694e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 169535e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen if (scsi_host_dif_capable(sdp->host, type)) 169635e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen sd_printk(KERN_NOTICE, sdkp, 169735e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen "Enabling DIF Type %u protection\n", type); 169835e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen else 169935e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen sd_printk(KERN_NOTICE, sdkp, 170035e1a5d90b66487d754ef2f2dcbf1007f806d921Martin K. Petersen "Disabling DIF Type %u protection\n", type); 1701e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen} 1702e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 17030da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcoxstatic void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp, 17040da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox struct scsi_sense_hdr *sshdr, int sense_valid, 17050da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox int the_result) 17060da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox{ 17070da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sd_print_result(sdkp, the_result); 17080da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox if (driver_byte(the_result) & DRIVER_SENSE) 17090da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sd_print_sense_hdr(sdkp, sshdr); 17100da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox else 17110da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sd_printk(KERN_NOTICE, sdkp, "Sense not available.\n"); 17120da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 17130da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox /* 17140da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox * Set dirty bit for removable devices if not ready - 17150da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox * sometimes drives will not report this properly. 17160da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox */ 17170da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox if (sdp->removable && 17180da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sense_valid && sshdr->sense_key == NOT_READY) 17192bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo set_media_not_present(sdkp); 17200da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 17210da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox /* 17220da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox * We used to set media_present to 0 here to indicate no media 17230da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox * in the drive, but some drives fail read capacity even with 17240da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox * media present, so we can't do that. 17250da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox */ 17260da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sdkp->capacity = 0; /* unknown mapped to zero - as usual */ 17270da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox} 17280da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 17290da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox#define RC16_LEN 32 17300da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox#if RC16_LEN > SD_BUF_SIZE 17310da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox#error RC16_LEN must not be more than SD_BUF_SIZE 17320da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox#endif 17330da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 17343233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley#define READ_CAPACITY_RETRIES_ON_RESET 10 17353233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley 17360da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcoxstatic int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, 17370da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox unsigned char *buffer) 1738ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley{ 17391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char cmd[16]; 17401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_sense_hdr sshdr; 17411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int sense_valid = 0; 17420da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox int the_result; 17433233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley int retries = 3, reset_retries = READ_CAPACITY_RETRIES_ON_RESET; 1744ea09bcc9c298d3057270abd78a973fc678d55c4cMartin K. Petersen unsigned int alignment; 17450da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox unsigned long long lba; 17460da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox unsigned sector_size; 17471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17485ce524bdff367b4abda20bcfd4dafd9d30c773dfHans de Goede if (sdp->no_read_capacity_16) 17495ce524bdff367b4abda20bcfd4dafd9d30c773dfHans de Goede return -EINVAL; 17505ce524bdff367b4abda20bcfd4dafd9d30c773dfHans de Goede 17511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do { 17520da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox memset(cmd, 0, 16); 17530da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox cmd[0] = SERVICE_ACTION_IN; 17540da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox cmd[1] = SAI_READ_CAPACITY_16; 17550da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox cmd[13] = RC16_LEN; 17560da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox memset(buffer, 0, RC16_LEN); 17570da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 1758ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE, 17590da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox buffer, RC16_LEN, &sshdr, 17600da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox SD_TIMEOUT, SD_MAX_RETRIES, NULL); 17611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1762ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley if (media_not_present(sdkp, &sshdr)) 17630da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox return -ENODEV; 17641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17652b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox if (the_result) { 1766ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley sense_valid = scsi_sense_valid(&sshdr); 17672b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox if (sense_valid && 17682b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox sshdr.sense_key == ILLEGAL_REQUEST && 17692b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox (sshdr.asc == 0x20 || sshdr.asc == 0x24) && 17702b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox sshdr.ascq == 0x00) 17712b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox /* Invalid Command Operation Code or 17722b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox * Invalid Field in CDB, just retry 17732b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox * silently with RC10 */ 17742b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox return -EINVAL; 17753233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley if (sense_valid && 17763233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley sshdr.sense_key == UNIT_ATTENTION && 17773233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley sshdr.asc == 0x29 && sshdr.ascq == 0x00) 17783233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley /* Device reset might occur several times, 17793233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley * give it one more chance */ 17803233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley if (--reset_retries > 0) 17813233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley continue; 17822b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox } 17831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retries--; 17841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } while (the_result && retries); 17861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17870da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox if (the_result) { 1788e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, "READ CAPACITY(16) failed\n"); 17890da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox read_capacity_error(sdkp, sdp, &sshdr, sense_valid, the_result); 17900da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox return -EINVAL; 17910da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox } 1792e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen 17938f76d151b010980d137bfdc736d1d8f64b489165Dave Hansen sector_size = get_unaligned_be32(&buffer[8]); 17948f76d151b010980d137bfdc736d1d8f64b489165Dave Hansen lba = get_unaligned_be64(&buffer[0]); 17950da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 17960da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sd_read_protection_type(sdkp, buffer); 17970da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 17980da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox if ((sizeof(sdkp->capacity) == 4) && (lba >= 0xffffffffULL)) { 17990da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a " 18000da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox "kernel compiled with support for large block " 18010da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox "devices.\n"); 18020da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sdkp->capacity = 0; 18030da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox return -EOVERFLOW; 18040da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox } 18050da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 1806ea09bcc9c298d3057270abd78a973fc678d55c4cMartin K. Petersen /* Logical blocks per physical block exponent */ 1807526f7c7950bbf1271e59177d70d74438c2ef96deMartin K. Petersen sdkp->physical_block_size = (1 << (buffer[13] & 0xf)) * sector_size; 1808ea09bcc9c298d3057270abd78a973fc678d55c4cMartin K. Petersen 1809ea09bcc9c298d3057270abd78a973fc678d55c4cMartin K. Petersen /* Lowest aligned logical block */ 1810ea09bcc9c298d3057270abd78a973fc678d55c4cMartin K. Petersen alignment = ((buffer[14] & 0x3f) << 8 | buffer[15]) * sector_size; 1811ea09bcc9c298d3057270abd78a973fc678d55c4cMartin K. Petersen blk_queue_alignment_offset(sdp->request_queue, alignment); 1812ea09bcc9c298d3057270abd78a973fc678d55c4cMartin K. Petersen if (alignment && sdkp->first_scan) 1813ea09bcc9c298d3057270abd78a973fc678d55c4cMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, 1814ea09bcc9c298d3057270abd78a973fc678d55c4cMartin K. Petersen "physical block alignment offset: %u\n", alignment); 1815ea09bcc9c298d3057270abd78a973fc678d55c4cMartin K. Petersen 1816c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen if (buffer[14] & 0x80) { /* LBPME */ 1817c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sdkp->lbpme = 1; 1818e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 1819c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen if (buffer[14] & 0x40) /* LBPRZ */ 1820c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sdkp->lbprz = 1; 1821e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 1822c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sd_config_discard(sdkp, SD_LBP_WS16); 1823e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen } 1824e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 18250da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sdkp->capacity = lba + 1; 18260da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox return sector_size; 18270da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox} 18280da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 18290da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcoxstatic int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp, 18300da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox unsigned char *buffer) 18310da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox{ 18320da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox unsigned char cmd[16]; 18330da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox struct scsi_sense_hdr sshdr; 18340da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox int sense_valid = 0; 18350da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox int the_result; 18363233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley int retries = 3, reset_retries = READ_CAPACITY_RETRIES_ON_RESET; 18370da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sector_t lba; 18380da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox unsigned sector_size; 18390da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 18400da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox do { 18410da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox cmd[0] = READ_CAPACITY; 18420da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox memset(&cmd[1], 0, 9); 18430da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox memset(buffer, 0, 8); 18440da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 18450da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE, 18460da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox buffer, 8, &sshdr, 18470da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox SD_TIMEOUT, SD_MAX_RETRIES, NULL); 18480da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 18490da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox if (media_not_present(sdkp, &sshdr)) 18500da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox return -ENODEV; 18510da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 18523233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley if (the_result) { 18530da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sense_valid = scsi_sense_valid(&sshdr); 18543233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley if (sense_valid && 18553233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley sshdr.sense_key == UNIT_ATTENTION && 18563233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley sshdr.asc == 0x29 && sshdr.ascq == 0x00) 18573233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley /* Device reset might occur several times, 18583233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley * give it one more chance */ 18593233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley if (--reset_retries > 0) 18603233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley continue; 18613233ac19811fe17033b537832ca7b59df8bf4aa9James Bottomley } 18620da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox retries--; 18630da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 18640da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox } while (the_result && retries); 18650da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 18660da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox if (the_result) { 18670da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sd_printk(KERN_NOTICE, sdkp, "READ CAPACITY failed\n"); 18680da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox read_capacity_error(sdkp, sdp, &sshdr, sense_valid, the_result); 18690da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox return -EINVAL; 18700da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox } 18710da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 18728f76d151b010980d137bfdc736d1d8f64b489165Dave Hansen sector_size = get_unaligned_be32(&buffer[4]); 18738f76d151b010980d137bfdc736d1d8f64b489165Dave Hansen lba = get_unaligned_be32(&buffer[0]); 18740da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 18755ce524bdff367b4abda20bcfd4dafd9d30c773dfHans de Goede if (sdp->no_read_capacity_16 && (lba == 0xffffffff)) { 18765ce524bdff367b4abda20bcfd4dafd9d30c773dfHans de Goede /* Some buggy (usb cardreader) devices return an lba of 18775ce524bdff367b4abda20bcfd4dafd9d30c773dfHans de Goede 0xffffffff when the want to report a size of 0 (with 18785ce524bdff367b4abda20bcfd4dafd9d30c773dfHans de Goede which they really mean no media is present) */ 18795ce524bdff367b4abda20bcfd4dafd9d30c773dfHans de Goede sdkp->capacity = 0; 18805cc103506289de7ee0a0b526ae0381541990cad4Linus Torvalds sdkp->physical_block_size = sector_size; 18815ce524bdff367b4abda20bcfd4dafd9d30c773dfHans de Goede return sector_size; 18825ce524bdff367b4abda20bcfd4dafd9d30c773dfHans de Goede } 18835ce524bdff367b4abda20bcfd4dafd9d30c773dfHans de Goede 18840da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox if ((sizeof(sdkp->capacity) == 4) && (lba == 0xffffffff)) { 18850da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a " 18860da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox "kernel compiled with support for large block " 18870da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox "devices.\n"); 18880da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sdkp->capacity = 0; 18890da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox return -EOVERFLOW; 18900da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox } 18910da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 18920da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sdkp->capacity = lba + 1; 1893526f7c7950bbf1271e59177d70d74438c2ef96deMartin K. Petersen sdkp->physical_block_size = sector_size; 18940da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox return sector_size; 18950da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox} 18960da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 18972b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcoxstatic int sd_try_rc16_first(struct scsi_device *sdp) 18982b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox{ 1899f87146bba523cad0196aa8e80ca9e8243d7a6c0cHannes Reinecke if (sdp->host->max_cmd_len < 16) 1900f87146bba523cad0196aa8e80ca9e8243d7a6c0cHannes Reinecke return 0; 1901b18504e4a631e31edd939fe569342274927d4b41Alan Stern if (sdp->try_rc_10_first) 1902b18504e4a631e31edd939fe569342274927d4b41Alan Stern return 0; 19032b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox if (sdp->scsi_level > SCSI_SPC_2) 19042b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox return 1; 19052b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox if (scsi_device_protection(sdp)) 19062b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox return 1; 19072b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox return 0; 19082b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox} 19092b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox 19100da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox/* 19110da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox * read disk capacity 19120da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox */ 19130da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcoxstatic void 19140da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcoxsd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) 19150da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox{ 19160da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox int sector_size; 19170da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox struct scsi_device *sdp = sdkp->device; 191870a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sector_t old_capacity = sdkp->capacity; 19190da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox 19202b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox if (sd_try_rc16_first(sdp)) { 19210da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sector_size = read_capacity_16(sdkp, sdp, buffer); 19220da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox if (sector_size == -EOVERFLOW) 19231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto got_data; 19242b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox if (sector_size == -ENODEV) 19252b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox return; 19262b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox if (sector_size < 0) 19272b301307f63dbecf06d91f58f003c7fb7addee24Matthew Wilcox sector_size = read_capacity_10(sdkp, sdp, buffer); 19280da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox if (sector_size < 0) 19290da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox return; 19301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 19310da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sector_size = read_capacity_10(sdkp, sdp, buffer); 19320da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox if (sector_size == -EOVERFLOW) 19330da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox goto got_data; 19340da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox if (sector_size < 0) 19350da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox return; 19360da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox if ((sizeof(sdkp->capacity) > 4) && 19370da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox (sdkp->capacity > 0xffffffffULL)) { 19380da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox int old_sector_size = sector_size; 19390da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sd_printk(KERN_NOTICE, sdkp, "Very big device. " 19400da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox "Trying to use READ CAPACITY(16).\n"); 19410da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sector_size = read_capacity_16(sdkp, sdp, buffer); 19420da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox if (sector_size < 0) { 19430da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sd_printk(KERN_NOTICE, sdkp, 19440da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox "Using 0xffffffff as device size\n"); 19450da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sdkp->capacity = 1 + (sector_t) 0xffffffff; 19460da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox sector_size = old_sector_size; 19470da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox goto got_data; 19480da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox } 19490da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox } 19500da205e01bc58cfad660659e3c901223d3596c57Matthew Wilcox } 19511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19525c211caa9f341f9eefbda89436d1440d1eccb3bcAlan Stern /* Some devices are known to return the total number of blocks, 19535c211caa9f341f9eefbda89436d1440d1eccb3bcAlan Stern * not the highest block number. Some devices have versions 19545c211caa9f341f9eefbda89436d1440d1eccb3bcAlan Stern * which do this and others which do not. Some devices we might 19555c211caa9f341f9eefbda89436d1440d1eccb3bcAlan Stern * suspect of doing this but we don't know for certain. 19565c211caa9f341f9eefbda89436d1440d1eccb3bcAlan Stern * 19575c211caa9f341f9eefbda89436d1440d1eccb3bcAlan Stern * If we know the reported capacity is wrong, decrement it. If 19585c211caa9f341f9eefbda89436d1440d1eccb3bcAlan Stern * we can only guess, then assume the number of blocks is even 19595c211caa9f341f9eefbda89436d1440d1eccb3bcAlan Stern * (usually true but not always) and err on the side of lowering 19605c211caa9f341f9eefbda89436d1440d1eccb3bcAlan Stern * the capacity. 19615c211caa9f341f9eefbda89436d1440d1eccb3bcAlan Stern */ 19625c211caa9f341f9eefbda89436d1440d1eccb3bcAlan Stern if (sdp->fix_capacity || 19635c211caa9f341f9eefbda89436d1440d1eccb3bcAlan Stern (sdp->guess_capacity && (sdkp->capacity & 0x01))) { 19645c211caa9f341f9eefbda89436d1440d1eccb3bcAlan Stern sd_printk(KERN_INFO, sdkp, "Adjusting the sector count " 19655c211caa9f341f9eefbda89436d1440d1eccb3bcAlan Stern "from its reported value: %llu\n", 19665c211caa9f341f9eefbda89436d1440d1eccb3bcAlan Stern (unsigned long long) sdkp->capacity); 19671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds --sdkp->capacity; 196861bf54b71d5abf767ee46284be19965d7253ddbfOliver Neukum } 196961bf54b71d5abf767ee46284be19965d7253ddbfOliver Neukum 19701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsgot_data: 19711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sector_size == 0) { 19721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sector_size = 512; 1973e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, "Sector size 0 reported, " 1974e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen "assuming 512.\n"); 19751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 19761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 19771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sector_size != 512 && 19781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sector_size != 1024 && 19791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sector_size != 2048 && 19801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sector_size != 4096 && 19811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sector_size != 256) { 1982e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, "Unsupported sector size %d.\n", 1983e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sector_size); 19841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 19851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The user might want to re-format the drive with 19861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a supported sectorsize. Once this happens, it 19871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * would be relatively trivial to set the thing up. 19881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * For this reason, we leave the thing in the table. 19891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 19901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sdkp->capacity = 0; 19911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 19921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * set a bogus sector size so the normal read/write 19931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * logic in the block layer will eventually refuse any 19941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * request on this device without tripping over power 19951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of two sector size assumptions 19961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 19971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sector_size = 512; 19981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1999e1defc4ff0cf57aca6c5e3ff99fa503f5943c1f1Martin K. Petersen blk_queue_logical_block_size(sdp->request_queue, sector_size); 20007404ad3b6d04efbd918e9e2e776bf560fbedf47dJames Bottomley 20011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 20027404ad3b6d04efbd918e9e2e776bf560fbedf47dJames Bottomley char cap_str_2[10], cap_str_10[10]; 2003520a2c2741747062e75f91cd0faddb564fbc64d2H. Peter Anvin u64 sz = (u64)sdkp->capacity << ilog2(sector_size); 20041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20057404ad3b6d04efbd918e9e2e776bf560fbedf47dJames Bottomley string_get_size(sz, STRING_UNITS_2, cap_str_2, 20067404ad3b6d04efbd918e9e2e776bf560fbedf47dJames Bottomley sizeof(cap_str_2)); 20077404ad3b6d04efbd918e9e2e776bf560fbedf47dJames Bottomley string_get_size(sz, STRING_UNITS_10, cap_str_10, 20087404ad3b6d04efbd918e9e2e776bf560fbedf47dJames Bottomley sizeof(cap_str_10)); 20091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2010ea09bcc9c298d3057270abd78a973fc678d55c4cMartin K. Petersen if (sdkp->first_scan || old_capacity != sdkp->capacity) { 201170a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sd_printk(KERN_NOTICE, sdkp, 2012ea09bcc9c298d3057270abd78a973fc678d55c4cMartin K. Petersen "%llu %d-byte logical blocks: (%s/%s)\n", 201370a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen (unsigned long long)sdkp->capacity, 201470a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sector_size, cap_str_10, cap_str_2); 2015ea09bcc9c298d3057270abd78a973fc678d55c4cMartin K. Petersen 2016526f7c7950bbf1271e59177d70d74438c2ef96deMartin K. Petersen if (sdkp->physical_block_size != sector_size) 2017ea09bcc9c298d3057270abd78a973fc678d55c4cMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, 2018ea09bcc9c298d3057270abd78a973fc678d55c4cMartin K. Petersen "%u-byte physical blocks\n", 2019526f7c7950bbf1271e59177d70d74438c2ef96deMartin K. Petersen sdkp->physical_block_size); 2020ea09bcc9c298d3057270abd78a973fc678d55c4cMartin K. Petersen } 20211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 20221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Rescale capacity to 512-byte units */ 20241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sector_size == 4096) 20251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sdkp->capacity <<= 3; 20261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (sector_size == 2048) 20271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sdkp->capacity <<= 2; 20281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (sector_size == 1024) 20291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sdkp->capacity <<= 1; 20301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (sector_size == 256) 20311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sdkp->capacity >>= 1; 20321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2033526f7c7950bbf1271e59177d70d74438c2ef96deMartin K. Petersen blk_queue_physical_block_size(sdp->request_queue, 2034526f7c7950bbf1271e59177d70d74438c2ef96deMartin K. Petersen sdkp->physical_block_size); 20351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sdkp->device->sector_size = sector_size; 20361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 20371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* called with buffer of length 512 */ 20391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int 2040ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomleysd_do_mode_sense(struct scsi_device *sdp, int dbd, int modepage, 2041ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley unsigned char *buffer, int len, struct scsi_mode_data *data, 2042ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley struct scsi_sense_hdr *sshdr) 20431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2044ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley return scsi_mode_sense(sdp, dbd, modepage, buffer, len, 20451cf72699c1530c3e4ac3d58344f6a6a40a2f46d3James Bottomley SD_TIMEOUT, SD_MAX_RETRIES, data, 2046ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley sshdr); 20471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 20481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 20501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * read write protect setting, if possible - called only in sd_revalidate_disk() 2051489708007785389941a89fa06aedc5ec53303c96Al Viro * called with buffer of length SD_BUF_SIZE 20521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 20531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 2054e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersensd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer) 2055ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley{ 20561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int res; 2057ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley struct scsi_device *sdp = sdkp->device; 20581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_mode_data data; 205970a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen int old_wp = sdkp->write_prot; 20601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_disk_ro(sdkp->disk, 0); 2062ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley if (sdp->skip_ms_page_3f) { 2063e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, "Assuming Write Enabled\n"); 20641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 20651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 20661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2067ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley if (sdp->use_192_bytes_for_3f) { 2068ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley res = sd_do_mode_sense(sdp, 0, 0x3F, buffer, 192, &data, NULL); 20691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 20701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 20711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * First attempt: ask for all pages (0x3F), but only 4 bytes. 20721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We have to start carefully: some devices hang if we ask 20731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for more than is available. 20741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2075ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley res = sd_do_mode_sense(sdp, 0, 0x3F, buffer, 4, &data, NULL); 20761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 20781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Second attempt: ask for page 0 When only page 0 is 20791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * implemented, a request for page 3F may return Sense Key 20801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5: Illegal Request, Sense Code 24: Invalid field in 20811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * CDB. 20821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 20831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!scsi_status_is_good(res)) 2084ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley res = sd_do_mode_sense(sdp, 0, 0, buffer, 4, &data, NULL); 20851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 20871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Third attempt: ask 255 bytes, as we did earlier. 20881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 20891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!scsi_status_is_good(res)) 2090ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley res = sd_do_mode_sense(sdp, 0, 0x3F, buffer, 255, 2091ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley &data, NULL); 20921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 20931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!scsi_status_is_good(res)) { 2095e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_printk(KERN_WARNING, sdkp, 2096e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen "Test WP failed, assume Write Enabled\n"); 20971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 20981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sdkp->write_prot = ((data.device_specific & 0x80) != 0); 20991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_disk_ro(sdkp->disk, sdkp->write_prot); 210070a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen if (sdkp->first_scan || old_wp != sdkp->write_prot) { 210170a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sd_printk(KERN_NOTICE, sdkp, "Write Protect is %s\n", 210270a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sdkp->write_prot ? "on" : "off"); 210370a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sd_printk(KERN_DEBUG, sdkp, 210470a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen "Mode Sense: %02x %02x %02x %02x\n", 210570a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen buffer[0], buffer[1], buffer[2], buffer[3]); 210670a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen } 21071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 21081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 21091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sd_read_cache_type - called only from sd_revalidate_disk() 2112489708007785389941a89fa06aedc5ec53303c96Al Viro * called with buffer of length SD_BUF_SIZE 21131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 21141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 2115e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersensd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) 2116631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro{ 21171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len = 0, res; 2118ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley struct scsi_device *sdp = sdkp->device; 21191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2120631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro int dbd; 2121631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro int modepage; 21220bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov int first_len; 21231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_mode_data data; 21241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_sense_hdr sshdr; 212570a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen int old_wce = sdkp->WCE; 212670a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen int old_rcd = sdkp->RCD; 212770a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen int old_dpofua = sdkp->DPOFUA; 21281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21290bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov first_len = 4; 21300bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov if (sdp->skip_ms_page_8) { 21310bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov if (sdp->type == TYPE_RBC) 21320bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov goto defaults; 21330bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov else { 21340bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov if (sdp->skip_ms_page_3f) 21350bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov goto defaults; 21360bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov modepage = 0x3F; 21370bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov if (sdp->use_192_bytes_for_3f) 21380bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov first_len = 192; 21390bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov dbd = 0; 21400bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov } 21410bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov } else if (sdp->type == TYPE_RBC) { 2142631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro modepage = 6; 2143631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro dbd = 8; 2144631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro } else { 2145631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro modepage = 8; 2146631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro dbd = 0; 2147631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro } 2148631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro 21491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* cautiously ask */ 21500bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov res = sd_do_mode_sense(sdp, dbd, modepage, buffer, first_len, 21510bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov &data, &sshdr); 21521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!scsi_status_is_good(res)) 21541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto bad_sense; 21551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21566d73c8514da241c6b1b8d710a6294786604d7142Al Viro if (!data.header_length) { 21576d73c8514da241c6b1b8d710a6294786604d7142Al Viro modepage = 6; 21580bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov first_len = 0; 2159e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_printk(KERN_ERR, sdkp, "Missing header in MODE_SENSE response\n"); 21606d73c8514da241c6b1b8d710a6294786604d7142Al Viro } 21616d73c8514da241c6b1b8d710a6294786604d7142Al Viro 21621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* that went OK, now ask for the proper length */ 21631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = data.length; 21641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 21661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We're only interested in the first three bytes, actually. 21671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * But the data cache page is defined for the first 20. 21681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 21691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (len < 3) 21701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto bad_sense; 21710bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov else if (len > SD_BUF_SIZE) { 21720bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov sd_printk(KERN_NOTICE, sdkp, "Truncating mode parameter " 21730bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov "data from %d to %d bytes\n", len, SD_BUF_SIZE); 21740bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov len = SD_BUF_SIZE; 21750bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov } 21760bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov if (modepage == 0x3F && sdp->use_192_bytes_for_3f) 21770bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov len = 192; 21781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get the data */ 21800bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov if (len > first_len) 21810bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, 21820bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov &data, &sshdr); 21831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (scsi_status_is_good(res)) { 2185631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro int offset = data.header_length + data.block_descriptor_length; 21861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21870bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov while (offset < len) { 21880bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov u8 page_code = buffer[offset] & 0x3F; 21890bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov u8 spf = buffer[offset] & 0x40; 21900bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov 21910bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov if (page_code == 8 || page_code == 6) { 21920bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov /* We're interested only in the first 3 bytes. 21930bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov */ 21940bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov if (len - offset <= 2) { 21950bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov sd_printk(KERN_ERR, sdkp, "Incomplete " 21960bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov "mode parameter data\n"); 21970bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov goto defaults; 21980bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov } else { 21990bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov modepage = page_code; 22000bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov goto Page_found; 22010bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov } 22020bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov } else { 22030bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov /* Go to the next page */ 22040bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov if (spf && len - offset > 3) 22050bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov offset += 4 + (buffer[offset+2] << 8) + 22060bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov buffer[offset+3]; 22070bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov else if (!spf && len - offset > 1) 22080bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov offset += 2 + buffer[offset+1]; 22090bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov else { 22100bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov sd_printk(KERN_ERR, sdkp, "Incomplete " 22110bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov "mode parameter data\n"); 22120bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov goto defaults; 22130bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov } 22140bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov } 2215489708007785389941a89fa06aedc5ec53303c96Al Viro } 2216489708007785389941a89fa06aedc5ec53303c96Al Viro 22170bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov if (modepage == 0x3F) { 22180bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov sd_printk(KERN_ERR, sdkp, "No Caching mode page " 22190bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov "present\n"); 22200bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov goto defaults; 22210bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov } else if ((buffer[offset] & 0x3f) != modepage) { 2222e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_printk(KERN_ERR, sdkp, "Got wrong page\n"); 2223631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro goto defaults; 2224631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro } 22250bcaa11154f07502e68375617e5650173eea8e50Luben Tuikov Page_found: 2226631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro if (modepage == 8) { 2227631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0); 2228631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0); 2229631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro } else { 2230631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro sdkp->WCE = ((buffer[offset + 2] & 0x01) == 0); 2231631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro sdkp->RCD = 0; 2232631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro } 22331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2234007365ad60387df30f02f01fdc2b6e6432f6c265Tejun Heo sdkp->DPOFUA = (data.device_specific & 0x10) != 0; 2235007365ad60387df30f02f01fdc2b6e6432f6c265Tejun Heo if (sdkp->DPOFUA && !sdkp->device->use_10_for_rw) { 2236e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, 2237e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen "Uses READ/WRITE(6), disabling FUA\n"); 2238007365ad60387df30f02f01fdc2b6e6432f6c265Tejun Heo sdkp->DPOFUA = 0; 2239007365ad60387df30f02f01fdc2b6e6432f6c265Tejun Heo } 2240007365ad60387df30f02f01fdc2b6e6432f6c265Tejun Heo 224170a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen if (sdkp->first_scan || old_wce != sdkp->WCE || 224270a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen old_rcd != sdkp->RCD || old_dpofua != sdkp->DPOFUA) 224370a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sd_printk(KERN_NOTICE, sdkp, 224470a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen "Write cache: %s, read cache: %s, %s\n", 224570a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sdkp->WCE ? "enabled" : "disabled", 224670a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sdkp->RCD ? "disabled" : "enabled", 224770a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sdkp->DPOFUA ? "supports DPO and FUA" 224870a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen : "doesn't support DPO or FUA"); 22491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 22511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 22521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsbad_sense: 2254ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley if (scsi_sense_valid(&sshdr) && 22551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sshdr.sense_key == ILLEGAL_REQUEST && 22561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sshdr.asc == 0x24 && sshdr.ascq == 0x0) 2257e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen /* Invalid field in CDB */ 2258e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, "Cache data unavailable\n"); 22591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 2260e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_printk(KERN_ERR, sdkp, "Asking for cache data failed\n"); 22611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdefaults: 2263e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_printk(KERN_ERR, sdkp, "Assuming drive cache: write through\n"); 22641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sdkp->WCE = 0; 22651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sdkp->RCD = 0; 2266489708007785389941a89fa06aedc5ec53303c96Al Viro sdkp->DPOFUA = 0; 22671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 22681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2269e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen/* 2270e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen * The ATO bit indicates whether the DIF application tag is available 2271e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen * for use by the operating system. 2272e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen */ 2273439d77f70f18ebe2b28757b141e67a25575fe363H Hartley Sweetenstatic void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer) 2274e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen{ 2275e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen int res, offset; 2276e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen struct scsi_device *sdp = sdkp->device; 2277e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen struct scsi_mode_data data; 2278e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen struct scsi_sense_hdr sshdr; 2279e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 2280e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen if (sdp->type != TYPE_DISK) 2281e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen return; 2282e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 2283e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen if (sdkp->protection_type == 0) 2284e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen return; 2285e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 2286e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen res = scsi_mode_sense(sdp, 1, 0x0a, buffer, 36, SD_TIMEOUT, 2287e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen SD_MAX_RETRIES, &data, &sshdr); 2288e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 2289e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen if (!scsi_status_is_good(res) || !data.header_length || 2290e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen data.length < 6) { 2291e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen sd_printk(KERN_WARNING, sdkp, 2292e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen "getting Control mode page failed, assume no ATO\n"); 2293e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 2294e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen if (scsi_sense_valid(&sshdr)) 2295e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen sd_print_sense_hdr(sdkp, &sshdr); 2296e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 2297e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen return; 2298e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen } 2299e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 2300e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen offset = data.header_length + data.block_descriptor_length; 2301e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 2302e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen if ((buffer[offset] & 0x3f) != 0x0a) { 2303e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen sd_printk(KERN_ERR, sdkp, "ATO Got wrong page\n"); 2304e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen return; 2305e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen } 2306e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 2307e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen if ((buffer[offset + 5] & 0x80) == 0) 2308e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen return; 2309e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 2310e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen sdkp->ATO = 1; 2311e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 2312e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen return; 2313e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen} 2314e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen 23151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 2316d11b6916961d6ec7d7215332cbbe9feec086721dMartin K. Petersen * sd_read_block_limits - Query disk device for preferred I/O sizes. 2317d11b6916961d6ec7d7215332cbbe9feec086721dMartin K. Petersen * @disk: disk to query 2318d11b6916961d6ec7d7215332cbbe9feec086721dMartin K. Petersen */ 2319d11b6916961d6ec7d7215332cbbe9feec086721dMartin K. Petersenstatic void sd_read_block_limits(struct scsi_disk *sdkp) 2320d11b6916961d6ec7d7215332cbbe9feec086721dMartin K. Petersen{ 2321d11b6916961d6ec7d7215332cbbe9feec086721dMartin K. Petersen unsigned int sector_sz = sdkp->device->sector_size; 2322bb2d3de1885cd69a5fc92af99c4e0c05eb5fc122Martin K. Petersen const int vpd_len = 64; 2323e3deec090558d5cb5ffdc574e5560f3ed9723394James Bottomley unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL); 2324d11b6916961d6ec7d7215332cbbe9feec086721dMartin K. Petersen 2325e3deec090558d5cb5ffdc574e5560f3ed9723394James Bottomley if (!buffer || 2326e3deec090558d5cb5ffdc574e5560f3ed9723394James Bottomley /* Block Limits VPD */ 2327e3deec090558d5cb5ffdc574e5560f3ed9723394James Bottomley scsi_get_vpd_page(sdkp->device, 0xb0, buffer, vpd_len)) 2328e3deec090558d5cb5ffdc574e5560f3ed9723394James Bottomley goto out; 2329d11b6916961d6ec7d7215332cbbe9feec086721dMartin K. Petersen 2330d11b6916961d6ec7d7215332cbbe9feec086721dMartin K. Petersen blk_queue_io_min(sdkp->disk->queue, 2331d11b6916961d6ec7d7215332cbbe9feec086721dMartin K. Petersen get_unaligned_be16(&buffer[6]) * sector_sz); 2332d11b6916961d6ec7d7215332cbbe9feec086721dMartin K. Petersen blk_queue_io_opt(sdkp->disk->queue, 2333d11b6916961d6ec7d7215332cbbe9feec086721dMartin K. Petersen get_unaligned_be32(&buffer[12]) * sector_sz); 2334d11b6916961d6ec7d7215332cbbe9feec086721dMartin K. Petersen 2335c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen if (buffer[3] == 0x3c) { 2336c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen unsigned int lba_count, desc_count; 2337e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 2338c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sdkp->max_ws_blocks = 2339c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen (u32) min_not_zero(get_unaligned_be64(&buffer[36]), 2340c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen (u64)0xffffffff); 2341e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 2342c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen if (!sdkp->lbpme) 2343045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen goto out; 2344045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen 2345c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen lba_count = get_unaligned_be32(&buffer[20]); 2346c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen desc_count = get_unaligned_be32(&buffer[24]); 2347045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen 2348c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen if (lba_count && desc_count) 2349c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sdkp->max_unmap_blocks = lba_count; 2350e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 2351c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sdkp->unmap_granularity = get_unaligned_be32(&buffer[28]); 2352e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 2353e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen if (buffer[32] & 0x80) 2354c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sdkp->unmap_alignment = 2355e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen get_unaligned_be32(&buffer[32]) & ~(1 << 31); 2356c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 2357c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen if (!sdkp->lbpvpd) { /* LBP VPD page not provided */ 2358c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 2359c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen if (sdkp->max_unmap_blocks) 2360c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sd_config_discard(sdkp, SD_LBP_UNMAP); 2361c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen else 2362c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sd_config_discard(sdkp, SD_LBP_WS16); 2363c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 2364c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen } else { /* LBP VPD page tells us what to use */ 2365c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen 2366c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen if (sdkp->lbpu && sdkp->max_unmap_blocks) 2367c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sd_config_discard(sdkp, SD_LBP_UNMAP); 2368c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen else if (sdkp->lbpws) 2369c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sd_config_discard(sdkp, SD_LBP_WS16); 2370c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen else if (sdkp->lbpws10) 2371c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sd_config_discard(sdkp, SD_LBP_WS10); 2372c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen else 2373c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sd_config_discard(sdkp, SD_LBP_DISABLE); 2374c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen } 2375e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen } 2376e339c1a7c09ef736dca7b3a4353c7742557d9f8fMartin K. Petersen 2377e3deec090558d5cb5ffdc574e5560f3ed9723394James Bottomley out: 2378d11b6916961d6ec7d7215332cbbe9feec086721dMartin K. Petersen kfree(buffer); 2379d11b6916961d6ec7d7215332cbbe9feec086721dMartin K. Petersen} 2380d11b6916961d6ec7d7215332cbbe9feec086721dMartin K. Petersen 2381d11b6916961d6ec7d7215332cbbe9feec086721dMartin K. Petersen/** 23823821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen * sd_read_block_characteristics - Query block dev. characteristics 23833821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen * @disk: disk to query 23843821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen */ 23853821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersenstatic void sd_read_block_characteristics(struct scsi_disk *sdkp) 23863821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen{ 2387e3deec090558d5cb5ffdc574e5560f3ed9723394James Bottomley unsigned char *buffer; 23883821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen u16 rot; 2389bb2d3de1885cd69a5fc92af99c4e0c05eb5fc122Martin K. Petersen const int vpd_len = 64; 23903821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen 2391e3deec090558d5cb5ffdc574e5560f3ed9723394James Bottomley buffer = kmalloc(vpd_len, GFP_KERNEL); 23923821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen 2393e3deec090558d5cb5ffdc574e5560f3ed9723394James Bottomley if (!buffer || 2394e3deec090558d5cb5ffdc574e5560f3ed9723394James Bottomley /* Block Device Characteristics VPD */ 2395e3deec090558d5cb5ffdc574e5560f3ed9723394James Bottomley scsi_get_vpd_page(sdkp->device, 0xb1, buffer, vpd_len)) 2396e3deec090558d5cb5ffdc574e5560f3ed9723394James Bottomley goto out; 23973821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen 23983821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen rot = get_unaligned_be16(&buffer[4]); 23993821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen 24003821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen if (rot == 1) 24013821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen queue_flag_set_unlocked(QUEUE_FLAG_NONROT, sdkp->disk->queue); 24023821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen 2403e3deec090558d5cb5ffdc574e5560f3ed9723394James Bottomley out: 24043821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen kfree(buffer); 24053821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen} 24063821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen 2407045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen/** 2408c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen * sd_read_block_provisioning - Query provisioning VPD page 2409045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen * @disk: disk to query 2410045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen */ 2411c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersenstatic void sd_read_block_provisioning(struct scsi_disk *sdkp) 2412045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen{ 2413045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen unsigned char *buffer; 2414045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen const int vpd_len = 8; 2415045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen 2416c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen if (sdkp->lbpme == 0) 2417045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen return; 2418045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen 2419045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen buffer = kmalloc(vpd_len, GFP_KERNEL); 2420045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen 2421045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen if (!buffer || scsi_get_vpd_page(sdkp->device, 0xb2, buffer, vpd_len)) 2422045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen goto out; 2423045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen 2424c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sdkp->lbpvpd = 1; 2425c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sdkp->lbpu = (buffer[5] >> 7) & 1; /* UNMAP */ 2426c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sdkp->lbpws = (buffer[5] >> 6) & 1; /* WRITE SAME(16) with UNMAP */ 2427c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sdkp->lbpws10 = (buffer[5] >> 5) & 1; /* WRITE SAME(10) with UNMAP */ 2428045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen 2429045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen out: 2430045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen kfree(buffer); 2431045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen} 2432045d3fe766b01921e24e2d4178e011b3b09ad4d6Martin K. Petersen 2433ffd4bc2a984fab40ed969163efdff321490e8032Martin K. Petersenstatic int sd_try_extended_inquiry(struct scsi_device *sdp) 2434ffd4bc2a984fab40ed969163efdff321490e8032Martin K. Petersen{ 2435ffd4bc2a984fab40ed969163efdff321490e8032Martin K. Petersen /* 2436ffd4bc2a984fab40ed969163efdff321490e8032Martin K. Petersen * Although VPD inquiries can go to SCSI-2 type devices, 2437ffd4bc2a984fab40ed969163efdff321490e8032Martin K. Petersen * some USB ones crash on receiving them, and the pages 2438ffd4bc2a984fab40ed969163efdff321490e8032Martin K. Petersen * we currently ask for are for SPC-3 and beyond 2439ffd4bc2a984fab40ed969163efdff321490e8032Martin K. Petersen */ 244009b6b51b0b6c1b9bb61815baf205e4d74c89ff04Alan Stern if (sdp->scsi_level > SCSI_SPC_2 && !sdp->skip_vpd_pages) 2441ffd4bc2a984fab40ed969163efdff321490e8032Martin K. Petersen return 1; 2442ffd4bc2a984fab40ed969163efdff321490e8032Martin K. Petersen return 0; 2443ffd4bc2a984fab40ed969163efdff321490e8032Martin K. Petersen} 2444ffd4bc2a984fab40ed969163efdff321490e8032Martin K. Petersen 24453821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen/** 24461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sd_revalidate_disk - called the first time a new disk is seen, 24471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * performs disk spin up, read_capacity, etc. 24481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @disk: struct gendisk we care about 24491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/ 24501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int sd_revalidate_disk(struct gendisk *disk) 24511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 24521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_disk *sdkp = scsi_disk(disk); 24531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_device *sdp = sdkp->device; 24541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *buffer; 24554913efe456c987057e5d36a3f0a55422a9072caeTejun Heo unsigned flush = 0; 24561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2457fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, 2458fa0d34be06213e02a4df29a9d34ca915728a8434Martin K. Petersen "sd_revalidate_disk\n")); 24591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 24611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If the device is offline, don't try and read capacity or any 24621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of the other niceties. 24631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 24641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!scsi_device_online(sdp)) 24651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 24661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2467a6123f142924a5e21f6d48e6e3c67d9060726caaBernhard Walle buffer = kmalloc(SD_BUF_SIZE, GFP_KERNEL); 24681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!buffer) { 2469e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_printk(KERN_WARNING, sdkp, "sd_revalidate_disk: Memory " 2470e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen "allocation failure.\n"); 2471ea73a9f23906c374b697cd5b0d64f6dceced63deJames Bottomley goto out; 24721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 24731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2474e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_spinup_disk(sdkp); 24751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 24771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Without media there is no reason to ask; moreover, some devices 24781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * react badly if we do. 24791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 24801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sdkp->media_present) { 2481e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_read_capacity(sdkp, buffer); 2482ffd4bc2a984fab40ed969163efdff321490e8032Martin K. Petersen 2483ffd4bc2a984fab40ed969163efdff321490e8032Martin K. Petersen if (sd_try_extended_inquiry(sdp)) { 2484c98a0eb0e90d1caa8a92913cd45462102cbd5eafMartin K. Petersen sd_read_block_provisioning(sdkp); 2485ffd4bc2a984fab40ed969163efdff321490e8032Martin K. Petersen sd_read_block_limits(sdkp); 2486ffd4bc2a984fab40ed969163efdff321490e8032Martin K. Petersen sd_read_block_characteristics(sdkp); 2487ffd4bc2a984fab40ed969163efdff321490e8032Martin K. Petersen } 2488ffd4bc2a984fab40ed969163efdff321490e8032Martin K. Petersen 2489e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_read_write_protect_flag(sdkp, buffer); 2490e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_read_cache_type(sdkp, buffer); 2491e0597d70012c82e16ee152270a55d89d8bf66693Martin K. Petersen sd_read_app_tag_own(sdkp, buffer); 24921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2493461d4e90c8cd049718884cd17c955e231140d3beTejun Heo 249470a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sdkp->first_scan = 0; 249570a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen 2496461d4e90c8cd049718884cd17c955e231140d3beTejun Heo /* 2497461d4e90c8cd049718884cd17c955e231140d3beTejun Heo * We now have all cache related info, determine how we deal 24984913efe456c987057e5d36a3f0a55422a9072caeTejun Heo * with flush requests. 2499461d4e90c8cd049718884cd17c955e231140d3beTejun Heo */ 25004913efe456c987057e5d36a3f0a55422a9072caeTejun Heo if (sdkp->WCE) { 25014913efe456c987057e5d36a3f0a55422a9072caeTejun Heo flush |= REQ_FLUSH; 25024913efe456c987057e5d36a3f0a55422a9072caeTejun Heo if (sdkp->DPOFUA) 25034913efe456c987057e5d36a3f0a55422a9072caeTejun Heo flush |= REQ_FUA; 25044913efe456c987057e5d36a3f0a55422a9072caeTejun Heo } 2505461d4e90c8cd049718884cd17c955e231140d3beTejun Heo 25064913efe456c987057e5d36a3f0a55422a9072caeTejun Heo blk_queue_flush(sdkp->disk->queue, flush); 2507461d4e90c8cd049718884cd17c955e231140d3beTejun Heo 25081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_capacity(disk, sdkp->capacity); 25091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(buffer); 25101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds out: 25121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 25131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 25141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 251672ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo * sd_unlock_native_capacity - unlock native capacity 251772ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo * @disk: struct gendisk to set capacity for 251872ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo * 251972ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo * Block layer calls this function if it detects that partitions 252072ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo * on @disk reach beyond the end of the device. If the SCSI host 252172ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo * implements ->unlock_native_capacity() method, it's invoked to 252272ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo * give it a chance to adjust the device capacity. 252372ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo * 252472ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo * CONTEXT: 252572ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo * Defined by block layer. Might sleep. 252672ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo */ 252772ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heostatic void sd_unlock_native_capacity(struct gendisk *disk) 252872ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo{ 252972ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo struct scsi_device *sdev = scsi_disk(disk)->device; 253072ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo 253172ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo if (sdev->host->hostt->unlock_native_capacity) 253272ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo sdev->host->hostt->unlock_native_capacity(sdev); 253372ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo} 253472ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo 253572ec24bd7725545bc149d80cbd21a7578d9aa206Tejun Heo/** 25363e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * sd_format_disk_name - format disk name 25373e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * @prefix: name prefix - ie. "sd" for SCSI disks 25383e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * @index: index of the disk to format name for 25393e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * @buf: output buffer 25403e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * @buflen: length of the output buffer 25413e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * 25423e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * SCSI disk names starts at sda. The 26th device is sdz and the 25433e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * 27th is sdaa. The last one for two lettered suffix is sdzz 25443e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * which is followed by sdaaa. 25453e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * 25463e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * This is basically 26 base counting with one extra 'nil' entry 25473ad2f3fbb961429d2aa627465ae4829758bc7e07Daniel Mack * at the beginning from the second digit on and can be 25483e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * determined using similar method as 26 base conversion with the 25493e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * index shifted -1 after each digit is computed. 25503e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * 25513e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * CONTEXT: 25523e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * Don't care. 25533e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * 25543e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * RETURNS: 25553e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo * 0 on success, -errno on failure. 25563e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo */ 25573e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heostatic int sd_format_disk_name(char *prefix, int index, char *buf, int buflen) 25583e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo{ 25593e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo const int base = 'z' - 'a' + 1; 25603e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo char *begin = buf + strlen(prefix); 25613e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo char *end = buf + buflen; 25623e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo char *p; 25633e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo int unit; 25643e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo 25653e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo p = end - 1; 25663e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo *p = '\0'; 25673e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo unit = base; 25683e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo do { 25693e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo if (p == begin) 25703e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo return -EINVAL; 25713e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo *--p = 'a' + (index % unit); 25723e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo index = (index / unit) - 1; 25733e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo } while (index >= 0); 25743e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo 25753e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo memmove(begin, p, end - p); 25763e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo memcpy(buf, prefix, strlen(prefix)); 25773e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo 25783e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo return 0; 25793e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo} 25803e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo 25814ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven/* 25824ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven * The asynchronous part of sd_probe 25834ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven */ 25844ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Venstatic void sd_probe_async(void *data, async_cookie_t cookie) 25854ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven{ 25864ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven struct scsi_disk *sdkp = data; 25874ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven struct scsi_device *sdp; 25884ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven struct gendisk *gd; 25894ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven u32 index; 25904ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven struct device *dev; 25914ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven 25924ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven sdp = sdkp->device; 25934ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven gd = sdkp->disk; 25944ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven index = sdkp->index; 25954ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven dev = &sdp->sdev_gendev; 25964ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven 25971a03ae0f556a931aa3747b70e44b78308f5b0590Michael Reed gd->major = sd_major((index & 0xf0) >> 4); 25981a03ae0f556a931aa3747b70e44b78308f5b0590Michael Reed gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); 25991a03ae0f556a931aa3747b70e44b78308f5b0590Michael Reed gd->minors = SD_MINORS; 26001a03ae0f556a931aa3747b70e44b78308f5b0590Michael Reed 26014ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven gd->fops = &sd_fops; 26024ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven gd->private_data = &sdkp->driver; 26034ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven gd->queue = sdkp->device->request_queue; 26044ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven 260570a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen /* defaults, until the device tells us otherwise */ 260670a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sdp->sector_size = 512; 260770a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sdkp->capacity = 0; 260870a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sdkp->media_present = 1; 260970a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sdkp->write_prot = 0; 261070a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sdkp->WCE = 0; 261170a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sdkp->RCD = 0; 261270a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sdkp->ATO = 0; 261370a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen sdkp->first_scan = 1; 261418a4d0a22ed6c54b67af7718c305cd010f09ddf8Martin K. Petersen sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS; 261570a9b8734660698eb91efb8947a9e691d40235e1Martin K. Petersen 26164ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven sd_revalidate_disk(gd); 26174ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven 26184ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven blk_queue_prep_rq(sdp->request_queue, sd_prep_fn); 2619f1126e950d28ff875d96ed6a04a9ff96c7bfc357FUJITA Tomonori blk_queue_unprep_rq(sdp->request_queue, sd_unprep_fn); 26204ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven 26214ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven gd->driverfs_dev = &sdp->sdev_gendev; 262297fedbbe1046b3118f49df249840ca21041eefe4NeilBrown gd->flags = GENHD_FL_EXT_DEVT; 26232bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo if (sdp->removable) { 26244ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven gd->flags |= GENHD_FL_REMOVABLE; 26252bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo gd->events |= DISK_EVENT_MEDIA_CHANGE; 26262bae0093cab4ee0a7a8728fdfc35b74569350863Tejun Heo } 26274ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven 26284ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven add_disk(gd); 26294ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven sd_dif_config_host(sdkp); 26304ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven 26313821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen sd_revalidate_disk(gd); 26323821d768912a47ddbd6cab52943a8284df88003cMartin K. Petersen 26334ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", 26344ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven sdp->removable ? "removable " : ""); 2635478a8a0543021172220feeb0b39bb1b3e43c988fAlan Stern scsi_autopm_put_device(sdp); 2636ea038f63ac52439e7816295fa6064fe95e6c1f51James Bottomley put_device(&sdkp->dev); 26374ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven} 26384ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven 26393e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo/** 26401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sd_probe - called during driver initialization and whenever a 26411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * new scsi device is attached to the system. It is called once 26421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for each scsi device (not just disks) present. 26431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @dev: pointer to device object 26441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 26451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns 0 if successful (or not interested in this scsi device 26461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (e.g. scanner)); 1 when there is an error. 26471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 26481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Note: this function is invoked from the scsi mid-level. 26491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This function sets up the mapping between a given 26501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * <host,channel,id,lun> (found in sdp) and new device name 26511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (e.g. /dev/sda). More precisely it is the block device major 26521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and minor number that is chosen here. 26531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 26542db93ce8cc1801ccb32a2f19062d110e5a9d4282Petr Uzel * Assume sd_probe is not re-entrant (for time being) 26552db93ce8cc1801ccb32a2f19062d110e5a9d4282Petr Uzel * Also think about sd_probe() and sd_remove() running coincidentally. 26561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/ 26571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int sd_probe(struct device *dev) 26581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 26591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_device *sdp = to_scsi_device(dev); 26601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct scsi_disk *sdkp; 26611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct gendisk *gd; 2662439d77f70f18ebe2b28757b141e67a25575fe363H Hartley Sweeten int index; 26631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int error; 26641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds error = -ENODEV; 2666631e8a1398ce4cfef8b30678d51daf0c64313a09Al Viro if (sdp->type != TYPE_DISK && sdp->type != TYPE_MOD && sdp->type != TYPE_RBC) 26671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 26681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26699ccfc756a70d454dfa82f48897e2883560c01a0eJames Bottomley SCSI_LOG_HLQUEUE(3, sdev_printk(KERN_INFO, sdp, 26702db93ce8cc1801ccb32a2f19062d110e5a9d4282Petr Uzel "sd_probe\n")); 26711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds error = -ENOMEM; 267324669f75a3231fa37444977c92d1f4838bec1233Jes Sorensen sdkp = kzalloc(sizeof(*sdkp), GFP_KERNEL); 26741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!sdkp) 26751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 26761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2677689d6fac40b41c7bf154f362deaf442548e4dc81Tejun Heo gd = alloc_disk(SD_MINORS); 26781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!gd) 26791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_free; 26801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2681f27bac2761cab5a2e212dea602d22457a9aa6943Tejun Heo do { 2682f27bac2761cab5a2e212dea602d22457a9aa6943Tejun Heo if (!ida_pre_get(&sd_index_ida, GFP_KERNEL)) 2683f27bac2761cab5a2e212dea602d22457a9aa6943Tejun Heo goto out_put; 26841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26854034cc68157bfa0b6622efe368488d3d3e20f4e6Tejun Heo spin_lock(&sd_index_lock); 2686f27bac2761cab5a2e212dea602d22457a9aa6943Tejun Heo error = ida_get_new(&sd_index_ida, &index); 26874034cc68157bfa0b6622efe368488d3d3e20f4e6Tejun Heo spin_unlock(&sd_index_lock); 2688f27bac2761cab5a2e212dea602d22457a9aa6943Tejun Heo } while (error == -EAGAIN); 26891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 269021208ae5a21fd5f337e987cde11374eaf2fe70b4Dave Kleikamp if (error) { 269121208ae5a21fd5f337e987cde11374eaf2fe70b4Dave Kleikamp sdev_printk(KERN_WARNING, sdp, "sd_probe: memory exhausted.\n"); 26921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_put; 26931a03ae0f556a931aa3747b70e44b78308f5b0590Michael Reed } 26941a03ae0f556a931aa3747b70e44b78308f5b0590Michael Reed 26953e1a7ff8a0a7b948f2684930166954f9e8e776feTejun Heo error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN); 269621208ae5a21fd5f337e987cde11374eaf2fe70b4Dave Kleikamp if (error) { 269721208ae5a21fd5f337e987cde11374eaf2fe70b4Dave Kleikamp sdev_printk(KERN_WARNING, sdp, "SCSI disk (sd) name length exceeded.\n"); 2698f27bac2761cab5a2e212dea602d22457a9aa6943Tejun Heo goto out_free_index; 269921208ae5a21fd5f337e987cde11374eaf2fe70b4Dave Kleikamp } 2700f27bac2761cab5a2e212dea602d22457a9aa6943Tejun Heo 27011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sdkp->device = sdp; 27021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sdkp->driver = &sd_template; 27031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sdkp->disk = gd; 27041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sdkp->index = index; 2705409f3499a2cfcd1e9c2857c53af7fcce069f027fArnd Bergmann atomic_set(&sdkp->openers, 0); 27061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2707601e7638254c118fca135af9b1a9f35061420f62James Bottomley if (!sdp->request_queue->rq_timeout) { 2708601e7638254c118fca135af9b1a9f35061420f62James Bottomley if (sdp->type != TYPE_MOD) 2709601e7638254c118fca135af9b1a9f35061420f62James Bottomley blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT); 2710601e7638254c118fca135af9b1a9f35061420f62James Bottomley else 2711601e7638254c118fca135af9b1a9f35061420f62James Bottomley blk_queue_rq_timeout(sdp->request_queue, 2712601e7638254c118fca135af9b1a9f35061420f62James Bottomley SD_MOD_TIMEOUT); 2713601e7638254c118fca135af9b1a9f35061420f62James Bottomley } 2714601e7638254c118fca135af9b1a9f35061420f62James Bottomley 2715601e7638254c118fca135af9b1a9f35061420f62James Bottomley device_initialize(&sdkp->dev); 2716478a8a0543021172220feeb0b39bb1b3e43c988fAlan Stern sdkp->dev.parent = dev; 2717601e7638254c118fca135af9b1a9f35061420f62James Bottomley sdkp->dev.class = &sd_disk_class; 2718478a8a0543021172220feeb0b39bb1b3e43c988fAlan Stern dev_set_name(&sdkp->dev, dev_name(dev)); 2719601e7638254c118fca135af9b1a9f35061420f62James Bottomley 2720601e7638254c118fca135af9b1a9f35061420f62James Bottomley if (device_add(&sdkp->dev)) 2721601e7638254c118fca135af9b1a9f35061420f62James Bottomley goto out_free_index; 2722601e7638254c118fca135af9b1a9f35061420f62James Bottomley 2723478a8a0543021172220feeb0b39bb1b3e43c988fAlan Stern get_device(dev); 2724478a8a0543021172220feeb0b39bb1b3e43c988fAlan Stern dev_set_drvdata(dev, sdkp); 2725601e7638254c118fca135af9b1a9f35061420f62James Bottomley 2726ea038f63ac52439e7816295fa6064fe95e6c1f51James Bottomley get_device(&sdkp->dev); /* prevent release before async_schedule */ 27274ace92fc112c6069b4fcb95a31d3142d4a43ff2aArjan van de Ven async_schedule(sd_probe_async, sdkp); 27281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 27301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2731f27bac2761cab5a2e212dea602d22457a9aa6943Tejun Heo out_free_index: 27324034cc68157bfa0b6622efe368488d3d3e20f4e6Tejun Heo spin_lock(&sd_index_lock); 2733f27bac2761cab5a2e212dea602d22457a9aa6943Tejun Heo ida_remove(&sd_index_ida, index); 27344034cc68157bfa0b6622efe368488d3d3e20f4e6Tejun Heo spin_unlock(&sd_index_lock); 27356bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley out_put: 27361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds put_disk(gd); 27376bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley out_free: 27381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(sdkp); 27396bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley out: 27401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return error; 27411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 27421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 27441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sd_remove - called whenever a scsi disk (previously recognized by 27451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sd_probe) is detached from the system. It is called (potentially 27461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * multiple times) during sd module unload. 27471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @sdp: pointer to mid level scsi device object 27481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 27491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Note: this function is invoked from the scsi mid-level. 27501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This function potentially frees up a device name (e.g. /dev/sdc) 27511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that could be re-used by a subsequent sd_probe(). 27521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This function is not called when the built-in sd driver is "exit-ed". 27531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/ 27541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int sd_remove(struct device *dev) 27551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2756601e7638254c118fca135af9b1a9f35061420f62James Bottomley struct scsi_disk *sdkp; 27571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2758601e7638254c118fca135af9b1a9f35061420f62James Bottomley sdkp = dev_get_drvdata(dev); 2759478a8a0543021172220feeb0b39bb1b3e43c988fAlan Stern scsi_autopm_get_device(sdkp->device); 2760478a8a0543021172220feeb0b39bb1b3e43c988fAlan Stern 2761478a8a0543021172220feeb0b39bb1b3e43c988fAlan Stern async_synchronize_full(); 2762b391277a56b9eaaff4474339c703e574ed7fab5bHannes Reinecke blk_queue_prep_rq(sdkp->device->request_queue, scsi_prep_fn); 276382b6d57fb11644fe25c8a1346627ad0027673daeFUJITA Tomonori blk_queue_unprep_rq(sdkp->device->request_queue, NULL); 2764ee959b00c335d7780136c5abda37809191fe52c3Tony Jones device_del(&sdkp->dev); 27651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_gendisk(sdkp->disk); 27661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sd_shutdown(dev); 276739b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern 27680b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven mutex_lock(&sd_ref_mutex); 276939b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern dev_set_drvdata(dev, NULL); 2770ee959b00c335d7780136c5abda37809191fe52c3Tony Jones put_device(&sdkp->dev); 27710b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven mutex_unlock(&sd_ref_mutex); 27721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 27741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 27751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 27771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * scsi_disk_release - Called to free the scsi_disk structure 2778ee959b00c335d7780136c5abda37809191fe52c3Tony Jones * @dev: pointer to embedded class device 27791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 27800b9506723826c68b50fa33e345700ddcac1bed36Arjan van de Ven * sd_ref_mutex must be held entering this routine. Because it is 27811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * called on last put, you should always use the scsi_disk_get() 27821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * scsi_disk_put() helpers which manipulate the semaphore directly 2783ee959b00c335d7780136c5abda37809191fe52c3Tony Jones * and never do a direct put_device. 27841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/ 2785ee959b00c335d7780136c5abda37809191fe52c3Tony Jonesstatic void scsi_disk_release(struct device *dev) 27861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2787ee959b00c335d7780136c5abda37809191fe52c3Tony Jones struct scsi_disk *sdkp = to_scsi_disk(dev); 27881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct gendisk *disk = sdkp->disk; 27891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27904034cc68157bfa0b6622efe368488d3d3e20f4e6Tejun Heo spin_lock(&sd_index_lock); 2791f27bac2761cab5a2e212dea602d22457a9aa6943Tejun Heo ida_remove(&sd_index_ida, sdkp->index); 27924034cc68157bfa0b6622efe368488d3d3e20f4e6Tejun Heo spin_unlock(&sd_index_lock); 27931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds disk->private_data = NULL; 27951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds put_disk(disk); 279639b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern put_device(&sdkp->device->sdev_gendev); 27971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(sdkp); 27991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 28001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2801cc5d2c8c64804564617a7be71c73a075a426d1c6James Bottomleystatic int sd_start_stop_device(struct scsi_disk *sdkp, int start) 2802c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo{ 2803c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo unsigned char cmd[6] = { START_STOP }; /* START_VALID */ 2804c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo struct scsi_sense_hdr sshdr; 2805cc5d2c8c64804564617a7be71c73a075a426d1c6James Bottomley struct scsi_device *sdp = sdkp->device; 2806c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo int res; 2807c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 2808c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo if (start) 2809c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo cmd[4] |= 1; /* START */ 2810c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 2811d2886ea368a67704ecc13e69075f18a9d74cb12bStefan Richter if (sdp->start_stop_pwr_cond) 2812d2886ea368a67704ecc13e69075f18a9d74cb12bStefan Richter cmd[4] |= start ? 1 << 4 : 3 << 4; /* Active or Standby */ 2813d2886ea368a67704ecc13e69075f18a9d74cb12bStefan Richter 2814c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo if (!scsi_device_online(sdp)) 2815c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo return -ENODEV; 2816c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 2817c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr, 2818f4f4e47e4af6b02dd1c425b931c65d0165356e33FUJITA Tomonori SD_TIMEOUT, SD_MAX_RETRIES, NULL); 2819c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo if (res) { 2820cc5d2c8c64804564617a7be71c73a075a426d1c6James Bottomley sd_printk(KERN_WARNING, sdkp, "START_STOP FAILED\n"); 2821cc5d2c8c64804564617a7be71c73a075a426d1c6James Bottomley sd_print_result(sdkp, res); 2822c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo if (driver_byte(res) & DRIVER_SENSE) 2823cc5d2c8c64804564617a7be71c73a075a426d1c6James Bottomley sd_print_sense_hdr(sdkp, &sshdr); 2824c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo } 2825c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 2826c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo return res; 2827c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo} 2828c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 28291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 28301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Send a SYNCHRONIZE CACHE instruction down to the device through 28311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the normal SCSI command structure. Wait for the command to 28321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * complete. 28331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 28341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void sd_shutdown(struct device *dev) 28351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 283639b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); 28371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!sdkp) 28391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; /* this can happen */ 28401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 284154f57588463db1105f4a93b2902a6f95cb8f796aLin Ming if (pm_runtime_suspended(dev)) 284254f57588463db1105f4a93b2902a6f95cb8f796aLin Ming goto exit; 284354f57588463db1105f4a93b2902a6f95cb8f796aLin Ming 284439b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern if (sdkp->WCE) { 2845e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); 2846e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen sd_sync_cache(sdkp); 284739b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern } 2848c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 2849cc5d2c8c64804564617a7be71c73a075a426d1c6James Bottomley if (system_state != SYSTEM_RESTART && sdkp->device->manage_start_stop) { 2850cc5d2c8c64804564617a7be71c73a075a426d1c6James Bottomley sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); 2851cc5d2c8c64804564617a7be71c73a075a426d1c6James Bottomley sd_start_stop_device(sdkp, 0); 2852c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo } 2853c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 285454f57588463db1105f4a93b2902a6f95cb8f796aLin Mingexit: 285539b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern scsi_disk_put(sdkp); 285639b7f1e25a412b0ef31e516cfc2fa4f40235f263Alan Stern} 28571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2858c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heostatic int sd_suspend(struct device *dev, pm_message_t mesg) 2859c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo{ 2860c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); 286109ff92fea2890c697a36d8b26f5a3ea725ef8fb4Alan Stern int ret = 0; 2862c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 2863c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo if (!sdkp) 2864c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo return 0; /* this can happen */ 2865c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 2866c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo if (sdkp->WCE) { 2867cc5d2c8c64804564617a7be71c73a075a426d1c6James Bottomley sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); 2868c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo ret = sd_sync_cache(sdkp); 2869c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo if (ret) 287009ff92fea2890c697a36d8b26f5a3ea725ef8fb4Alan Stern goto done; 2871c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo } 2872c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 28733a2d5b700132f35401f1d9e22fe3c2cab02c2549Rafael J. Wysocki if ((mesg.event & PM_EVENT_SLEEP) && sdkp->device->manage_start_stop) { 2874cc5d2c8c64804564617a7be71c73a075a426d1c6James Bottomley sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); 2875cc5d2c8c64804564617a7be71c73a075a426d1c6James Bottomley ret = sd_start_stop_device(sdkp, 0); 2876c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo } 2877c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 287809ff92fea2890c697a36d8b26f5a3ea725ef8fb4Alan Sterndone: 287909ff92fea2890c697a36d8b26f5a3ea725ef8fb4Alan Stern scsi_disk_put(sdkp); 288009ff92fea2890c697a36d8b26f5a3ea725ef8fb4Alan Stern return ret; 2881c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo} 2882c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 2883c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heostatic int sd_resume(struct device *dev) 2884c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo{ 2885c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); 288609ff92fea2890c697a36d8b26f5a3ea725ef8fb4Alan Stern int ret = 0; 2887c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 2888cc5d2c8c64804564617a7be71c73a075a426d1c6James Bottomley if (!sdkp->device->manage_start_stop) 288909ff92fea2890c697a36d8b26f5a3ea725ef8fb4Alan Stern goto done; 2890c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 2891cc5d2c8c64804564617a7be71c73a075a426d1c6James Bottomley sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); 289209ff92fea2890c697a36d8b26f5a3ea725ef8fb4Alan Stern ret = sd_start_stop_device(sdkp, 1); 2893c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 289409ff92fea2890c697a36d8b26f5a3ea725ef8fb4Alan Sterndone: 289509ff92fea2890c697a36d8b26f5a3ea725ef8fb4Alan Stern scsi_disk_put(sdkp); 289609ff92fea2890c697a36d8b26f5a3ea725ef8fb4Alan Stern return ret; 2897c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo} 2898c3c94c5a2fb43a654e777f509d5032b0db8ed09fTejun Heo 28991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 29001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * init_sd - entry point for this driver (both when built in or when 29011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a module). 29021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 29031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Note: this function registers this driver with the scsi mid-level. 29041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/ 29051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init init_sd(void) 29061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 29075e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzik int majors = 0, i, err; 29081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n")); 29101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < SD_MAJORS; i++) 29121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (register_blkdev(sd_major(i), "sd") == 0) 29131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds majors++; 29141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!majors) 29161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENODEV; 29171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29185e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzik err = class_register(&sd_disk_class); 29195e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzik if (err) 29205e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzik goto err_out; 29216bdaa1f17dd32ec62345c7b57842f53e6278a2faJames Bottomley 29225e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzik err = scsi_register_driver(&sd_template.gendrv); 29235e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzik if (err) 29245e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzik goto err_out_class; 29255e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzik 29264e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen sd_cdb_cache = kmem_cache_create("sd_ext_cdb", SD_EXT_CDB_SIZE, 29274e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen 0, 0, NULL); 29284e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen if (!sd_cdb_cache) { 29294e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen printk(KERN_ERR "sd: can't init extended cdb cache\n"); 29304e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen goto err_out_class; 29314e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen } 29324e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen 29334e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen sd_cdb_pool = mempool_create_slab_pool(SD_MEMPOOL_SIZE, sd_cdb_cache); 29344e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen if (!sd_cdb_pool) { 29354e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen printk(KERN_ERR "sd: can't init extended cdb pool\n"); 29364e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen goto err_out_cache; 29374e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen } 29384e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen 29395e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzik return 0; 29405e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzik 29414e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersenerr_out_cache: 29424e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen kmem_cache_destroy(sd_cdb_cache); 29434e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen 29445e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzikerr_out_class: 29455e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzik class_unregister(&sd_disk_class); 29465e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzikerr_out: 29475e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzik for (i = 0; i < SD_MAJORS; i++) 29485e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzik unregister_blkdev(sd_major(i), "sd"); 29495e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzik return err; 29501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 29511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 29531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * exit_sd - exit point for this driver (when it is a module). 29541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 29551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Note: this function unregisters this driver from the scsi mid-level. 29561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds **/ 29571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit exit_sd(void) 29581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 29591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 29601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n")); 29621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29634e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen mempool_destroy(sd_cdb_pool); 29644e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen kmem_cache_destroy(sd_cdb_cache); 29654e7392ec582cf06753b0969ca9ab959923e38493Martin K. Petersen 29661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scsi_unregister_driver(&sd_template.gendrv); 29675e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzik class_unregister(&sd_disk_class); 29685e4009ba3d5af40f5615fdb4304cc4a9947cca0aJeff Garzik 29691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < SD_MAJORS; i++) 29701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unregister_blkdev(sd_major(i), "sd"); 29711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 29721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(init_sd); 29741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(exit_sd); 2975e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen 2976e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersenstatic void sd_print_sense_hdr(struct scsi_disk *sdkp, 2977e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen struct scsi_sense_hdr *sshdr) 2978e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen{ 29792e4c332913b5d39fef686b3964098f0d8fd97eadDavid Miller sd_printk(KERN_INFO, sdkp, " "); 2980e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen scsi_show_sense_hdr(sshdr); 29812e4c332913b5d39fef686b3964098f0d8fd97eadDavid Miller sd_printk(KERN_INFO, sdkp, " "); 2982e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen scsi_show_extd_sense(sshdr->asc, sshdr->ascq); 2983e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen} 2984e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen 2985e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersenstatic void sd_print_result(struct scsi_disk *sdkp, int result) 2986e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen{ 29872e4c332913b5d39fef686b3964098f0d8fd97eadDavid Miller sd_printk(KERN_INFO, sdkp, " "); 2988e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen scsi_show_result(result); 2989e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen} 2990e73aec8247032ee730b5f38edf48922c4f72522eMartin K. Petersen 2991