/*
 * Copyright (c) 2023 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/storage/disk_access.h>
#include <zephyr/sys/byteorder.h>

#include "usbd_msc_scsi.h"

#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(usbd_msc, CONFIG_USBD_MSC_LOG_LEVEL);

#define INQUIRY_VERSION_SPC_2	0x04
#define INQUIRY_VERSION_SPC_3	0x05
#define INQUIRY_VERSION_SPC_4	0x06
#define INQUIRY_VERSION_SPC_5	0x07

/* Claim conformance to SPC-2 because this allows us to implement less commands
 * and do not care about multiple reserved bits that became actual options
 * later on. DO NOT change unless you make sure that all mandatory commands are
 * implemented and all options (e.g. vpd pages) that are mandatory at given
 * version are also implemented.
 */
#define CLAIMED_CONFORMANCE_VERSION INQUIRY_VERSION_SPC_2

#define T10_VENDOR_LENGTH	8
#define T10_PRODUCT_LENGTH	16
#define T10_REVISION_LENGTH	4

/* Optional, however Windows insists on reading Unit Serial Number.
 * There doesn't seem to be requirement on minimum product serial number length,
 * however when the number is not available the device shall return ASCII spaces
 * in the field.
 */
#define UNIT_SERIAL_NUMBER "  "

/* Every SCSI command has to abide to the general handling rules. Use macros
 * to allow generating boilerplate handling code.
 */
#define SCSI_CMD_STRUCT(opcode) struct scsi_##opcode##_cmd
#define SCSI_CMD_HANDLER(opcode)					\
static int scsi_##opcode(struct scsi_ctx *ctx,				\
			 struct scsi_##opcode##_cmd *cmd,		\
			 uint8_t data_in_buf[static CONFIG_USBD_MSC_SCSI_BUFFER_SIZE])

/* SAM-6 5.2 Command descriptor block (CDB)
 * Table 43 – CONTROL byte
 */
#define GET_CONTROL_NACA(cmd)		(cmd->control & BIT(2))

/* SPC-5 4.3.3 Variable type data field requirements
 * Table 25 — Code set enumeration
 */
enum code_set {
	CODE_SET_BINARY = 0x1,
	CODE_SET_ASCII = 0x2,
	CODE_SET_UTF8 = 0x3,
};

/* SPC-5 F.3.1 Operation codes Table F.2 — Operation codes */
enum scsi_opcode {
	TEST_UNIT_READY = 0x00,
	REQUEST_SENSE = 0x03,
	INQUIRY = 0x12,
	MODE_SENSE_6 = 0x1A,
	START_STOP_UNIT = 0x1B,
	PREVENT_ALLOW_MEDIUM_REMOVAL = 0x1E,
	READ_FORMAT_CAPACITIES = 0x23,
	READ_CAPACITY_10 = 0x25,
	READ_10 = 0x28,
	WRITE_10 = 0x2A,
	MODE_SENSE_10 = 0x5A,
};

SCSI_CMD_STRUCT(TEST_UNIT_READY) {
	uint8_t opcode;
	uint32_t reserved;
	uint8_t control;
} __packed;

/* DESC bit was reserved in SPC-2 and is optional since SPC-3 */
#define GET_REQUEST_SENSE_DESC(cmd)	(cmd->desc & BIT(0))

SCSI_CMD_STRUCT(REQUEST_SENSE) {
	uint8_t opcode;
	uint8_t desc;
	uint8_t reserved2;
	uint8_t reserved3;
	uint8_t allocation_length;
	uint8_t control;
} __packed;

#define SENSE_VALID			BIT(7)
#define SENSE_CODE_CURRENT_ERRORS	0x70
#define SENSE_CODE_DEFERRED_ERRORS	0x71

#define SENSE_FILEMARK			BIT(7)
#define SENSE_EOM			BIT(6)
#define SENSE_ILI			BIT(5)
#define SENSE_KEY_MASK			BIT_MASK(4)

#define SENSE_SKSV			BIT(7)

struct scsi_request_sense_response {
	uint8_t valid_code;
	uint8_t obsolete;
	uint8_t filemark_eom_ili_sense_key;
	uint32_t information;
	uint8_t additional_sense_length;
	uint32_t command_specific_information;
	uint16_t additional_sense_with_qualifier;
	uint8_t field_replaceable_unit_code;
	uint8_t sksv;
	uint16_t sense_key_specific;
} __packed;

