linux/drivers/scsi/scsi_ioctl.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Changes:
 * Arnaldo Carvalho de Melo <[email protected]> 08/23/2000
 * - get rid of some verify_areas and use __copy*user and __get/put_user
 *   for the ones that remain
 */
#include <linux/module.h>
#include <linux/blkdev.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/cdrom.h>

#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/sg.h>
#include <scsi/scsi_dbg.h>

#include "scsi_logging.h"

#define NORMAL_RETRIES
#define IOCTL_NORMAL_TIMEOUT

#define MAX_BUF

/**
 * ioctl_probe  --  return host identification
 * @host:	host to identify
 * @buffer:	userspace buffer for identification
 *
 * Return an identifying string at @buffer, if @buffer is non-NULL, filling
 * to the length stored at * (int *) @buffer.
 */
static int ioctl_probe(struct Scsi_Host *host, void __user *buffer)
{}

static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
				  int timeout, int retries)
{}

int scsi_set_medium_removal(struct scsi_device *sdev, char state)
{}
EXPORT_SYMBOL();

/*
 * The scsi_ioctl_get_pci() function places into arg the value
 * pci_dev::slot_name (8 characters) for the PCI device (if any).
 * Returns: 0 on success
 *          -ENXIO if there isn't a PCI device pointer
 *                 (could be because the SCSI driver hasn't been
 *                  updated yet, or because it isn't a SCSI
 *                  device)
 *          any copy_to_user() error on failure there
 */
static int scsi_ioctl_get_pci(struct scsi_device *sdev, void __user *arg)
{}

static int sg_get_version(int __user *p)
{}

static int sg_set_timeout(struct scsi_device *sdev, int __user *p)
{}

static int sg_get_reserved_size(struct scsi_device *sdev, int __user *p)
{}

static int sg_set_reserved_size(struct scsi_device *sdev, int __user *p)
{}

/*
 * will always return that we are ATAPI even for a real SCSI drive, I'm not
 * so sure this is worth doing anything about (why would you care??)
 */
static int sg_emulated_host(struct request_queue *q, int __user *p)
{}

static int scsi_get_idlun(struct scsi_device *sdev, void __user *argp)
{}

static int scsi_send_start_stop(struct scsi_device *sdev, int data)
{}

/*
 * Check if the given command is allowed.
 *
 * Only a subset of commands are allowed for unprivileged users. Commands used
 * to format the media, update the firmware, etc. are not permitted.
 */
bool scsi_cmd_allowed(unsigned char *cmd, bool open_for_write)
{}
EXPORT_SYMBOL();

static int scsi_fill_sghdr_rq(struct scsi_device *sdev, struct request *rq,
		struct sg_io_hdr *hdr, bool open_for_write)
{}

static int scsi_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
		struct bio *bio)
{}

static int sg_io(struct scsi_device *sdev, struct sg_io_hdr *hdr,
		bool open_for_write)
{}

/**
 * sg_scsi_ioctl  --  handle deprecated SCSI_IOCTL_SEND_COMMAND ioctl
 * @q:		request queue to send scsi commands down
 * @open_for_write: is the file / block device opened for writing?
 * @sic:	userspace structure describing the command to perform
 *
 * Send down the scsi command described by @sic to the device below
 * the request queue @q.
 *
 * Notes:
 *   -  This interface is deprecated - users should use the SG_IO
 *      interface instead, as this is a more flexible approach to
 *      performing SCSI commands on a device.
 *   -  The SCSI command length is determined by examining the 1st byte
 *      of the given command. There is no way to override this.
 *   -  Data transfers are limited to PAGE_SIZE
 *   -  The length (x + y) must be at least OMAX_SB_LEN bytes long to
 *      accommodate the sense buffer when an error occurs.
 *      The sense buffer is truncated to OMAX_SB_LEN (16) bytes so that
 *      old code will not be surprised.
 *   -  If a Unix error occurs (e.g. ENOMEM) then the user will receive
 *      a negative return and the Unix error code in 'errno'.
 *      If the SCSI command succeeds then 0 is returned.
 *      Positive numbers returned are the compacted SCSI error codes (4
 *      bytes in one int) where the lowest byte is the SCSI status.
 */
static int sg_scsi_ioctl(struct request_queue *q, bool open_for_write,
		struct scsi_ioctl_command __user *sic)
{}

int put_sg_io_hdr(const struct sg_io_hdr *hdr, void __user *argp)
{}
EXPORT_SYMBOL();

int get_sg_io_hdr(struct sg_io_hdr *hdr, const void __user *argp)
{}
EXPORT_SYMBOL();

#ifdef CONFIG_COMPAT
struct compat_cdrom_generic_command {};
#endif

static int scsi_get_cdrom_generic_arg(struct cdrom_generic_command *cgc,
				      const void __user *arg)
{}

static int scsi_put_cdrom_generic_arg(const struct cdrom_generic_command *cgc,
				      void __user *arg)
{}

static int scsi_cdrom_send_packet(struct scsi_device *sdev, bool open_for_write,
		void __user *arg)
{}

static int scsi_ioctl_sg_io(struct scsi_device *sdev, bool open_for_write,
		void __user *argp)
{}

/**
 * scsi_ioctl - Dispatch ioctl to scsi device
 * @sdev: scsi device receiving ioctl
 * @open_for_write: is the file / block device opened for writing?
 * @cmd: which ioctl is it
 * @arg: data associated with ioctl
 *
 * Description: The scsi_ioctl() function differs from most ioctls in that it
 * does not take a major/minor number as the dev field.  Rather, it takes
 * a pointer to a &struct scsi_device.
 */
int scsi_ioctl(struct scsi_device *sdev, bool open_for_write, int cmd,
		void __user *arg)
{}
EXPORT_SYMBOL();

/*
 * We can process a reset even when a device isn't fully operable.
 */
int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev, int cmd,
		bool ndelay)
{}
EXPORT_SYMBOL_GPL();