public inbox for io-uring@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v2 0/3] bsg: add io_uring command support for SCSI passthrough
@ 2026-01-15  1:24 Yang Xiuwei
  2026-01-15  1:24 ` [RFC PATCH v2 1/3] bsg: add bsg_uring_cmd uapi structure Yang Xiuwei
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Yang Xiuwei @ 2026-01-15  1:24 UTC (permalink / raw)
  To: linux-scsi, linux-block, io-uring
  Cc: fujita.tomonori, axboe, James.Bottomley, martin.petersen,
	bvanassche, Yang Xiuwei

This RFC series adds io_uring command support to the BSG (Block layer
SCSI Generic) driver, enabling asynchronous SCSI passthrough operations
via io_uring.

Motivation:
-----------
The current BSG interface uses ioctl() for SCSI passthrough, which is
synchronous and has limitations for high-performance applications. By
integrating with io_uring, we can provide:

1. Asynchronous I/O support for better scalability
2. Zero-copy I/O via io_uring fixed buffers
3. Better integration with modern async I/O frameworks
4. Reduced system call overhead

Design:
-------
The implementation follows the io_uring uring_cmd pattern used by other
drivers (e.g., nvme). Key design decisions:

1. UAPI Structure: A new bsg_uring_cmd structure is defined that fits
   within the 80-byte cmd field of a 128-byte SQE, with 24 bytes reserved
   for future extensions. The structure uses protocol-agnostic field names
   to support multiple protocols beyond SCSI.

2. Status Information: SCSI status (device_status, host_status,
   driver_status, sense_len, resid_len) is returned in the CQE res2 field
   using a compact 64-bit encoding.

3. Zero-copy Support: The implementation supports both traditional
   user buffers and io_uring fixed buffers for zero-copy I/O.

4. Async Completion: Command completion is handled via task work to
   safely access user space and copy sense data.

5. Non-blocking I/O: Support for IO_URING_F_NONBLOCK flag to enable
   non-blocking command submission.

Limitations:
-----------
- Currently only SCSI commands are supported (BSG_PROTOCOL_SCSI)
- Scatter/gather I/O (iovec arrays) is not currently supported, but
  the data structure includes fields for future implementation.
- Bidirectional transfers are not supported (consistent with existing
  BSG behavior).

Testing:
--------
A user-space test program has been developed to validate the
implementation, including:
- Basic SCSI commands (INQUIRY, READ CAPACITY (10), READ (10),
  WRITE (10))
- Zero-copy mode using fixed buffers
- Error handling (invalid flags, unsupported features)

The test program is available separately and can be provided upon request.

Changes since v1:
-----------------
- Renamed SCSI-specific fields (cdb_addr/cdb_len) to protocol-agnostic
  names (request/request_len) to support multiple protocols beyond SCSI
- Removed __packed attribute and optimized field alignment to avoid
  suboptimal code generation on architectures that don't support unaligned
  accesses
- Simplified data transfer structure: unified din_xferp/dout_xferp into a
  single xfer_addr field with xfer_dir to indicate direction (0=read, 1=write),
  consistent with existing BSG behavior where bidirectional transfers are not
  supported
- Updated implementation to use new protocol-agnostic field names

Yang Xiuwei (3):
  bsg: add bsg_uring_cmd uapi structure
  bsg: add uring_cmd support to BSG generic layer
  bsg: implement SCSI BSG uring_cmd handler

 block/bsg.c              |  28 +++++
 drivers/scsi/scsi_bsg.c  | 222 +++++++++++++++++++++++++++++++++++++++
 include/linux/bsg.h      |   4 +
 include/uapi/linux/bsg.h |  19 ++++
 4 files changed, 273 insertions(+)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [RFC PATCH v2 1/3] bsg: add bsg_uring_cmd uapi structure
  2026-01-15  1:24 [RFC PATCH v2 0/3] bsg: add io_uring command support for SCSI passthrough Yang Xiuwei
@ 2026-01-15  1:24 ` Yang Xiuwei
  2026-01-15  1:24 ` [RFC PATCH v2 2/3] bsg: add uring_cmd support to BSG generic layer Yang Xiuwei
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Yang Xiuwei @ 2026-01-15  1:24 UTC (permalink / raw)
  To: linux-scsi, linux-block, io-uring
  Cc: fujita.tomonori, axboe, James.Bottomley, martin.petersen,
	bvanassche, Yang Xiuwei

Add the bsg_uring_cmd structure to the BSG UAPI header to support
io_uring-based SCSI passthrough operations via IORING_OP_URING_CMD.

Signed-off-by: Yang Xiuwei <yangxiuwei@kylinos.cn>
---
 include/uapi/linux/bsg.h | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/include/uapi/linux/bsg.h b/include/uapi/linux/bsg.h
index cd6302def5ed..0a589e2ceb3b 100644
--- a/include/uapi/linux/bsg.h
+++ b/include/uapi/linux/bsg.h
@@ -63,5 +63,24 @@ struct sg_io_v4 {
 	__u32 padding;
 };
 
+struct bsg_uring_cmd {
+	/* Command request related */
+	__u64 request;		/* [i], [*i] command descriptor address */
+	__u32 request_len;	/* [i] command descriptor length in bytes */
+	/* Protocol related */
+	__u32 protocol;		/* [i] protocol type (BSG_PROTOCOL_*) */
+	__u32 subprotocol;	/* [i] subprotocol type (BSG_SUB_PROTOCOL_*) */
+	/* Response data related */
+	__u32 max_response_len;	/* [i] response buffer size in bytes */
+	__u64 response;		/* [i], [*o] response data address */
+	/* Data transfer related */
+	__u64 xfer_addr;	/* [i] data transfer buffer address */
+	__u32 xfer_len;		/* [i] data transfer length in bytes */
+	__u32 xfer_dir;		/* [i] 0=din (read), 1=dout (write) */
+	__u32 iovec_count;	/* [i] iovec array count, 0 for flat buffer */
+	/* Control related */
+	__u32 timeout_ms;	/* [i] timeout in milliseconds */
+	__u8  reserved[24];	/* reserved for future extension */
+};
 
 #endif /* _UAPIBSG_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC PATCH v2 2/3] bsg: add uring_cmd support to BSG generic layer
  2026-01-15  1:24 [RFC PATCH v2 0/3] bsg: add io_uring command support for SCSI passthrough Yang Xiuwei
  2026-01-15  1:24 ` [RFC PATCH v2 1/3] bsg: add bsg_uring_cmd uapi structure Yang Xiuwei