#define INQUIRY_EVPD		BIT(0)
/* CMDDT in SPC-2, but obsolete since SPC-3 */
#define INQUIRY_CMDDT_OBSOLETE	BIT(1)

enum vpd_page_code {
	VPD_SUPPORTED_VPD_PAGES = 0x00,
	VPD_UNIT_SERIAL_NUMBER = 0x80,
	VPD_DEVICE_IDENTIFICATION = 0x83,
};

/* SPC-5 Table 517 — DESIGNATOR TYPE field */
enum designator_type {
	DESIGNATOR_VENDOR = 0x0,
	DESIGNATOR_T10_VENDOR_ID_BASED = 0x1,
	DESIGNATOR_EUI_64_BASED = 0x2,
	DESIGNATOR_NAA = 0x3,
	DESIGNATOR_RELATIVE_TARGET_PORT_IDENTIFIER = 0x4,
	DESIGNATOR_TARGET_PORT_GROUP = 0x5,
	DESIGNATOR_MD5_LOGICAL_UNIT_IDENTIFIER = 0x6,
	DESIGNATOR_SCSI_NAME_STRING = 0x8,
	DESIGNATOR_PROTOCOL_SPECIFIC_PORT_IDENTIFIER = 0x9,
	DESIGNATOR_UUID_IDENTIFIER = 0xA,
};

SCSI_CMD_STRUCT(INQUIRY) {
	uint8_t opcode;
	uint8_t cmddt_evpd;
	uint8_t page_code;
	/* Allocation length was 8-bit (LSB only) in SPC-2. MSB was reserved
	 * and hence SPC-2 compliant initiators should set it to 0.
	 */
	uint16_t allocation_length;
	uint8_t control;
} __packed;

struct scsi_inquiry_response {
	uint8_t peripheral;
	uint8_t rmb;
	uint8_t version;
	uint8_t format;
	uint8_t additional_length;
	uint8_t sccs;
	uint8_t encserv;
	uint8_t cmdque;
	char scsi_vendor[T10_VENDOR_LENGTH];
	char product[T10_PRODUCT_LENGTH];
	char revision[T10_REVISION_LENGTH];
	/* SPC-5 states the standard INQUIRY should contain at least 36 bytes.
	 * We do the minimum required (and thus end the inquiry response here),
	 * as there is no real use in Zephyr for vendor specific data and/or
	 * parameters and we don't claim conformance to specific versions.
	 */
} __packed;

#define MODE_SENSE_PAGE_CODE_ALL_PAGES		0x3F

SCSI_CMD_STRUCT(MODE_SENSE_6) {
	uint8_t opcode;
	uint8_t dbd;
	uint8_t page;
	uint8_t subpage;
	uint8_t allocation_length;
	uint8_t control;
} __packed;

/* SPC-5 7.5.6 Mode parameter header formats
 * Table 443 — Mode parameter header(6)
 */
struct scsi_mode_sense_6_response {
	uint8_t mode_data_length;
	uint8_t medium_type;
	uint8_t device_specific_parameter;
	uint8_t block_descriptor_length;
} __packed;

#define GET_IMMED(cmd)				(cmd->immed & BIT(0))
#define GET_POWER_CONDITION_MODIFIER(cmd)	(cmd->condition & BIT_MASK(4))
#define GET_POWER_CONDITION(cmd)		((cmd->start & 0xF0) >> 4)
#define GET_NO_FLUSH(cmd)			(cmd->start & BIT(2))
#define GET_LOEJ(cmd)				(cmd->start & BIT(1))
#define GET_START(cmd)				(cmd->start & BIT(0))
/* SBC-4 Table 114 — POWER CONDITION and POWER CONDITION MODIFIER field */
enum power_condition {
	POWER_COND_START_VALID = 0x0,
	POWER_COND_ACTIVE = 0x1,
	POWER_COND_IDLE = 0x2,
	POWER_COND_STANDBY = 0x3,
	POWER_COND_LU_CONTROL = 0x7,
	POWER_COND_FORCE_IDLE_0 = 0xA,
	POWER_COND_FORCE_STANDBY_0 = 0xB,
};

SCSI_CMD_STRUCT(START_STOP_UNIT) {
	uint8_t opcode;
	uint8_t immed;
	uint8_t reserved;
	uint8_t condition;
	uint8_t start;
	uint8_t control;
} __packed;

