diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2017-08-22 07:08:27 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2017-09-19 14:09:11 +0200 |
commit | e5b5728cd330f533e02e483af8973ad7ffccce8b (patch) | |
tree | f47dcecd074391ef42adfeae7d8d4fda94c69bcf /include/scsi | |
parent | 37b6045c455275af37f0433b05b0dad123e14daf (diff) |
scsi: move non-emulation specific code to scsi/
util/scsi.c includes some SCSI code that is shared by block/iscsi.c and
hw/scsi, but the introduction of the persistent reservation helper
will add many more instances of this. There is also include/block/scsi.h,
which actually is not part of the core block layer.
The persistent reservation manager will also need a home. A scsi/
directory provides one for both the aforementioned shared code and
the PR manager code.
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'include/scsi')
-rw-r--r-- | include/scsi/scsi.h | 20 | ||||
-rw-r--r-- | include/scsi/utils.h | 119 |
2 files changed, 119 insertions, 20 deletions
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h deleted file mode 100644 index fe330385d8..0000000000 --- a/include/scsi/scsi.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * SCSI helpers - * - * Copyright 2017 Red Hat, Inc. - * - * Authors: - * Fam Zheng <famz@redhat.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ -#ifndef QEMU_SCSI_H -#define QEMU_SCSI_H - -int scsi_sense_to_errno(int key, int asc, int ascq); -int scsi_sense_buf_to_errno(const uint8_t *sense, size_t sense_size); - -#endif diff --git a/include/scsi/utils.h b/include/scsi/utils.h new file mode 100644 index 0000000000..90bf4dce6e --- /dev/null +++ b/include/scsi/utils.h @@ -0,0 +1,119 @@ +#ifndef SCSI_UTILS_H +#define SCSI_UTILS_H 1 + +#ifdef CONFIG_LINUX +#include <scsi/sg.h> +#endif + +#define SCSI_CMD_BUF_SIZE 16 +#define SCSI_SENSE_LEN 18 +#define SCSI_SENSE_LEN_SCANNER 32 +#define SCSI_INQUIRY_LEN 36 + +enum SCSIXferMode { + SCSI_XFER_NONE, /* TEST_UNIT_READY, ... */ + SCSI_XFER_FROM_DEV, /* READ, INQUIRY, MODE_SENSE, ... */ + SCSI_XFER_TO_DEV, /* WRITE, MODE_SELECT, ... */ +}; + +typedef struct SCSICommand { + uint8_t buf[SCSI_CMD_BUF_SIZE]; + int len; + size_t xfer; + uint64_t lba; + enum SCSIXferMode mode; +} SCSICommand; + +typedef struct SCSISense { + uint8_t key; + uint8_t asc; + uint8_t ascq; +} SCSISense; + +/* + * Predefined sense codes + */ + +/* No sense data available */ +extern const struct SCSISense sense_code_NO_SENSE; +/* LUN not ready, Manual intervention required */ +extern const struct SCSISense sense_code_LUN_NOT_READY; +/* LUN not ready, Medium not present */ +extern const struct SCSISense sense_code_NO_MEDIUM; +/* LUN not ready, medium removal prevented */ +extern const struct SCSISense sense_code_NOT_READY_REMOVAL_PREVENTED; +/* Hardware error, internal target failure */ +extern const struct SCSISense sense_code_TARGET_FAILURE; +/* Illegal request, invalid command operation code */ +extern const struct SCSISense sense_code_INVALID_OPCODE; +/* Illegal request, LBA out of range */ +extern const struct SCSISense sense_code_LBA_OUT_OF_RANGE; +/* Illegal request, Invalid field in CDB */ +extern const struct SCSISense sense_code_INVALID_FIELD; +/* Illegal request, Invalid field in parameter list */ +extern const struct SCSISense sense_code_INVALID_PARAM; +/* Illegal request, Parameter list length error */ +extern const struct SCSISense sense_code_INVALID_PARAM_LEN; +/* Illegal request, LUN not supported */ +extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED; +/* Illegal request, Saving parameters not supported */ +extern const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED; +/* Illegal request, Incompatible format */ +extern const struct SCSISense sense_code_INCOMPATIBLE_FORMAT; +/* Illegal request, medium removal prevented */ +extern const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED; +/* Illegal request, Invalid Transfer Tag */ +extern const struct SCSISense sense_code_INVALID_TAG; +/* Command aborted, I/O process terminated */ +extern const struct SCSISense sense_code_IO_ERROR; +/* Command aborted, I_T Nexus loss occurred */ +extern const struct SCSISense sense_code_I_T_NEXUS_LOSS; +/* Command aborted, Logical Unit failure */ +extern const struct SCSISense sense_code_LUN_FAILURE; +/* Command aborted, Overlapped Commands Attempted */ +extern const struct SCSISense sense_code_OVERLAPPED_COMMANDS; +/* LUN not ready, Capacity data has changed */ +extern const struct SCSISense sense_code_CAPACITY_CHANGED; +/* LUN not ready, Medium not present */ +extern const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM; +/* Unit attention, Power on, reset or bus device reset occurred */ +extern const struct SCSISense sense_code_RESET; +/* Unit attention, Medium may have changed*/ +extern const struct SCSISense sense_code_MEDIUM_CHANGED; +/* Unit attention, Reported LUNs data has changed */ +extern const struct SCSISense sense_code_REPORTED_LUNS_CHANGED; +/* Unit attention, Device internal reset */ +extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET; +/* Data Protection, Write Protected */ +extern const struct SCSISense sense_code_WRITE_PROTECTED; +/* Data Protection, Space Allocation Failed Write Protect */ +extern const struct SCSISense sense_code_SPACE_ALLOC_FAILED; + +#define SENSE_CODE(x) sense_code_ ## x + +int scsi_sense_to_errno(int key, int asc, int ascq); +int scsi_sense_buf_to_errno(const uint8_t *sense, size_t sense_size); + +int scsi_convert_sense(uint8_t *in_buf, int in_len, + uint8_t *buf, int len, bool fixed); +const char *scsi_command_name(uint8_t cmd); + +uint64_t scsi_cmd_lba(SCSICommand *cmd); +uint32_t scsi_data_cdb_xfer(uint8_t *buf); +uint32_t scsi_cdb_xfer(uint8_t *buf); +int scsi_cdb_length(uint8_t *buf); + +/* Linux SG_IO interface. */ +#ifdef CONFIG_LINUX +#define SG_ERR_DRIVER_TIMEOUT 0x06 +#define SG_ERR_DRIVER_SENSE 0x08 + +#define SG_ERR_DID_OK 0x00 +#define SG_ERR_DID_NO_CONNECT 0x01 +#define SG_ERR_DID_BUS_BUSY 0x02 +#define SG_ERR_DID_TIME_OUT 0x03 + +#define SG_ERR_DRIVER_SENSE 0x08 +#endif + +#endif |