cregit-Linux how code gets into the kernel

Release 4.11 drivers/scsi/sd.c

Directory: drivers/scsi
/*
 *      sd.c Copyright (C) 1992 Drew Eckhardt
 *           Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale
 *
 *      Linux scsi disk driver
 *              Initial versions: Drew Eckhardt
 *              Subsequent revisions: Eric Youngdale
 *      Modification history:
 *       - Drew Eckhardt <drew@colorado.edu> original
 *       - Eric Youngdale <eric@andante.org> add scatter-gather, multiple 
 *         outstanding request, and other enhancements.
 *         Support loadable low-level scsi drivers.
 *       - Jirka Hanika <geo@ff.cuni.cz> support more scsi disks using 
 *         eight major numbers.
 *       - Richard Gooch <rgooch@atnf.csiro.au> support devfs.
 *       - Torben Mathiasen <tmm@image.dk> Resource allocation fixes in 
 *         sd_init and cleanups.
 *       - Alex Davis <letmein@erols.com> Fix problem where partition info
 *         not being read in sd_open. Fix problem where removable media 
 *         could be ejected after sd_open.
 *       - Douglas Gilbert <dgilbert@interlog.com> cleanup for lk 2.5.x
 *       - Badari Pulavarty <pbadari@us.ibm.com>, Matthew Wilcox 
 *         <willy@debian.org>, Kurt Garloff <garloff@suse.de>: 
 *         Support 32k/1M disks.
 *
 *      Logging policy (needs CONFIG_SCSI_LOGGING defined):
 *       - setting up transfer: SCSI_LOG_HLQUEUE levels 1 and 2
 *       - end of transfer (bh + scsi_lib): SCSI_LOG_HLCOMPLETE level 1
 *       - entering sd_ioctl: SCSI_LOG_IOCTL level 1
 *       - entering other commands: SCSI_LOG_HLQUEUE level 3
 *      Note: when the logging level is set by the user, it must be greater
 *      than the level indicated above to trigger output.       
 */

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/bio.h>
#include <linux/genhd.h>
#include <linux/hdreg.h>
#include <linux/errno.h>
#include <linux/idr.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/string_helpers.h>
#include <linux/async.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/pr.h>
#include <linux/t10-pi.h>
#include <linux/uaccess.h>
#include <asm/unaligned.h>

#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_dbg.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_driver.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/scsicam.h>

#include "sd.h"
#include "scsi_priv.h"
#include "scsi_logging.h"

MODULE_AUTHOR("Eric Youngdale");
MODULE_DESCRIPTION("SCSI disk (sd) driver");
MODULE_LICENSE("GPL");


MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK0_MAJOR);

MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK1_MAJOR);

MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK2_MAJOR);

MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK3_MAJOR);

MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK4_MAJOR);

MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK5_MAJOR);

MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK6_MAJOR);

MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK7_MAJOR);

MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK8_MAJOR);

MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK9_MAJOR);

MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK10_MAJOR);

MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK11_MAJOR);

MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK12_MAJOR);

MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK13_MAJOR);

MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK14_MAJOR);

MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK15_MAJOR);

MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK);

MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD);

MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC);

MODULE_ALIAS_SCSI_DEVICE(TYPE_ZBC);

#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)

#define SD_MINORS	16
#else

#define SD_MINORS	0
#endif

static void sd_config_discard(struct scsi_disk *, unsigned int);
static void sd_config_write_same(struct scsi_disk *);
static int  sd_revalidate_disk(struct gendisk *);
static void sd_unlock_native_capacity(struct gendisk *disk);
static int  sd_probe(struct device *);
static int  sd_remove(struct device *);
static void sd_shutdown(struct device *);
static int sd_suspend_system(struct device *);
static int sd_suspend_runtime(struct device *);
static int sd_resume(struct device *);
static void sd_rescan(struct device *);
static int sd_init_command(struct scsi_cmnd *SCpnt);
static void sd_uninit_command(struct scsi_cmnd *SCpnt);
static int sd_done(struct scsi_cmnd *);
static int sd_eh_action(struct scsi_cmnd *, int);
static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer);
static void scsi_disk_release(struct device *cdev);
static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
static void sd_print_result(const struct scsi_disk *, const char *, int);

static DEFINE_SPINLOCK(sd_index_lock);
static DEFINE_IDA(sd_index_ida);

/* This semaphore is used to mediate the 0->1 reference get in the
 * face of object destruction (i.e. we can't allow a get on an
 * object after last put) */
static DEFINE_MUTEX(sd_ref_mutex);