#define GET_PREVENT(cmd)			(cmd->prevent & BIT_MASK(2))
/* SBC-4 Table 77 — PREVENT field */
enum prevent_field {
	MEDIUM_REMOVAL_ALLOWED = 0,
	MEDIUM_REMOVAL_SHALL_BE_PREVENTED = 1,
	PREVENT_OBSOLETE_2 = 2,
	PREVENT_OBSOLETE_3 = 3,
};

SCSI_CMD_STRUCT(PREVENT_ALLOW_MEDIUM_REMOVAL) {
	uint8_t opcode;
	uint8_t reserved1;
	uint8_t reserved2;
	uint8_t reserved3;
	uint8_t prevent;
	uint8_t control;
} __packed;

SCSI_CMD_STRUCT(READ_FORMAT_CAPACITIES) {
	uint8_t opcode;
	uint8_t reserved1;
	uint8_t reserved2;
	uint8_t reserved3;
	uint8_t reserved4;
	uint8_t reserved5;
	uint8_t reserved6;
	uint16_t allocation_length;
	uint8_t control;
} __packed;

struct capacity_list_header {
	uint8_t reserved1;
	uint8_t reserved2;
	uint8_t reserved3;
	uint8_t capacity_list_length;
} __packed;

enum descriptor_types {
	UNFORMATTED_OR_BLANK_MEDIA = 1,
	FORMATTED_MEDIA = 2,
	NO_MEDIA_PRESENT_OR_UNKNOWN_CAPACITY = 3,
};

struct current_maximum_capacity_descriptor {
	uint32_t number_of_blocks;
	uint8_t type;
	uint32_t block_length : 24;
} __packed;

struct scsi_read_format_capacities_response {
	struct capacity_list_header header;
	struct current_maximum_capacity_descriptor desc;
} __packed;

SCSI_CMD_STRUCT(READ_CAPACITY_10) {
	uint8_t opcode;
	uint8_t reserved_or_obsolete[8];
	uint8_t control;
} __packed;

struct scsi_read_capacity_10_response {
	uint32_t last_lba;
	uint32_t block_length;
} __packed;

SCSI_CMD_STRUCT(READ_10) {
	uint8_t opcode;
	uint8_t rdprotect;
	uint32_t lba;
	uint8_t group_number;
	uint16_t transfer_length;
	uint8_t control;
} __packed;

SCSI_CMD_STRUCT(WRITE_10) {
	uint8_t opcode;
	uint8_t wrprotect;
	uint32_t lba;
	uint8_t group_number;
	uint16_t transfer_length;
	uint8_t control;
} __packed;

SCSI_CMD_STRUCT(MODE_SENSE_10) {
	uint8_t opcode;
	uint8_t llbaa_dbd;
	uint8_t page;
	uint8_t subpage;
	uint8_t reserved4;
	uint8_t reserved5;
	uint8_t reserved6;
	uint16_t allocation_length;
	uint8_t control;
} __packed;

/* SPC-5 7.5.6 Mode parameter header formats
 * Table 444 — Mode parameter header(10)
 */
struct scsi_mode_sense_10_response {
	uint16_t mode_data_length;
	uint8_t medium_type;
	uint8_t device_specific_parameter;
	uint8_t longlba;
	uint8_t reserved5;
	uint16_t block_descriptor_length;
} __packed;

static int update_disk_info(struct scsi_ctx *const ctx)
{
	int status = disk_access_status(ctx->disk);

	if (disk_access_ioctl(ctx->disk, DISK_IOCTL_GET_SECTOR_COUNT, &ctx->sector_count) != 0) {
		ctx->sector_count = 0;
		status = -EIO;
	}

	if (disk_access_ioctl(ctx->disk, DISK_IOCTL_GET_SECTOR_SIZE, &ctx->sector_size) != 0) {
		ctx->sector_size = 0;
		status = -EIO;
	}

	if (ctx->sector_size > CONFIG_USBD_MSC_SCSI_BUFFER_SIZE) {
		status = -ENOMEM;
	}

	return status;
}

static size_t good(struct scsi_ctx *ctx, size_t data_in_bytes)
{
	ctx->status = GOOD;
	ctx->sense_key = NO_SENSE;
	ctx->asc = NO_ADDITIONAL_SENSE_INFORMATION;

	return data_in_bytes;
}

static size_t illegal_request(struct scsi_ctx *ctx, enum scsi_additional_sense_code asc)
{
	ctx->status = CHECK_CONDITION;
	ctx->sense_key = ILLEGAL_REQUEST;
	ctx->asc = asc;

	return 0;
}

