minix/drivers/usb_storage/scsi.h
Kees Jongenburger dfb2b8398d usb:adding usb mass storage driver.
Change-Id: I9e431d56eddfeec21413c290b2fa7ad35b566f6b

http://gerrit.minix3.org/#/c/2690/
2014-07-28 17:05:39 +02:00

143 lines
4.7 KiB
C
Executable file

/*
* SCSI commands related definitions
*/
#ifndef _SCSI_H_
#define _SCSI_H_
#if 0
#include <sys/endian.h> /* be16dec... */
#else
#define be16enc(base, val) { \
(base)[0] = (((val) >> 8) & 0xff); \
(base)[1] = ((val) & 0xff); \
}
#define be16dec(base) \
(((base)[0] << 8) | (base)[1])
#define be32enc(base, val) { \
(base)[0] = (((val) >> 24) & 0xff); \
(base)[1] = (((val) >> 16) & 0xff); \
(base)[2] = (((val) >> 8) & 0xff); \
(base)[3] = ((val) & 0xff); \
}
#define be32dec(base) \
(((base)[0] << 24) | ((base)[1] << 16) | \
((base)[2] << 8) | (base)[3])
#endif
#include "bulk.h"
#define SCSI_FORMAT_UNIT (0x04)
#define SCSI_INQUIRY (0x12)
#define SCSI_START_STOP (0x1B)
#define SCSI_MODE_SELECT (0x55)
#define SCSI_MODE_SENSE (0x5A)
#define SCSI_PREVENT_ALLOW (0x1E)
#define SCSI_READ (0x28)
#define SCSI_READ_12 (0xA8)
#define SCSI_READ_CAPACITY (0x25)
#define SCSI_READ_FORMAT_CAP (0x23)
#define SCSI_REQUEST_SENSE (0x03)
#define SCSI_REZERO_UNIT (0x01)
#define SCSI_SEEK (0x2B)
#define SCSI_SEND_DIAGNOSTIC (0x1D)
#define SCSI_TEST_UNIT_READY (0x00)
#define SCSI_VERIFY (0x2F)
#define SCSI_WRITE (0x2A)
#define SCSI_WRITE_12 (0xAA)
#define SCSI_WRITE_VERIFY (0x2E)
#define SCSI_INQUIRY_DATA_LEN (36)
#define SCSI_INQUIRY_CMD_LEN (6)
#define SCSI_MODE_SENSE_FLEX_DATA_LEN (32)
#define SCSI_MODE_SENSE_CMD_LEN (12)
#define SCSI_READ_DATA_LEN (0)
#define SCSI_READ_CMD_LEN (10)
#define SCSI_READ_CAPACITY_DATA_LEN (8)
#define SCSI_READ_CAPACITY_CMD_LEN (10)
#define SCSI_TEST_DATA_LEN (0)
#define SCSI_TEST_CMD_LEN (6)
#define SCSI_WRITE_DATA_LEN (0)
#define SCSI_WRITE_CMD_LEN (10)
/* These macros are immune to unaligned access
* so they can be used on any address */
/* 1 Byte SCSI operation */
#define SCSI_WR1(base, offset, value)\
(((uint8_t*)(base))[offset] = value)
#define SCSI_RD1(base, offset)\
(((uint8_t*)(base))[offset])
#define SCSI_SET1(base, offset, value)\
(((uint8_t*)(base))[offset] |= value)
/* 2 Byte SCSI operation */
#define SCSI_WR2(base, offset, value)\
be16enc( &(((uint8_t*)(base))[offset]), value )
#define SCSI_RD2(base, offset)\
be16dec( &(((uint8_t*)(base))[offset]) )
/* 4 Byte SCSI operation */
#define SCSI_WR4(base, offset, value)\
be32enc( &(((uint8_t*)(base))[offset]), value )
#define SCSI_RD4(base, offset)\
be32dec( &(((uint8_t*)(base))[offset]) )
#define SCSI_SET_INQUIRY_OP_CODE(x) SCSI_WR1((x), 0, SCSI_INQUIRY)
#define SCSI_SET_INQUIRY_EVPD(x) SCSI_SET1((x), 1, 0x01)
#define SCSI_SET_INQUIRY_CMDDT(x) SCSI_SET1((x), 1, 0x02)
#define SCSI_SET_INQUIRY_PAGE_CODE(x, code) SCSI_WR1((x), 2, code)
#define SCSI_SET_INQUIRY_ALLOC_LEN(x, len) SCSI_WR1((x), 4, len)
#define SCSI_GET_INQUIRY_PERIPH_QUALIF(x) ((SCSI_RD1(x, 0) >> 5) & 0x7)
#define SCSI_GET_INQUIRY_VENDOR_NAME(x) ((const char *)(&((x)[8])))
#define SCSI_INQUIRY_VENDOR_NAME_LEN (8)
#define SCSI_GET_INQUIRY_PRODUCT_NAME(x) ((const char *)(&((x)[16])))
#define SCSI_INQUIRY_PRODUCT_NAME_LEN (16)
#define SCSI_MODE_SENSE_FLEXIBLE_DISK_PAGE (0x5)
#define SCSI_SET_MODE_SENSE_OP_CODE(x) SCSI_WR1((x), 0, \
SCSI_MODE_SENSE)
#define SCSI_SET_MODE_SENSE_PAGE_CODE(x, code) SCSI_SET1((x), 2, \
(code)&0x3F)
#define SCSI_GET_MODE_SENSE_CYLINDERS(x) SCSI_RD2((x), 8)
#define SCSI_GET_MODE_SENSE_HEADS(x) SCSI_RD1((x), 4)
#define SCSI_GET_MODE_SENSE_SECTORS(x) SCSI_RD1((x), 5)
#define SCSI_SET_READ_OP_CODE(x) SCSI_WR1((x), 0, SCSI_READ)
#define SCSI_SET_READ_LBA(x, lba) SCSI_WR4((x), 2, (lba))
#define SCSI_SET_READ_BLEN(x, len) SCSI_WR2((x), 7, (len))
#define SCSI_SET_READ_CAPACITY_OP_CODE(x) SCSI_WR1((x), 0, \
SCSI_READ_CAPACITY)
#define SCSI_SET_READ_CAPACITY_LBA(x, lba) SCSI_WR4((x), 2, (lba))
#define SCSI_SET_READ_CAPACITY_PMI(x) SCSI_SET1((x), 8, 0x01)
#define SCSI_GET_READ_CAPACITY_LBA(x) SCSI_RD4((x), 0)
#define SCSI_GET_READ_CAPACITY_BLEN(x) SCSI_RD4((x), 4)
#define SCSI_SET_TEST_OP_CODE(x) SCSI_WR1((x), 0, \
SCSI_TEST_UNIT_READY)
#define SCSI_SET_WRITE_OP_CODE(x) SCSI_WR1((x), 0, SCSI_WRITE)
#define SCSI_SET_WRITE_LBA(x, lba) SCSI_WR4((x), 2, (lba))
#define SCSI_SET_WRITE_BLEN(x, len) SCSI_WR2((x), 7, (len))
typedef struct scsi_transfer {
unsigned int lba; /* logical block address */
unsigned int length; /* transfer length */
}
scsi_transfer;
/*---------------------------*
* declared functions *
*---------------------------*/
int create_scsi_cmd(mass_storage_cbw *, int, struct scsi_transfer *);
int check_inquiry_reply(uint8_t *);
int check_read_capacity_reply(uint8_t *, uint32_t *, uint32_t *);
int check_mode_sense_reply(uint8_t *, unsigned *, unsigned *, unsigned *);
int check_csw(mass_storage_csw *, unsigned int);
#endif /* !_SCSI_H_ */