@ 2026-01-15  1:24 ` Yang Xiuwei
  2026-01-15  1:24 ` [RFC PATCH v2 3/3] bsg: implement SCSI BSG uring_cmd handler Yang Xiuwei
  2026-01-16  4:25 ` [RFC PATCH v3 0/3] bsg: add io_uring command support for SCSI passthrough Yang Xiuwei
  3 siblings, 0 replies; 9+ messages in thread
From: Yang Xiuwei @ 2026-01-15  1:24 UTC (permalink / raw)
  To: linux-scsi, linux-block, io-uring
  Cc: fujita.tomonori, axboe, James.Bottomley, martin.petersen,
	bvanassche, Yang Xiuwei

Add io_uring command handler to the generic BSG layer. This handler
validates that SQE128 and CQE32 flags are set (required for the command
structure and status information), then delegates to the SCSI-specific
handler.

Signed-off-by: Yang Xiuwei <yangxiuwei@kylinos.cn>
---
 block/bsg.c             | 28 ++++++++++++++++++++++++++++
 drivers/scsi/scsi_bsg.c |  7 +++++++
 include/linux/bsg.h     |  4 ++++
 3 files changed, 39 insertions(+)

diff --git a/block/bsg.c b/block/bsg.c
index 72157a59b788..cdccf86b8673 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -12,6 +12,7 @@
 #include <linux/idr.h>
 #include <linux/bsg.h>
 #include <linux/slab.h>
+#include <linux/io_uring/cmd.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_ioctl.h>
@@ -158,11 +159,38 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	}
 }
 
+static int bsg_uring_cmd_checks(unsigned int issue_flags)
+{
+	/* BSG passthrough requires big SQE/CQE support */
+	if ((issue_flags & (IO_URING_F_SQE128|IO_URING_F_CQE32)) !=
+	    (IO_URING_F_SQE128|IO_URING_F_CQE32))
+		return -EOPNOTSUPP;
+	return 0;
+}
+
+static int bsg_uring_cmd(struct io_uring_cmd *ioucmd, unsigned int issue_flags)
+{
+	struct bsg_device *bd = to_bsg_device(file_inode(ioucmd->file));
+	struct request_queue *q = bd->queue;
+	bool open_for_write = ioucmd->file->f_mode & FMODE_WRITE;
+	int ret;
+
+	if (!q)
+		return -EINVAL;
+
+	ret = bsg_uring_cmd_checks(issue_flags);
+	if (ret)
+		return ret;
+
+	return scsi_bsg_uring_cmd(q, ioucmd, issue_flags, open_for_write);
+}
+
 static const struct file_operations bsg_fops = {
 	.open		=	bsg_open,
 	.release	=	bsg_release,
 	.unlocked_ioctl	=	bsg_ioctl,
 	.compat_ioctl	=	compat_ptr_ioctl,
+	.uring_cmd	=	bsg_uring_cmd,
 	.owner		=	THIS_MODULE,
 	.llseek		=	default_llseek,
 };
diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c
index a9a9ec086a7e..4399a25990fc 100644
--- a/drivers/scsi/scsi_bsg.c
+++ b/drivers/scsi/scsi_bsg.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/bsg.h>
+#include <linux/io_uring/cmd.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_ioctl.h>
 #include <scsi/scsi_cmnd.h>
@@ -9,6 +10,12 @@
 
 #define uptr64(val) ((void __user *)(uintptr_t)(val))
 
+int scsi_bsg_uring_cmd(struct request_queue *q, struct io_uring_cmd *ioucmd,
+		       unsigned int issue_flags, bool open_for_write)
+{
+	return -EOPNOTSUPP;
+}
+
 static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
 		bool open_for_write, unsigned int timeout)
 {
diff --git a/include/linux/bsg.h b/include/linux/bsg.h
index ee2df73edf83..68ec50b5e97c 100644
--- a/include/linux/bsg.h
+++ b/include/linux/bsg.h
@@ -7,6 +7,7 @@
 struct bsg_device;
 struct device;
 struct request_queue;
+struct io_uring_cmd;
 
 typedef int (bsg_sg_io_fn)(struct request_queue *, struct sg_io_v4 *hdr,
 		bool open_for_write, unsigned int timeout);
@@ -16,4 +17,7 @@ struct bsg_device *bsg_register_queue(struct request_queue *q,
 		bsg_sg_io_fn *sg_io_fn);
 void bsg_unregister_queue(struct bsg_device *bcd);
 
+int scsi_bsg_uring_cmd(struct request_queue *q, struct io_uring_cmd *ioucmd,
+		       unsigned int issue_flags, bool open_for_write);
+
 #endif /* _LINUX_BSG_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC PATCH v2 3/3] bsg: implement SCSI BSG uring_cmd handler
  2026-01-15  1:24 [RFC PATCH v2 0/3] bsg: add io_uring command support for SCSI passthrough Yang Xiuwei
  2026-01-15  1:24 ` [RFC PATCH v2 1/3] bsg: add bsg_uring_cmd uapi structure Yang Xiuwei
  2026-01-15  1:24 ` [RFC PATCH v2 2/3] bsg: add uring_cmd support to BSG generic layer Yang Xiuwei
@ 2026-01-15  1:24 ` Yang Xiuwei
  2026-01-16  4:25 ` [RFC PATCH v3 0/3] bsg: add io_uring command support for SCSI passthrough Yang Xiuwei
  3 siblings, 0 replies; 9+ messages in thread
From: Yang Xiuwei @ 2026-01-15  1:24 UTC (permalink / raw)
  To: linux-scsi, linux-block, io-uring
  Cc: fujita.tomonori, axboe, James.Bottomley, martin.petersen,
	bvanassche, Yang Xiuwei

Implement the SCSI-specific io_uring command handler for BSG. This
handler processes SCSI passthrough commands asynchronously via io_uring,
supporting both traditional user buffers and zero-copy fixed buffers.

Key features:
- Async command execution with proper completion handling
- Zero-copy support via io_uring fixed buffers
- Status information returned in CQE res2 field
- Non-blocking I/O support via IO_URING_F_NONBLOCK
- Proper error handling and validation

The implementation uses a PDU structure overlaying io_uring_cmd.pdu[32]
to store temporary state during command execution. Completion is handled
via task work to safely access user space.

This patch replaces the stub implementation from patch 2/3 with the full
implementation.

Signed-off-by: Yang Xiuwei <yangxiuwei@kylinos.cn>
---
 drivers/scsi/scsi_bsg.c | 217 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 216 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c
index 4399a25990fc..e1bc46884dc7 100644
--- a/drivers/scsi/scsi_bsg.c
+++ b/drivers/scsi/scsi_bsg.c
@@ -10,10 +10,225 @@
 
 #define uptr64(val) ((void __user *)(uintptr_t)(val))
 
+/*
+ * BSG io_uring PDU structure overlaying io_uring_cmd.pdu[32].
+ * Stores temporary data needed during command execution.
+ */
+struct scsi_bsg_uring_cmd_pdu {
+	struct bio *bio;		/* mapped user buffer, unmap in task work */
+	struct request *req;		/* block request, freed in task work */
+	u64 sense_addr;			/* user space response buffer address (SCSI: sense data) */
+	u32 resid_len;			/* residual transfer length */
+	/* Protocol-specific status fields using union for extensibility */
+	union {
+		struct {
+			u8 device_status;	/* SCSI device status (low 8 bits of result) */
+			u8 driver_status;	/* SCSI driver status (DRIVER_SENSE if check) */
+			u8 host_status;		/* SCSI host status (host_byte of result) */
+			u8 sense_len_wr;	/* actual sense data length written */
+		} scsi;
+		/* Future protocols can add their own status layouts here */
+	};
+};
+
+static inline struct scsi_bsg_uring_cmd_pdu *scsi_bsg_uring_cmd_pdu(
+	struct io_uring_cmd *ioucmd)
+{
+	return io_uring_cmd_to_pdu(ioucmd, struct scsi_bsg_uring_cmd_pdu);
+}
+
+/*
+ * Task work callback executed in process context.
+ * Builds res2 with status information and copies sense data to user space.
+ * res2 layout (64-bit):
+ *   0-7:   device_status
+ *   8-15:  driver_status
+ *   16-23: host_status
+ *   24-31: sense_len_wr
+ *   32-63: resid_len
+ */
+static void scsi_bsg_uring_task_cb(struct io_tw_req tw_req, io_tw_token_t tw)
+{
+	struct io_uring_cmd *ioucmd = io_uring_cmd_from_tw(tw_req);
+	struct scsi_bsg_uring_cmd_pdu *pdu = scsi_bsg_uring_cmd_pdu(ioucmd);
+	struct scsi_cmnd *scmd;
+	struct request *rq = pdu->req;
+	int ret = 0;
+	u64 res2;
+
+	scmd = blk_mq_rq_to_pdu(rq);
+
+	if (pdu->bio)
+		blk_rq_unmap_user(pdu->bio);
+
+	/* Build res2 with status information */
+	res2 = ((u64)pdu->resid_len << 32) |
+	       ((u64)(pdu->scsi.sense_len_wr & 0xff) << 24) |
+	       ((u64)(pdu->scsi.host_status & 0xff) << 16) |
+	       ((u64)(pdu->scsi.driver_status & 0xff) << 8) |
+	       (pdu->scsi.device_status & 0xff);
+
+	if (pdu->scsi.sense_len_wr && pdu->sense_addr) {
+		if (copy_to_user(uptr64(pdu->sense_addr), scmd->sense_buffer,
+				 pdu->scsi.sense_len_wr))
+			ret = -EFAULT;
+	}
+
+	blk_mq_free_request(rq);
+	io_uring_cmd_done32(ioucmd, ret, res2,
+			    IO_URING_CMD_TASK_WORK_ISSUE_FLAGS);
+}
+
+/*
+ * Async completion callback executed in interrupt/atomic context.
+ * Saves SCSI status information and schedules task work for final completion.
+ */
+static enum rq_end_io_ret scsi_bsg_uring_cmd_done(struct request *req,
+						  blk_status_t status)
+{
+	struct io_uring_cmd *ioucmd = req->end_io_data;
+	struct scsi_bsg_uring_cmd_pdu *pdu = scsi_bsg_uring_cmd_pdu(ioucmd);
+	struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req);
+
+	/* Pack SCSI status fields into union */
+	pdu->scsi.device_status = scmd->result & 0xff;
+	pdu->scsi.host_status = host_byte(scmd->result);
+	pdu->scsi.driver_status = 0;
+	pdu->scsi.sense_len_wr = 0;
+
+	if (scsi_status_is_check_condition(scmd->result)) {
+		pdu->scsi.driver_status = DRIVER_SENSE;
+		if (pdu->sense_addr)
+			pdu->scsi.sense_len_wr = min_t(u8, scmd->sense_len, SCSI_SENSE_BUFFERSIZE);
+	}
+
+	pdu->resid_len = scmd->resid_len;
+
+	io_uring_cmd_do_in_task_lazy(ioucmd, scsi_bsg_uring_task_cb);
+	return RQ_END_IO_NONE;
+}
+
+/*
+ * Validate bsg_uring_cmd structure parameters.
+ * Note: xfer_dir must match the actual SCSI command direction.
+ * The direction is determined by the CDB, and user space should
+ * set xfer_dir accordingly (0=READ, 1=WRITE).
+ */
+static int scsi_bsg_validate_uring_cmd(const struct bsg_uring_cmd *cmd)
+{
+	if (cmd->protocol != BSG_PROTOCOL_SCSI ||
+	    cmd->subprotocol != BSG_SUB_PROTOCOL_SCSI_CMD)
+		return -EINVAL;
+
+	if (!cmd->request || cmd->request_len == 0)
+		return -EINVAL;
+
+	if (cmd->xfer_dir > 1)
+		return -EINVAL;
+
+	if (cmd->iovec_count > 0)
+		return -EOPNOTSUPP;
+
+	return 0;
+}
+
+/*
+ * Map user buffer to request, supporting both zero-copy (fixed buffers)
+ * and traditional mode.
+ */
+static int scsi_bsg_map_user_buffer(struct request *req,
+				    struct io_uring_cmd *ioucmd,
+				    unsigned int issue_flags, gfp_t gfp_mask)
+{
+	const struct bsg_uring_cmd *cmd = io_uring_sqe_cmd(ioucmd->sqe);
+	struct iov_iter iter;
+	int ret;
+
+	if (ioucmd->flags & IORING_URING_CMD_FIXED) {
+		ret = io_uring_cmd_import_fixed(cmd->xfer_addr, cmd->xfer_len,
+						cmd->xfer_dir, &iter, ioucmd,
+						issue_flags);
+		if (ret < 0)
+			return ret;
+		ret = blk_rq_map_user_iov(req->q, req, NULL, &iter, gfp_mask);
+	} else {
+		ret = blk_rq_map_user(req->q, req, NULL,
+				      uptr64(cmd->xfer_addr), cmd->xfer_len,
+				      gfp_mask);
+	}
+
+	return ret;
+}
+
 int scsi_bsg_uring_cmd(struct request_queue *q, struct io_uring_cmd *ioucmd,
 		       unsigned int issue_flags, bool open_for_write)
 {
-	return -EOPNOTSUPP;
+	struct scsi_bsg_uring_cmd_pdu *pdu = scsi_bsg_uring_cmd_pdu(ioucmd);
+	const struct bsg_uring_cmd *cmd = io_uring_sqe_cmd(ioucmd->sqe);
+	struct scsi_cmnd *scmd;
+	struct request *req;
+	blk_mq_req_flags_t blk_flags = 0;
+	gfp_t gfp_mask = GFP_KERNEL;
+	int ret;
+
+	ret = scsi_bsg_validate_uring_cmd(cmd);
+	if (ret)
+		return ret;
+
+	if (issue_flags & IO_URING_F_NONBLOCK) {
+		blk_flags = BLK_MQ_REQ_NOWAIT;
+		gfp_mask = GFP_NOWAIT;
+	}
+
+	req = scsi_alloc_request(q, cmd->xfer_dir ?
+				 REQ_OP_DRV_OUT : REQ_OP_DRV_IN, blk_flags);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	scmd = blk_mq_rq_to_pdu(req);
+	scmd->cmd_len = cmd->request_len;
+	if (scmd->cmd_len > sizeof(scmd->cmnd)) {
+		ret = -EINVAL;
+		goto out_free_req;
+	}
+	scmd->allowed = SG_DEFAULT_RETRIES;
+
+	if (copy_from_user(scmd->cmnd, uptr64(cmd->request), cmd->request_len)) {
+		ret = -EFAULT;
+		goto out_free_req;
+	}
+
+	if (!scsi_cmd_allowed(scmd->cmnd, open_for_write)) {
+		ret = -EPERM;
+		goto out_free_req;
+	}
+
+	pdu->sense_addr = cmd->response;
+	scmd->sense_len = cmd->max_response_len ?
+		min(cmd->max_response_len, SCSI_SENSE_BUFFERSIZE) : SCSI_SENSE_BUFFERSIZE;
+
+	if (cmd->xfer_len > 0) {
+		ret = scsi_bsg_map_user_buffer(req, ioucmd, issue_flags, gfp_mask);
+		if (ret)
+			goto out_free_req;
+		pdu->bio = req->bio;
+	} else {
+		pdu->bio = NULL;
+	}
+
+	req->timeout = cmd->timeout_ms ?
+		msecs_to_jiffies(cmd->timeout_ms) : BLK_DEFAULT_SG_TIMEOUT;
+
+	req->end_io = scsi_bsg_uring_cmd_done;
+	req->end_io_data = ioucmd;
+	pdu->req = req;
+
+	blk_execute_rq_nowait(req, false);
+	return -EIOCBQUEUED;
+
+out_free_req:
+	blk_mq_free_request(req);
+	return ret;
 }
 
 static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC PATCH v3 0/3] bsg: add io_uring command support for SCSI passthrough
  2026-01-15  1:24 [RFC PATCH v2 0/3] bsg: add io_uring command support for SCSI passthrough Yang Xiuwei
                   ` (2 preceding siblings ...)
  2026-01-15  1:24 ` [RFC PATCH v2 3/3] bsg: implement SCSI BSG uring_cmd handler Yang Xiuwei
@ 2026-01-16  4:25 ` Yang Xiuwei
  2026-01-16  4:25   ` [RFC PATCH v3 1/3] bsg: add bsg_uring_cmd uapi structure Yang Xiuwei
                     ` (3 more replies)
  3 siblings, 4 replies; 9+ messages in thread