static size_t not_ready(struct scsi_ctx *ctx, enum scsi_additional_sense_code asc)
{
	ctx->status = CHECK_CONDITION;
	ctx->sense_key = NOT_READY;
	ctx->asc = asc;

	return 0;
}

static size_t medium_error(struct scsi_ctx *ctx, enum scsi_additional_sense_code asc)
{
	ctx->status = CHECK_CONDITION;
	ctx->sense_key = MEDIUM_ERROR;
	ctx->asc = asc;

	return 0;
}

void scsi_init(struct scsi_ctx *ctx, const char *disk, const char *vendor,
	       const char *product, const char *revision)
{
	memset(ctx, 0, sizeof(struct scsi_ctx));
	ctx->disk = disk;
	ctx->vendor = vendor;
	ctx->product = product;
	ctx->revision = revision;

	scsi_reset(ctx);
}

void scsi_reset(struct scsi_ctx *ctx)
{
	ctx->prevent_removal = false;
	ctx->medium_loaded = true;
}

/* SPC-5 TEST UNIT READY command */
SCSI_CMD_HANDLER(TEST_UNIT_READY)
{
	if (!ctx->medium_loaded || update_disk_info(ctx) != DISK_STATUS_OK) {
		return not_ready(ctx, MEDIUM_NOT_PRESENT);
	} else {
		return good(ctx, 0);
	}
}

/* SPC-5 REQUEST SENSE command */
SCSI_CMD_HANDLER(REQUEST_SENSE)
{
	struct scsi_request_sense_response r;
	int length;

	ctx->cmd_is_data_read = true;

	/* SPC-2 should ignore DESC (it was reserved)
	 * SPC-3 can ignore DESC if not supported
	 * SPC-4 and later shall error out if DESC is not supported
	 */
	if ((CLAIMED_CONFORMANCE_VERSION >= INQUIRY_VERSION_SPC_4) &&
	    (GET_REQUEST_SENSE_DESC(cmd))) {
		return illegal_request(ctx, INVALID_FIELD_IN_CDB);
	}

	r.valid_code = SENSE_CODE_CURRENT_ERRORS;
	r.obsolete = 0;
	r.filemark_eom_ili_sense_key = ctx->sense_key & SENSE_KEY_MASK;
	r.information = sys_cpu_to_be32(0);
	r.additional_sense_length = sizeof(struct scsi_request_sense_response) - 1 -
		offsetof(struct scsi_request_sense_response, additional_sense_length);
	r.command_specific_information = sys_cpu_to_be32(0);
	r.additional_sense_with_qualifier = sys_cpu_to_be16(ctx->asc);
	r.field_replaceable_unit_code = 0;
	r.sksv = 0;
	r.sense_key_specific = sys_cpu_to_be16(0);

	BUILD_ASSERT(sizeof(r) <= CONFIG_USBD_MSC_SCSI_BUFFER_SIZE);
	length = MIN(cmd->allocation_length, sizeof(r));
	memcpy(data_in_buf, &r, length);

	/* REQUEST SENSE completed successfully, old sense information is
	 * cleared according to SPC-5.
	 */
	return good(ctx, length);
}

static int fill_inquiry(struct scsi_ctx *ctx,
			uint8_t buf[static CONFIG_USBD_MSC_SCSI_BUFFER_SIZE])
{
	/* For simplicity prepare whole response on stack and then copy
	 * requested length.
	 */
	struct scsi_inquiry_response r;

	memset(&r, 0, sizeof(struct scsi_inquiry_response));

	/* Accessible; Direct access block device (SBC) */
	r.peripheral = 0x00;
	/* Removable; not a part of conglomerate. Note that when device is
	 * accessible via USB Mass Storage, it should always be marked as
	 * removable to allow Safely Remove Hardware.
	 */
	r.rmb = 0x80;
	r.version = CLAIMED_CONFORMANCE_VERSION;
	/* ACA not supported; No SAM-5 LUNs; Complies to SPC */
	r.format = 0x02;
	r.additional_length = sizeof(struct scsi_inquiry_response) - 1 -
		offsetof(struct scsi_inquiry_response, additional_length);
	/* No embedded storage array controller available */
	r.sccs = 0x00;
	/* No embedded enclosure services */
	r.encserv = 0x00;
	/* Does not support SAM-5 command management model */
	r.cmdque = 0x00;

	strncpy(r.scsi_vendor, ctx->vendor, sizeof(r.scsi_vendor));
	strncpy(r.product, ctx->product, sizeof(r.product));
	strncpy(r.revision, ctx->revision, sizeof(r.revision));

	BUILD_ASSERT(sizeof(r) <= CONFIG_USBD_MSC_SCSI_BUFFER_SIZE);
	memcpy(buf, &r, sizeof(r));
	return sizeof(r);
}

