linux那些事儿之我是scsi硬盘,Linux那些事儿之我是SCSI硬盘(7)从应用层走来的ioctl - fudan...

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 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值