Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/block/scsi_ioctl.c
15109 views
1
/*
2
* Copyright (C) 2001 Jens Axboe <[email protected]>
3
*
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License version 2 as
6
* published by the Free Software Foundation.
7
*
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
*
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public Licens
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-
17
*
18
*/
19
#include <linux/kernel.h>
20
#include <linux/errno.h>
21
#include <linux/string.h>
22
#include <linux/module.h>
23
#include <linux/blkdev.h>
24
#include <linux/capability.h>
25
#include <linux/completion.h>
26
#include <linux/cdrom.h>
27
#include <linux/slab.h>
28
#include <linux/times.h>
29
#include <asm/uaccess.h>
30
31
#include <scsi/scsi.h>
32
#include <scsi/scsi_ioctl.h>
33
#include <scsi/scsi_cmnd.h>
34
35
struct blk_cmd_filter {
36
unsigned long read_ok[BLK_SCSI_CMD_PER_LONG];
37
unsigned long write_ok[BLK_SCSI_CMD_PER_LONG];
38
};
39
40
static struct blk_cmd_filter blk_default_cmd_filter;
41
42
/* Command group 3 is reserved and should never be used. */
43
const unsigned char scsi_command_size_tbl[8] =
44
{
45
6, 10, 10, 12,
46
16, 12, 10, 10
47
};
48
EXPORT_SYMBOL(scsi_command_size_tbl);
49
50
#include <scsi/sg.h>
51
52
static int sg_get_version(int __user *p)
53
{
54
static const int sg_version_num = 30527;
55
return put_user(sg_version_num, p);
56
}
57
58
static int scsi_get_idlun(struct request_queue *q, int __user *p)
59
{
60
return put_user(0, p);
61
}
62
63
static int scsi_get_bus(struct request_queue *q, int __user *p)
64
{
65
return put_user(0, p);
66
}
67
68
static int sg_get_timeout(struct request_queue *q)
69
{
70
return jiffies_to_clock_t(q->sg_timeout);
71
}
72
73
static int sg_set_timeout(struct request_queue *q, int __user *p)
74
{
75
int timeout, err = get_user(timeout, p);
76
77
if (!err)
78
q->sg_timeout = clock_t_to_jiffies(timeout);
79
80
return err;
81
}
82
83
static int sg_get_reserved_size(struct request_queue *q, int __user *p)
84
{
85
unsigned val = min(q->sg_reserved_size, queue_max_sectors(q) << 9);
86
87
return put_user(val, p);
88
}
89
90
static int sg_set_reserved_size(struct request_queue *q, int __user *p)
91
{
92
int size, err = get_user(size, p);
93
94
if (err)
95
return err;
96
97
if (size < 0)
98
return -EINVAL;
99
if (size > (queue_max_sectors(q) << 9))
100
size = queue_max_sectors(q) << 9;
101
102
q->sg_reserved_size = size;
103
return 0;
104
}
105
106
/*
107
* will always return that we are ATAPI even for a real SCSI drive, I'm not
108
* so sure this is worth doing anything about (why would you care??)
109
*/
110
static int sg_emulated_host(struct request_queue *q, int __user *p)
111
{
112
return put_user(1, p);
113
}
114
115
static void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter)
116
{
117
/* Basic read-only commands */
118
__set_bit(TEST_UNIT_READY, filter->read_ok);
119
__set_bit(REQUEST_SENSE, filter->read_ok);
120
__set_bit(READ_6, filter->read_ok);
121
__set_bit(READ_10, filter->read_ok);
122
__set_bit(READ_12, filter->read_ok);
123
__set_bit(READ_16, filter->read_ok);
124
__set_bit(READ_BUFFER, filter->read_ok);
125
__set_bit(READ_DEFECT_DATA, filter->read_ok);
126
__set_bit(READ_CAPACITY, filter->read_ok);
127
__set_bit(READ_LONG, filter->read_ok);
128
__set_bit(INQUIRY, filter->read_ok);
129
__set_bit(MODE_SENSE, filter->read_ok);
130
__set_bit(MODE_SENSE_10, filter->read_ok);
131
__set_bit(LOG_SENSE, filter->read_ok);
132
__set_bit(START_STOP, filter->read_ok);
133
__set_bit(GPCMD_VERIFY_10, filter->read_ok);
134
__set_bit(VERIFY_16, filter->read_ok);
135
__set_bit(REPORT_LUNS, filter->read_ok);
136
__set_bit(SERVICE_ACTION_IN, filter->read_ok);
137
__set_bit(RECEIVE_DIAGNOSTIC, filter->read_ok);
138
__set_bit(MAINTENANCE_IN, filter->read_ok);
139
__set_bit(GPCMD_READ_BUFFER_CAPACITY, filter->read_ok);
140
141
/* Audio CD commands */
142
__set_bit(GPCMD_PLAY_CD, filter->read_ok);
143
__set_bit(GPCMD_PLAY_AUDIO_10, filter->read_ok);
144
__set_bit(GPCMD_PLAY_AUDIO_MSF, filter->read_ok);
145
__set_bit(GPCMD_PLAY_AUDIO_TI, filter->read_ok);
146
__set_bit(GPCMD_PAUSE_RESUME, filter->read_ok);
147
148
/* CD/DVD data reading */
149
__set_bit(GPCMD_READ_CD, filter->read_ok);
150
__set_bit(GPCMD_READ_CD_MSF, filter->read_ok);
151
__set_bit(GPCMD_READ_DISC_INFO, filter->read_ok);
152
__set_bit(GPCMD_READ_CDVD_CAPACITY, filter->read_ok);
153
__set_bit(GPCMD_READ_DVD_STRUCTURE, filter->read_ok);
154
__set_bit(GPCMD_READ_HEADER, filter->read_ok);
155
__set_bit(GPCMD_READ_TRACK_RZONE_INFO, filter->read_ok);
156
__set_bit(GPCMD_READ_SUBCHANNEL, filter->read_ok);
157
__set_bit(GPCMD_READ_TOC_PMA_ATIP, filter->read_ok);
158
__set_bit(GPCMD_REPORT_KEY, filter->read_ok);
159
__set_bit(GPCMD_SCAN, filter->read_ok);
160
__set_bit(GPCMD_GET_CONFIGURATION, filter->read_ok);
161
__set_bit(GPCMD_READ_FORMAT_CAPACITIES, filter->read_ok);
162
__set_bit(GPCMD_GET_EVENT_STATUS_NOTIFICATION, filter->read_ok);
163
__set_bit(GPCMD_GET_PERFORMANCE, filter->read_ok);
164
__set_bit(GPCMD_SEEK, filter->read_ok);
165
__set_bit(GPCMD_STOP_PLAY_SCAN, filter->read_ok);
166
167
/* Basic writing commands */
168
__set_bit(WRITE_6, filter->write_ok);
169
__set_bit(WRITE_10, filter->write_ok);
170
__set_bit(WRITE_VERIFY, filter->write_ok);
171
__set_bit(WRITE_12, filter->write_ok);
172
__set_bit(WRITE_VERIFY_12, filter->write_ok);
173
__set_bit(WRITE_16, filter->write_ok);
174
__set_bit(WRITE_LONG, filter->write_ok);
175
__set_bit(WRITE_LONG_2, filter->write_ok);
176
__set_bit(ERASE, filter->write_ok);
177
__set_bit(GPCMD_MODE_SELECT_10, filter->write_ok);
178
__set_bit(MODE_SELECT, filter->write_ok);
179
__set_bit(LOG_SELECT, filter->write_ok);
180
__set_bit(GPCMD_BLANK, filter->write_ok);
181
__set_bit(GPCMD_CLOSE_TRACK, filter->write_ok);
182
__set_bit(GPCMD_FLUSH_CACHE, filter->write_ok);
183
__set_bit(GPCMD_FORMAT_UNIT, filter->write_ok);
184
__set_bit(GPCMD_REPAIR_RZONE_TRACK, filter->write_ok);
185
__set_bit(GPCMD_RESERVE_RZONE_TRACK, filter->write_ok);
186
__set_bit(GPCMD_SEND_DVD_STRUCTURE, filter->write_ok);
187
__set_bit(GPCMD_SEND_EVENT, filter->write_ok);
188
__set_bit(GPCMD_SEND_KEY, filter->write_ok);
189
__set_bit(GPCMD_SEND_OPC, filter->write_ok);
190
__set_bit(GPCMD_SEND_CUE_SHEET, filter->write_ok);
191
__set_bit(GPCMD_SET_SPEED, filter->write_ok);
192
__set_bit(GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL, filter->write_ok);
193
__set_bit(GPCMD_LOAD_UNLOAD, filter->write_ok);
194
__set_bit(GPCMD_SET_STREAMING, filter->write_ok);
195
__set_bit(GPCMD_SET_READ_AHEAD, filter->write_ok);
196
}
197
198
int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm)
199
{
200
struct blk_cmd_filter *filter = &blk_default_cmd_filter;
201
202
/* root can do any command. */
203
if (capable(CAP_SYS_RAWIO))
204
return 0;
205
206
/* if there's no filter set, assume we're filtering everything out */
207
if (!filter)
208
return -EPERM;
209
210
/* Anybody who can open the device can do a read-safe command */
211
if (test_bit(cmd[0], filter->read_ok))
212
return 0;
213
214
/* Write-safe commands require a writable open */
215
if (test_bit(cmd[0], filter->write_ok) && has_write_perm)
216
return 0;
217
218
return -EPERM;
219
}
220
EXPORT_SYMBOL(blk_verify_command);
221
222
static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
223
struct sg_io_hdr *hdr, fmode_t mode)
224
{
225
if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len))
226
return -EFAULT;
227
if (blk_verify_command(rq->cmd, mode & FMODE_WRITE))
228
return -EPERM;
229
230
/*
231
* fill in request structure
232
*/
233
rq->cmd_len = hdr->cmd_len;
234
rq->cmd_type = REQ_TYPE_BLOCK_PC;
235
236
rq->timeout = msecs_to_jiffies(hdr->timeout);
237
if (!rq->timeout)
238
rq->timeout = q->sg_timeout;
239
if (!rq->timeout)
240
rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
241
if (rq->timeout < BLK_MIN_SG_TIMEOUT)
242
rq->timeout = BLK_MIN_SG_TIMEOUT;
243
244
return 0;
245
}
246
247
static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
248
struct bio *bio)
249
{
250
int r, ret = 0;
251
252
/*
253
* fill in all the output members
254
*/
255
hdr->status = rq->errors & 0xff;
256
hdr->masked_status = status_byte(rq->errors);
257
hdr->msg_status = msg_byte(rq->errors);
258
hdr->host_status = host_byte(rq->errors);
259
hdr->driver_status = driver_byte(rq->errors);
260
hdr->info = 0;
261
if (hdr->masked_status || hdr->host_status || hdr->driver_status)
262
hdr->info |= SG_INFO_CHECK;
263
hdr->resid = rq->resid_len;
264
hdr->sb_len_wr = 0;
265
266
if (rq->sense_len && hdr->sbp) {
267
int len = min((unsigned int) hdr->mx_sb_len, rq->sense_len);
268
269
if (!copy_to_user(hdr->sbp, rq->sense, len))
270
hdr->sb_len_wr = len;
271
else
272
ret = -EFAULT;
273
}
274
275
r = blk_rq_unmap_user(bio);
276
if (!ret)
277
ret = r;
278
blk_put_request(rq);
279
280
return ret;
281
}
282
283
static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
284
struct sg_io_hdr *hdr, fmode_t mode)
285
{
286
unsigned long start_time;
287
int writing = 0, ret = 0;
288
struct request *rq;
289
char sense[SCSI_SENSE_BUFFERSIZE];
290
struct bio *bio;
291
292
if (hdr->interface_id != 'S')
293
return -EINVAL;
294
if (hdr->cmd_len > BLK_MAX_CDB)
295
return -EINVAL;
296
297
if (hdr->dxfer_len > (queue_max_hw_sectors(q) << 9))
298
return -EIO;
299
300
if (hdr->dxfer_len)
301
switch (hdr->dxfer_direction) {
302
default:
303
return -EINVAL;
304
case SG_DXFER_TO_DEV:
305
writing = 1;
306
break;
307
case SG_DXFER_TO_FROM_DEV:
308
case SG_DXFER_FROM_DEV:
309
break;
310
}
311
312
rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL);
313
if (!rq)
314
return -ENOMEM;
315
316
if (blk_fill_sghdr_rq(q, rq, hdr, mode)) {
317
blk_put_request(rq);
318
return -EFAULT;
319
}
320
321
if (hdr->iovec_count) {
322
const int size = sizeof(struct sg_iovec) * hdr->iovec_count;
323
size_t iov_data_len;
324
struct sg_iovec *sg_iov;
325
struct iovec *iov;
326
int i;
327
328
sg_iov = kmalloc(size, GFP_KERNEL);
329
if (!sg_iov) {
330
ret = -ENOMEM;
331
goto out;
332
}
333
334
if (copy_from_user(sg_iov, hdr->dxferp, size)) {
335
kfree(sg_iov);
336
ret = -EFAULT;
337
goto out;
338
}
339
340
/*
341
* Sum up the vecs, making sure they don't overflow
342
*/
343
iov = (struct iovec *) sg_iov;
344
iov_data_len = 0;
345
for (i = 0; i < hdr->iovec_count; i++) {
346
if (iov_data_len + iov[i].iov_len < iov_data_len) {
347
kfree(sg_iov);
348
ret = -EINVAL;
349
goto out;
350
}
351
iov_data_len += iov[i].iov_len;
352
}
353
354
/* SG_IO howto says that the shorter of the two wins */
355
if (hdr->dxfer_len < iov_data_len) {
356
hdr->iovec_count = iov_shorten(iov,
357
hdr->iovec_count,
358
hdr->dxfer_len);
359
iov_data_len = hdr->dxfer_len;
360
}
361
362
ret = blk_rq_map_user_iov(q, rq, NULL, sg_iov, hdr->iovec_count,
363
iov_data_len, GFP_KERNEL);
364
kfree(sg_iov);
365
} else if (hdr->dxfer_len)
366
ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len,
367
GFP_KERNEL);
368
369
if (ret)
370
goto out;
371
372
bio = rq->bio;
373
memset(sense, 0, sizeof(sense));
374
rq->sense = sense;
375
rq->sense_len = 0;
376
rq->retries = 0;
377
378
start_time = jiffies;
379
380
/* ignore return value. All information is passed back to caller
381
* (if he doesn't check that is his problem).
382
* N.B. a non-zero SCSI status is _not_ necessarily an error.
383
*/
384
blk_execute_rq(q, bd_disk, rq, 0);
385
386
hdr->duration = jiffies_to_msecs(jiffies - start_time);
387
388
return blk_complete_sghdr_rq(rq, hdr, bio);
389
out:
390
blk_put_request(rq);
391
return ret;
392
}
393
394
/**
395
* sg_scsi_ioctl -- handle deprecated SCSI_IOCTL_SEND_COMMAND ioctl
396
* @file: file this ioctl operates on (optional)
397
* @q: request queue to send scsi commands down
398
* @disk: gendisk to operate on (option)
399
* @sic: userspace structure describing the command to perform
400
*
401
* Send down the scsi command described by @sic to the device below
402
* the request queue @q. If @file is non-NULL it's used to perform
403
* fine-grained permission checks that allow users to send down
404
* non-destructive SCSI commands. If the caller has a struct gendisk
405
* available it should be passed in as @disk to allow the low level
406
* driver to use the information contained in it. A non-NULL @disk
407
* is only allowed if the caller knows that the low level driver doesn't
408
* need it (e.g. in the scsi subsystem).
409
*
410
* Notes:
411
* - This interface is deprecated - users should use the SG_IO
412
* interface instead, as this is a more flexible approach to
413
* performing SCSI commands on a device.
414
* - The SCSI command length is determined by examining the 1st byte
415
* of the given command. There is no way to override this.
416
* - Data transfers are limited to PAGE_SIZE
417
* - The length (x + y) must be at least OMAX_SB_LEN bytes long to
418
* accommodate the sense buffer when an error occurs.
419
* The sense buffer is truncated to OMAX_SB_LEN (16) bytes so that
420
* old code will not be surprised.
421
* - If a Unix error occurs (e.g. ENOMEM) then the user will receive
422
* a negative return and the Unix error code in 'errno'.
423
* If the SCSI command succeeds then 0 is returned.
424
* Positive numbers returned are the compacted SCSI error codes (4
425
* bytes in one int) where the lowest byte is the SCSI status.
426
*/
427
#define OMAX_SB_LEN 16 /* For backward compatibility */
428
int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
429
struct scsi_ioctl_command __user *sic)
430
{
431
struct request *rq;
432
int err;
433
unsigned int in_len, out_len, bytes, opcode, cmdlen;
434
char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE];
435
436
if (!sic)
437
return -EINVAL;
438
439
/*
440
* get in an out lengths, verify they don't exceed a page worth of data
441
*/
442
if (get_user(in_len, &sic->inlen))
443
return -EFAULT;
444
if (get_user(out_len, &sic->outlen))
445
return -EFAULT;
446
if (in_len > PAGE_SIZE || out_len > PAGE_SIZE)
447
return -EINVAL;
448
if (get_user(opcode, sic->data))
449
return -EFAULT;
450
451
bytes = max(in_len, out_len);
452
if (bytes) {
453
buffer = kzalloc(bytes, q->bounce_gfp | GFP_USER| __GFP_NOWARN);
454
if (!buffer)
455
return -ENOMEM;
456
457
}
458
459
rq = blk_get_request(q, in_len ? WRITE : READ, __GFP_WAIT);
460
461
cmdlen = COMMAND_SIZE(opcode);
462
463
/*
464
* get command and data to send to device, if any
465
*/
466
err = -EFAULT;
467
rq->cmd_len = cmdlen;
468
if (copy_from_user(rq->cmd, sic->data, cmdlen))
469
goto error;
470
471
if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
472
goto error;
473
474
err = blk_verify_command(rq->cmd, mode & FMODE_WRITE);
475
if (err)
476
goto error;
477
478
/* default. possible overriden later */
479
rq->retries = 5;
480
481
switch (opcode) {
482
case SEND_DIAGNOSTIC:
483
case FORMAT_UNIT:
484
rq->timeout = FORMAT_UNIT_TIMEOUT;
485
rq->retries = 1;
486
break;
487
case START_STOP:
488
rq->timeout = START_STOP_TIMEOUT;
489
break;
490
case MOVE_MEDIUM:
491
rq->timeout = MOVE_MEDIUM_TIMEOUT;
492
break;
493
case READ_ELEMENT_STATUS:
494
rq->timeout = READ_ELEMENT_STATUS_TIMEOUT;
495
break;
496
case READ_DEFECT_DATA:
497
rq->timeout = READ_DEFECT_DATA_TIMEOUT;
498
rq->retries = 1;
499
break;
500
default:
501
rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
502
break;
503
}
504
505
if (bytes && blk_rq_map_kern(q, rq, buffer, bytes, __GFP_WAIT)) {
506
err = DRIVER_ERROR << 24;
507
goto out;
508
}
509
510
memset(sense, 0, sizeof(sense));
511
rq->sense = sense;
512
rq->sense_len = 0;
513
rq->cmd_type = REQ_TYPE_BLOCK_PC;
514
515
blk_execute_rq(q, disk, rq, 0);
516
517
out:
518
err = rq->errors & 0xff; /* only 8 bit SCSI status */
519
if (err) {
520
if (rq->sense_len && rq->sense) {
521
bytes = (OMAX_SB_LEN > rq->sense_len) ?
522
rq->sense_len : OMAX_SB_LEN;
523
if (copy_to_user(sic->data, rq->sense, bytes))
524
err = -EFAULT;
525
}
526
} else {
527
if (copy_to_user(sic->data, buffer, out_len))
528
err = -EFAULT;
529
}
530
531
error:
532
kfree(buffer);
533
blk_put_request(rq);
534
return err;
535
}
536
EXPORT_SYMBOL_GPL(sg_scsi_ioctl);
537
538
/* Send basic block requests */
539
static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk,
540
int cmd, int data)
541
{
542
struct request *rq;
543
int err;
544
545
rq = blk_get_request(q, WRITE, __GFP_WAIT);
546
rq->cmd_type = REQ_TYPE_BLOCK_PC;
547
rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
548
rq->cmd[0] = cmd;
549
rq->cmd[4] = data;
550
rq->cmd_len = 6;
551
err = blk_execute_rq(q, bd_disk, rq, 0);
552
blk_put_request(rq);
553
554
return err;
555
}
556
557
static inline int blk_send_start_stop(struct request_queue *q,
558
struct gendisk *bd_disk, int data)
559
{
560
return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data);
561
}
562
563
int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mode,
564
unsigned int cmd, void __user *arg)
565
{
566
int err;
567
568
if (!q || blk_get_queue(q))
569
return -ENXIO;
570
571
switch (cmd) {
572
/*
573
* new sgv3 interface
574
*/
575
case SG_GET_VERSION_NUM:
576
err = sg_get_version(arg);
577
break;
578
case SCSI_IOCTL_GET_IDLUN:
579
err = scsi_get_idlun(q, arg);
580
break;
581
case SCSI_IOCTL_GET_BUS_NUMBER:
582
err = scsi_get_bus(q, arg);
583
break;
584
case SG_SET_TIMEOUT:
585
err = sg_set_timeout(q, arg);
586
break;
587
case SG_GET_TIMEOUT:
588
err = sg_get_timeout(q);
589
break;
590
case SG_GET_RESERVED_SIZE:
591
err = sg_get_reserved_size(q, arg);
592
break;
593
case SG_SET_RESERVED_SIZE:
594
err = sg_set_reserved_size(q, arg);
595
break;
596
case SG_EMULATED_HOST:
597
err = sg_emulated_host(q, arg);
598
break;
599
case SG_IO: {
600
struct sg_io_hdr hdr;
601
602
err = -EFAULT;
603
if (copy_from_user(&hdr, arg, sizeof(hdr)))
604
break;
605
err = sg_io(q, bd_disk, &hdr, mode);
606
if (err == -EFAULT)
607
break;
608
609
if (copy_to_user(arg, &hdr, sizeof(hdr)))
610
err = -EFAULT;
611
break;
612
}
613
case CDROM_SEND_PACKET: {
614
struct cdrom_generic_command cgc;
615
struct sg_io_hdr hdr;
616
617
err = -EFAULT;
618
if (copy_from_user(&cgc, arg, sizeof(cgc)))
619
break;
620
cgc.timeout = clock_t_to_jiffies(cgc.timeout);
621
memset(&hdr, 0, sizeof(hdr));
622
hdr.interface_id = 'S';
623
hdr.cmd_len = sizeof(cgc.cmd);
624
hdr.dxfer_len = cgc.buflen;
625
err = 0;
626
switch (cgc.data_direction) {
627
case CGC_DATA_UNKNOWN:
628
hdr.dxfer_direction = SG_DXFER_UNKNOWN;
629
break;
630
case CGC_DATA_WRITE:
631
hdr.dxfer_direction = SG_DXFER_TO_DEV;
632
break;
633
case CGC_DATA_READ:
634
hdr.dxfer_direction = SG_DXFER_FROM_DEV;
635
break;
636
case CGC_DATA_NONE:
637
hdr.dxfer_direction = SG_DXFER_NONE;
638
break;
639
default:
640
err = -EINVAL;
641
}
642
if (err)
643
break;
644
645
hdr.dxferp = cgc.buffer;
646
hdr.sbp = cgc.sense;
647
if (hdr.sbp)
648
hdr.mx_sb_len = sizeof(struct request_sense);
649
hdr.timeout = jiffies_to_msecs(cgc.timeout);
650
hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd;
651
hdr.cmd_len = sizeof(cgc.cmd);
652
653
err = sg_io(q, bd_disk, &hdr, mode);
654
if (err == -EFAULT)
655
break;
656
657
if (hdr.status)
658
err = -EIO;
659
660
cgc.stat = err;
661
cgc.buflen = hdr.resid;
662
if (copy_to_user(arg, &cgc, sizeof(cgc)))
663
err = -EFAULT;
664
665
break;
666
}
667
668
/*
669
* old junk scsi send command ioctl
670
*/
671
case SCSI_IOCTL_SEND_COMMAND:
672
printk(KERN_WARNING "program %s is using a deprecated SCSI ioctl, please convert it to SG_IO\n", current->comm);
673
err = -EINVAL;
674
if (!arg)
675
break;
676
677
err = sg_scsi_ioctl(q, bd_disk, mode, arg);
678
break;
679
case CDROMCLOSETRAY:
680
err = blk_send_start_stop(q, bd_disk, 0x03);
681
break;
682
case CDROMEJECT:
683
err = blk_send_start_stop(q, bd_disk, 0x02);
684
break;
685
default:
686
err = -ENOTTY;
687
}
688
689
blk_put_queue(q);
690
return err;
691
}
692
EXPORT_SYMBOL(scsi_cmd_ioctl);
693
694
static int __init blk_scsi_ioctl_init(void)
695
{
696
blk_set_cmd_filter_defaults(&blk_default_cmd_filter);
697
return 0;
698
}
699
fs_initcall(blk_scsi_ioctl_init);
700
701