1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Emulation of enough SCSI commands to find and read from a unit
4 *
5 * Copyright 2022 Google LLC
6 * Written by Simon Glass <sjg@chromium.org>
7 *
8 * implementations of SCSI functions required so that CONFIG_SCSI can be enabled
9 * for sandbox
10 */
11
12#ifndef __scsi_emul_h
13#define __scsi_emul_h
14
15/**
16 * struct scsi_emul_info - information for emulating a SCSI device
17 *
18 * @vendor: Vendor name
19 * @product: Product name
20 * @block_size: Block size of device in bytes (normally 512)
21 * @file_size: Size of the backing file for this emulator, in bytes
22 * @seek_block: Seek position for file (block number)
23 *
24 * @phase: Current SCSI phase
25 * @buff_used: Number of bytes ready to transfer back to host
26 * @read_len: Number of bytes of data left in the current read command
27 * @alloc_len: Allocation length from the last incoming command
28 * @transfer_len: Transfer length from CBW header
29 * @buff: Data buffer for outgoing data
30 */
31struct scsi_emul_info {
32	/* provided by the caller: */
33	void *buff;
34	const char *vendor;
35	const char *product;
36	int block_size;
37	loff_t file_size;
38	int seek_block;
39
40	/* state maintained by the emulator: */
41	enum scsi_cmd_phase phase;
42	int buff_used;
43	int read_len;
44	int write_len;
45	uint seek_pos;
46	int alloc_len;
47	uint transfer_len;
48};
49
50/**
51 * Return value from sb_scsi_emul_command() indicates that a read or write is
52 * being started
53 */
54enum {
55	SCSI_EMUL_DO_READ	= 1,
56	SCSI_EMUL_DO_WRITE	= 2,
57};
58
59/**
60 * sb_scsi_emul_command() - Process a SCSI command
61 *
62 * This sets up the response in info->buff and updates various other values
63 * in info.
64 *
65 * If SCSI_EMUL_DO_READ is returned then the caller should set up so that the
66 * backing file can be read, or return an error status if there is no file.
67 *
68 * @info: Emulation information
69 * @req: Request to process
70 * @len: Length of request in bytes
71 * @return SCSI_EMUL_DO_READ if a read has started, SCSI_EMUL_DO_WRITE if a
72 *	write has started, 0 if some other operation has started, -ve if there
73 *	was an error
74 */
75int sb_scsi_emul_command(struct scsi_emul_info *info,
76			 const struct scsi_cmd *req, int len);
77
78#endif
79