Commit 78011042 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Martin K. Petersen
Browse files

scsi: bsg: Move bsg_scsi_ops to drivers/scsi/

Move the SCSI-specific bsg code in the SCSI midlayer instead of in the
common bsg code.  This just keeps the common bsg code block/ and also
allows building it as a module.

Link: https://lore.kernel.org/r/20210724072033.1284840-15-hch@lst.de


Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent d52fe8f4
Loading
Loading
Loading
Loading
+3 −20
Original line number Diff line number Diff line
@@ -35,29 +35,12 @@ config BLK_SCSI_REQUEST
config BLK_CGROUP_RWSTAT
	bool

config BLK_DEV_BSG
	bool "Block layer SG support v4"
	default y
	select BLK_SCSI_REQUEST
	help
	  Saying Y here will enable generic SG (SCSI generic) v4 support
	  for any block device.

	  Unlike SG v3 (aka block/scsi_ioctl.c drivers/scsi/sg.c), SG v4
	  can handle complicated SCSI commands: tagged variable length cdbs
	  with bidirectional data transfers and generic request/response
	  protocols (e.g. Task Management Functions and SMP in Serial
	  Attached SCSI).

	  This option is required by recent UDEV versions to properly
	  access device serial numbers, etc.

	  If unsure, say Y.
config BLK_DEV_BSG_COMMON
	tristate

config BLK_DEV_BSGLIB
	bool "Block layer SG support v4 helper lib"
	select BLK_DEV_BSG
	select BLK_SCSI_REQUEST
	select BLK_DEV_BSG_COMMON
	help
	  Subsystems will normally enable this if needed. Users will not
	  normally need to manually enable this.
+1 −1
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@ obj-$(CONFIG_BLOCK) := bio.o elevator.o blk-core.o blk-sysfs.o \

obj-$(CONFIG_BOUNCE)		+= bounce.o
obj-$(CONFIG_BLK_SCSI_REQUEST)	+= scsi_ioctl.o
obj-$(CONFIG_BLK_DEV_BSG)	+= bsg.o
obj-$(CONFIG_BLK_DEV_BSG_COMMON) += bsg.o
obj-$(CONFIG_BLK_DEV_BSGLIB)	+= bsg-lib.o
obj-$(CONFIG_BLK_CGROUP)	+= blk-cgroup.o
obj-$(CONFIG_BLK_CGROUP_RWSTAT)	+= blk-cgroup-rwstat.o
+1 −94
Original line number Diff line number Diff line
@@ -15,9 +15,6 @@

#include <scsi/scsi.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_driver.h>
#include <scsi/sg.h>

#define BSG_DESCRIPTION	"Block layer SCSI generic (bsg) driver"
@@ -54,86 +51,6 @@ static inline struct hlist_head *bsg_dev_idx_hash(int index)

#define uptr64(val) ((void __user *)(uintptr_t)(val))

static int bsg_scsi_check_proto(struct sg_io_v4 *hdr)
{
	if (hdr->protocol != BSG_PROTOCOL_SCSI  ||
	    hdr->subprotocol != BSG_SUB_PROTOCOL_SCSI_CMD)
		return -EINVAL;
	return 0;
}

static int bsg_scsi_fill_hdr(struct request *rq, struct sg_io_v4 *hdr,
		fmode_t mode)
{
	struct scsi_request *sreq = scsi_req(rq);

	if (hdr->dout_xfer_len && hdr->din_xfer_len) {
		pr_warn_once("BIDI support in bsg has been removed.\n");
		return -EOPNOTSUPP;
	}

	sreq->cmd_len = hdr->request_len;
	if (sreq->cmd_len > BLK_MAX_CDB) {
		sreq->cmd = kzalloc(sreq->cmd_len, GFP_KERNEL);
		if (!sreq->cmd)
			return -ENOMEM;
	}

	if (copy_from_user(sreq->cmd, uptr64(hdr->request), sreq->cmd_len))
		return -EFAULT;
	if (blk_verify_command(sreq->cmd, mode))
		return -EPERM;
	return 0;
}

