From 7fafbe1fc13bec744d1fcc70ba431fa77472680a Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Wed, 4 Jan 2017 00:26:52 +0100 Subject: imxtools/scsitools: rework stmp scsi API Sanitize the whole library by hiding most of the horrible details of the implementation. This means that all logical/drive/table attributes are exported in structures that are internally filled by higher-level API functions. This makes the code much more readable and prepares for a split between scsitool and the stmp scsi library. Change-Id: Id85d450b25cf99cd7c0896c6fc35bcd00babe9e1 --- utils/imxtools/scsitools/stmp_scsi.h | 169 ++++++++++++++++++++++++++++++++++- 1 file changed, 167 insertions(+), 2 deletions(-) (limited to 'utils/imxtools/scsitools/stmp_scsi.h') diff --git a/utils/imxtools/scsitools/stmp_scsi.h b/utils/imxtools/scsitools/stmp_scsi.h index 1a035cc649..68d77daeec 100644 --- a/utils/imxtools/scsitools/stmp_scsi.h +++ b/utils/imxtools/scsitools/stmp_scsi.h @@ -84,7 +84,7 @@ struct scsi_stmp_logical_table_entry_t #define SCSI_STMP_DRIVE_TAG_USER_STORAGE 0xa #define SCSI_STMP_DRIVE_TAG_SYSTEM_BOOT 0x50 -struct scsi_stmp_logical_table_t +struct scsi_stmp_logical_table_header_t { uint16_t count; /* big-endian */ } __attribute__((packed)); @@ -135,7 +135,7 @@ struct scsi_stmp_logical_media_info_manufacturer_t } __attribute__((packed)); #define SCSI_STMP_DRIVE_INFO_SECTOR_SIZE 0 /** Sector Size (bytes) */ -#define SCSI_STMP_DRIVe_INFO_ERASE_SIZE 1 /** Erase Size (bytes) */ +#define SCSI_STMP_DRIVE_INFO_ERASE_SIZE 1 /** Erase Size (bytes) */ #define SCSI_STMP_DRIVE_INFO_SIZE 2 /** Total Size (bytes) */ #define SCSI_STMP_DRIVE_INFO_SIZE_MEGA 3 /** Total Size (mega-bytes) */ #define SCSI_STMP_DRIVE_INFO_SECTOR_COUNT 4 /** Sector Count */ @@ -187,6 +187,14 @@ struct scsi_stmp_logical_drive_info_type_t uint8_t type; } __attribute__((packed)); +struct scsi_stmp_logical_drive_info_version_t +{ + uint16_t major; + uint16_t minor; + uint16_t revision; +} __attribute__((packed)); + +struct stmp_device_t; typedef struct stmp_device_t *stmp_device_t; typedef void (*stmp_printf_t)(void *user, const char *fmt, ...); @@ -197,4 +205,161 @@ typedef void (*stmp_printf_t)(void *user, const char *fmt, ...); #define STMP_READ (1 << 1) #define STMP_WRITE (1 << 2) +uint16_t stmp_fix_endian16be(uint16_t w); +uint32_t stmp_fix_endian32be(uint32_t w); +uint64_t stmp_fix_endian64be(uint64_t w); +/* returns NULL on error */ +stmp_device_t stmp_open(rb_scsi_device_t dev, unsigned flags, void *user, stmp_printf_t printf); +void stmp_close(stmp_device_t dev); +/* returns <0 on error and status otherwise */ +int stmp_scsi(stmp_device_t dev, uint8_t *cdb, int cdb_size, unsigned flags, + void *sense, int *sense_size, void *buffer, int *buf_size); +/* returns != 0 on error */ +int stmp_sense_analysis(stmp_device_t dev, int status, uint8_t *sense, int sense_size); +void stmp_printf(rb_scsi_device_t dev, const char *fmt, ...); +void stmp_debugf(rb_scsi_device_t dev, const char *fmt, ...); + +/** + * Mid-level API + */ + +/* returns !=0 on error */ +int stmp_scsi_inquiry(stmp_device_t dev, uint8_t *dev_type, char vendor[9], char product[17]); + +int stmp_scsi_get_protocol_version(stmp_device_t dev, void *buf, int *len); +int stmp_scsi_get_chip_major_rev_id(stmp_device_t dev, void *buf, int *len); +int stmp_scsi_get_rom_rev_id(stmp_device_t dev, void *buf, int *len); +int stmp_scsi_read_logical_drive_sectors(stmp_device_t dev, uint8_t drive, uint64_t address, + uint32_t count, void *buffer, int *buffer_size); +int stmp_scsi_write_logical_drive_sectors(stmp_device_t dev, uint8_t drive, uint64_t address, + uint32_t count, void *buffer, int *buffer_size); +/* the following functions *DO NOT* fix the endianness of the structures */ +int stmp_scsi_get_logical_table(stmp_device_t dev, int entry_count, void *buf, int *len); +int stmp_scsi_get_serial_number(stmp_device_t dev, uint8_t info, void *data, int *len); +int stmp_scsi_get_logical_media_info(stmp_device_t dev, uint8_t info, void *data, int *len); +int stmp_scsi_get_logical_drive_info(stmp_device_t dev, uint8_t drive, uint8_t info, void *data, int *len); +int stmp_scsi_get_device_info(stmp_device_t dev, uint8_t info, void *data, int *len); +/* these helper functions fix the endianness for the previous calls, or returns != 0 + * if they don't know about this info or the size doesn't match */ +int stmp_fix_logical_media_info(uint8_t info, void *data, int len); +int stmp_fix_logical_drive_info(uint8_t info, void *data, int len); +int stmp_fix_device_info(uint8_t info, void *data, int len); + +/** + * High-Level API + */ + +struct stmp_logical_media_table_t +{ + struct scsi_stmp_logical_table_header_t header; + struct scsi_stmp_logical_table_entry_t entry[]; +}__attribute__((packed)) table; + +struct stmp_logical_media_info_t +{ + struct + { + bool nr_drives; + bool size; + bool alloc_size; + bool initialised; + bool state; + bool write_protected; + bool type; + bool serial_len; + bool serial; + bool system; + bool present; + bool page_size; + bool vendor; + bool nand_id; + bool nr_devices; + }has; + uint16_t nr_drives; + uint64_t size; + uint32_t alloc_size; + uint8_t initialised; + uint8_t state; + uint8_t write_protected; + uint8_t type; + uint32_t serial_len; + uint8_t *serial; /* must be released with free() */ + uint8_t system; + uint8_t present; + uint32_t page_size; + uint32_t vendor; + uint8_t nand_id[6]; + uint32_t nr_devices; +}; + +#define SCSI_STMP_DRIVE_INFO_SECTOR_SIZE 0 /** Sector Size (bytes) */ +#define SCSI_STMP_DRIVE_INFO_ERASE_SIZE 1 /** Erase Size (bytes) */ +#define SCSI_STMP_DRIVE_INFO_SIZE 2 /** Total Size (bytes) */ +#define SCSI_STMP_DRIVE_INFO_SIZE_MEGA 3 /** Total Size (mega-bytes) */ +#define SCSI_STMP_DRIVE_INFO_SECTOR_COUNT 4 /** Sector Count */ +#define SCSI_STMP_DRIVE_INFO_TYPE 5 /** Drive Type */ +#define SCSI_STMP_DRIVE_INFO_TAG 6 /** Drive Tag */ +#define SCSI_STMP_DRIVE_INFO_COMPONENT_VERSION 7 /** Component Version */ +#define SCSI_STMP_DRIVE_INFO_PROJECT_VERSION 8 /** Project Version */ +#define SCSI_STMP_DRIVE_INFO_IS_WRITE_PROTECTED 9 /** Is Write Protected */ +#define SCSI_STMP_DRIVE_INFO_SERIAL_NUMBER_SIZE 10 /** Serial Number Size */ +#define SCSI_STMP_DRIVE_INFO_SERIAL_NUMBER 11 /** Serial Number */ +#define SCSI_STMP_DRIVE_INFO_MEDIA_PRESENT 12 /** Is Media Present */ +#define SCSI_STMP_DRIVE_INFO_MEDIA_CHANGE 13 /** Media Change */ +#define SCSI_STMP_DRIVE_INFO_SECTOR_ALLOCATION 14 /** Sector Allocation */ + +struct stmp_logical_drive_info_t +{ + struct + { + bool sector_size; + bool erase_size; + bool size; + bool sector_count; + bool type; + bool tag; + bool component_version; + bool project_version; + bool write_protected; + bool serial_len; + bool serial; + bool present; + bool change; + bool sector_alloc; + }has; + uint32_t sector_size; + uint32_t erase_size; + uint64_t size; + uint64_t sector_count; + uint32_t type; + uint8_t tag; + struct scsi_stmp_logical_drive_info_version_t component_version; + struct scsi_stmp_logical_drive_info_version_t project_version; + uint8_t write_protected; + uint32_t serial_len; + uint8_t *serial; + uint8_t present; + uint8_t change; + uint32_t sector_alloc; +}; + +int stmp_get_protocol_version(stmp_device_t dev, struct scsi_stmp_protocol_version_t *ver); +int stmp_get_chip_major_rev_id(stmp_device_t dev, uint16_t *ver); +int stmp_get_rom_rev_id(stmp_device_t dev, uint16_t *ver); +/* return 0 on success, buffers must be released with free() */ +int stmp_get_device_serial(stmp_device_t dev, uint8_t **buffer, int *len); +int stmp_get_logical_media_info(stmp_device_t dev, struct stmp_logical_media_info_t *info); +int stmp_get_logical_media_table(stmp_device_t dev, struct stmp_logical_media_table_t **table); +int stmp_get_logical_drive_info(stmp_device_t dev, uint8_t drive, struct stmp_logical_drive_info_t *info); +int stmp_read_logical_drive_sectors(stmp_device_t dev, uint8_t drive, uint64_t address, + uint32_t count, void *buffer, int buffer_size); +int stmp_write_logical_drive_sectors(stmp_device_t dev, uint8_t drive, uint64_t address, + uint32_t count, void *buffer, int buffer_size); +/* string helpers */ +const char *stmp_get_logical_media_type_string(uint32_t type); +const char *stmp_get_logical_media_vendor_string(uint32_t type); +const char *stmp_get_logical_drive_type_string(uint32_t type); +const char *stmp_get_logical_drive_tag_string(uint32_t type); +const char *stmp_get_logical_media_state_string(uint8_t state); + #endif /* __STMP_SCSI__ */ -- cgit v1.2.3