static struct kmem_cache *sd_cdb_cache;

static mempool_t *sd_cdb_pool;


static const char *sd_cache_types[] = {
	"write through", "none", "write back",
	"write back, no read (daft)"
};


static void sd_set_flush_flag(struct scsi_disk *sdkp) { bool wc = false, fua = false; if (sdkp->WCE) { wc = true; if (sdkp->DPOFUA) fua = true; } blk_queue_write_cache(sdkp->disk->queue, wc, fua); }

Contributors

PersonTokensPropCommitsCommitProp
Vaughan Cao3869.09%150.00%
Jens Axboe1730.91%150.00%
Total55100.00%2100.00%


static ssize_t cache_type_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int i, ct = -1, rcd, wce, sp; struct scsi_disk *sdkp = to_scsi_disk(dev); struct scsi_device *sdp = sdkp->device; char buffer[64]; char *buffer_data; struct scsi_mode_data data; struct scsi_sense_hdr sshdr; static const char temp[] = "temporary "; int len; if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC) /* no cache control on RBC devices; theoretically they * can do it, but there's probably so many exceptions * it's not worth the risk */ return -EINVAL; if (strncmp(buf, temp, sizeof(temp) - 1) == 0) { buf += sizeof(temp) - 1; sdkp->cache_override = 1; } else { sdkp->cache_override = 0; } for (i = 0; i < ARRAY_SIZE(sd_cache_types); i++) { len = strlen(sd_cache_types[i]); if (strncmp(sd_cache_types[i], buf, len) == 0 && buf[len] == '\n') { ct = i; break; } } if (ct < 0) return -EINVAL; rcd = ct & 0x01 ? 1 : 0; wce = (ct & 0x02) && !sdkp->write_prot ? 1 : 0; if (sdkp->cache_override) { sdkp->WCE = wce; sdkp->RCD = rcd; sd_set_flush_flag(sdkp); return count; } if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), SD_TIMEOUT, SD_MAX_RETRIES, &data, NULL)) return -EINVAL; len = min_t(size_t, sizeof(buffer), data.length - data.header_length - data.block_descriptor_length); buffer_data = buffer + data.header_length + data.block_descriptor_length; buffer_data[2] &= ~0x05; buffer_data[2] |= wce << 2 | rcd; sp = buffer_data[0] & 0x80 ? 1 : 0; buffer_data[0] &= ~0x80; if (scsi_mode_select(sdp, 1, sp, 8, buffer_data, len, SD_TIMEOUT, SD_MAX_RETRIES, &data, &sshdr)) { if (scsi_sense_valid(&sshdr)) sd_print_sense_hdr(sdkp, &sshdr); return -EINVAL; } revalidate_disk(sdkp->disk); return count; }

Contributors

PersonTokensPropCommitsCommitProp
James Bottomley39389.73%214.29%
Gabriel Krisman Bertazi81.83%17.14%
Tony Jones81.83%17.14%
Sujit Reddy Thumma71.60%17.14%
Hannes Reinecke61.37%17.14%
Vaughan Cao51.14%17.14%
Andrew Morton30.68%17.14%
H Hartley Sweeten20.46%17.14%
Ben Hutchings20.46%17.14%
Greg Kroah-Hartman10.23%17.14%
Martin K. Petersen10.23%17.14%
Tobias Klauser10.23%17.14%
Andrew Patterson10.23%17.14%
Total438100.00%14100.00%


static ssize_t manage_start_stop_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); struct scsi_device *sdp = sdkp->device; return snprintf(buf, 20, "%u\n", sdp->manage_start_stop); }

Contributors

PersonTokensPropCommitsCommitProp
Tejun Heo3769.81%133.33%
Greg Kroah-Hartman815.09%133.33%
Tony Jones815.09%133.33%
Total53100.00%3100.00%


static ssize_t manage_start_stop_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct scsi_disk *sdkp = to_scsi_disk(dev); struct scsi_device *sdp = sdkp->device; if (!capable(CAP_SYS_ADMIN)) return -EACCES; sdp->manage_start_stop = simple_strtoul(buf, NULL, 10); return count; }

Contributors

PersonTokensPropCommitsCommitProp
Brian King6185.92%133.33%
Tony Jones811.27%133.33%
Greg Kroah-Hartman22.82%133.33%
Total71100.00%3100.00%

static DEVICE_ATTR_RW(manage_start_stop);
static ssize_t allow_restart_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart); }

Contributors