From: Yang Xiuwei @ 2026-01-16  4:25 UTC (permalink / raw)
  To: linux-scsi, linux-block, io-uring
  Cc: fujita.tomonori, axboe, James.Bottomley, martin.petersen,
	bvanassche, Yang Xiuwei

This RFC series adds io_uring command support to the BSG (Block layer
SCSI Generic) driver, enabling asynchronous SCSI passthrough operations
with zero-copy support via fixed buffers.

The implementation follows the io_uring uring_cmd pattern used by other
drivers (e.g., nvme). A new bsg_uring_cmd structure fits within the 80-byte
cmd field of a 128-byte SQE, with 8 bytes reserved for future extensions.
The structure uses protocol-agnostic field names and follows the sg_io_v4
design with separate din_xferp/dout_xferp fields. SCSI status information
is returned in the CQE res2 field using a compact 64-bit encoding.

Currently only BSG_SUB_PROTOCOL_SCSI_CMD is implemented. Scatter/gather
I/O and bidirectional transfers are not yet supported.

The implementation has been tested with a user-space test program covering
basic SCSI commands (INQUIRY, READ CAPACITY, READ, WRITE), zero-copy mode,
and error handling.

Changes since v1:
-----------------
- Protocol-agnostic field names (request/request_len instead of cdb_addr/cdb_len)
- Removed __packed attribute for better code generation
- Reduced reserved space from 16 bytes to 8 bytes to fit within 80-byte SQE

