diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/bsg.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/block/bsg.c b/block/bsg.c index 6d139d20ec99..9dc5d36a52e5 100644 --- a/block/bsg.c +++ b/block/bsg.c | |||
@@ -945,8 +945,27 @@ bsg_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
945 | void __user *uarg = (void __user *) arg; | 945 | void __user *uarg = (void __user *) arg; |
946 | return scsi_cmd_ioctl(file, bd->disk, cmd, uarg); | 946 | return scsi_cmd_ioctl(file, bd->disk, cmd, uarg); |
947 | } | 947 | } |
948 | case SG_IO: | 948 | case SG_IO: { |
949 | return -EINVAL; | 949 | struct request *rq; |
950 | struct bio *bio; | ||
951 | struct sg_io_v4 hdr; | ||
952 | |||
953 | if (copy_from_user(&hdr, uarg, sizeof(hdr))) | ||
954 | return -EFAULT; | ||
955 | |||
956 | rq = bsg_map_hdr(bd, &hdr); | ||
957 | if (IS_ERR(rq)) | ||
958 | return PTR_ERR(rq); | ||
959 | |||
960 | bio = rq->bio; | ||
961 | blk_execute_rq(bd->queue, bd->disk, rq, 0); | ||
962 | blk_complete_sgv4_hdr_rq(rq, &hdr, bio); | ||
963 | |||
964 | if (copy_to_user(uarg, &hdr, sizeof(hdr))) | ||
965 | return -EFAULT; | ||
966 | else | ||
967 | return 0; | ||
968 | } | ||
950 | /* | 969 | /* |
951 | * block device ioctls | 970 | * block device ioctls |
952 | */ | 971 | */ |