| 1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ |
| 2 | #ifndef BSG_H |
| 3 | #define BSG_H |
| 4 | |
| 5 | #include <linux/types.h> |
| 6 | |
| 7 | #define BSG_PROTOCOL_SCSI		0 |
| 8 | |
| 9 | #define BSG_SUB_PROTOCOL_SCSI_CMD	0 |
| 10 | #define BSG_SUB_PROTOCOL_SCSI_TMF	1 |
| 11 | #define BSG_SUB_PROTOCOL_SCSI_TRANSPORT	2 |
| 12 | |
| 13 | /* |
| 14 | * For flag constants below: |
| 15 | * sg.h sg_io_hdr also has bits defined for it's flags member. These |
| 16 | * two flag values (0x10 and 0x20) have the same meaning in sg.h . For |
| 17 | * bsg the BSG_FLAG_Q_AT_HEAD flag is ignored since it is the deafult. |
| 18 | */ |
| 19 | #define BSG_FLAG_Q_AT_TAIL 0x10 /* default is Q_AT_HEAD */ |
| 20 | #define BSG_FLAG_Q_AT_HEAD 0x20 |
| 21 | |
| 22 | struct sg_io_v4 { |
| 23 | 	__s32 guard;		/* [i] 'Q' to differentiate from v3 */ |
| 24 | 	__u32 protocol;		/* [i] 0 -> SCSI , .... */ |
| 25 | 	__u32 subprotocol;	/* [i] 0 -> SCSI command, 1 -> SCSI task |
| 26 | 				 management function, .... */ |
| 27 | |
| 28 | 	__u32 request_len;	/* [i] in bytes */ |
| 29 | 	__u64 request;		/* [i], [*i] {SCSI: cdb} */ |
| 30 | 	__u64 request_tag;	/* [i] {SCSI: task tag (only if flagged)} */ |
| 31 | 	__u32 request_attr;	/* [i] {SCSI: task attribute} */ |
| 32 | 	__u32 request_priority;	/* [i] {SCSI: task priority} */ |
| 33 | 	__u32 request_extra;	/* [i] {spare, for padding} */ |
| 34 | 	__u32 max_response_len;	/* [i] in bytes */ |
| 35 | 	__u64 response;		/* [i], [*o] {SCSI: (auto)sense data} */ |
| 36 | |
| 37 | /* "dout_": data out (to device); "din_": data in (from device) */ |
| 38 | 	__u32 dout_iovec_count;	/* [i] 0 -> "flat" dout transfer else |
| 39 | 				 dout_xfer points to array of iovec */ |
| 40 | 	__u32 dout_xfer_len;	/* [i] bytes to be transferred to device */ |
| 41 | 	__u32 din_iovec_count;	/* [i] 0 -> "flat" din transfer */ |
| 42 | 	__u32 din_xfer_len;	/* [i] bytes to be transferred from device */ |
| 43 | 	__u64 dout_xferp;	/* [i], [*i] */ |
| 44 | 	__u64 din_xferp;	/* [i], [*o] */ |
| 45 | |
| 46 | 	__u32 timeout;		/* [i] units: millisecond */ |
| 47 | 	__u32 flags;		/* [i] bit mask */ |
| 48 | 	__u64 usr_ptr;		/* [i->o] unused internally */ |
| 49 | 	__u32 spare_in;		/* [i] */ |
| 50 | |
| 51 | 	__u32 driver_status;	/* [o] 0 -> ok */ |
| 52 | 	__u32 transport_status;	/* [o] 0 -> ok */ |
| 53 | 	__u32 device_status;	/* [o] {SCSI: command completion status} */ |
| 54 | 	__u32 retry_delay;	/* [o] {SCSI: status auxiliary information} */ |
| 55 | 	__u32 info;		/* [o] additional information */ |
| 56 | 	__u32 duration;		/* [o] time to complete, in milliseconds */ |
| 57 | 	__u32 response_len;	/* [o] bytes of response actually written */ |
| 58 | 	__s32 din_resid;	/* [o] din_xfer_len - actual_din_xfer_len */ |
| 59 | 	__s32 dout_resid;	/* [o] dout_xfer_len - actual_dout_xfer_len */ |
| 60 | 	__u64 generated_tag;	/* [o] {SCSI: transport generated task tag} */ |
| 61 | 	__u32 spare_out;	/* [o] */ |
| 62 | |
| 63 | 	__u32 padding; |
| 64 | }; |
| 65 | |
| 66 | struct bsg_uring_cmd { |
| 67 | 	__u64 request;		/* [i], [*i] command descriptor address */ |
| 68 | 	__u32 request_len;	/* [i] command descriptor length in bytes */ |
| 69 | 	__u32 protocol;		/* [i] protocol type (BSG_PROTOCOL_*) */ |
| 70 | 	__u32 subprotocol;	/* [i] subprotocol type (BSG_SUB_PROTOCOL_*) */ |
| 71 | 	__u32 max_response_len;	/* [i] response buffer size in bytes */ |
| 72 | |
| 73 | 	__u64 response;		/* [i], [*o] response data address */ |
| 74 | 	__u64 dout_xferp;	/* [i], [*i] */ |
| 75 | 	__u32 dout_xfer_len;	/* [i] bytes to be transferred to device */ |
| 76 | 	__u32 dout_iovec_count;	/* [i] 0 -> "flat" dout transfer else |
| 77 | 				 * dout_xferp points to array of iovec |
| 78 | 				 */ |
| 79 | 	__u64 din_xferp;	/* [i], [*o] */ |
| 80 | 	__u32 din_xfer_len;	/* [i] bytes to be transferred from device */ |
| 81 | 	__u32 din_iovec_count;	/* [i] 0 -> "flat" din transfer */ |
| 82 | |
| 83 | 	__u32 timeout_ms;	/* [i] timeout in milliseconds */ |
| 84 | 	__u8 reserved[12];	/* reserved for future extension */ |
| 85 | }; |
| 86 | |
| 87 | |
| 88 | |
| 89 | /* |
| 90 | * SCSI BSG io_uring completion (res2, 64-bit) |
| 91 | * |
| 92 | * When using BSG_PROTOCOL_SCSI + BSG_SUB_PROTOCOL_SCSI_CMD with |
| 93 | * IORING_OP_URING_CMD, the completion queue entry (CQE) contains: |
| 94 | * - result: errno (0 on success) |
| 95 | * - res2: packed SCSI status |
| 96 | * |
| 97 | * res2 bit layout: |
| 98 | * [0..7] device_status (SCSI status byte, e.g. CHECK_CONDITION) |
| 99 | * [8..15] driver_status (e.g. DRIVER_SENSE when sense data is valid) |
| 100 | * [16..23] host_status (e.g. DID_OK, DID_TIME_OUT) |
| 101 | * [24..31] sense_len_wr (bytes of sense data written to response buffer) |
| 102 | * [32..63] resid_len (residual transfer length) |
| 103 | */ |
| 104 | static __inline__ __u8 bsg_scsi_res2_device_status(__u64 res2) |
| 105 | { |
| 106 | 	return res2 & 0xff; |
| 107 | } |
| 108 | static __inline__ __u8 bsg_scsi_res2_driver_status(__u64 res2) |
| 109 | { |
| 110 | 	return res2 >> 8; |
| 111 | } |
| 112 | static __inline__ __u8 bsg_scsi_res2_host_status(__u64 res2) |
| 113 | { |
| 114 | 	return res2 >> 16; |
| 115 | } |
| 116 | static __inline__ __u8 bsg_scsi_res2_sense_len(__u64 res2) |
| 117 | { |
| 118 | 	return res2 >> 24; |
| 119 | } |
| 120 | static __inline__ __u32 bsg_scsi_res2_resid_len(__u64 res2) |
| 121 | { |
| 122 | 	return res2 >> 32; |
| 123 | } |
| 124 | static __inline__ __u64 bsg_scsi_res2_build(__u8 device_status, __u8 driver_status, |
| 125 | 					__u8 host_status, __u8 sense_len_wr, |
| 126 | 					__u32 resid_len) |
| 127 | { |
| 128 | 	return ((__u64)(__u32)(resid_len) << 32) | |
| 129 | 		((__u64)sense_len_wr << 24) | |
| 130 | 		((__u64)host_status << 16) | |
| 131 | 		((__u64)driver_status << 8) | |
| 132 | 		(__u64)device_status; |
| 133 | } |
| 134 | |
| 135 | #endif /* BSG_H */ |