summaryrefslogtreecommitdiff
path: root/drivers/scsi/st.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2025-12-05 19:56:50 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2025-12-05 19:56:50 -0800
commit7eb7f5723df50a7d5564aa609e4c147f669a5cb4 (patch)
tree495927c82f799fad6bafa9069773db94c454cbd7 /drivers/scsi/st.c
parent3af870aedbff10bfed220e280b57a405e972229f (diff)
parent82f78acd5a9270370ef4aa3f032ede25f3dc91ee (diff)
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley: "Usual driver updates (ufs, lpfc, target, qla2xxx) plus assorted cleanups and fixes including the WQ_PERCPU series. The biggest core change is the new allocation of pseudo-devices which allow the sending of internal commands to a given SCSI target" * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (147 commits) scsi: MAINTAINERS: Add the UFS include directory scsi: scsi_debug: Support injecting unaligned write errors scsi: qla2xxx: Fix improper freeing of purex item scsi: ufs: rockchip: Fix compile error without CONFIG_GPIOLIB scsi: ufs: rockchip: Reset controller on PRE_CHANGE of hce enable notify scsi: ufs: core: Use scsi_device_busy() scsi: ufs: core: Fix single doorbell mode support scsi: pm80xx: Add WQ_PERCPU to alloc_workqueue() users scsi: target: Add WQ_PERCPU to alloc_workqueue() users scsi: qedi: Add WQ_PERCPU to alloc_workqueue() users scsi: target: ibmvscsi: Add WQ_PERCPU to alloc_workqueue() users scsi: qedf: Add WQ_PERCPU to alloc_workqueue() users scsi: bnx2fc: Add WQ_PERCPU to alloc_workqueue() users scsi: be2iscsi: Add WQ_PERCPU to alloc_workqueue() users scsi: message: fusion: Add WQ_PERCPU to alloc_workqueue() users scsi: lpfc: WQ_PERCPU added to alloc_workqueue() users scsi: scsi_transport_fc: WQ_PERCPU added to alloc_workqueue users() scsi: scsi_dh_alua: WQ_PERCPU added to alloc_workqueue() users scsi: qla2xxx: WQ_PERCPU added to alloc_workqueue() users scsi: target: sbp: Replace use of system_unbound_wq with system_dfl_wq ...
Diffstat (limited to 'drivers/scsi/st.c')
-rw-r--r--drivers/scsi/st.c89
1 files changed, 66 insertions, 23 deletions
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 74a6830b7ed8..168f25e4aaa3 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3526,8 +3526,64 @@ static int partition_tape(struct scsi_tape *STp, int size)
out:
return result;
}
-
+/*
+ * Handles any extra state needed for ioctls which are not st-specific.
+ * Called with the scsi_tape lock held, released before return
+ */
+static long st_common_ioctl(struct scsi_tape *STp, struct st_modedef *STm,
+ struct file *file, unsigned int cmd_in,
+ unsigned long arg)
+{
+ int i, retval = 0;
+
+ if (!STm->defined) {
+ retval = -ENXIO;
+ goto out;
+ }
+
+ switch (cmd_in) {
+ case SCSI_IOCTL_GET_IDLUN:
+ case SCSI_IOCTL_GET_BUS_NUMBER:
+ case SCSI_IOCTL_GET_PCI:
+ break;
+ case SG_IO:
+ case SCSI_IOCTL_SEND_COMMAND:
+ case CDROM_SEND_PACKET:
+ if (!capable(CAP_SYS_RAWIO)) {
+ retval = -EPERM;
+ goto out;
+ }
+ fallthrough;
+ default:
+ if ((i = flush_buffer(STp, 0)) < 0) {
+ retval = i;
+ goto out;
+ } else { /* flush_buffer succeeds */
+ if (STp->can_partitions) {
+ i = switch_partition(STp);
+ if (i < 0) {
+ retval = i;
+ goto out;
+ }
+ }
+ }
+ }
+ mutex_unlock(&STp->lock);
+
+ retval = scsi_ioctl(STp->device, file->f_mode & FMODE_WRITE,
+ cmd_in, (void __user *)arg);
+ if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) {
+ /* unload */
+ STp->rew_at_close = 0;
+ STp->ready = ST_NO_TAPE;
+ }
+
+ return retval;
+out:
+ mutex_unlock(&STp->lock);
+ return retval;
+}
/* The ioctl command */
static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
@@ -3565,6 +3621,15 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
if (retval)
goto out;
+ switch (cmd_in) {
+ case MTIOCPOS:
+ case MTIOCGET:
+ case MTIOCTOP:
+ break;
+ default:
+ return st_common_ioctl(STp, STm, file, cmd_in, arg);
+ }
+
cmd_type = _IOC_TYPE(cmd_in);
cmd_nr = _IOC_NR(cmd_in);
@@ -3876,29 +3941,7 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
}
mt_pos.mt_blkno = blk;
retval = put_user_mtpos(p, &mt_pos);
- goto out;
- }
- mutex_unlock(&STp->lock);
-
- switch (cmd_in) {
- case SG_IO:
- case SCSI_IOCTL_SEND_COMMAND:
- case CDROM_SEND_PACKET:
- if (!capable(CAP_SYS_RAWIO))
- return -EPERM;
- break;
- default:
- break;
}
-
- retval = scsi_ioctl(STp->device, file->f_mode & FMODE_WRITE, cmd_in, p);
- if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) {
- /* unload */
- STp->rew_at_close = 0;
- STp->ready = ST_NO_TAPE;
- }
- return retval;
-
out:
mutex_unlock(&STp->lock);
return retval;