1
2
3
4
5
6
7
8#include <linux/module.h>
9#include <linux/blkdev.h>
10#include <linux/interrupt.h>
11#include <linux/errno.h>
12#include <linux/kernel.h>
13#include <linux/sched.h>
14#include <linux/mm.h>
15#include <linux/string.h>
16#include <linux/uaccess.h>
17#include <linux/cdrom.h>
18
19#include <scsi/scsi.h>
20#include <scsi/scsi_cmnd.h>
21#include <scsi/scsi_device.h>
22#include <scsi/scsi_eh.h>
23#include <scsi/scsi_host.h>
24#include <scsi/scsi_ioctl.h>
25#include <scsi/sg.h>
26#include <scsi/scsi_dbg.h>
27
28#include "scsi_logging.h"
29
30#define NORMAL_RETRIES 5
31#define IOCTL_NORMAL_TIMEOUT (10 * HZ)
32
33#define MAX_BUF PAGE_SIZE
34
35
36
37
38
39
40
41
42
43static int ioctl_probe(struct Scsi_Host *host, void __user *buffer)
44{
45 unsigned int len, slen;
46 const char *string;
47
48 if (buffer) {
49 if (get_user(len, (unsigned int __user *) buffer))
50 return -EFAULT;
51
52 if (host->hostt->info)
53 string = host->hostt->info(host);
54 else
55 string = host->hostt->name;
56 if (string) {
57 slen = strlen(string);
58 if (len > slen)
59 len = slen + 1;
60 if (copy_to_user(buffer, string, len))
61 return -EFAULT;
62 }
63 }
64 return 1;
65}
66
67static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
68 int timeout, int retries)
69{
70 int result;
71 struct scsi_sense_hdr sshdr;
72
73 SCSI_LOG_IOCTL(1, sdev_printk(KERN_INFO, sdev,
74 "Trying ioctl with scsi command %d\n", *cmd));
75
76 result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0,
77 &sshdr, timeout, retries, NULL);
78
79 SCSI_LOG_IOCTL(2, sdev_printk(KERN_INFO, sdev,
80 "Ioctl returned 0x%x\n", result));
81
82 if (result < 0)
83 goto out;
84 if (scsi_sense_valid(&sshdr)) {
85 switch (sshdr.sense_key) {
86 case ILLEGAL_REQUEST:
87 if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
88 sdev->lockable = 0;
89 else
90 sdev_printk(KERN_INFO, sdev,
91 "ioctl_internal_command: "
92 "ILLEGAL REQUEST "
93 "asc=0x%x ascq=0x%x\n",
94 sshdr.asc, sshdr.ascq);
95 break;
96 case NOT_READY:
97 if (sdev->removable)
98 break;
99 fallthrough;
100 case UNIT_ATTENTION:
101 if (sdev->removable) {
102 sdev->changed = 1;
103 result = 0;
104 break;
105 }
106 fallthrough;
107 default:
108 sdev_printk(KERN_INFO, sdev,
109 "ioctl_internal_command return code = %x\n",
110 result);
111 scsi_print_sense_hdr(sdev, NULL, &sshdr);
112 break;
113 }
114 }
115out:
116 SCSI_LOG_IOCTL(2, sdev_printk(KERN_INFO, sdev,
117 "IOCTL Releasing command\n"));
118 return result;
119}
120
121int scsi_set_medium_removal(struct scsi_device *sdev, char state)
122{
123 char scsi_cmd[MAX_COMMAND_SIZE];
124 int ret;
125
126 if (!sdev->removable || !sdev->lockable)
127 return 0;
128
129 scsi_cmd[0] = ALLOW_MEDIUM_REMOVAL;
130 scsi_cmd[1] = 0;
131 scsi_cmd[2] = 0;
132 scsi_cmd[3] = 0;
133 scsi_cmd[4] = state;
134 scsi_cmd[5] = 0;
135
136 ret = ioctl_internal_command(sdev, scsi_cmd,
137 IOCTL_NORMAL_TIMEOUT, NORMAL_RETRIES);
138 if (ret == 0)
139 sdev->locked = (state == SCSI_REMOVAL_PREVENT);
140 return ret;
141}
142EXPORT_SYMBOL(scsi_set_medium_removal);
143
144
145
146
147
148
149
150
151
152
153
154static int scsi_ioctl_get_pci(struct scsi_device *sdev, void __user *arg)
155{
156 struct device *dev = scsi_get_device(sdev->host);
157 const char *name;
158
159 if (!dev)
160 return -ENXIO;
161
162 name = dev_name(dev);
163
164
165
166 return copy_to_user(arg, name, min(strlen(name), (size_t)20))
167 ? -EFAULT: 0;
168}
169
170static int sg_get_version(int __user *p)
171{
172 static const int sg_version_num = 30527;
173 return put_user(sg_version_num, p);
174}
175
176static int sg_set_timeout(struct scsi_device *sdev, int __user *p)
177{
178 int timeout, err = get_user(timeout, p);
179
180 if (!err)
181 sdev->sg_timeout = clock_t_to_jiffies(timeout);
182
183 return err;
184}
185
186static int sg_get_reserved_size(struct scsi_device *sdev, int __user *p)
187{
188 int val = min(sdev->sg_reserved_size,
189 queue_max_bytes(sdev->request_queue));
190
191 return put_user(val, p);
192}
193
194static int sg_set_reserved_size(struct scsi_device *sdev, int __user *p)
195{
196 int size, err = get_user(size, p);
197
198 if (err)
199 return err;
200
201 if (size < 0)
202 return -EINVAL;
203
204 sdev->sg_reserved_size = min_t(unsigned int, size,
205 queue_max_bytes(sdev->request_queue));
206 return 0;
207}
208
209
210
211
212
213static int sg_emulated_host(struct request_queue *q, int __user *p)
214{
215 return put_user(1, p);
216}
217
218static int scsi_get_idlun(struct scsi_device *sdev, void __user *argp)
219{
220 struct scsi_idlun v = {
221 .dev_id = (sdev->id & 0xff) +
222 ((sdev->lun & 0xff) << 8) +
223 ((sdev->channel & 0xff) << 16) +
224 ((sdev->host->host_no & 0xff) << 24),
225 .host_unique_id = sdev->host->unique_id
226 };
227 if (copy_to_user(argp, &v, sizeof(struct scsi_idlun)))
228 return -EFAULT;
229 return 0;
230}
231
232static int scsi_send_start_stop(struct scsi_device *sdev, int data)
233{
234 u8 cdb[MAX_COMMAND_SIZE] = { };
235
236 cdb[0] = START_STOP;
237 cdb[4] = data;
238 return ioctl_internal_command(sdev, cdb, START_STOP_TIMEOUT,
239 NORMAL_RETRIES);
240}
241
242
243
244
245
246
247
248bool scsi_cmd_allowed(unsigned char *cmd, fmode_t mode)
249{
250
251 if (capable(CAP_SYS_RAWIO))
252 return true;
253
254
255 switch (cmd[0]) {
256
257 case TEST_UNIT_READY:
258 case REQUEST_SENSE:
259 case READ_6:
260 case READ_10:
261 case READ_12:
262 case READ_16:
263 case READ_BUFFER:
264 case READ_DEFECT_DATA:
265 case READ_CAPACITY:
266 case READ_LONG:
267 case INQUIRY:
268 case MODE_SENSE:
269 case MODE_SENSE_10:
270 case LOG_SENSE:
271 case START_STOP:
272 case GPCMD_VERIFY_10:
273 case VERIFY_16:
274 case REPORT_LUNS:
275 case SERVICE_ACTION_IN_16:
276 case RECEIVE_DIAGNOSTIC:
277 case MAINTENANCE_IN:
278 case GPCMD_READ_BUFFER_CAPACITY:
279
280 case GPCMD_PLAY_CD:
281 case GPCMD_PLAY_AUDIO_10:
282 case GPCMD_PLAY_AUDIO_MSF:
283 case GPCMD_PLAY_AUDIO_TI:
284 case GPCMD_PAUSE_RESUME:
285
286 case GPCMD_READ_CD:
287 case GPCMD_READ_CD_MSF:
288 case GPCMD_READ_DISC_INFO:
289 case GPCMD_READ_DVD_STRUCTURE:
290 case GPCMD_READ_HEADER:
291 case GPCMD_READ_TRACK_RZONE_INFO:
292 case GPCMD_READ_SUBCHANNEL:
293 case GPCMD_READ_TOC_PMA_ATIP:
294 case GPCMD_REPORT_KEY:
295 case GPCMD_SCAN:
296 case GPCMD_GET_CONFIGURATION:
297 case GPCMD_READ_FORMAT_CAPACITIES:
298 case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
299 case GPCMD_GET_PERFORMANCE:
300 case GPCMD_SEEK:
301 case GPCMD_STOP_PLAY_SCAN:
302
303 case ZBC_IN:
304 return true;
305
306 case WRITE_6:
307 case WRITE_10:
308 case WRITE_VERIFY:
309 case WRITE_12:
310 case WRITE_VERIFY_12:
311 case WRITE_16:
312 case WRITE_LONG:
313 case WRITE_LONG_2:
314 case WRITE_SAME:
315 case WRITE_SAME_16:
316 case WRITE_SAME_32:
317 case ERASE:
318 case GPCMD_MODE_SELECT_10:
319 case MODE_SELECT:
320 case LOG_SELECT:
321 case GPCMD_BLANK:
322 case GPCMD_CLOSE_TRACK:
323 case GPCMD_FLUSH_CACHE:
324 case GPCMD_FORMAT_UNIT:
325 case GPCMD_REPAIR_RZONE_TRACK:
326 case GPCMD_RESERVE_RZONE_TRACK:
327 case GPCMD_SEND_DVD_STRUCTURE:
328 case GPCMD_SEND_EVENT:
329 case GPCMD_SEND_OPC:
330 case GPCMD_SEND_CUE_SHEET:
331 case GPCMD_SET_SPEED:
332 case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
333 case GPCMD_LOAD_UNLOAD:
334 case GPCMD_SET_STREAMING:
335 case GPCMD_SET_READ_AHEAD:
336
337 case ZBC_OUT:
338 return (mode & FMODE_WRITE);
339 default:
340 return false;
341 }
342}
343EXPORT_SYMBOL(scsi_cmd_allowed);
344
345static int scsi_fill_sghdr_rq(struct scsi_device *sdev, struct request *rq,
346 struct sg_io_hdr *hdr, fmode_t mode)
347{
348 struct scsi_request *req = scsi_req(rq);
349
350 if (copy_from_user(req->cmd, hdr->cmdp, hdr->cmd_len))
351 return -EFAULT;
352 if (!scsi_cmd_allowed(req->cmd, mode))
353 return -EPERM;
354
355
356
357
358 req->cmd_len = hdr->cmd_len;
359
360 rq->timeout = msecs_to_jiffies(hdr->timeout);
361 if (!rq->timeout)
362 rq->timeout = sdev->sg_timeout;
363 if (!rq->timeout)
364 rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
365 if (rq->timeout < BLK_MIN_SG_TIMEOUT)
366 rq->timeout = BLK_MIN_SG_TIMEOUT;
367
368 return 0;
369}
370
371static int scsi_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
372 struct bio *bio)
373{
374 struct scsi_request *req = scsi_req(rq);
375 int r, ret = 0;
376
377
378
379
380 hdr->status = req->result & 0xff;
381 hdr->masked_status = status_byte(req->result);
382 hdr->msg_status = COMMAND_COMPLETE;
383 hdr->host_status = host_byte(req->result);
384 hdr->driver_status = 0;
385 if (scsi_status_is_check_condition(hdr->status))
386 hdr->driver_status = DRIVER_SENSE;
387 hdr->info = 0;
388 if (hdr->masked_status || hdr->host_status || hdr->driver_status)
389 hdr->info |= SG_INFO_CHECK;
390 hdr->resid = req->resid_len;
391 hdr->sb_len_wr = 0;
392
393 if (req->sense_len && hdr->sbp) {
394 int len = min((unsigned int) hdr->mx_sb_len, req->sense_len);
395
396 if (!copy_to_user(hdr->sbp, req->sense, len))
397 hdr->sb_len_wr = len;
398 else
399 ret = -EFAULT;
400 }
401
402 r = blk_rq_unmap_user(bio);
403 if (!ret)
404 ret = r;
405
406 return ret;
407}
408
409static int sg_io(struct scsi_device *sdev, struct gendisk *disk,
410 struct sg_io_hdr *hdr, fmode_t mode)
411{
412 unsigned long start_time;
413 ssize_t ret = 0;
414 int writing = 0;
415 int at_head = 0;
416 struct request *rq;
417 struct scsi_request *req;
418 struct bio *bio;
419
420 if (hdr->interface_id != 'S')
421 return -EINVAL;
422
423 if (hdr->dxfer_len > (queue_max_hw_sectors(sdev->request_queue) << 9))
424 return -EIO;
425
426 if (hdr->dxfer_len)
427 switch (hdr->dxfer_direction) {
428 default:
429 return -EINVAL;
430 case SG_DXFER_TO_DEV:
431 writing = 1;
432 break;
433 case SG_DXFER_TO_FROM_DEV:
434 case SG_DXFER_FROM_DEV:
435 break;
436 }
437 if (hdr->flags & SG_FLAG_Q_AT_HEAD)
438 at_head = 1;
439
440 ret = -ENOMEM;
441 rq = blk_get_request(sdev->request_queue, writing ?
442 REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
443 if (IS_ERR(rq))
444 return PTR_ERR(rq);
445 req = scsi_req(rq);
446
447 if (hdr->cmd_len > BLK_MAX_CDB) {
448 req->cmd = kzalloc(hdr->cmd_len, GFP_KERNEL);
449 if (!req->cmd)
450 goto out_put_request;
451 }
452
453 ret = scsi_fill_sghdr_rq(sdev, rq, hdr, mode);
454 if (ret < 0)
455 goto out_free_cdb;
456
457 ret = 0;
458 if (hdr->iovec_count) {
459 struct iov_iter i;
460 struct iovec *iov = NULL;
461
462 ret = import_iovec(rq_data_dir(rq), hdr->dxferp,
463 hdr->iovec_count, 0, &iov, &i);
464 if (ret < 0)
465 goto out_free_cdb;
466
467
468 iov_iter_truncate(&i, hdr->dxfer_len);
469
470 ret = blk_rq_map_user_iov(rq->q, rq, NULL, &i, GFP_KERNEL);
471 kfree(iov);
472 } else if (hdr->dxfer_len)
473 ret = blk_rq_map_user(rq->q, rq, NULL, hdr->dxferp,
474 hdr->dxfer_len, GFP_KERNEL);
475
476 if (ret)
477 goto out_free_cdb;
478
479 bio = rq->bio;
480 req->retries = 0;
481
482 start_time = jiffies;
483
484 blk_execute_rq(disk, rq, at_head);
485
486 hdr->duration = jiffies_to_msecs(jiffies - start_time);
487
488 ret = scsi_complete_sghdr_rq(rq, hdr, bio);
489
490out_free_cdb:
491 scsi_req_free_cmd(req);
492out_put_request:
493 blk_put_request(rq);
494 return ret;
495}
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531static int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk,
532 fmode_t mode, struct scsi_ioctl_command __user *sic)
533{
534 enum { OMAX_SB_LEN = 16 };
535 struct request *rq;
536 struct scsi_request *req;
537 int err;
538 unsigned int in_len, out_len, bytes, opcode, cmdlen;
539 char *buffer = NULL;
540
541 if (!sic)
542 return -EINVAL;
543
544
545
546
547 if (get_user(in_len, &sic->inlen))
548 return -EFAULT;
549 if (get_user(out_len, &sic->outlen))
550 return -EFAULT;
551 if (in_len > PAGE_SIZE || out_len > PAGE_SIZE)
552 return -EINVAL;
553 if (get_user(opcode, sic->data))
554 return -EFAULT;
555
556 bytes = max(in_len, out_len);
557 if (bytes) {
558 buffer = kzalloc(bytes, GFP_NOIO | GFP_USER | __GFP_NOWARN);
559 if (!buffer)
560 return -ENOMEM;
561
562 }
563
564 rq = blk_get_request(q, in_len ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
565 if (IS_ERR(rq)) {
566 err = PTR_ERR(rq);
567 goto error_free_buffer;
568 }
569 req = scsi_req(rq);
570
571 cmdlen = COMMAND_SIZE(opcode);
572
573
574
575
576 err = -EFAULT;
577 req->cmd_len = cmdlen;
578 if (copy_from_user(req->cmd, sic->data, cmdlen))
579 goto error;
580
581 if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
582 goto error;
583
584 err = -EPERM;
585 if (!scsi_cmd_allowed(req->cmd, mode))
586 goto error;
587
588
589 req->retries = 5;
590
591 switch (opcode) {
592 case SEND_DIAGNOSTIC:
593 case FORMAT_UNIT:
594 rq->timeout = FORMAT_UNIT_TIMEOUT;
595 req->retries = 1;
596 break;
597 case START_STOP:
598 rq->timeout = START_STOP_TIMEOUT;
599 break;
600 case MOVE_MEDIUM:
601 rq->timeout = MOVE_MEDIUM_TIMEOUT;
602 break;
603 case READ_ELEMENT_STATUS:
604 rq->timeout = READ_ELEMENT_STATUS_TIMEOUT;
605 break;
606 case READ_DEFECT_DATA:
607 rq->timeout = READ_DEFECT_DATA_TIMEOUT;
608 req->retries = 1;
609 break;
610 default:
611 rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
612 break;
613 }
614
615 if (bytes) {
616 err = blk_rq_map_kern(q, rq, buffer, bytes, GFP_NOIO);
617 if (err)
618 goto error;
619 }
620
621 blk_execute_rq(disk, rq, 0);
622
623 err = req->result & 0xff;
624 if (err) {
625 if (req->sense_len && req->sense) {
626 bytes = (OMAX_SB_LEN > req->sense_len) ?
627 req->sense_len : OMAX_SB_LEN;
628 if (copy_to_user(sic->data, req->sense, bytes))
629 err = -EFAULT;
630 }
631 } else {
632 if (copy_to_user(sic->data, buffer, out_len))
633 err = -EFAULT;
634 }
635
636error:
637 blk_put_request(rq);
638
639error_free_buffer:
640 kfree(buffer);
641
642 return err;
643}
644
645int put_sg_io_hdr(const struct sg_io_hdr *hdr, void __user *argp)
646{
647#ifdef CONFIG_COMPAT
648 if (in_compat_syscall()) {
649 struct compat_sg_io_hdr hdr32 = {
650 .interface_id = hdr->interface_id,
651 .dxfer_direction = hdr->dxfer_direction,
652 .cmd_len = hdr->cmd_len,
653 .mx_sb_len = hdr->mx_sb_len,
654 .iovec_count = hdr->iovec_count,
655 .dxfer_len = hdr->dxfer_len,
656 .dxferp = (uintptr_t)hdr->dxferp,
657 .cmdp = (uintptr_t)hdr->cmdp,
658 .sbp = (uintptr_t)hdr->sbp,
659 .timeout = hdr->timeout,
660 .flags = hdr->flags,
661 .pack_id = hdr->pack_id,
662 .usr_ptr = (uintptr_t)hdr->usr_ptr,
663 .status = hdr->status,
664 .masked_status = hdr->masked_status,
665 .msg_status = hdr->msg_status,
666 .sb_len_wr = hdr->sb_len_wr,
667 .host_status = hdr->host_status,
668 .driver_status = hdr->driver_status,
669 .resid = hdr->resid,
670 .duration = hdr->duration,
671 .info = hdr->info,
672 };
673
674 if (copy_to_user(argp, &hdr32, sizeof(hdr32)))
675 return -EFAULT;
676
677 return 0;
678 }
679#endif
680
681 if (copy_to_user(argp, hdr, sizeof(*hdr)))
682 return -EFAULT;
683
684 return 0;
685}
686EXPORT_SYMBOL(put_sg_io_hdr);
687
688int get_sg_io_hdr(struct sg_io_hdr *hdr, const void __user *argp)
689{
690#ifdef CONFIG_COMPAT
691 struct compat_sg_io_hdr hdr32;
692
693 if (in_compat_syscall()) {
694 if (copy_from_user(&hdr32, argp, sizeof(hdr32)))
695 return -EFAULT;
696
697 *hdr = (struct sg_io_hdr) {
698 .interface_id = hdr32.interface_id,
699 .dxfer_direction = hdr32.dxfer_direction,
700 .cmd_len = hdr32.cmd_len,
701 .mx_sb_len = hdr32.mx_sb_len,
702 .iovec_count = hdr32.iovec_count,
703 .dxfer_len = hdr32.dxfer_len,
704 .dxferp = compat_ptr(hdr32.dxferp),
705 .cmdp = compat_ptr(hdr32.cmdp),
706 .sbp = compat_ptr(hdr32.sbp),
707 .timeout = hdr32.timeout,
708 .flags = hdr32.flags,
709 .pack_id = hdr32.pack_id,
710 .usr_ptr = compat_ptr(hdr32.usr_ptr),
711 .status = hdr32.status,
712 .masked_status = hdr32.masked_status,
713 .msg_status = hdr32.msg_status,
714 .sb_len_wr = hdr32.sb_len_wr,
715 .host_status = hdr32.host_status,
716 .driver_status = hdr32.driver_status,
717 .resid = hdr32.resid,
718 .duration = hdr32.duration,
719 .info = hdr32.info,
720 };
721
722 return 0;
723 }
724#endif
725
726 if (copy_from_user(hdr, argp, sizeof(*hdr)))
727 return -EFAULT;
728
729 return 0;
730}
731EXPORT_SYMBOL(get_sg_io_hdr);
732
733#ifdef CONFIG_COMPAT
734struct compat_cdrom_generic_command {
735 unsigned char cmd[CDROM_PACKET_SIZE];
736 compat_caddr_t buffer;
737 compat_uint_t buflen;
738 compat_int_t stat;
739 compat_caddr_t sense;
740 unsigned char data_direction;
741 unsigned char pad[3];
742 compat_int_t quiet;
743 compat_int_t timeout;
744 compat_caddr_t unused;
745};
746#endif
747
748static int scsi_get_cdrom_generic_arg(struct cdrom_generic_command *cgc,
749 const void __user *arg)
750{
751#ifdef CONFIG_COMPAT
752 if (in_compat_syscall()) {
753 struct compat_cdrom_generic_command cgc32;
754
755 if (copy_from_user(&cgc32, arg, sizeof(cgc32)))
756 return -EFAULT;
757
758 *cgc = (struct cdrom_generic_command) {
759 .buffer = compat_ptr(cgc32.buffer),
760 .buflen = cgc32.buflen,
761 .stat = cgc32.stat,
762 .sense = compat_ptr(cgc32.sense),
763 .data_direction = cgc32.data_direction,
764 .quiet = cgc32.quiet,
765 .timeout = cgc32.timeout,
766 .unused = compat_ptr(cgc32.unused),
767 };
768 memcpy(&cgc->cmd, &cgc32.cmd, CDROM_PACKET_SIZE);
769 return 0;
770 }
771#endif
772 if (copy_from_user(cgc, arg, sizeof(*cgc)))
773 return -EFAULT;
774
775 return 0;
776}
777
778static int scsi_put_cdrom_generic_arg(const struct cdrom_generic_command *cgc,
779 void __user *arg)
780{
781#ifdef CONFIG_COMPAT
782 if (in_compat_syscall()) {
783 struct compat_cdrom_generic_command cgc32 = {
784 .buffer = (uintptr_t)(cgc->buffer),
785 .buflen = cgc->buflen,
786 .stat = cgc->stat,
787 .sense = (uintptr_t)(cgc->sense),
788 .data_direction = cgc->data_direction,
789 .quiet = cgc->quiet,
790 .timeout = cgc->timeout,
791 .unused = (uintptr_t)(cgc->unused),
792 };
793 memcpy(&cgc32.cmd, &cgc->cmd, CDROM_PACKET_SIZE);
794
795 if (copy_to_user(arg, &cgc32, sizeof(cgc32)))
796 return -EFAULT;
797
798 return 0;
799 }
800#endif
801 if (copy_to_user(arg, cgc, sizeof(*cgc)))
802 return -EFAULT;
803
804 return 0;
805}
806
807static int scsi_cdrom_send_packet(struct scsi_device *sdev, struct gendisk *disk,
808 fmode_t mode, void __user *arg)
809{
810 struct cdrom_generic_command cgc;
811 struct sg_io_hdr hdr;
812 int err;
813
814 err = scsi_get_cdrom_generic_arg(&cgc, arg);
815 if (err)
816 return err;
817
818 cgc.timeout = clock_t_to_jiffies(cgc.timeout);
819 memset(&hdr, 0, sizeof(hdr));
820 hdr.interface_id = 'S';
821 hdr.cmd_len = sizeof(cgc.cmd);
822 hdr.dxfer_len = cgc.buflen;
823 switch (cgc.data_direction) {
824 case CGC_DATA_UNKNOWN:
825 hdr.dxfer_direction = SG_DXFER_UNKNOWN;
826 break;
827 case CGC_DATA_WRITE:
828 hdr.dxfer_direction = SG_DXFER_TO_DEV;
829 break;
830 case CGC_DATA_READ:
831 hdr.dxfer_direction = SG_DXFER_FROM_DEV;
832 break;
833 case CGC_DATA_NONE:
834 hdr.dxfer_direction = SG_DXFER_NONE;
835 break;
836 default:
837 return -EINVAL;
838 }
839
840 hdr.dxferp = cgc.buffer;
841 hdr.sbp = cgc.sense;
842 if (hdr.sbp)
843 hdr.mx_sb_len = sizeof(struct request_sense);
844 hdr.timeout = jiffies_to_msecs(cgc.timeout);
845 hdr.cmdp = ((struct cdrom_generic_command __user *) arg)->cmd;
846 hdr.cmd_len = sizeof(cgc.cmd);
847
848 err = sg_io(sdev, disk, &hdr, mode);
849 if (err == -EFAULT)
850 return -EFAULT;
851
852 if (hdr.status)
853 return -EIO;
854
855 cgc.stat = err;
856 cgc.buflen = hdr.resid;
857 if (scsi_put_cdrom_generic_arg(&cgc, arg))
858 return -EFAULT;
859
860 return err;
861}
862
863static int scsi_ioctl_sg_io(struct scsi_device *sdev, struct gendisk *disk,
864 fmode_t mode, void __user *argp)
865{
866 struct sg_io_hdr hdr;
867 int error;
868
869 error = get_sg_io_hdr(&hdr, argp);
870 if (error)
871 return error;
872 error = sg_io(sdev, disk, &hdr, mode);
873 if (error == -EFAULT)
874 return error;
875 if (put_sg_io_hdr(&hdr, argp))
876 return -EFAULT;
877 return error;
878}
879
880
881
882
883
884
885
886
887
888
889
890
891
892int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode,
893 int cmd, void __user *arg)
894{
895 struct request_queue *q = sdev->request_queue;
896 struct scsi_sense_hdr sense_hdr;
897
898
899
900 switch (cmd) {
901 case SCSI_IOCTL_SEND_COMMAND:
902 case SCSI_IOCTL_TEST_UNIT_READY:
903 case SCSI_IOCTL_BENCHMARK_COMMAND:
904 case SCSI_IOCTL_SYNC:
905 case SCSI_IOCTL_START_UNIT:
906 case SCSI_IOCTL_STOP_UNIT:
907 printk(KERN_WARNING "program %s is using a deprecated SCSI "
908 "ioctl, please convert it to SG_IO\n", current->comm);
909 break;
910 default:
911 break;
912 }
913
914 switch (cmd) {
915 case SG_GET_VERSION_NUM:
916 return sg_get_version(arg);
917 case SG_SET_TIMEOUT:
918 return sg_set_timeout(sdev, arg);
919 case SG_GET_TIMEOUT:
920 return jiffies_to_clock_t(sdev->sg_timeout);
921 case SG_GET_RESERVED_SIZE:
922 return sg_get_reserved_size(sdev, arg);
923 case SG_SET_RESERVED_SIZE:
924 return sg_set_reserved_size(sdev, arg);
925 case SG_EMULATED_HOST:
926 return sg_emulated_host(q, arg);
927 case SG_IO:
928 return scsi_ioctl_sg_io(sdev, disk, mode, arg);
929 case SCSI_IOCTL_SEND_COMMAND:
930 return sg_scsi_ioctl(q, disk, mode, arg);
931 case CDROM_SEND_PACKET:
932 return scsi_cdrom_send_packet(sdev, disk, mode, arg);
933 case CDROMCLOSETRAY:
934 return scsi_send_start_stop(sdev, 3);
935 case CDROMEJECT:
936 return scsi_send_start_stop(sdev, 2);
937 case SCSI_IOCTL_GET_IDLUN:
938 return scsi_get_idlun(sdev, arg);
939 case SCSI_IOCTL_GET_BUS_NUMBER:
940 return put_user(sdev->host->host_no, (int __user *)arg);
941 case SCSI_IOCTL_PROBE_HOST:
942 return ioctl_probe(sdev->host, arg);
943 case SCSI_IOCTL_DOORLOCK:
944 return scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
945 case SCSI_IOCTL_DOORUNLOCK:
946 return scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
947 case SCSI_IOCTL_TEST_UNIT_READY:
948 return scsi_test_unit_ready(sdev, IOCTL_NORMAL_TIMEOUT,
949 NORMAL_RETRIES, &sense_hdr);
950 case SCSI_IOCTL_START_UNIT:
951 return scsi_send_start_stop(sdev, 1);
952 case SCSI_IOCTL_STOP_UNIT:
953 return scsi_send_start_stop(sdev, 0);
954 case SCSI_IOCTL_GET_PCI:
955 return scsi_ioctl_get_pci(sdev, arg);
956 case SG_SCSI_RESET:
957 return scsi_ioctl_reset(sdev, arg);
958 }
959
960#ifdef CONFIG_COMPAT
961 if (in_compat_syscall()) {
962 if (!sdev->host->hostt->compat_ioctl)
963 return -EINVAL;
964 return sdev->host->hostt->compat_ioctl(sdev, cmd, arg);
965 }
966#endif
967 if (!sdev->host->hostt->ioctl)
968 return -EINVAL;
969 return sdev->host->hostt->ioctl(sdev, cmd, arg);
970}
971EXPORT_SYMBOL(scsi_ioctl);
972
973
974
975
976int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev, int cmd,
977 bool ndelay)
978{
979 if (cmd == SG_SCSI_RESET && ndelay) {
980 if (scsi_host_in_recovery(sdev->host))
981 return -EAGAIN;
982 } else {
983 if (!scsi_block_when_processing_errors(sdev))
984 return -ENODEV;
985 }
986
987 return 0;
988}
989EXPORT_SYMBOL_GPL(scsi_ioctl_block_when_processing_errors);
990