1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Amaury Pouly 2017-01-04 00:26:52 +01:00
parent 0fd869423a
commit 7fafbe1fc1
2 changed files with 608 additions and 379 deletions

File diff suppressed because it is too large Load diff

View file

@ -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__ */