PersonTokensPropCommitsCommitProp
James Bottomley2554.35%225.00%
Tony Jones817.39%112.50%
Greg Kroah-Hartman715.22%112.50%
Jens Axboe24.35%112.50%
Linus Torvalds (pre-git)24.35%112.50%
Christoph Hellwig24.35%225.00%
Total46100.00%8100.00%


static ssize_t allow_restart_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct scsi_disk *sdkp = to_scsi_disk(dev); struct scsi_device *sdp = sdkp->device; if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC) return -EINVAL; sdp->allow_restart = simple_strtoul(buf, NULL, 10); return count; }

Contributors

PersonTokensPropCommitsCommitProp
Greg Kroah-Hartman4752.81%114.29%
James Bottomley1820.22%114.29%
Tony Jones88.99%114.29%
Hannes Reinecke66.74%114.29%
Jens Axboe66.74%228.57%
Alex Tomas44.49%114.29%
Total89100.00%7100.00%

static DEVICE_ATTR_RW(allow_restart);
static ssize_t cache_type_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); int ct = sdkp->RCD + 2*sdkp->WCE; return snprintf(buf, 40, "%s\n", sd_cache_types[ct]); }

Contributors

PersonTokensPropCommitsCommitProp
Tejun Heo3458.62%133.33%
Greg Kroah-Hartman1627.59%133.33%
Tony Jones813.79%133.33%
Total58100.00%3100.00%

static DEVICE_ATTR_RW(cache_type);
static ssize_t FUA_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); return snprintf(buf, 20, "%u\n", sdkp->DPOFUA); }

Contributors

PersonTokensPropCommitsCommitProp
Brian King3272.73%133.33%
Tony Jones818.18%133.33%
Greg Kroah-Hartman49.09%133.33%
Total44100.00%3100.00%

static DEVICE_ATTR_RO(FUA);
static ssize_t protection_type_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); return snprintf(buf, 20, "%u\n", sdkp->protection_type); }

Contributors

PersonTokensPropCommitsCommitProp
Martin K. Petersen4397.73%150.00%
Greg Kroah-Hartman12.27%150.00%
Total44100.00%2100.00%


static ssize_t protection_type_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct scsi_disk *sdkp = to_scsi_disk(dev); unsigned int val; int err; if (!capable(CAP_SYS_ADMIN)) return -EACCES; err = kstrtouint(buf, 10, &val); if (err) return err; if (val >= 0 && val <= T10_PI_TYPE3_PROTECTION) sdkp->protection_type = val; return count; }

Contributors

PersonTokensPropCommitsCommitProp
Martin K. Petersen8997.80%250.00%
Christoph Hellwig11.10%125.00%
Greg Kroah-Hartman11.10%125.00%
Total91100.00%4100.00%

static DEVICE_ATTR_RW(protection_type);
static ssize_t protection_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); struct scsi_device *sdp = sdkp->device; unsigned int dif, dix; dif = scsi_host_dif_capable(sdp->host, sdkp->protection_type); dix = scsi_host_dix_capable(sdp->host, sdkp->protection_type); if (!dix && scsi_host_dix_capable(sdp->host, T10_PI_TYPE0_PROTECTION)) { dif = 0; dix = 1; } if (!dif && !dix) return snprintf(buf, 20, "none\n"); return snprintf(buf, 20, "%s%u\n", dix ? "dix" : "dif", dif); }

Contributors

PersonTokensPropCommitsCommitProp
Martin K. Petersen12998.47%250.00%
Greg Kroah-Hartman10.76%125.00%
Christoph Hellwig10.76%125.00%
Total131100.00%4100.00%

static DEVICE_ATTR_RO(protection_mode);
static ssize_t app_tag_own_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); return snprintf(buf, 20, "%u\n", sdkp->ATO); }

Contributors

PersonTokensPropCommitsCommitProp
Martin K. Petersen4397.73%266.67%
Greg Kroah-Hartman12.27%133.33%
Total44100.00%3100.00%

static DEVICE_ATTR_RO(app_tag_own);
static ssize_t thin_provisioning_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); return snprintf(buf, 20, "%u\n", sdkp->lbpme); }

Contributors

PersonTokensPropCommitsCommitProp
Martin K. Petersen4397.73%266.67%
Greg Kroah-Hartman12.27%133.33%
Total44100.00%3100.00%

