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 return -ENXIO;

531

532 switch (cmd) {

533 /*

534 * new sgv3 interface

535 */

536 case SG_GET_VERSION_NUM:

537 err = sg_get_version(arg);

538 break;

539 case SCSI_IOCTL_GET_IDLUN:

540 err = scsi_get_idlun(q, arg);

541 break;

542 case SCSI_IOCTL_GET_BUS_NUMBER:

543 err = scsi_get_bus(q, arg);

544 break;

545 case SG_SET_TIMEOUT:

546 err = sg_set_timeout(q, arg);

547 break;

548 case SG_GET_TIMEOUT:

549 err = sg_get_timeout(q);

550 break;

551 case SG_GET_RESERVED_SIZE:

552 err = sg_get_reserved_size(q, arg);

553 break;

554 case SG_SET_RESERVED_SIZE:

555 err = sg_set_reserved_size(q, arg);

556 break;

557 case SG_EMULATED_HOST:

558 err = sg_emulated_host(q, arg);

559 break;

560 case SG_IO: {

561 struct sg_io_hdr hdr;

562

563 err = -EFAULT;

564 if (copy_from_user(&hdr, arg, sizeof(hdr)))

565 break;

566 err = sg_io(file, q, bd_disk, &hdr);

567 if (err == -EFAULT)

568 break;

569

570 if (copy_to_user(arg, &hdr, sizeof(hdr)))

571 err = -EFAULT;

572 break;

573 }

574 case CDROM_SEND_PACKET: {

575 struct cdrom_generic_command cgc;

576 struct sg_io_hdr hdr;

577

578 err = -EFAULT;

579 if (copy_from_user(&cgc, arg, sizeof(cgc)))

580 break;

581 cgc.timeout = clock_t_to_jiffies(cgc.timeout);

582 memset(&hdr, 0, sizeof(hdr));

583 hdr.interface_id = ‘S’;

584 hdr.cmd_len = sizeof(cgc.cmd);

585 hdr.dxfer_len = cgc.buflen;

586 err = 0;

587 switch (cgc.data_direction) {

588 case CGC_DATA_UNKNOWN:

589 hdr.dxfer_direction = SG_DXFER_UNKNOWN;

590 break;

591 case CGC_DATA_WRITE:

592 hdr.dxfer_direction = SG_DXFER_TO_DEV;

593 break;

594 case CGC_DATA_READ:

595 hdr.dxfer_direction = SG_DXFER_FROM_DEV;

596 break;

597 case CGC_DATA_NONE:

598 hdr.dxfer_direction = SG_DXFER_NONE;

599 break;

600 default:

601 err = -EINVAL;

602 }

603 if (err)

604 break;

605

606 hdr.dxferp = cgc.buffer;

607 hdr.sbp = cgc.sense;

608 if (hdr.sbp)

609 hdr.mx_sb_len = sizeof(struct request_sense);

610 hdr.timeout = cgc.timeout;

611 hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd;

612 hdr.cmd_len = sizeof(cgc.cmd);

613

614 err = sg_io(file, q, bd_disk, &hdr);

615 if (err == -EFAULT)

616 break;

617

618 if (hdr.status)

619 err = -EIO;

620

621 cgc.stat = err;

622 cgc.buflen = hdr.resid;

623 if (copy_to_user(arg, &cgc, sizeof(cgc)))

624 err = -EFAULT;

625

626 break;

627 }

628

629 /*

630 * old junk scsi send command ioctl

631 */

632 case SCSI_IOCTL_SEND_COMMAND:

633 printk(KERN_WARNING "program %s is using a deprecated SCSI ioctl, please convert it to SG_IO/ n", current->comm);

634 err = -EINVAL;

635 if (!arg)

636 break;

637

638 err = sg_scsi_ioctl(file, q, bd_disk, arg);

639 break;

640 case CDROMCLOSETRAY:

641 err = blk_send_start_stop(q, bd_disk, 0x03);

642 break;

643 case CDROMEJECT:

644 err = blk_send_start_stop(q, bd_disk, 0x02);

645 break;

646 default:

647 err = -ENOTTY;

648 }

649

650 blk_put_queue(q);

651 return err;

652 }

爱情使人忘记时间,时间也使人忘记爱情。

Linux那些事儿之我是SCSI硬盘(7)从应用层走来的ioctl – fudan

相关文章:

你感兴趣的文章:

标签云: