520 int scsi_cmd_ioctl(struct file *file, struct gendisk *bd_disk, unsigned int cmd, void __user *arg) 521 { 522 request_queue_t *q; 523 int err; 524 525 q = bd_disk-queue; 526 if (!q) 527 return -ENXIO; 528 529 if (blk_get_queue(q)) 530 r
520 int scsi_cmd_ioctl(struct file *file, struct gendisk *bd_disk, unsigned int cmd, void __user *arg)
521 {
522request_queue_t *q;
523int err;
524
525q = bd_disk->queue;
526if (!q)
527return -ENXIO;
528
529if (blk_get_queue(q))
530return -ENXIO;
531
532switch (cmd) {
533/*
534* new sgv3 interface
535*/
536case SG_GET_VERSION_NUM:
537err = sg_get_version(arg);
538break;
539case SCSI_IOCTL_GET_IDLUN:
540err = scsi_get_idlun(q, arg);
541break;
542case SCSI_IOCTL_GET_BUS_NUMBER:
543err = scsi_get_bus(q, arg);
544break;
545case SG_SET_TIMEOUT:
546err = sg_set_timeout(q, arg);
547break;
548case SG_GET_TIMEOUT:
549err = sg_get_timeout(q);
550break;
551case SG_GET_RESERVED_SIZE:
552err = sg_get_reserved_size(q, arg);
553break;
554case SG_SET_RESERVED_SIZE:
555err = sg_set_reserved_size(q, arg);
556break;
557case SG_EMULATED_HOST:
558err = sg_emulated_host(q, arg);
559break;
560case SG_IO: {
561struct sg_io_hdr hdr;
562
563err = -EFAULT;
564if (copy_from_user(&hdr, arg, sizeof(hdr)))
565break;
566err = sg_io(file, q, bd_disk, &hdr);
567if (err == -EFAULT)
568break;
569
570if (copy_to_user(arg, &hdr, sizeof(hdr)))
571err = -EFAULT;
572break;
573}
574case CDROM_SEND_PACKET: {
575struct cdrom_generic_command cgc;
576struct sg_io_hdr hdr;
577
578err = -EFAULT;
579if (copy_from_user(&cgc, arg, sizeof(cgc)))
580break;
581cgc.timeout = clock_t_to_jiffies(cgc.timeout);
582memset(&hdr, 0, sizeof(hdr));
583hdr.interface_id = 'S';
584hdr.cmd_len = sizeof(cgc.cmd);
585hdr.dxfer_len = cgc.buflen;
586err = 0;
587switch (cgc.data_direction) {
588case CGC_DATA_UNKNOWN:
589hdr.dxfer_direction = SG_DXFER_UNKNOWN;
590break;
591case CGC_DATA_WRITE:
592hdr.dxfer_direction = SG_DXFER_TO_DEV;
593break;
594case CGC_DATA_READ:
595hdr.dxfer_direction = SG_DXFER_FROM_DEV;
596break;
597case CGC_DATA_NONE:
598hdr.dxfer_direction = SG_DXFER_NONE;
599break;
600default:
601err = -EINVAL;
602}
603if (err)
604break;
605
606hdr.dxferp = cgc.buffer;
607hdr.sbp = cgc.sense;
608if (hdr.sbp)
609hdr.mx_sb_len = sizeof(struct request_sense);
610hdr.timeout = cgc.timeout;
611hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd;
612hdr.cmd_len = sizeof(cgc.cmd);
613
614err = sg_io(file, q, bd_disk, &hdr);
615if (err == -EFAULT)
616break;
617
618if (hdr.status)
619err = -EIO;
620
621cgc.stat = err;
622cgc.buflen = hdr.resid;
623if (copy_to_user(arg, &cgc, sizeof(cgc)))
624err = -EFAULT;
625
626break;
627}
628
629/*
630* old junk scsi send command ioctl
631*/
632case SCSI_IOCTL_SEND_COMMAND:
633printk(KERN_WARNING "program %s is using a deprecated SCSI ioctl, please convert it to SG_IO/n", current->comm);
634err = -EINVAL;
635if (!arg)
636break;
637
638err = sg_scsi_ioctl(file, q, bd_disk, arg);
639break;
640case CDROMCLOSETRAY:
641err = blk_send_start_stop(q, bd_disk, 0x03);
642break;
643case CDROMEJECT:
644err = blk_send_start_stop(q, bd_disk, 0x02);
645break;
646default:
647err = -ENOTTY;
648}
649
650blk_put_queue(q);
651return err;
652 }