static DEVICE_ATTR_RO(thin_provisioning); static const char *lbp_mode[] = { [SD_LBP_FULL] = "full", [SD_LBP_UNMAP] = "unmap", [SD_LBP_WS16] = "writesame_16", [SD_LBP_WS10] = "writesame_10", [SD_LBP_ZERO] = "writesame_zero", [SD_LBP_DISABLE] = "disabled", };
static ssize_t provisioning_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); return snprintf(buf, 20, "%s\n", lbp_mode[sdkp->provisioning_mode]); }

Contributors

PersonTokensPropCommitsCommitProp
Martin K. Petersen4697.87%150.00%
Greg Kroah-Hartman12.13%150.00%
Total47100.00%2100.00%


static ssize_t provisioning_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct scsi_disk *sdkp = to_scsi_disk(dev); struct scsi_device *sdp = sdkp->device; if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (sd_is_zoned(sdkp)) { sd_config_discard(sdkp, SD_LBP_DISABLE); return count; } if (sdp->type != TYPE_DISK) return -EINVAL; if (!strncmp(buf, lbp_mode[SD_LBP_UNMAP], 20)) sd_config_discard(sdkp, SD_LBP_UNMAP); else if (!strncmp(buf, lbp_mode[SD_LBP_WS16], 20)) sd_config_discard(sdkp, SD_LBP_WS16); else if (!strncmp(buf, lbp_mode[SD_LBP_WS10], 20)) sd_config_discard(sdkp, SD_LBP_WS10); else if (!strncmp(buf, lbp_mode[SD_LBP_ZERO], 20)) sd_config_discard(sdkp, SD_LBP_ZERO); else if (!strncmp(buf, lbp_mode[SD_LBP_DISABLE], 20)) sd_config_discard(sdkp, SD_LBP_DISABLE); else return -EINVAL; return count; }

Contributors

PersonTokensPropCommitsCommitProp
Martin K. Petersen18890.38%133.33%
Hannes Reinecke199.13%133.33%
Greg Kroah-Hartman10.48%133.33%
Total208100.00%3100.00%

static DEVICE_ATTR_RW(provisioning_mode);
static ssize_t max_medium_access_timeouts_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); return snprintf(buf, 20, "%u\n", sdkp->max_medium_access_timeouts); }

Contributors

PersonTokensPropCommitsCommitProp
Martin K. Petersen4397.73%150.00%
Greg Kroah-Hartman12.27%150.00%
Total44100.00%2100.00%


static ssize_t max_medium_access_timeouts_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct scsi_disk *sdkp = to_scsi_disk(dev); int err; if (!capable(CAP_SYS_ADMIN)) return -EACCES; err = kstrtouint(buf, 10, &sdkp->max_medium_access_timeouts); return err ? err : count; }

Contributors

PersonTokensPropCommitsCommitProp
Martin K. Petersen6998.57%150.00%
Greg Kroah-Hartman11.43%150.00%
Total70100.00%2100.00%

static DEVICE_ATTR_RW(max_medium_access_timeouts);
static ssize_t max_write_same_blocks_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); return snprintf(buf, 20, "%u\n", sdkp->max_ws_blocks); }

Contributors

PersonTokensPropCommitsCommitProp
Martin K. Petersen4397.73%150.00%
Greg Kroah-Hartman12.27%150.00%
Total44100.00%2100.00%


static ssize_t max_write_same_blocks_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct scsi_disk *sdkp = to_scsi_disk(dev); struct scsi_device *sdp = sdkp->device; unsigned long max; int err; if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC) return -EINVAL; err = kstrtoul(buf, 10, &max); if (err) return err; if (max == 0) sdp->no_write_same = 1; else if (max <= SD_MAX_WS16_BLOCKS) { sdp->no_write_same = 0; sdkp->max_ws_blocks = max; } sd_config_write_same(sdkp); return count; }

Contributors

PersonTokensPropCommitsCommitProp
Martin K. Petersen13395.00%250.00%
Hannes Reinecke64.29%125.00%
Greg Kroah-Hartman10.71%125.00%
Total140100.00%4100.00%

static DEVICE_ATTR_RW(max_write_same_blocks); static struct attribute *sd_disk_attrs[] = { &dev_attr_cache_type.attr, &dev_attr_FUA.attr, &dev_attr_allow_restart.attr, &dev_attr_manage_start_stop.attr, &dev_attr_protection_type.attr, &dev_attr_protection_mode.attr, &dev_attr_app_tag_own.attr, &dev_attr_thin_provisioning.attr, &dev_attr_provisioning_mode.attr, &dev_attr_max_write_same_blocks.attr, &dev_attr_max_medium_access_timeouts.attr, NULL, }; ATTRIBUTE_GROUPS(sd_disk); static struct class sd_disk_class = { .name = "scsi_disk", .owner = THIS_MODULE, .dev_release = scsi_disk_release, .dev_groups = sd_disk_groups, }; static const struct dev_pm_ops sd_pm_ops = { .suspend = sd_suspend_system, .resume = sd_resume, .poweroff = sd_suspend_system, .restore = sd_resume, .runtime_suspend = sd_suspend_runtime, .runtime_resume = sd_resume, }; static struct scsi_driver sd_template = { .gendrv = { .name = "sd", .owner = THIS_MODULE, .probe = sd_probe, .remove = sd_remove, .shutdown = sd_shutdown, .pm = &sd_pm_ops, }, .rescan = sd_rescan, .init_command = sd_init_command, .uninit_command = sd_uninit_command, .done = sd_done, .eh_action = sd_eh_action, }; /* * Dummy kobj_map->probe function. * The default ->probe function will call modprobe, which is * pointless as this module is already loaded. */
static struct kobject *sd_default_probe(dev_t devt, int *partno, void *data) { return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Hannes Reinecke22100.00%1100.00%
Total22100.00%1100.00%

/* * Device no to disk mapping: * * major disc2 disc p1 * |............|.............|....|....| <- dev_t * 31 20 19 8 7 4 3 0 * * Inside a major, we have 16k disks, however mapped non- * contiguously. The first 16 disks are for major0, the next * ones with major1, ... Disk 256 is for major0 again, disk 272 * for major1, ... * As we stay compatible with our numbering scheme, we can reuse * the well-know SCSI majors 8, 65--71, 136--143. */
static int sd_major(int major_idx) { switch (major_idx) { case 0: return SCSI_DISK0_MAJOR; case 1 ... 7: return SCSI_DISK1_MAJOR + major_idx - 1; case 8 ... 15: return SCSI_DISK8_MAJOR + major_idx - 8; default: BUG(); return 0; /* shut up gcc */ } }

Contributors

PersonTokensPropCommitsCommitProp
Christoph Hellwig5196.23%150.00%
Badari Pulavarty23.77%150.00%
Total53100.00%2100.00%


static struct scsi_disk *scsi_disk_get(struct gendisk *disk) { struct scsi_disk *sdkp = NULL; mutex_lock(&sd_ref_mutex); if (disk->private_data) { sdkp = scsi_disk(disk); if (scsi_device_get(sdkp->device) == 0) get_device(&sdkp->dev); else sdkp = NULL; } mutex_unlock(&sd_ref_mutex); return sdkp; }

Contributors

PersonTokensPropCommitsCommitProp
James Bottomley2635.14%114.29%
Mike Anderson1824.32%114.29%
Alan Stern1824.32%114.29%
Christoph Hellwig79.46%114.29%
Arjan van de Ven22.70%114.29%
Tony Jones22.70%114.29%
Greg Kroah-Hartman11.35%114.29%
Total74100.00%7100.00%


static void scsi_disk_put(struct scsi_disk *sdkp) { struct scsi_device *sdev = sdkp->device; mutex_lock(&sd_ref_mutex); put_device(&sdkp->dev); scsi_device_put(sdev); mutex_unlock(&sd_ref_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Mike Anderson2044.44%116.67%
Alan Stern1022.22%116.67%
James Bottomley920.00%233.33%
Arjan van de Ven48.89%116.67%
Tony Jones24.44%116.67%
Total45100.00%6100.00%


static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd, unsigned int dix, unsigned int dif) { struct bio *bio = scmd->request->bio; unsigned int prot_op = sd_prot_op(rq_data_dir(scmd->request), dix, dif); unsigned int protect = 0; if (dix) { /* DIX Type 0, 1, 2, 3 */ if (bio_integrity_flagged(bio, BIP_IP_CHECKSUM)) scmd->prot_flags |= SCSI_PROT_IP_CHECKSUM; if (bio_integrity_flagged(bio, BIP_CTRL_NOCHECK) == false) scmd->prot_flags |= SCSI_PROT_GUARD_CHECK; } if (dif != T10_PI_TYPE3_PROTECTION) { /* DIX/DIF Type 0, 1, 2 */ scmd->prot_flags |= SCSI_PROT_REF_INCREMENT; if (bio_integrity_flagged(bio, BIP_CTRL_NOCHECK) == false) scmd->prot_flags |= SCSI_PROT_REF_CHECK; } if (dif) { /* DIX/DIF Type 1, 2, 3 */ scmd->prot_flags |= SCSI_PROT_TRANSFER_PI;