static int fill_vpd_page(struct scsi_ctx *ctx, enum vpd_page_code page,
			 uint8_t buf[static CONFIG_USBD_MSC_SCSI_BUFFER_SIZE])
{
	uint16_t offset = 0;
	uint8_t *page_start = &buf[4];

	switch (page) {
	case VPD_SUPPORTED_VPD_PAGES:
		/* Page Codes must appear in ascending order */
		page_start[offset++] = VPD_SUPPORTED_VPD_PAGES;
		page_start[offset++] = VPD_UNIT_SERIAL_NUMBER;
		page_start[offset++] = VPD_DEVICE_IDENTIFICATION;
		break;
	case VPD_DEVICE_IDENTIFICATION:
		/* Absolute minimum is one vendor based descriptor formed by
		 * concatenating Vendor ID and Unit Serial Number
		 *
		 * Other descriptors (EUI-64 or NAA) should be there but should
		 * is equivalent to "it is strongly recommended" and adding them
		 * is pretty much problematic because these descriptors involve
		 * (additional) unique identifiers.
		 */
		page_start[offset++] = CODE_SET_ASCII;
		page_start[offset++] = DESIGNATOR_T10_VENDOR_ID_BASED;
		page_start[offset++] = 0x00;
		page_start[offset++] = T10_VENDOR_LENGTH + sizeof(UNIT_SERIAL_NUMBER) - 1;
		strncpy(&page_start[offset], ctx->vendor, T10_VENDOR_LENGTH);
		offset += T10_VENDOR_LENGTH;
		memcpy(&page_start[offset], UNIT_SERIAL_NUMBER, sizeof(UNIT_SERIAL_NUMBER) - 1);
		offset += sizeof(UNIT_SERIAL_NUMBER) - 1;
		break;
	case VPD_UNIT_SERIAL_NUMBER:
		memcpy(page_start, UNIT_SERIAL_NUMBER, sizeof(UNIT_SERIAL_NUMBER) - 1);
		offset += sizeof(UNIT_SERIAL_NUMBER) - 1;
		break;
	default:
		return -ENOTSUP;
	}

	/* Accessible; Direct access block device (SBC) */
	buf[0] = 0x00;
	buf[1] = page;
	sys_put_be16(offset, &buf[2]);
	return offset + 4;
}

/* SPC-5 6.7 INQUIRY command */
SCSI_CMD_HANDLER(INQUIRY)
{
	int ret;

	ctx->cmd_is_data_read = true;

	if (cmd->cmddt_evpd & INQUIRY_CMDDT_OBSOLETE) {
		/* Optional in SPC-2 and later obsoleted, do not support it */
		ret = -EINVAL;
	} else if (cmd->cmddt_evpd & INQUIRY_EVPD) {
		/* Linux won't ask for VPD unless enabled with
		 * echo "Zephyr:Disk:0x10000000" > /proc/scsi/device_info
		 */
		ret = MIN(sys_be16_to_cpu(cmd->allocation_length),
			  fill_vpd_page(ctx, cmd->page_code, data_in_buf));
	} else if (cmd->page_code != 0) {
		LOG_WRN("Page Code is %d but EVPD set", cmd->page_code);
		ret = -EINVAL;
	} else {
		/* Standard inquiry */
		ret = MIN(sys_be16_to_cpu(cmd->allocation_length),
			  fill_inquiry(ctx, data_in_buf));
	}

	if (ret < 0) {
		return illegal_request(ctx, INVALID_FIELD_IN_CDB);
	}
	return good(ctx, ret);
}

/* SPC-5 6.14 MODE SENSE(6) command */
SCSI_CMD_HANDLER(MODE_SENSE_6)
{
	struct scsi_mode_sense_6_response r;
	int length;

	ctx->cmd_is_data_read = true;

	if (cmd->page != MODE_SENSE_PAGE_CODE_ALL_PAGES || cmd->subpage != 0) {
		return illegal_request(ctx, INVALID_FIELD_IN_CDB);
	}

	r.mode_data_length = 3;
	r.medium_type = 0x00;
	r.device_specific_parameter = 0x00;
	r.block_descriptor_length = 0x00;

	BUILD_ASSERT(sizeof(r) <= CONFIG_USBD_MSC_SCSI_BUFFER_SIZE);
	length = MIN(cmd->allocation_length, sizeof(r));
	memcpy(data_in_buf, &r, length);
	return good(ctx, length);
}

