scsi: scsi_ioctl: Call scsi_cmd_ioctl() from scsi_ioctl()
Ensure SCSI ULD only has to call a single ioctl helper. This also adds a bunch of missing ioctls to the ch driver, and removes the need for a duplicate implementation of SCSI_IOCTL_SEND_COMMAND command. Link: https://lore.kernel.org/r/20210724072033.1284840-12-hch@lst.de Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
4f07bfc561
commit
2e27f576ab
|
@ -877,7 +877,7 @@ static long ch_ioctl(struct file *file,
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return scsi_ioctl(ch->device, cmd, argp);
|
return scsi_ioctl(ch->device, NULL, file->f_mode, cmd, argp);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,6 +192,8 @@ static int scsi_ioctl_get_pci(struct scsi_device *sdev, void __user *arg)
|
||||||
/**
|
/**
|
||||||
* scsi_ioctl - Dispatch ioctl to scsi device
|
* scsi_ioctl - Dispatch ioctl to scsi device
|
||||||
* @sdev: scsi device receiving ioctl
|
* @sdev: scsi device receiving ioctl
|
||||||
|
* @disk: disk receiving the ioctl
|
||||||
|
* @mode: mode the block/char device is opened with
|
||||||
* @cmd: which ioctl is it
|
* @cmd: which ioctl is it
|
||||||
* @arg: data associated with ioctl
|
* @arg: data associated with ioctl
|
||||||
*
|
*
|
||||||
|
@ -199,10 +201,13 @@ static int scsi_ioctl_get_pci(struct scsi_device *sdev, void __user *arg)
|
||||||
* does not take a major/minor number as the dev field. Rather, it takes
|
* does not take a major/minor number as the dev field. Rather, it takes
|
||||||
* a pointer to a &struct scsi_device.
|
* a pointer to a &struct scsi_device.
|
||||||
*/
|
*/
|
||||||
int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
|
int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode,
|
||||||
|
int cmd, void __user *arg)
|
||||||
{
|
{
|
||||||
|
struct request_queue *q = sdev->request_queue;
|
||||||
char scsi_cmd[MAX_COMMAND_SIZE];
|
char scsi_cmd[MAX_COMMAND_SIZE];
|
||||||
struct scsi_sense_hdr sense_hdr;
|
struct scsi_sense_hdr sense_hdr;
|
||||||
|
int error;
|
||||||
|
|
||||||
/* Check for deprecated ioctls ... all the ioctls which don't
|
/* Check for deprecated ioctls ... all the ioctls which don't
|
||||||
* follow the new unique numbering scheme are deprecated */
|
* follow the new unique numbering scheme are deprecated */
|
||||||
|
@ -220,6 +225,12 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cmd != SCSI_IOCTL_GET_IDLUN && cmd != SCSI_IOCTL_GET_BUS_NUMBER) {
|
||||||
|
error = scsi_cmd_ioctl(q, disk, mode, cmd, arg);
|
||||||
|
if (error != -ENOTTY)
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SCSI_IOCTL_GET_IDLUN: {
|
case SCSI_IOCTL_GET_IDLUN: {
|
||||||
struct scsi_idlun v = {
|
struct scsi_idlun v = {
|
||||||
|
@ -237,10 +248,6 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
|
||||||
return put_user(sdev->host->host_no, (int __user *)arg);
|
return put_user(sdev->host->host_no, (int __user *)arg);
|
||||||
case SCSI_IOCTL_PROBE_HOST:
|
case SCSI_IOCTL_PROBE_HOST:
|
||||||
return ioctl_probe(sdev->host, arg);
|
return ioctl_probe(sdev->host, arg);
|
||||||
case SCSI_IOCTL_SEND_COMMAND:
|
|
||||||
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
|
|
||||||
return -EACCES;
|
|
||||||
return sg_scsi_ioctl(sdev->request_queue, NULL, 0, arg);
|
|
||||||
case SCSI_IOCTL_DOORLOCK:
|
case SCSI_IOCTL_DOORLOCK:
|
||||||
return scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
|
return scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
|
||||||
case SCSI_IOCTL_DOORUNLOCK:
|
case SCSI_IOCTL_DOORUNLOCK:
|
||||||
|
|
|
@ -1571,23 +1571,7 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
|
||||||
|
|
||||||
if (is_sed_ioctl(cmd))
|
if (is_sed_ioctl(cmd))
|
||||||
return sed_ioctl(sdkp->opal_dev, cmd, p);
|
return sed_ioctl(sdkp->opal_dev, cmd, p);
|
||||||
|
return scsi_ioctl(sdp, disk, mode, cmd, p);
|
||||||
/*
|
|
||||||
* Send SCSI addressing ioctls directly to mid level, send other
|
|
||||||
* ioctls to block level and then onto mid level if they can't be
|
|
||||||
* resolved.
|
|
||||||
*/
|
|
||||||
switch (cmd) {
|
|
||||||
case SCSI_IOCTL_GET_IDLUN:
|
|
||||||
case SCSI_IOCTL_GET_BUS_NUMBER:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, p);
|
|
||||||
if (error != -ENOTTY)
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return scsi_ioctl(sdp, cmd, p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_media_not_present(struct scsi_disk *sdkp)
|
static void set_media_not_present(struct scsi_disk *sdkp)
|
||||||
|
|
|
@ -1165,7 +1165,7 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
|
||||||
ret = sg_ioctl_common(filp, sdp, sfp, cmd_in, p);
|
ret = sg_ioctl_common(filp, sdp, sfp, cmd_in, p);
|
||||||
if (ret != -ENOIOCTLCMD)
|
if (ret != -ENOIOCTLCMD)
|
||||||
return ret;
|
return ret;
|
||||||
return scsi_ioctl(sdp->device, cmd_in, p);
|
return scsi_ioctl(sdp->device, NULL, filp->f_mode, cmd_in, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __poll_t
|
static __poll_t
|
||||||
|
|
|
@ -574,24 +574,12 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
|
||||||
|
|
||||||
scsi_autopm_get_device(sdev);
|
scsi_autopm_get_device(sdev);
|
||||||
|
|
||||||
/*
|
if (ret != CDROMCLOSETRAY && ret != CDROMEJECT) {
|
||||||
* Send SCSI addressing ioctls directly to mid level, send other
|
|
||||||
* ioctls to cdrom/block level.
|
|
||||||
*/
|
|
||||||
switch (cmd) {
|
|
||||||
case SCSI_IOCTL_GET_IDLUN:
|
|
||||||
case SCSI_IOCTL_GET_BUS_NUMBER:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp);
|
|
||||||
if (ret != -ENOTTY)
|
|
||||||
goto put;
|
|
||||||
ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg);
|
ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg);
|
||||||
if (ret != -ENOSYS)
|
if (ret != -ENOSYS)
|
||||||
goto put;
|
goto put;
|
||||||
}
|
}
|
||||||
|
ret = scsi_ioctl(sdev, disk, mode, cmd, argp);
|
||||||
ret = scsi_ioctl(sdev, cmd, argp);
|
|
||||||
|
|
||||||
put:
|
put:
|
||||||
scsi_autopm_put_device(sdev);
|
scsi_autopm_put_device(sdev);
|
||||||
|
|
|
@ -3823,24 +3823,16 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
|
||||||
mutex_unlock(&STp->lock);
|
mutex_unlock(&STp->lock);
|
||||||
|
|
||||||
switch (cmd_in) {
|
switch (cmd_in) {
|
||||||
case SCSI_IOCTL_GET_IDLUN:
|
|
||||||
case SCSI_IOCTL_GET_BUS_NUMBER:
|
|
||||||
break;
|
|
||||||
case SG_IO:
|
case SG_IO:
|
||||||
case SCSI_IOCTL_SEND_COMMAND:
|
case SCSI_IOCTL_SEND_COMMAND:
|
||||||
case CDROM_SEND_PACKET:
|
case CDROM_SEND_PACKET:
|
||||||
if (!capable(CAP_SYS_RAWIO))
|
if (!capable(CAP_SYS_RAWIO))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
fallthrough;
|
|
||||||
default:
|
default:
|
||||||
retval = scsi_cmd_ioctl(STp->disk->queue, STp->disk,
|
|
||||||
file->f_mode, cmd_in, p);
|
|
||||||
if (retval != -ENOTTY)
|
|
||||||
return retval;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = scsi_ioctl(STp->device, cmd_in, p);
|
retval = scsi_ioctl(STp->device, STp->disk, file->f_mode, cmd_in, p);
|
||||||
if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) {
|
if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) {
|
||||||
/* unload */
|
/* unload */
|
||||||
STp->rew_at_close = 0;
|
STp->rew_at_close = 0;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
|
struct gendisk;
|
||||||
struct scsi_device;
|
struct scsi_device;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -43,7 +44,8 @@ typedef struct scsi_fctargaddress {
|
||||||
|
|
||||||
int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev,
|
int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev,
|
||||||
int cmd, bool ndelay);
|
int cmd, bool ndelay);
|
||||||
extern int scsi_ioctl(struct scsi_device *, int, void __user *);
|
int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode,
|
||||||
|
int cmd, void __user *arg);
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
#endif /* _SCSI_IOCTL_H */
|
#endif /* _SCSI_IOCTL_H */
|
||||||
|
|
Loading…
Reference in New Issue