static int bsg_scsi_complete_rq(struct request *rq, struct sg_io_v4 *hdr)
{
	struct scsi_request *sreq = scsi_req(rq);
	int ret = 0;

	/*
	 * fill in all the output members
	 */
	hdr->device_status = sreq->result & 0xff;
	hdr->transport_status = host_byte(sreq->result);
	hdr->driver_status = 0;
	if (scsi_status_is_check_condition(sreq->result))
		hdr->driver_status = DRIVER_SENSE;
	hdr->info = 0;
	if (hdr->device_status || hdr->transport_status || hdr->driver_status)
		hdr->info |= SG_INFO_CHECK;
	hdr->response_len = 0;

	if (sreq->sense_len && hdr->response) {
		int len = min_t(unsigned int, hdr->max_response_len,
					sreq->sense_len);

		if (copy_to_user(uptr64(hdr->response), sreq->sense, len))
			ret = -EFAULT;
		else
			hdr->response_len = len;
	}

	if (rq_data_dir(rq) == READ)
		hdr->din_resid = sreq->resid_len;
	else
		hdr->dout_resid = sreq->resid_len;

	return ret;
}

static void bsg_scsi_free_rq(struct request *rq)
{
	scsi_req_free_cmd(scsi_req(rq));
}

static const struct bsg_ops bsg_scsi_ops = {
	.check_proto		= bsg_scsi_check_proto,
	.fill_hdr		= bsg_scsi_fill_hdr,
	.complete_rq		= bsg_scsi_complete_rq,
	.free_rq		= bsg_scsi_free_rq,
};

static int bsg_sg_io(struct request_queue *q, fmode_t mode, void __user *uarg)
{
	struct request *rq;
@@ -487,17 +404,7 @@ int bsg_register_queue(struct request_queue *q, struct device *parent,
	mutex_unlock(&bsg_mutex);
	return ret;
}

int bsg_scsi_register_queue(struct request_queue *q, struct device *parent)
{
	if (!blk_queue_scsi_passthrough(q)) {
		WARN_ONCE(true, "Attempt to register a non-SCSI queue\n");
		return -EINVAL;
	}

	return bsg_register_queue(q, parent, dev_name(parent), &bsg_scsi_ops);
}
EXPORT_SYMBOL_GPL(bsg_scsi_register_queue);
EXPORT_SYMBOL_GPL(bsg_register_queue);

static struct cdev bsg_cdev;

+13 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ config SCSI
	select SCSI_DMA if HAS_DMA
	select SG_POOL
	select BLK_SCSI_REQUEST
	select BLK_DEV_BSG_COMMON if BLK_DEV_BSG
	help
	  If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or
	  any other SCSI device under Linux, say Y and make sure that you know
@@ -140,6 +141,18 @@ config CHR_DEV_SG

	  If unsure, say N.

config BLK_DEV_BSG
	bool "/dev/bsg support (SG v4)"
	depends on SCSI
	default y
	help
	  Saying Y here will enable generic SG (SCSI generic) v4 support
	  for any SCSI device.

	  This option is required by UDEV to access device serial numbers, etc.

	  If unsure, say Y.

config CHR_DEV_SCH
	tristate "SCSI media changer support"
	depends on SCSI
+1 −0
Original line number Diff line number Diff line
@@ -168,6 +168,7 @@ scsi_mod-$(CONFIG_BLK_DEBUG_FS) += scsi_debugfs.o
scsi_mod-y			+= scsi_trace.o scsi_logging.o
scsi_mod-$(CONFIG_PM)		+= scsi_pm.o
scsi_mod-$(CONFIG_SCSI_DH)	+= scsi_dh.o
scsi_mod-$(CONFIG_BLK_DEV_BSG)	+= scsi_bsg.o

hv_storvsc-y			:= storvsc_drv.o

Loading