1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
36const unsigned char scsi_command_size[8] =
37{
38 6, 10, 10, 12,
39 16, 12, 10, 10
40};
41
42EXPORT_SYMBOL(scsi_command_size);
43
44#include <scsi/sg.h>
45
46static int sg_get_version(int __user *p)
47{
48 static const int sg_version_num = 30527;
49 return put_user(sg_version_num, p);
50}
51
52static int scsi_get_idlun(struct request_queue *q, int __user *p)
53{
54 return put_user(0, p);
55}
56
57static int scsi_get_bus(struct request_queue *q, int __user *p)
58{
59 return put_user(0, p);
60}
61
62static int sg_get_timeout(struct request_queue *q)
63{
64 return q->sg_timeout / (HZ / USER_HZ);
65}
66
67static int sg_set_timeout(struct request_queue *q, int __user *p)
68{
69 int timeout, err = get_user(timeout, p);
70
71 if (!err)
72 q->sg_timeout = timeout * (HZ / USER_HZ);
73
74 return err;
75}
76
77static int sg_get_reserved_size(struct request_queue *q, int __user *p)
78{
79 unsigned val = min(q->sg_reserved_size, q->max_sectors << 9);
80
81 return put_user(val, p);
82}
83
84static int sg_set_reserved_size(struct request_queue *q, int __user *p)
85{
86 int size, err = get_user(size, p);
87
88 if (err)
89 return err;
90
91 if (size < 0)
92 return -EINVAL;
93 if (size > (q->max_sectors << 9))
94 size = q->max_sectors << 9;
95
96 q->sg_reserved_size = size;
97 return 0;
98}
99
100
101
102
103
104static int sg_emulated_host(struct request_queue *q, int __user *p)
105{
106 return put_user(1, p);
107}
108
109#define CMD_READ_SAFE 0x01
110#define CMD_WRITE_SAFE 0x02
111#define CMD_WARNED 0x04
112#define safe_for_read(cmd) [cmd] = CMD_READ_SAFE
113#define safe_for_write(cmd) [cmd] = CMD_WRITE_SAFE
114
115int blk_verify_command(unsigned char *cmd, int has_write_perm)
116{
117 static unsigned char cmd_type[256] = {
118
119
120 safe_for_read(TEST_UNIT_READY),
121 safe_for_read(REQUEST_SENSE),
122 safe_for_read(READ_6),
123 safe_for_read(READ_10),
124 safe_for_read(READ_12),
125 safe_for_read(READ_16),
126 safe_for_read(READ_BUFFER),
127 safe_for_read(READ_DEFECT_DATA),
128 safe_for_read(READ_LONG),
129 safe_for_read(INQUIRY),
130 safe_for_read(MODE_SENSE),
131 safe_for_read(MODE_SENSE_10),
132 safe_for_read(LOG_SENSE),
133 safe_for_read(START_STOP),
134 safe_for_read(GPCMD_VERIFY_10),
135 safe_for_read(VERIFY_16),
136
137
138 safe_for_read(GPCMD_PLAY_CD),
139 safe_for_read(GPCMD_PLAY_AUDIO_10),
140 safe_for_read(GPCMD_PLAY_AUDIO_MSF),
141 safe_for_read(GPCMD_PLAY_AUDIO_TI),
142 safe_for_read(GPCMD_PAUSE_RESUME),
143
144
145 safe_for_read(GPCMD_READ_BUFFER_CAPACITY),
146 safe_for_read(GPCMD_READ_CD),
147 safe_for_read(GPCMD_READ_CD_MSF),
148 safe_for_read(GPCMD_READ_DISC_INFO),
149 safe_for_read(GPCMD_READ_CDVD_CAPACITY),
150 safe_for_read(GPCMD_READ_DVD_STRUCTURE),
151 safe_for_read(GPCMD_READ_HEADER),
152 safe_for_read(GPCMD_READ_TRACK_RZONE_INFO),
153 safe_for_read(GPCMD_READ_SUBCHANNEL),
154 safe_for_read(GPCMD_READ_TOC_PMA_ATIP),
155 safe_for_read(GPCMD_REPORT_KEY),
156 safe_for_read(GPCMD_SCAN),
157 safe_for_read(GPCMD_GET_CONFIGURATION),
158 safe_for_read(GPCMD_READ_FORMAT_CAPACITIES),
159 safe_for_read(GPCMD_GET_EVENT_STATUS_NOTIFICATION),
160 safe_for_read(GPCMD_GET_PERFORMANCE),
161 safe_for_read(GPCMD_SEEK),
162 safe_for_read(GPCMD_STOP_PLAY_SCAN),
163
164
165 safe_for_write(WRITE_6),
166 safe_for_write(WRITE_10),
167 safe_for_write(WRITE_VERIFY),
168 safe_for_write(WRITE_12),
169 safe_for_write(WRITE_VERIFY_12),
170 safe_for_write(WRITE_16),
171 safe_for_write(WRITE_LONG),
172 safe_for_write(WRITE_LONG_2),
173 safe_for_write(ERASE),
174 safe_for_write(GPCMD_MODE_SELECT_10),
175 safe_for_write(MODE_SELECT),
176 safe_for_write(LOG_SELECT),
177 safe_for_write(GPCMD_BLANK),
178 safe_for_write(GPCMD_CLOSE_TRACK),
179 safe_for_write(GPCMD_FLUSH_CACHE),
180 safe_for_write(GPCMD_FORMAT_UNIT),
181 safe_for_write(GPCMD_REPAIR_RZONE_TRACK),
182 safe_for_write(GPCMD_RESERVE_RZONE_TRACK),
183 safe_for_write(GPCMD_SEND_DVD_STRUCTURE),
184 safe_for_write(GPCMD_SEND_EVENT),
185 safe_for_write(GPCMD_SEND_KEY),
186 safe_for_write(GPCMD_SEND_OPC),
187 safe_for_write(GPCMD_SEND_CUE_SHEET),
188 safe_for_write(GPCMD_SET_SPEED),
189 safe_for_write(GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL),
190 safe_for_write(GPCMD_LOAD_UNLOAD),
191 safe_for_write(GPCMD_SET_STREAMING),
192 };
193 unsigned char type = cmd_type[cmd[0]];
194
195
196 if (type & CMD_READ_SAFE)
197 return 0;
198
199
200 if ((type & CMD_WRITE_SAFE) && has_write_perm)
201 return 0;
202
203
204 if (capable(CAP_SYS_RAWIO))
205 return 0;
206
207 if (!type) {
208 cmd_type[cmd[0]] = CMD_WARNED;
209 printk(KERN_WARNING "scsi: unknown opcode 0x%02x\n", cmd[0]);
210 }
211
212
213 return -EPERM;
214}
215EXPORT_SYMBOL_GPL(blk_verify_command);
216
217static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
218 struct sg_io_hdr *hdr, int has_write_perm)
219{
220 memset(rq->cmd, 0, BLK_MAX_CDB);
221
222 if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len))
223 return -EFAULT;
224 if (blk_verify_command(rq->cmd, has_write_perm))
225 return -EPERM;
226
227
228
229
230 rq->cmd_len = hdr->cmd_len;
231 rq->cmd_type = REQ_TYPE_BLOCK_PC;
232
233 rq->timeout = (hdr->timeout * HZ) / 1000;
234 if (!rq->timeout)
235 rq->timeout = q->sg_timeout;
236 if (!rq->timeout)
237 rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
238
239 return 0;
240}
241
242
243
244
245
246static int blk_unmap_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr)
247{
248 blk_rq_unmap_user(rq->bio);
249 blk_put_request(rq);
250 return 0;
251}
252
253static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
254 struct bio *bio)
255{
256 int r, ret = 0;
257
258
259
260
261 hdr->status = rq->errors & 0xff;
262 hdr->masked_status = status_byte(rq->errors);
263 hdr->msg_status = msg_byte(rq->errors);
264 hdr->host_status = host_byte(rq->errors);
265 hdr->driver_status = driver_byte(rq->errors);
266 hdr->info = 0;
267 if (hdr->masked_status || hdr->host_status || hdr->driver_status)
268 hdr->info |= SG_INFO_CHECK;
269 hdr->resid = rq->data_len;
270 hdr->sb_len_wr = 0;
271
272 if (rq->sense_len && hdr->sbp) {
273 int len = min((unsigned int) hdr->mx_sb_len, rq->sense_len);
274
275 if (!copy_to_user(hdr->sbp, rq->sense, len))
276 hdr->sb_len_wr = len;
277 else
278 ret = -EFAULT;
279 }
280
281 rq->bio = bio;
282 r = blk_unmap_sghdr_rq(rq, hdr);
283 if (ret)
284 r = ret;
285
286 return r;
287}
288
289static int sg_io(struct file *file, struct request_queue *q,
290 struct gendisk *bd_disk, struct sg_io_hdr *hdr)
291{
292 unsigned long start_time;
293 int writing = 0, ret = 0, has_write_perm = 0;
294 struct request *rq;
295 char sense[SCSI_SENSE_BUFFERSIZE];
296 struct bio *bio;
297
298 if (hdr->interface_id != 'S')
299 return -EINVAL;
300 if (hdr->cmd_len > BLK_MAX_CDB)
301 return -EINVAL;
302
303 if (hdr->dxfer_len > (q->max_hw_sectors << 9))
304 return -EIO;
305
306 if (hdr->dxfer_len)
307 switch (hdr->dxfer_direction) {
308 default:
309 return -EINVAL;
310 case SG_DXFER_TO_DEV:
311 writing = 1;
312 break;
313 case SG_DXFER_TO_FROM_DEV:
314 case SG_DXFER_FROM_DEV:
315 break;
316 }
317
318 rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL);
319 if (!rq)
320 return -ENOMEM;
321
322 if (file)
323 has_write_perm = file->f_mode & FMODE_WRITE;
324
325 if (blk_fill_sghdr_rq(q, rq, hdr, has_write_perm)) {
326 blk_put_request(rq);
327 return -EFAULT;
328 }
329
330 if (hdr->iovec_count) {
331 const int size = sizeof(struct sg_iovec) * hdr->iovec_count;
332 struct sg_iovec *iov;
333
334 iov = kmalloc(size, GFP_KERNEL);
335 if (!iov) {
336 ret = -ENOMEM;
337 goto out;
338 }
339
340 if (copy_from_user(iov, hdr->dxferp, size)) {
341 kfree(iov);
342 ret = -EFAULT;
343 goto out;
344 }
345
346 ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count,
347 hdr->dxfer_len);
348 kfree(iov);
349 } else if (hdr->dxfer_len)
350 ret = blk_rq_map_user(q, rq, hdr->dxferp, hdr->dxfer_len);
351
352 if (ret)
353 goto out;
354
355 bio = rq->bio;
356 memset(sense, 0, sizeof(sense));
357 rq->sense = sense;
358 rq->sense_len = 0;
359 rq->retries = 0;
360
361 start_time = jiffies;
362
363
364
365
366
367 blk_execute_rq(q, bd_disk, rq, 0);
368
369 hdr->duration = ((jiffies - start_time) * 1000) / HZ;
370
371 return blk_complete_sghdr_rq(rq, hdr, bio);
372out:
373 blk_put_request(rq);
374 return ret;
375}
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410#define OMAX_SB_LEN 16
411int sg_scsi_ioctl(struct file *file, struct request_queue *q,
412 struct gendisk *disk, struct scsi_ioctl_command __user *sic)
413{
414 struct request *rq;
415 int err;
416 unsigned int in_len, out_len, bytes, opcode, cmdlen;
417 char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE];
418
419 if (!sic)
420 return -EINVAL;
421
422
423
424
425 if (get_user(in_len, &sic->inlen))
426 return -EFAULT;
427 if (get_user(out_len, &sic->outlen))
428 return -EFAULT;
429 if (in_len > PAGE_SIZE || out_len > PAGE_SIZE)
430 return -EINVAL;
431 if (get_user(opcode, sic->data))
432 return -EFAULT;
433
434 bytes = max(in_len, out_len);
435 if (bytes) {
436 buffer = kzalloc(bytes, q->bounce_gfp | GFP_USER| __GFP_NOWARN);
437 if (!buffer)
438 return -ENOMEM;
439
440 }
441
442 rq = blk_get_request(q, in_len ? WRITE : READ, __GFP_WAIT);
443
444 cmdlen = COMMAND_SIZE(opcode);
445
446
447
448
449 err = -EFAULT;
450 rq->cmd_len = cmdlen;
451 if (copy_from_user(rq->cmd, sic->data, cmdlen))
452 goto error;
453
454 if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
455 goto error;
456
457 err = blk_verify_command(rq->cmd, file->f_mode & FMODE_WRITE);
458 if (err)
459 goto error;
460
461
462 rq->retries = 5;
463
464 switch (opcode) {
465 case SEND_DIAGNOSTIC:
466 case FORMAT_UNIT:
467 rq->timeout = FORMAT_UNIT_TIMEOUT;
468 rq->retries = 1;
469 break;
470 case START_STOP:
471 rq->timeout = START_STOP_TIMEOUT;
472 break;
473 case MOVE_MEDIUM:
474 rq->timeout = MOVE_MEDIUM_TIMEOUT;
475 break;
476 case READ_ELEMENT_STATUS:
477 rq->timeout = READ_ELEMENT_STATUS_TIMEOUT;
478 break;
479 case READ_DEFECT_DATA:
480 rq->timeout = READ_DEFECT_DATA_TIMEOUT;
481 rq->retries = 1;
482 break;
483 default:
484 rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
485 break;
486 }
487
488 if (bytes && blk_rq_map_kern(q, rq, buffer, bytes, __GFP_WAIT)) {
489 err = DRIVER_ERROR << 24;
490 goto out;
491 }
492
493 memset(sense, 0, sizeof(sense));
494 rq->sense = sense;
495 rq->sense_len = 0;
496 rq->cmd_type = REQ_TYPE_BLOCK_PC;
497
498 blk_execute_rq(q, disk, rq, 0);
499
500out:
501 err = rq->errors & 0xff;
502 if (err) {
503 if (rq->sense_len && rq->sense) {
504 bytes = (OMAX_SB_LEN > rq->sense_len) ?
505 rq->sense_len : OMAX_SB_LEN;
506 if (copy_to_user(sic->data, rq->sense, bytes))
507 err = -EFAULT;
508 }
509 } else {
510 if (copy_to_user(sic->data, buffer, out_len))
511 err = -EFAULT;
512 }
513
514error:
515 kfree(buffer);
516 blk_put_request(rq);
517 return err;
518}
519EXPORT_SYMBOL_GPL(sg_scsi_ioctl);
520
521
522static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk,
523 int cmd, int data)
524{
525 struct request *rq;
526 int err;
527
528 rq = blk_get_request(q, WRITE, __GFP_WAIT);
529 rq->cmd_type = REQ_TYPE_BLOCK_PC;
530 rq->data = NULL;
531 rq->data_len = 0;
532 rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
533 memset(rq->cmd, 0, sizeof(rq->cmd));
534 rq->cmd[0] = cmd;
535 rq->cmd[4] = data;
536 rq->cmd_len = 6;
537 err = blk_execute_rq(q, bd_disk, rq, 0);
538 blk_put_request(rq);
539
540 return err;
541}
542
543static inline int blk_send_start_stop(struct request_queue *q,
544 struct gendisk *bd_disk, int data)
545{
546 return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data);
547}
548
549int scsi_cmd_ioctl(struct file *file, struct request_queue *q,
550 struct gendisk *bd_disk, unsigned int cmd, void __user *arg)
551{
552 int err;
553
554 if (!q || blk_get_queue(q))
555 return -ENXIO;
556
557 switch (cmd) {
558
559
560
561 case SG_GET_VERSION_NUM:
562 err = sg_get_version(arg);
563 break;
564 case SCSI_IOCTL_GET_IDLUN:
565 err = scsi_get_idlun(q, arg);
566 break;
567 case SCSI_IOCTL_GET_BUS_NUMBER:
568 err = scsi_get_bus(q, arg);
569 break;
570 case SG_SET_TIMEOUT:
571 err = sg_set_timeout(q, arg);
572 break;
573 case SG_GET_TIMEOUT:
574 err = sg_get_timeout(q);
575 break;
576 case SG_GET_RESERVED_SIZE:
577 err = sg_get_reserved_size(q, arg);
578 break;
579 case SG_SET_RESERVED_SIZE:
580 err = sg_set_reserved_size(q, arg);
581 break;
582 case SG_EMULATED_HOST:
583 err = sg_emulated_host(q, arg);
584 break;
585 case SG_IO: {
586 struct sg_io_hdr hdr;
587
588 err = -EFAULT;
589 if (copy_from_user(&hdr, arg, sizeof(hdr)))
590 break;
591 err = sg_io(file, q, bd_disk, &hdr);
592 if (err == -EFAULT)
593 break;
594
595 if (copy_to_user(arg, &hdr, sizeof(hdr)))
596 err = -EFAULT;
597 break;
598 }
599 case CDROM_SEND_PACKET: {
600 struct cdrom_generic_command cgc;
601 struct sg_io_hdr hdr;
602
603 err = -EFAULT;
604 if (copy_from_user(&cgc, arg, sizeof(cgc)))
605 break;
606 cgc.timeout = clock_t_to_jiffies(cgc.timeout);
607 memset(&hdr, 0, sizeof(hdr));
608 hdr.interface_id = 'S';
609 hdr.cmd_len = sizeof(cgc.cmd);
610 hdr.dxfer_len = cgc.buflen;
611 err = 0;
612 switch (cgc.data_direction) {
613 case CGC_DATA_UNKNOWN:
614 hdr.dxfer_direction = SG_DXFER_UNKNOWN;
615 break;
616 case CGC_DATA_WRITE:
617 hdr.dxfer_direction = SG_DXFER_TO_DEV;
618 break;
619 case CGC_DATA_READ:
620 hdr.dxfer_direction = SG_DXFER_FROM_DEV;
621 break;
622 case CGC_DATA_NONE:
623 hdr.dxfer_direction = SG_DXFER_NONE;
624 break;
625 default:
626 err = -EINVAL;
627 }
628 if (err)
629 break;
630
631 hdr.dxferp = cgc.buffer;
632 hdr.sbp = cgc.sense;
633 if (hdr.sbp)
634 hdr.mx_sb_len = sizeof(struct request_sense);
635 hdr.timeout = cgc.timeout;
636 hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd;
637 hdr.cmd_len = sizeof(cgc.cmd);
638
639 err = sg_io(file, q, bd_disk, &hdr);
640 if (err == -EFAULT)
641 break;
642
643 if (hdr.status)
644 err = -EIO;
645
646 cgc.stat = err;
647 cgc.buflen = hdr.resid;
648 if (copy_to_user(arg, &cgc, sizeof(cgc)))
649 err = -EFAULT;
650
651 break;
652 }
653
654
655
656
657 case SCSI_IOCTL_SEND_COMMAND:
658 printk(KERN_WARNING "program %s is using a deprecated SCSI ioctl, please convert it to SG_IO\n", current->comm);
659 err = -EINVAL;
660 if (!arg)
661 break;
662
663 err = sg_scsi_ioctl(file, q, bd_disk, arg);
664 break;
665 case CDROMCLOSETRAY:
666 err = blk_send_start_stop(q, bd_disk, 0x03);
667 break;
668 case CDROMEJECT:
669 err = blk_send_start_stop(q, bd_disk, 0x02);
670 break;
671 default:
672 err = -ENOTTY;
673 }
674
675 blk_put_queue(q);
676 return err;
677}
678
679EXPORT_SYMBOL(scsi_cmd_ioctl);
680