Why v2 was superseded:
----------------------
v2 unified din_xferp/dout_xferp into a single xfer_addr field, which
diverged from the established sg_io_v4 interface. v3 reverts to separate
din_xferp/dout_xferp fields to maintain consistency with the existing
BSG interface.

Yang Xiuwei (3):
  bsg: add bsg_uring_cmd uapi structure
  bsg: add uring_cmd support to BSG generic layer
  bsg: implement SCSI BSG uring_cmd handler

 block/bsg.c              |  66 ++++++++++++++
 drivers/scsi/scsi_bsg.c  | 192 +++++++++++++++++++++++++++++++++++++++
 include/linux/bsg.h       |   4 +
 include/uapi/linux/bsg.h  |  24 +++++
 4 files changed, 286 insertions(+)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [RFC PATCH v3 1/3] bsg: add bsg_uring_cmd uapi structure
  2026-01-16  4:25 ` [RFC PATCH v3 0/3] bsg: add io_uring command support for SCSI passthrough Yang Xiuwei
@ 2026-01-16  4:25   ` Yang Xiuwei
  2026-01-16  4:25   ` [RFC PATCH v3 2/3] bsg: add uring_cmd support to BSG generic layer Yang Xiuwei
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Yang Xiuwei @ 2026-01-16  4:25 UTC (permalink / raw)
  To: linux-scsi, linux-block, io-uring
  Cc: fujita.tomonori, axboe, James.Bottomley, martin.petersen,
	bvanassche, Yang Xiuwei

Add the bsg_uring_cmd structure to the BSG UAPI header to support
io_uring-based SCSI passthrough operations via IORING_OP_URING_CMD.

Signed-off-by: Yang Xiuwei <yangxiuwei@kylinos.cn>
---
 include/uapi/linux/bsg.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/include/uapi/linux/bsg.h b/include/uapi/linux/bsg.h
index cd6302def5ed..d9514b99b7a9 100644
--- a/include/uapi/linux/bsg.h
+++ b/include/uapi/linux/bsg.h
@@ -63,5 +63,29 @@ struct sg_io_v4 {
 	__u32 padding;
 };
 
+struct bsg_uring_cmd {
+	/* Command request related */
+	__u64 request;		/* [i], [*i] command descriptor address */
+	__u32 request_len;	/* [i] command descriptor length in bytes */
+	__u32 protocol;		/* [i] protocol type (BSG_PROTOCOL_*) */
+	__u32 subprotocol;	/* [i] subprotocol type (BSG_SUB_PROTOCOL_*) */
+	__u32 max_response_len;	/* [i] response buffer size in bytes */
+	/* Response data related */
+	__u64 response;		/* [i], [*o] response data address */
+	/* Data transfer related - dout */
+	__u64 dout_xferp;	/* [i], [*i] */
+	__u32 dout_xfer_len;	/* [i] bytes to be transferred to device */
+	__u32 dout_iovec_count;	/* [i] 0 -> "flat" dout transfer else
+				 * dout_xferp points to array of iovec
+				 */
+	/* Data transfer related - din */
+	__u64 din_xferp;	/* [i], [*o] */
+	__u32 din_xfer_len;	/* [i] bytes to be transferred from device */
+	__u32 din_iovec_count;	/* [i] 0 -> "flat" din transfer */
+	/* Control related */
+	__u32 timeout_ms;	/* [i] timeout in milliseconds */
+	__u32 flags;		/* [i] bit mask */
+	__u8  reserved[8];	/* reserved for future extension */
+};
 
 #endif /* _UAPIBSG_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC PATCH v3 2/3] bsg: add uring_cmd support to BSG generic layer
  2026-01-16  4:25 ` [RFC PATCH v3 0/3] bsg: add io_uring command support for SCSI passthrough Yang Xiuwei
  2026-01-16  4:25   ` [RFC PATCH v3 1/3] bsg: add bsg_uring_cmd uapi structure Yang Xiuwei
@ 2026-01-16  4:25   ` Yang Xiuwei
  2026-01-16  4:25   ` [RFC PATCH v3 3/3] bsg: implement SCSI BSG uring_cmd handler Yang Xiuwei
  2026-01-16  4:52   ` [RFC PATCH v3 0/3] bsg: add io_uring command support for SCSI passthrough Yang Xiuwei
  3 siblings, 0 replies; 9+ messages in thread
