1 // SPDX-License-Identifier: GPL-2.0+
3 * Emulation of enough SCSI commands to find and read from a unit
5 * Copyright 2022 Google LLC
6 * Written by Simon Glass <sjg@chromium.org>
8 * implementation of SCSI functions required so that CONFIG_SCSI can be enabled
12 #define LOG_CATEGORY UCLASS_SCSI
18 #include <scsi_emul.h>
20 int sb_scsi_emul_command(struct scsi_emul_info *info,
21 const struct scsi_cmd *req, int len)
26 log_debug("emul %x\n", *req->cmd);
29 struct scsi_inquiry_resp *resp = (void *)info->buff;
31 info->alloc_len = req->cmd[4];
32 memset(resp, '\0', sizeof(*resp));
33 resp->data_format = 1;
34 resp->additional_len = 0x1f;
35 strncpy(resp->vendor, info->vendor, sizeof(resp->vendor));
36 strncpy(resp->product, info->product, sizeof(resp->product));
37 strncpy(resp->revision, "1.0", sizeof(resp->revision));
38 info->buff_used = sizeof(*resp);
44 struct scsi_read_capacity_resp *resp = (void *)info->buff;
48 blocks = info->file_size / info->block_size - 1;
51 resp->last_block_addr = cpu_to_be32(blocks);
52 resp->block_len = cpu_to_be32(info->block_size);
53 info->buff_used = sizeof(*resp);
57 const struct scsi_read10_req *read_req = (void *)req;
59 info->seek_block = be32_to_cpu(read_req->lba);
60 info->read_len = be16_to_cpu(read_req->xfer_len);
61 info->buff_used = info->read_len * info->block_size;
62 ret = SCSI_EMUL_DO_READ;
66 const struct scsi_write10_req *write_req = (void *)req;
68 info->seek_block = be32_to_cpu(write_req->lba);
69 info->write_len = be16_to_cpu(write_req->xfer_len);
70 info->buff_used = info->write_len * info->block_size;
71 ret = SCSI_EMUL_DO_WRITE;
75 debug("Command not supported: %x\n", req->cmd[0]);
76 ret = -EPROTONOSUPPORT;
79 info->phase = info->transfer_len ? SCSIPH_DATA : SCSIPH_STATUS;
80 log_debug(" - done %x: ret=%d\n", *req->cmd, ret);