/* SBC-4 5.31 START STOP UNIT command */
SCSI_CMD_HANDLER(START_STOP_UNIT)
{
	bool medium_loaded = ctx->medium_loaded;

	/* Safe Hardware Removal is essentially START STOP UNIT command that
	 * asks to eject the media. Disk is shown as safely removed when
	 * device (SCSI target) responds with NOT READY/MEDIUM NOT PRESENT to
	 * TEST UNIT READY command
	 */
	if (GET_POWER_CONDITION(cmd) == POWER_COND_START_VALID) {
		if (GET_LOEJ(cmd)) {
			if (GET_START(cmd)) {
				medium_loaded = true;
			} else {
				medium_loaded = false;
			}
		}
	}

	if (!medium_loaded && ctx->medium_loaded && ctx->prevent_removal) {
		return illegal_request(ctx, MEDIUM_REMOVAL_PREVENTED);
	}

	ctx->medium_loaded = medium_loaded;
	return good(ctx, 0);
}

/* SBC-4 5.15 PREVENT ALLOW MEDIUM REMOVAL command */
SCSI_CMD_HANDLER(PREVENT_ALLOW_MEDIUM_REMOVAL)
{
	switch (GET_PREVENT(cmd)) {
	case MEDIUM_REMOVAL_ALLOWED:
		ctx->prevent_removal = false;
		break;
	case MEDIUM_REMOVAL_SHALL_BE_PREVENTED:
		ctx->prevent_removal = true;
		break;
	case PREVENT_OBSOLETE_2:
	case PREVENT_OBSOLETE_3:
		break;
	}

	return good(ctx, 0);
}

/* MMC-6 6.23 READ FORMAT CAPACITIES command
 * Microsoft Windows issues this command for all USB drives (no idea why)
 */
SCSI_CMD_HANDLER(READ_FORMAT_CAPACITIES)
{
	struct scsi_read_format_capacities_response r;
	int length;

	ctx->cmd_is_data_read = true;

	memset(&r, 0, sizeof(r));
	r.header.capacity_list_length = sizeof(r) - sizeof(r.header);

	if (update_disk_info(ctx) < 0) {
		r.desc.number_of_blocks = sys_cpu_to_be32(UINT32_MAX);
		r.desc.type = NO_MEDIA_PRESENT_OR_UNKNOWN_CAPACITY;
	} else {
		r.desc.number_of_blocks = sys_cpu_to_be32(ctx->sector_count);
		r.desc.type = FORMATTED_MEDIA;
	}
	r.desc.block_length = sys_cpu_to_be32(ctx->sector_size);

	ctx->cmd_is_data_read = true;

	BUILD_ASSERT(sizeof(r) <= CONFIG_USBD_MSC_SCSI_BUFFER_SIZE);
	length = MIN(sys_be16_to_cpu(cmd->allocation_length), sizeof(r));
	memcpy(data_in_buf, &r, length);
	return good(ctx, length);
}

/* SBC-4 5.20 READ CAPACITY (10) command */
SCSI_CMD_HANDLER(READ_CAPACITY_10)
{
	struct scsi_read_capacity_10_response r;

	ctx->cmd_is_data_read = true;

	if (!ctx->medium_loaded || update_disk_info(ctx) != DISK_STATUS_OK) {
		return not_ready(ctx, MEDIUM_NOT_PRESENT);
	}

	r.last_lba = sys_cpu_to_be32(ctx->sector_count ? ctx->sector_count - 1 : 0);
	r.block_length = sys_cpu_to_be32(ctx->sector_size);

	ctx->cmd_is_data_read = true;

	BUILD_ASSERT(sizeof(r) <= CONFIG_USBD_MSC_SCSI_BUFFER_SIZE);
	memcpy(data_in_buf, &r, sizeof(r));
	return good(ctx, sizeof(r));
}

static int
validate_transfer_length(struct scsi_ctx *ctx, uint32_t lba, uint16_t length)
{
	uint32_t last_lba = lba + length - 1;

	if (lba >= ctx->sector_count) {
		LOG_WRN("LBA %d is out of range", lba);
		return -EINVAL;
	}

	/* SBC-4 explicitly mentions that transfer length 0 is OK */
	if (length == 0) {
		return 0;
	}

	if ((last_lba >= ctx->sector_count) || (last_lba < lba)) {
		LOG_WRN("%d blocks starting at %d go out of bounds", length, lba);
		return -EINVAL;
	}

	return 0;
}