From: Yang Xiuwei @ 2026-01-16  4:25 UTC (permalink / raw)
  To: linux-scsi, linux-block, io-uring
  Cc: fujita.tomonori, axboe, James.Bottomley, martin.petersen,
	bvanassche, Yang Xiuwei

Add io_uring command handler to the generic BSG layer. This handler
validates that SQE128 and CQE32 flags are set (required for the command
structure and status information), then delegates to the SCSI-specific
handler.

Signed-off-by: Yang Xiuwei <yangxiuwei@kylinos.cn>
---
 block/bsg.c             | 66 +++++++++++++++++++++++++++++++++++++++++
 drivers/scsi/scsi_bsg.c |  7 +++++
 include/linux/bsg.h     |  4 +++
 3 files changed, 77 insertions(+)

diff --git a/block/bsg.c b/block/bsg.c
index 72157a59b788..51f9f3cc57c4 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -12,6 +12,7 @@
 #include <linux/idr.h>
 #include <linux/bsg.h>
 #include <linux/slab.h>
+#include <linux/io_uring/cmd.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_ioctl.h>
@@ -158,11 +159,76 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	}
 }
 
+static int bsg_check_uring_features(unsigned int issue_flags)
+{
+	/* BSG passthrough requires big SQE/CQE support */
+	if ((issue_flags & (IO_URING_F_SQE128|IO_URING_F_CQE32)) !=
+	    (IO_URING_F_SQE128|IO_URING_F_CQE32))
+		return -EOPNOTSUPP;
+	return 0;
+}
+
+static int bsg_validate_command(const struct bsg_uring_cmd *cmd)
+{
+	if (cmd->protocol != BSG_PROTOCOL_SCSI)
+		return -EINVAL;
+
+	if (cmd->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) {
+		if (!cmd->request || cmd->request_len == 0)
+			return -EINVAL;
+
+		if (cmd->dout_xfer_len && cmd->din_xfer_len) {
+			pr_warn_once("BIDI support in bsg has been removed.\n");
+			return -EOPNOTSUPP;
+		}
+
+		if (cmd->dout_iovec_count > 0 || cmd->din_iovec_count > 0)
+			return -EOPNOTSUPP;
+
+		return 0;
+	} else if (cmd->subprotocol == BSG_SUB_PROTOCOL_SCSI_TRANSPORT) {
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int bsg_uring_cmd(struct io_uring_cmd *ioucmd, unsigned int issue_flags)
+{
+	struct bsg_device *bd = to_bsg_device(file_inode(ioucmd->file));
+	struct request_queue *q = bd->queue;
+	bool open_for_write = ioucmd->file->f_mode & FMODE_WRITE;
+	const struct bsg_uring_cmd *cmd = io_uring_sqe_cmd(ioucmd->sqe);
+	int ret;
+
+	if (!q)
+		return -EINVAL;
+
+	ret = bsg_check_uring_features(issue_flags);
+	if (ret)
+		return ret;
+
+	ret = bsg_validate_command(cmd);
+	if (ret)
+		return ret;
+
+	if (cmd->protocol == BSG_PROTOCOL_SCSI) {
+		if (cmd->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD)
+			return scsi_bsg_uring_cmd(q, ioucmd, issue_flags, open_for_write);
+		else if (cmd->subprotocol == BSG_SUB_PROTOCOL_SCSI_TRANSPORT)
+			return -EOPNOTSUPP;
+		return -EINVAL;
+	}
+
+	return -EINVAL;
+}
+
 static const struct file_operations bsg_fops = {
 	.open		=	bsg_open,
 	.release	=	bsg_release,
 	.unlocked_ioctl	=	bsg_ioctl,
 	.compat_ioctl	=	compat_ptr_ioctl,
+	.uring_cmd	=	bsg_uring_cmd,
 	.owner		=	THIS_MODULE,
 	.llseek		=	default_llseek,
 };
diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c
index a9a9ec086a7e..4399a25990fc 100644
--- a/drivers/scsi/scsi_bsg.c
+++ b/drivers/scsi/scsi_bsg.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/bsg.h>
+#include <linux/io_uring/cmd.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_ioctl.h>
 #include <scsi/scsi_cmnd.h>
@@ -9,6 +10,12 @@
 
 #define uptr64(val) ((void __user *)(uintptr_t)(val))
 
+int scsi_bsg_uring_cmd(struct request_queue *q, struct io_uring_cmd *ioucmd,
+		       unsigned int issue_flags, bool open_for_write)
+{
+	return -EOPNOTSUPP;
+}
+
 static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
 		bool open_for_write, unsigned int timeout)
 {
diff --git a/include/linux/bsg.h b/include/linux/bsg.h
index ee2df73edf83..68ec50b5e97c 100644
--- a/include/linux/bsg.h
+++ b/include/linux/bsg.h
@@ -7,6 +7,7 @@
 struct bsg_device;
 struct device;
 struct request_queue;
+struct io_uring_cmd;
 
 typedef int (bsg_sg_io_fn)(struct request_queue *, struct sg_io_v4 *hdr,
 		bool open_for_write, unsigned int timeout);
@@ -16,4 +17,7 @@ struct bsg_device *bsg_register_queue(struct request_queue *q,
 		bsg_sg_io_fn *sg_io_fn);
 void bsg_unregister_queue(struct bsg_device *bcd);
 
+int scsi_bsg_uring_cmd(struct request_queue *q, struct io_uring_cmd *ioucmd,
+		       unsigned int issue_flags, bool open_for_write);
+
 #endif /* _LINUX_BSG_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC PATCH v3 3/3] bsg: implement SCSI BSG uring_cmd handler
  2026-01-16  4:25 ` [RFC PATCH v3 0/3] bsg: add io_uring command support for SCSI passthrough Yang Xiuwei
  2026-01-16  4:25   ` [RFC PATCH v3 1/3] bsg: add bsg_uring_cmd uapi structure Yang Xiuwei
  2026-01-16  4:25   ` [RFC PATCH v3 2/3] bsg: add uring_cmd support to BSG generic layer Yang Xiuwei
@ 2026-01-16  4:25   ` Yang Xiuwei
  2026-01-16  4:52   ` [RFC PATCH v3 0/3] bsg: add io_uring command support for SCSI passthrough Yang Xiuwei
  3 siblings, 0 replies; 9+ messages in thread
From: Yang Xiuwei @ 2026-01-16  4:25 UTC (permalink / raw)
  To: linux-scsi, linux-block, io-uring
  Cc: fujita.tomonori, axboe, James.Bottomley, martin.petersen,
	bvanassche, Yang Xiuwei

Implement the SCSI-specific io_uring command handler for BSG. This
handler processes SCSI passthrough commands asynchronously via io_uring,
supporting both traditional user buffers and zero-copy fixed buffers.

Key features:
- Async command execution with proper completion handling
- Zero-copy support via io_uring fixed buffers
- Status information returned in CQE res2 field
- Non-blocking I/O support via IO_URING_F_NONBLOCK
- Proper error handling and validation

The implementation uses a PDU structure overlaying io_uring_cmd.pdu[32]
to store temporary state during command execution. Completion is handled
via task work to safely access user space.

This patch replaces the stub implementation from patch 2/3 with the full
implementation.

Signed-off-by: Yang Xiuwei <yangxiuwei@kylinos.cn>
---
 drivers/scsi/scsi_bsg.c | 187 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 186 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c
index 4399a25990fc..3a45a597855a 100644
--- a/drivers/scsi/scsi_bsg.c
+++ b/drivers/scsi/scsi_bsg.c
@@ -10,10 +10,195 @@
 
 #define uptr64(val) ((void __user *)(uintptr_t)(val))
 
+/*
+ * BSG io_uring PDU structure overlaying io_uring_cmd.pdu[32].
+ * Stores temporary data needed during command execution.
+ */
+struct scsi_bsg_uring_cmd_pdu {
+	struct bio *bio;		/* mapped user buffer, unmap in task work */
+	struct request *req;		/* block request, freed in task work */
+	u64 response_addr;		/* user space response buffer address */
+	u32 resid_len;			/* residual transfer length */
+	/* Protocol-specific status fields using union for extensibility */
+	union {
+		struct {
+			u8 device_status;	/* SCSI device status (low 8 bits of result) */
+			u8 driver_status;	/* SCSI driver status (DRIVER_SENSE if check) */
+			u8 host_status;		/* SCSI host status (host_byte of result) */
+			u8 sense_len_wr;	/* actual sense data length written */
+		} scsi;
+		/* Future protocols can add their own status layouts here */
+	};
+};
+
+static inline struct scsi_bsg_uring_cmd_pdu *scsi_bsg_uring_cmd_pdu(
+	struct io_uring_cmd *ioucmd)
+{
+	return io_uring_cmd_to_pdu(ioucmd, struct scsi_bsg_uring_cmd_pdu);
+}
+
+/*
+ * Task work callback executed in process context.
+ * Builds res2 with status information and copies sense data to user space.
+ * res2 layout (64-bit):
+ *   0-7:   device_status
+ *   8-15:  driver_status
+ *   16-23: host_status
+ *   24-31: sense_len_wr
+ *   32-63: resid_len
+ */
+static void scsi_bsg_uring_task_cb(struct io_tw_req tw_req, io_tw_token_t tw)
+{
+	struct io_uring_cmd *ioucmd = io_uring_cmd_from_tw(tw_req);
+	struct scsi_bsg_uring_cmd_pdu *pdu = scsi_bsg_uring_cmd_pdu(ioucmd);
+	struct scsi_cmnd *scmd;
+	struct request *rq = pdu->req;
+	int ret = 0;
+	u64 res2;
+
+	scmd = blk_mq_rq_to_pdu(rq);
+
+	if (pdu->bio)
+		blk_rq_unmap_user(pdu->bio);
+
+	/* Build res2 with status information */
+	res2 = ((u64)pdu->resid_len << 32) |
+	       ((u64)(pdu->scsi.sense_len_wr & 0xff) << 24) |
+	       ((u64)(pdu->scsi.host_status & 0xff) << 16) |
+	       ((u64)(pdu->scsi.driver_status & 0xff) << 8) |
+	       (pdu->scsi.device_status & 0xff);
+
+	if (pdu->scsi.sense_len_wr && pdu->response_addr) {
+		if (copy_to_user(uptr64(pdu->response_addr), scmd->sense_buffer,
+				 pdu->scsi.sense_len_wr))
+			ret = -EFAULT;
+	}
+
+	blk_mq_free_request(rq);
+	io_uring_cmd_done32(ioucmd, ret, res2,
+			    IO_URING_CMD_TASK_WORK_ISSUE_FLAGS);
+}
+
+/*
+ * Async completion callback executed in interrupt/atomic context.
+ * Saves SCSI status information and schedules task work for final completion.
+ */
+static enum rq_end_io_ret scsi_bsg_uring_cmd_done(struct request *req,
+						  blk_status_t status)
+{
+	struct io_uring_cmd *ioucmd = req->end_io_data;
+	struct scsi_bsg_uring_cmd_pdu *pdu = scsi_bsg_uring_cmd_pdu(ioucmd);
+	struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req);
+
+	/* Pack SCSI status fields into union */
+	pdu->scsi.device_status = scmd->result & 0xff;
+	pdu->scsi.host_status = host_byte(scmd->result);
+	pdu->scsi.driver_status = 0;
+	pdu->scsi.sense_len_wr = 0;
+
+	if (scsi_status_is_check_condition(scmd->result)) {
+		pdu->scsi.driver_status = DRIVER_SENSE;
+		if (pdu->response_addr)
+			pdu->scsi.sense_len_wr = min_t(u8, scmd->sense_len, SCSI_SENSE_BUFFERSIZE);
+	}
+
+	pdu->resid_len = scmd->resid_len;
+
+	io_uring_cmd_do_in_task_lazy(ioucmd, scsi_bsg_uring_task_cb);
+	return RQ_END_IO_NONE;
+}
+
+static int scsi_bsg_map_user_buffer(struct request *req,
+				    struct io_uring_cmd *ioucmd,
+				    unsigned int issue_flags, gfp_t gfp_mask)
+{
+	const struct bsg_uring_cmd *cmd = io_uring_sqe_cmd(ioucmd->sqe);
+	struct iov_iter iter;
+	bool is_write = cmd->dout_xfer_len > 0;
+	u64 buf_addr = is_write ? cmd->dout_xferp : cmd->din_xferp;
+	unsigned long buf_len = is_write ? cmd->dout_xfer_len : cmd->din_xfer_len;
+	int ret;
+
+	if (ioucmd->flags & IORING_URING_CMD_FIXED) {
+		ret = io_uring_cmd_import_fixed(buf_addr, buf_len,
+						is_write ? WRITE : READ,
+						&iter, ioucmd, issue_flags);
+		if (ret < 0)
+			return ret;
+		ret = blk_rq_map_user_iov(req->q, req, NULL, &iter, gfp_mask);
+	} else {
+		ret = blk_rq_map_user(req->q, req, NULL, uptr64(buf_addr),
+				      buf_len, gfp_mask);
+	}
+
+	return ret;
+}
+
 int scsi_bsg_uring_cmd(struct request_queue *q, struct io_uring_cmd *ioucmd,
 		       unsigned int issue_flags, bool open_for_write)
 {
-	return -EOPNOTSUPP;
+	struct scsi_bsg_uring_cmd_pdu *pdu = scsi_bsg_uring_cmd_pdu(ioucmd);
+	const struct bsg_uring_cmd *cmd = io_uring_sqe_cmd(ioucmd->sqe);
+	struct scsi_cmnd *scmd;
+	struct request *req;
+	blk_mq_req_flags_t blk_flags = 0;
+	gfp_t gfp_mask = GFP_KERNEL;
+	int ret = 0;
+
+	if (issue_flags & IO_URING_F_NONBLOCK) {
+		blk_flags = BLK_MQ_REQ_NOWAIT;
+		gfp_mask = GFP_NOWAIT;
+	}
+
+	req = scsi_alloc_request(q, cmd->dout_xfer_len ?
+				 REQ_OP_DRV_OUT : REQ_OP_DRV_IN, blk_flags);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	scmd = blk_mq_rq_to_pdu(req);
+	scmd->cmd_len = cmd->request_len;
+	if (scmd->cmd_len > sizeof(scmd->cmnd)) {
+		ret = -EINVAL;
+		goto out_free_req;
+	}
+	scmd->allowed = SG_DEFAULT_RETRIES;
+
+	if (copy_from_user(scmd->cmnd, uptr64(cmd->request), cmd->request_len)) {
+		ret = -EFAULT;
+		goto out_free_req;
+	}
+
+	if (!scsi_cmd_allowed(scmd->cmnd, open_for_write)) {
+		ret = -EPERM;
+		goto out_free_req;
+	}
+
+	pdu->response_addr = cmd->response;
+	scmd->sense_len = cmd->max_response_len ?
+		min(cmd->max_response_len, SCSI_SENSE_BUFFERSIZE) : SCSI_SENSE_BUFFERSIZE;
+
+	if (cmd->dout_xfer_len || cmd->din_xfer_len) {
+		ret = scsi_bsg_map_user_buffer(req, ioucmd, issue_flags, gfp_mask);
+		if (ret)
+			goto out_free_req;
+		pdu->bio = req->bio;
+	} else {
+		pdu->bio = NULL;
+	}
+
+	req->timeout = cmd->timeout_ms ?
+		msecs_to_jiffies(cmd->timeout_ms) : BLK_DEFAULT_SG_TIMEOUT;
+
+	req->end_io = scsi_bsg_uring_cmd_done;
+	req->end_io_data = ioucmd;
+	pdu->req = req;
+
+	blk_execute_rq_nowait(req, false);
+	return -EIOCBQUEUED;
+
+out_free_req:
+	blk_mq_free_request(req);
+	return ret;
 }
 
 static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC PATCH v3 0/3] bsg: add io_uring command support for SCSI passthrough
  2026-01-16  4:25 ` [RFC PATCH v3 0/3] bsg: add io_uring command support for SCSI passthrough Yang Xiuwei
                     ` (2 preceding siblings ...)
  2026-01-16  4:25   ` [RFC PATCH v3 3/3] bsg: implement SCSI BSG uring_cmd handler Yang Xiuwei
@ 2026-01-16  4:52   ` Yang Xiuwei
  3 siblings, 0 replies; 9+ messages in thread
From: Yang Xiuwei @ 2026-01-16  4:52 UTC (permalink / raw)
  To: linux-scsi, linux-block, io-uring
  Cc: fujita.tomonori, axboe, James.Bottomley, martin.petersen,
	bvanassche, Yang Xiuwei

This RFC series adds io_uring command support to the BSG (Block layer
SCSI Generic) driver, enabling asynchronous SCSI passthrough operations
with zero-copy support via fixed buffers.

The implementation follows the io_uring uring_cmd pattern used by other
drivers (e.g., nvme). A new bsg_uring_cmd structure fits within the 80-byte
cmd field of a 128-byte SQE, with 8 bytes reserved for future extensions.
The structure uses protocol-agnostic field names and follows the sg_io_v4
design with separate din_xferp/dout_xferp fields. SCSI status information
is returned in the CQE res2 field using a compact 64-bit encoding.

Currently only BSG_SUB_PROTOCOL_SCSI_CMD is implemented. Scatter/gather
I/O and bidirectional transfers are not yet supported.

The implementation has been tested with a user-space test program covering
basic SCSI commands (INQUIRY, READ CAPACITY, READ, WRITE), zero-copy mode,
and error handling.

Changes since v1:
-----------------
- Protocol-agnostic field names (request/request_len instead of cdb_addr/cdb_len)
- Removed __packed attribute for better code generation
- Reduced reserved space from 16 bytes to 8 bytes to fit within 80-byte SQE

Why v2 was superseded:
----------------------
v2 unified din_xferp/dout_xferp into a single xfer_addr field, which
diverged from the established sg_io_v4 interface. v3 reverts to separate
din_xferp/dout_xferp fields to maintain consistency with the existing
BSG interface.

Yang Xiuwei (3):
  bsg: add bsg_uring_cmd uapi structure
  bsg: add uring_cmd support to BSG generic layer
  bsg: implement SCSI BSG uring_cmd handler

 block/bsg.c              |  66 ++++++++++++++
 drivers/scsi/scsi_bsg.c  | 192 +++++++++++++++++++++++++++++++++++++++
 include/linux/bsg.h       |   4 +
 include/uapi/linux/bsg.h  |  24 +++++
 4 files changed, 286 insertions(+)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-01-16  4:52 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-15  1:24 [RFC PATCH v2 0/3] bsg: add io_uring command support for SCSI passthrough Yang Xiuwei
2026-01-15  1:24 ` [RFC PATCH v2 1/3] bsg: add bsg_uring_cmd uapi structure Yang Xiuwei
2026-01-15  1:24 ` [RFC PATCH v2 2/3] bsg: add uring_cmd support to BSG generic layer Yang Xiuwei
2026-01-15  1:24 ` [RFC PATCH v2 3/3] bsg: implement SCSI BSG uring_cmd handler Yang Xiuwei
2026-01-16  4:25 ` [RFC PATCH v3 0/3] bsg: add io_uring command support for SCSI passthrough Yang Xiuwei
2026-01-16  4:25   ` [RFC PATCH v3 1/3] bsg: add bsg_uring_cmd uapi structure Yang Xiuwei
2026-01-16  4:25   ` [RFC PATCH v3 2/3] bsg: add uring_cmd support to BSG generic layer Yang Xiuwei
2026-01-16  4:25   ` [RFC PATCH v3 3/3] bsg: implement SCSI BSG uring_cmd handler Yang Xiuwei
2026-01-16  4:52   ` [RFC PATCH v3 0/3] bsg: add io_uring command support for SCSI passthrough Yang Xiuwei

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox