Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 2001 Jens Axboe <axboe@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/cdrom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/ratelimit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/times.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/uio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <scsi/scsi_ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <scsi/sg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) struct blk_cmd_filter {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	unsigned long read_ok[BLK_SCSI_CMD_PER_LONG];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	unsigned long write_ok[BLK_SCSI_CMD_PER_LONG];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) static struct blk_cmd_filter blk_default_cmd_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) /* Command group 3 is reserved and should never be used.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) const unsigned char scsi_command_size_tbl[8] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	6, 10, 10, 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	16, 12, 10, 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) EXPORT_SYMBOL(scsi_command_size_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) static int sg_get_version(int __user *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	static const int sg_version_num = 30527;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	return put_user(sg_version_num, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) static int scsi_get_idlun(struct request_queue *q, int __user *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	return put_user(0, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) static int scsi_get_bus(struct request_queue *q, int __user *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	return put_user(0, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) static int sg_get_timeout(struct request_queue *q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	return jiffies_to_clock_t(q->sg_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) static int sg_set_timeout(struct request_queue *q, int __user *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	int timeout, err = get_user(timeout, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		q->sg_timeout = clock_t_to_jiffies(timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) static int max_sectors_bytes(struct request_queue *q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	unsigned int max_sectors = queue_max_sectors(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	max_sectors = min_t(unsigned int, max_sectors, INT_MAX >> 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	return max_sectors << 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) static int sg_get_reserved_size(struct request_queue *q, int __user *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	int val = min_t(int, q->sg_reserved_size, max_sectors_bytes(q));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	return put_user(val, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) static int sg_set_reserved_size(struct request_queue *q, int __user *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	int size, err = get_user(size, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	if (size < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	q->sg_reserved_size = min(size, max_sectors_bytes(q));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  * will always return that we are ATAPI even for a real SCSI drive, I'm not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  * so sure this is worth doing anything about (why would you care??)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static int sg_emulated_host(struct request_queue *q, int __user *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	return put_user(1, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	/* Basic read-only commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	__set_bit(TEST_UNIT_READY, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	__set_bit(REQUEST_SENSE, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	__set_bit(READ_6, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	__set_bit(READ_10, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	__set_bit(READ_12, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	__set_bit(READ_16, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	__set_bit(READ_BUFFER, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	__set_bit(READ_DEFECT_DATA, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	__set_bit(READ_CAPACITY, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	__set_bit(READ_LONG, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	__set_bit(INQUIRY, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	__set_bit(MODE_SENSE, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	__set_bit(MODE_SENSE_10, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	__set_bit(LOG_SENSE, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	__set_bit(START_STOP, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	__set_bit(GPCMD_VERIFY_10, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	__set_bit(VERIFY_16, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	__set_bit(REPORT_LUNS, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	__set_bit(SERVICE_ACTION_IN_16, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	__set_bit(RECEIVE_DIAGNOSTIC, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	__set_bit(MAINTENANCE_IN, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	__set_bit(GPCMD_READ_BUFFER_CAPACITY, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	/* Audio CD commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	__set_bit(GPCMD_PLAY_CD, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	__set_bit(GPCMD_PLAY_AUDIO_10, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	__set_bit(GPCMD_PLAY_AUDIO_MSF, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	__set_bit(GPCMD_PLAY_AUDIO_TI, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	__set_bit(GPCMD_PAUSE_RESUME, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	/* CD/DVD data reading */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	__set_bit(GPCMD_READ_CD, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	__set_bit(GPCMD_READ_CD_MSF, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	__set_bit(GPCMD_READ_DISC_INFO, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	__set_bit(GPCMD_READ_CDVD_CAPACITY, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	__set_bit(GPCMD_READ_DVD_STRUCTURE, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	__set_bit(GPCMD_READ_HEADER, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	__set_bit(GPCMD_READ_TRACK_RZONE_INFO, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	__set_bit(GPCMD_READ_SUBCHANNEL, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	__set_bit(GPCMD_READ_TOC_PMA_ATIP, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	__set_bit(GPCMD_REPORT_KEY, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	__set_bit(GPCMD_SCAN, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	__set_bit(GPCMD_GET_CONFIGURATION, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	__set_bit(GPCMD_READ_FORMAT_CAPACITIES, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	__set_bit(GPCMD_GET_EVENT_STATUS_NOTIFICATION, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	__set_bit(GPCMD_GET_PERFORMANCE, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	__set_bit(GPCMD_SEEK, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	__set_bit(GPCMD_STOP_PLAY_SCAN, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	/* Basic writing commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	__set_bit(WRITE_6, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	__set_bit(WRITE_10, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	__set_bit(WRITE_VERIFY, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	__set_bit(WRITE_12, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	__set_bit(WRITE_VERIFY_12, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	__set_bit(WRITE_16, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	__set_bit(WRITE_LONG, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	__set_bit(WRITE_LONG_2, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	__set_bit(WRITE_SAME, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	__set_bit(WRITE_SAME_16, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	__set_bit(WRITE_SAME_32, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	__set_bit(ERASE, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	__set_bit(GPCMD_MODE_SELECT_10, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	__set_bit(MODE_SELECT, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	__set_bit(LOG_SELECT, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	__set_bit(GPCMD_BLANK, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	__set_bit(GPCMD_CLOSE_TRACK, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	__set_bit(GPCMD_FLUSH_CACHE, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	__set_bit(GPCMD_FORMAT_UNIT, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	__set_bit(GPCMD_REPAIR_RZONE_TRACK, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	__set_bit(GPCMD_RESERVE_RZONE_TRACK, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	__set_bit(GPCMD_SEND_DVD_STRUCTURE, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	__set_bit(GPCMD_SEND_EVENT, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	__set_bit(GPCMD_SEND_KEY, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	__set_bit(GPCMD_SEND_OPC, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	__set_bit(GPCMD_SEND_CUE_SHEET, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	__set_bit(GPCMD_SET_SPEED, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	__set_bit(GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	__set_bit(GPCMD_LOAD_UNLOAD, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	__set_bit(GPCMD_SET_STREAMING, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	__set_bit(GPCMD_SET_READ_AHEAD, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	/* ZBC Commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	__set_bit(ZBC_OUT, filter->write_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	__set_bit(ZBC_IN, filter->read_ok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int blk_verify_command(unsigned char *cmd, fmode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	struct blk_cmd_filter *filter = &blk_default_cmd_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	/* root can do any command. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	if (capable(CAP_SYS_RAWIO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	/* Anybody who can open the device can do a read-safe command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	if (test_bit(cmd[0], filter->read_ok))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	/* Write-safe commands require a writable open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	if (test_bit(cmd[0], filter->write_ok) && (mode & FMODE_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) EXPORT_SYMBOL(blk_verify_command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 			     struct sg_io_hdr *hdr, fmode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	struct scsi_request *req = scsi_req(rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	if (copy_from_user(req->cmd, hdr->cmdp, hdr->cmd_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	if (blk_verify_command(req->cmd, mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	 * fill in request structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	req->cmd_len = hdr->cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	rq->timeout = msecs_to_jiffies(hdr->timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	if (!rq->timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		rq->timeout = q->sg_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	if (!rq->timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	if (rq->timeout < BLK_MIN_SG_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		rq->timeout = BLK_MIN_SG_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 				 struct bio *bio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	struct scsi_request *req = scsi_req(rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	int r, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	 * fill in all the output members
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	hdr->status = req->result & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	hdr->masked_status = status_byte(req->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	hdr->msg_status = msg_byte(req->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	hdr->host_status = host_byte(req->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	hdr->driver_status = driver_byte(req->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	hdr->info = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	if (hdr->masked_status || hdr->host_status || hdr->driver_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		hdr->info |= SG_INFO_CHECK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	hdr->resid = req->resid_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	hdr->sb_len_wr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	if (req->sense_len && hdr->sbp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		int len = min((unsigned int) hdr->mx_sb_len, req->sense_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		if (!copy_to_user(hdr->sbp, req->sense, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 			hdr->sb_len_wr = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 			ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	r = blk_rq_unmap_user(bio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		ret = r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		struct sg_io_hdr *hdr, fmode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	unsigned long start_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	ssize_t ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	int writing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	int at_head = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	struct request *rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	struct scsi_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	struct bio *bio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	if (hdr->interface_id != 'S')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	if (hdr->dxfer_len > (queue_max_hw_sectors(q) << 9))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	if (hdr->dxfer_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		switch (hdr->dxfer_direction) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		case SG_DXFER_TO_DEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 			writing = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		case SG_DXFER_TO_FROM_DEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		case SG_DXFER_FROM_DEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	if (hdr->flags & SG_FLAG_Q_AT_HEAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		at_head = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	rq = blk_get_request(q, writing ? REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	if (IS_ERR(rq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		return PTR_ERR(rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	req = scsi_req(rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	if (hdr->cmd_len > BLK_MAX_CDB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		req->cmd = kzalloc(hdr->cmd_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		if (!req->cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 			goto out_put_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	ret = blk_fill_sghdr_rq(q, rq, hdr, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		goto out_free_cdb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	if (hdr->iovec_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		struct iov_iter i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		struct iovec *iov = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		ret = import_iovec(rq_data_dir(rq), hdr->dxferp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 				   hdr->iovec_count, 0, &iov, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 			goto out_free_cdb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		/* SG_IO howto says that the shorter of the two wins */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		iov_iter_truncate(&i, hdr->dxfer_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		ret = blk_rq_map_user_iov(q, rq, NULL, &i, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		kfree(iov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	} else if (hdr->dxfer_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 				      GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		goto out_free_cdb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	bio = rq->bio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	req->retries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	start_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	/* ignore return value. All information is passed back to caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	 * (if he doesn't check that is his problem).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	 * N.B. a non-zero SCSI status is _not_ necessarily an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	blk_execute_rq(q, bd_disk, rq, at_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	hdr->duration = jiffies_to_msecs(jiffies - start_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	ret = blk_complete_sghdr_rq(rq, hdr, bio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) out_free_cdb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	scsi_req_free_cmd(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) out_put_request:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	blk_put_request(rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)  * sg_scsi_ioctl  --  handle deprecated SCSI_IOCTL_SEND_COMMAND ioctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)  * @q:		request queue to send scsi commands down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)  * @disk:	gendisk to operate on (option)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)  * @mode:	mode used to open the file through which the ioctl has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)  *		submitted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)  * @sic:	userspace structure describing the command to perform
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)  * Send down the scsi command described by @sic to the device below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)  * the request queue @q.  If @file is non-NULL it's used to perform
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)  * fine-grained permission checks that allow users to send down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)  * non-destructive SCSI commands.  If the caller has a struct gendisk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)  * available it should be passed in as @disk to allow the low level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)  * driver to use the information contained in it.  A non-NULL @disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)  * is only allowed if the caller knows that the low level driver doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)  * need it (e.g. in the scsi subsystem).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)  * Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)  *   -  This interface is deprecated - users should use the SG_IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)  *      interface instead, as this is a more flexible approach to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)  *      performing SCSI commands on a device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)  *   -  The SCSI command length is determined by examining the 1st byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)  *      of the given command. There is no way to override this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)  *   -  Data transfers are limited to PAGE_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)  *   -  The length (x + y) must be at least OMAX_SB_LEN bytes long to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)  *      accommodate the sense buffer when an error occurs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)  *      The sense buffer is truncated to OMAX_SB_LEN (16) bytes so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)  *      old code will not be surprised.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)  *   -  If a Unix error occurs (e.g. ENOMEM) then the user will receive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)  *      a negative return and the Unix error code in 'errno'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)  *      If the SCSI command succeeds then 0 is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)  *      Positive numbers returned are the compacted SCSI error codes (4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)  *      bytes in one int) where the lowest byte is the SCSI status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		struct scsi_ioctl_command __user *sic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	enum { OMAX_SB_LEN = 16 };	/* For backward compatibility */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	struct request *rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	struct scsi_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	unsigned int in_len, out_len, bytes, opcode, cmdlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	char *buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	if (!sic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	 * get in an out lengths, verify they don't exceed a page worth of data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	if (get_user(in_len, &sic->inlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	if (get_user(out_len, &sic->outlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	if (in_len > PAGE_SIZE || out_len > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	if (get_user(opcode, sic->data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	bytes = max(in_len, out_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	if (bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		buffer = kzalloc(bytes, q->bounce_gfp | GFP_USER| __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		if (!buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	rq = blk_get_request(q, in_len ? REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	if (IS_ERR(rq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		err = PTR_ERR(rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		goto error_free_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	req = scsi_req(rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	cmdlen = COMMAND_SIZE(opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	 * get command and data to send to device, if any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	req->cmd_len = cmdlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	if (copy_from_user(req->cmd, sic->data, cmdlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	err = blk_verify_command(req->cmd, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	/* default.  possible overriden later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	req->retries = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	switch (opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	case SEND_DIAGNOSTIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	case FORMAT_UNIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		rq->timeout = FORMAT_UNIT_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		req->retries = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	case START_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		rq->timeout = START_STOP_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	case MOVE_MEDIUM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		rq->timeout = MOVE_MEDIUM_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	case READ_ELEMENT_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		rq->timeout = READ_ELEMENT_STATUS_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	case READ_DEFECT_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		rq->timeout = READ_DEFECT_DATA_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		req->retries = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	if (bytes && blk_rq_map_kern(q, rq, buffer, bytes, GFP_NOIO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		err = DRIVER_ERROR << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	blk_execute_rq(q, disk, rq, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	err = req->result & 0xff;	/* only 8 bit SCSI status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		if (req->sense_len && req->sense) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 			bytes = (OMAX_SB_LEN > req->sense_len) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 				req->sense_len : OMAX_SB_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 			if (copy_to_user(sic->data, req->sense, bytes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 				err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		if (copy_to_user(sic->data, buffer, out_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 			err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	blk_put_request(rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) error_free_buffer:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	kfree(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) EXPORT_SYMBOL_GPL(sg_scsi_ioctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /* Send basic block requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 			      int cmd, int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	struct request *rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	rq = blk_get_request(q, REQ_OP_SCSI_OUT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	if (IS_ERR(rq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		return PTR_ERR(rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	scsi_req(rq)->cmd[0] = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	scsi_req(rq)->cmd[4] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	scsi_req(rq)->cmd_len = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	blk_execute_rq(q, bd_disk, rq, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	err = scsi_req(rq)->result ? -EIO : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	blk_put_request(rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static inline int blk_send_start_stop(struct request_queue *q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 				      struct gendisk *bd_disk, int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) int put_sg_io_hdr(const struct sg_io_hdr *hdr, void __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	if (in_compat_syscall()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		struct compat_sg_io_hdr hdr32 =  {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 			.interface_id	 = hdr->interface_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 			.dxfer_direction = hdr->dxfer_direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 			.cmd_len	 = hdr->cmd_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 			.mx_sb_len	 = hdr->mx_sb_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 			.iovec_count	 = hdr->iovec_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 			.dxfer_len	 = hdr->dxfer_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 			.dxferp		 = (uintptr_t)hdr->dxferp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 			.cmdp		 = (uintptr_t)hdr->cmdp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 			.sbp		 = (uintptr_t)hdr->sbp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 			.timeout	 = hdr->timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 			.flags		 = hdr->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 			.pack_id	 = hdr->pack_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 			.usr_ptr	 = (uintptr_t)hdr->usr_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 			.status		 = hdr->status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 			.masked_status	 = hdr->masked_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 			.msg_status	 = hdr->msg_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 			.sb_len_wr	 = hdr->sb_len_wr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 			.host_status	 = hdr->host_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 			.driver_status	 = hdr->driver_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 			.resid		 = hdr->resid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 			.duration	 = hdr->duration,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 			.info		 = hdr->info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		if (copy_to_user(argp, &hdr32, sizeof(hdr32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	if (copy_to_user(argp, hdr, sizeof(*hdr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) EXPORT_SYMBOL(put_sg_io_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) int get_sg_io_hdr(struct sg_io_hdr *hdr, const void __user *argp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	struct compat_sg_io_hdr hdr32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	if (in_compat_syscall()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		if (copy_from_user(&hdr32, argp, sizeof(hdr32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 		*hdr = (struct sg_io_hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 			.interface_id	 = hdr32.interface_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 			.dxfer_direction = hdr32.dxfer_direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 			.cmd_len	 = hdr32.cmd_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 			.mx_sb_len	 = hdr32.mx_sb_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 			.iovec_count	 = hdr32.iovec_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 			.dxfer_len	 = hdr32.dxfer_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 			.dxferp		 = compat_ptr(hdr32.dxferp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 			.cmdp		 = compat_ptr(hdr32.cmdp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 			.sbp		 = compat_ptr(hdr32.sbp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 			.timeout	 = hdr32.timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 			.flags		 = hdr32.flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 			.pack_id	 = hdr32.pack_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 			.usr_ptr	 = compat_ptr(hdr32.usr_ptr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 			.status		 = hdr32.status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 			.masked_status	 = hdr32.masked_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 			.msg_status	 = hdr32.msg_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 			.sb_len_wr	 = hdr32.sb_len_wr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 			.host_status	 = hdr32.host_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 			.driver_status	 = hdr32.driver_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 			.resid		 = hdr32.resid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 			.duration	 = hdr32.duration,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 			.info		 = hdr32.info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	if (copy_from_user(hdr, argp, sizeof(*hdr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) EXPORT_SYMBOL(get_sg_io_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct compat_cdrom_generic_command {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	unsigned char	cmd[CDROM_PACKET_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	compat_caddr_t	buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	compat_uint_t	buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	compat_int_t	stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	compat_caddr_t	sense;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	unsigned char	data_direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	unsigned char	pad[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	compat_int_t	quiet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	compat_int_t	timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	compat_caddr_t	unused;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static int scsi_get_cdrom_generic_arg(struct cdrom_generic_command *cgc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 				      const void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	if (in_compat_syscall()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		struct compat_cdrom_generic_command cgc32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		if (copy_from_user(&cgc32, arg, sizeof(cgc32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 		*cgc = (struct cdrom_generic_command) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 			.buffer		= compat_ptr(cgc32.buffer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 			.buflen		= cgc32.buflen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 			.stat		= cgc32.stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 			.sense		= compat_ptr(cgc32.sense),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 			.data_direction	= cgc32.data_direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 			.quiet		= cgc32.quiet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 			.timeout	= cgc32.timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 			.unused		= compat_ptr(cgc32.unused),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		memcpy(&cgc->cmd, &cgc32.cmd, CDROM_PACKET_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	if (copy_from_user(cgc, arg, sizeof(*cgc)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) static int scsi_put_cdrom_generic_arg(const struct cdrom_generic_command *cgc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 				      void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	if (in_compat_syscall()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 		struct compat_cdrom_generic_command cgc32 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 			.buffer		= (uintptr_t)(cgc->buffer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 			.buflen		= cgc->buflen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 			.stat		= cgc->stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 			.sense		= (uintptr_t)(cgc->sense),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 			.data_direction	= cgc->data_direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 			.quiet		= cgc->quiet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 			.timeout	= cgc->timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 			.unused		= (uintptr_t)(cgc->unused),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 		memcpy(&cgc32.cmd, &cgc->cmd, CDROM_PACKET_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 		if (copy_to_user(arg, &cgc32, sizeof(cgc32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	if (copy_to_user(arg, cgc, sizeof(*cgc)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) static int scsi_cdrom_send_packet(struct request_queue *q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 				  struct gendisk *bd_disk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 				  fmode_t mode, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	struct cdrom_generic_command cgc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	struct sg_io_hdr hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	err = scsi_get_cdrom_generic_arg(&cgc, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	cgc.timeout = clock_t_to_jiffies(cgc.timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	memset(&hdr, 0, sizeof(hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	hdr.interface_id = 'S';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	hdr.cmd_len = sizeof(cgc.cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	hdr.dxfer_len = cgc.buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	switch (cgc.data_direction) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 		case CGC_DATA_UNKNOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 			hdr.dxfer_direction = SG_DXFER_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 		case CGC_DATA_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 			hdr.dxfer_direction = SG_DXFER_TO_DEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 		case CGC_DATA_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 			hdr.dxfer_direction = SG_DXFER_FROM_DEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 		case CGC_DATA_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 			hdr.dxfer_direction = SG_DXFER_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	hdr.dxferp = cgc.buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	hdr.sbp = cgc.sense;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	if (hdr.sbp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 		hdr.mx_sb_len = sizeof(struct request_sense);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	hdr.timeout = jiffies_to_msecs(cgc.timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	hdr.cmd_len = sizeof(cgc.cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 	err = sg_io(q, bd_disk, &hdr, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	if (err == -EFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	if (hdr.status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	cgc.stat = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	cgc.buflen = hdr.resid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	if (scsi_put_cdrom_generic_arg(&cgc, arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 		   unsigned int cmd, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	if (!q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		 * new sgv3 interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 		case SG_GET_VERSION_NUM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 			err = sg_get_version(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 		case SCSI_IOCTL_GET_IDLUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 			err = scsi_get_idlun(q, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 		case SCSI_IOCTL_GET_BUS_NUMBER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 			err = scsi_get_bus(q, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 		case SG_SET_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 			err = sg_set_timeout(q, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 		case SG_GET_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 			err = sg_get_timeout(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 		case SG_GET_RESERVED_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 			err = sg_get_reserved_size(q, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 		case SG_SET_RESERVED_SIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 			err = sg_set_reserved_size(q, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 		case SG_EMULATED_HOST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 			err = sg_emulated_host(q, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 		case SG_IO: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 			struct sg_io_hdr hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 			err = get_sg_io_hdr(&hdr, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 			err = sg_io(q, bd_disk, &hdr, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 			if (err == -EFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 			if (put_sg_io_hdr(&hdr, arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 				err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 		case CDROM_SEND_PACKET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 			err = scsi_cdrom_send_packet(q, bd_disk, mode, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 		 * old junk scsi send command ioctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 		case SCSI_IOCTL_SEND_COMMAND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 			printk(KERN_WARNING "program %s is using a deprecated SCSI ioctl, please convert it to SG_IO\n", current->comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 			if (!arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 			err = sg_scsi_ioctl(q, bd_disk, mode, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 		case CDROMCLOSETRAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 			err = blk_send_start_stop(q, bd_disk, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 		case CDROMEJECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 			err = blk_send_start_stop(q, bd_disk, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 			err = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) EXPORT_SYMBOL(scsi_cmd_ioctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) int scsi_verify_blk_ioctl(struct block_device *bd, unsigned int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	if (bd && !bdev_is_partition(bd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 	if (capable(CAP_SYS_RAWIO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 	return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) EXPORT_SYMBOL(scsi_verify_blk_ioctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) int scsi_cmd_blk_ioctl(struct block_device *bd, fmode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 		       unsigned int cmd, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 	ret = scsi_verify_blk_ioctl(bd, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 	return scsi_cmd_ioctl(bd->bd_disk->queue, bd->bd_disk, mode, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) EXPORT_SYMBOL(scsi_cmd_blk_ioctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)  * scsi_req_init - initialize certain fields of a scsi_request structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)  * @req: Pointer to a scsi_request structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)  * Initializes .__cmd[], .cmd, .cmd_len and .sense_len but no other members
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)  * of struct scsi_request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) void scsi_req_init(struct scsi_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 	memset(req->__cmd, 0, sizeof(req->__cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 	req->cmd = req->__cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 	req->cmd_len = BLK_MAX_CDB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 	req->sense_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) EXPORT_SYMBOL(scsi_req_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) static int __init blk_scsi_ioctl_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 	blk_set_cmd_filter_defaults(&blk_default_cmd_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) fs_initcall(blk_scsi_ioctl_init);