static size_t fill_read_10(struct scsi_ctx *ctx,
			   uint8_t buf[static CONFIG_USBD_MSC_SCSI_BUFFER_SIZE])
{
	uint32_t sectors;

	sectors = MIN(CONFIG_USBD_MSC_SCSI_BUFFER_SIZE, ctx->remaining_data) / ctx->sector_size;
	if (disk_access_read(ctx->disk, buf, ctx->lba, sectors) != 0) {
		/* Terminate transfer */
		sectors = 0;
	}
	ctx->lba += sectors;
	return sectors * ctx->sector_size;
}

SCSI_CMD_HANDLER(READ_10)
{
	uint32_t lba = sys_be32_to_cpu(cmd->lba);
	uint16_t transfer_length = sys_be16_to_cpu(cmd->transfer_length);

	ctx->cmd_is_data_read = true;

	if (!ctx->medium_loaded || update_disk_info(ctx) != DISK_STATUS_OK) {
		return not_ready(ctx, MEDIUM_NOT_PRESENT);
	}

	if (validate_transfer_length(ctx, lba, transfer_length)) {
		return illegal_request(ctx, LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE);
	}

	ctx->read_cb = fill_read_10;
	ctx->lba = lba;
	ctx->remaining_data = ctx->sector_size * transfer_length;

	return good(ctx, 0);
}

static size_t store_write_10(struct scsi_ctx *ctx, const uint8_t *buf, size_t length)
{
	uint32_t remaining_sectors;
	uint32_t sectors;
	bool error = false;

	remaining_sectors = ctx->remaining_data / ctx->sector_size;
	sectors = MIN(length, ctx->remaining_data) / ctx->sector_size;
	if (disk_access_write(ctx->disk, buf, ctx->lba, sectors) != 0) {
		/* Flush cache and terminate transfer */
		sectors = 0;
		remaining_sectors = 0;
		error = true;
	}

	/* Flush cache if this is the last sector in transfer */
	if (remaining_sectors - sectors == 0) {
		if (disk_access_ioctl(ctx->disk, DISK_IOCTL_CTRL_SYNC, NULL)) {
			LOG_ERR("Disk cache sync failed");
			error = true;
		}
	}

	ctx->lba += sectors;

	if (error) {
		return medium_error(ctx, WRITE_ERROR);
	} else {
		return sectors * ctx->sector_size;
	}
}

SCSI_CMD_HANDLER(WRITE_10)
{
	uint32_t lba = sys_be32_to_cpu(cmd->lba);
	uint16_t transfer_length = sys_be16_to_cpu(cmd->transfer_length);

	ctx->cmd_is_data_write = true;

	if (!ctx->medium_loaded || update_disk_info(ctx) != DISK_STATUS_OK) {
		return not_ready(ctx, MEDIUM_NOT_PRESENT);
	}

	if (validate_transfer_length(ctx, lba, transfer_length)) {
		return illegal_request(ctx, LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE);
	}

	ctx->write_cb = store_write_10;
	ctx->lba = lba;
	ctx->remaining_data = ctx->sector_size * transfer_length;

	return good(ctx, 0);
}

/* SPC-5 6.15 MODE SENSE(10) command */
SCSI_CMD_HANDLER(MODE_SENSE_10)
{
	struct scsi_mode_sense_10_response r;
	int length;

	ctx->cmd_is_data_read = true;

	if (cmd->page != MODE_SENSE_PAGE_CODE_ALL_PAGES || cmd->subpage != 0) {
		return illegal_request(ctx, INVALID_FIELD_IN_CDB);
	}

	r.mode_data_length = sys_cpu_to_be16(6);
	r.medium_type = 0x00;
	r.device_specific_parameter = 0x00;
	r.longlba = 0x00;
	r.reserved5 = 0x00;
	r.block_descriptor_length = sys_cpu_to_be16(0);

	BUILD_ASSERT(sizeof(r) <= CONFIG_USBD_MSC_SCSI_BUFFER_SIZE);
	length = MIN(sys_be16_to_cpu(cmd->allocation_length), sizeof(r));
	memcpy(data_in_buf, &r, length);

	return good(ctx, length);
}

int scsi_usb_boot_cmd_len(const uint8_t *cb, int len)
{
	/* Universal Serial Bus Mass Storage Specification For Bootability
	 * requires device to accept CBW padded to 12 bytes for commands
	 * documented in Bootability specification. Windows 11 uses padding
	 * for REQUEST SENSE command.
	 */
	if (len != 12) {
		return len;
	}

	switch (cb[0]) {
	case TEST_UNIT_READY:	return sizeof(SCSI_CMD_STRUCT(TEST_UNIT_READY));
	case REQUEST_SENSE:	return sizeof(SCSI_CMD_STRUCT(REQUEST_SENSE));
	case INQUIRY:		return sizeof(SCSI_CMD_STRUCT(INQUIRY));
	case READ_CAPACITY_10:	return sizeof(SCSI_CMD_STRUCT(READ_CAPACITY_10));
	case READ_10:		return sizeof(SCSI_CMD_STRUCT(READ_10));
	case WRITE_10:		return sizeof(SCSI_CMD_STRUCT(WRITE_10));
	case MODE_SENSE_10:	return sizeof(SCSI_CMD_STRUCT(MODE_SENSE_10));
	default:		return len;
	}
}

size_t scsi_cmd(struct scsi_ctx *ctx, const uint8_t *cb, int len,
		uint8_t data_in_buf[static CONFIG_USBD_MSC_SCSI_BUFFER_SIZE])
{
	ctx->cmd_is_data_read = false;
	ctx->cmd_is_data_write = false;
	ctx->remaining_data = 0;
	ctx->read_cb = NULL;
	ctx->write_cb = NULL;

#define SCSI_CMD(opcode) do {							\
	if (len == sizeof(SCSI_CMD_STRUCT(opcode)) && cb[0] == opcode) {	\
		LOG_DBG("SCSI " #opcode);					\
		if (GET_CONTROL_NACA(((SCSI_CMD_STRUCT(opcode)*)cb))) {		\
			return illegal_request(ctx, INVALID_FIELD_IN_CDB);	\
		}								\
		return scsi_##opcode(ctx, (SCSI_CMD_STRUCT(opcode)*)cb,		\
				     data_in_buf);				\
	}									\
} while (0)

	SCSI_CMD(TEST_UNIT_READY);
	SCSI_CMD(REQUEST_SENSE);
	SCSI_CMD(INQUIRY);
	SCSI_CMD(MODE_SENSE_6);
	SCSI_CMD(START_STOP_UNIT);
	SCSI_CMD(PREVENT_ALLOW_MEDIUM_REMOVAL);
	SCSI_CMD(READ_FORMAT_CAPACITIES);
	SCSI_CMD(READ_CAPACITY_10);
	SCSI_CMD(READ_10);
	SCSI_CMD(WRITE_10);
	SCSI_CMD(MODE_SENSE_10);

	LOG_ERR("Unknown SCSI opcode 0x%02x", cb[0]);
	return illegal_request(ctx, INVALID_FIELD_IN_CDB);
}

bool scsi_cmd_is_data_read(struct scsi_ctx *ctx)
{
	return ctx->cmd_is_data_read;
}

bool scsi_cmd_is_data_write(struct scsi_ctx *ctx)
{
	return ctx->cmd_is_data_write;
}

size_t scsi_cmd_remaining_data_len(struct scsi_ctx *ctx)
{
	return ctx->remaining_data;
}

size_t scsi_read_data(struct scsi_ctx *ctx,
		      uint8_t buf[static CONFIG_USBD_MSC_SCSI_BUFFER_SIZE])
{
	size_t retrieved = 0;

	__ASSERT_NO_MSG(ctx->cmd_is_data_read);

	if ((ctx->remaining_data > 0) && ctx->read_cb) {
		retrieved = ctx->read_cb(ctx, buf);
	}
	ctx->remaining_data -= retrieved;
	if (retrieved == 0) {
		/* Terminate transfer. Host will notice data residue. */
		ctx->remaining_data = 0;
	}
	return retrieved;
}

size_t scsi_write_data(struct scsi_ctx *ctx, const uint8_t *buf, size_t length)
{
	size_t processed = 0;

	__ASSERT_NO_MSG(ctx->cmd_is_data_write);

	length = MIN(length, ctx->remaining_data);
	if ((length > 0) && ctx->write_cb) {
		processed = ctx->write_cb(ctx, buf, length);
	}
	ctx->remaining_data -= processed;
	if (processed == 0) {
		/* Terminate transfer. Host will notice data residue. */
		ctx->remaining_data = 0;
	}
	return processed;
}

enum scsi_status_code scsi_cmd_get_status(struct scsi_ctx *ctx)
{
	return ctx->status;
}
