xref: /minix/minix/drivers/usb/usb_storage/scsi.h (revision 433d6423)
1 /*
2  * SCSI commands related definitions
3  */
4 
5 #ifndef _SCSI_H_
6 #define _SCSI_H_
7 
8 #if 0
9 #include <sys/endian.h>				/* be16dec... */
10 #else
11 #define be16enc(base, val) {						\
12 		(base)[0] = (((val) >> 8) & 0xff);			\
13 		(base)[1] = ((val) & 0xff);				\
14 		}
15 #define be16dec(base)							\
16 		(((base)[0] << 8) | (base)[1])
17 #define be32enc(base, val) {						\
18 		(base)[0] = (((val) >> 24) & 0xff);			\
19 		(base)[1] = (((val) >> 16) & 0xff);			\
20 		(base)[2] = (((val) >>  8) & 0xff);			\
21 		(base)[3] = ((val) & 0xff);				\
22 		}
23 #define be32dec(base)							\
24 		(((base)[0] << 24) | ((base)[1] << 16) |		\
25 		((base)[2] << 8) | (base)[3])
26 #endif
27 
28 #include "bulk.h"
29 
30 #define SCSI_FORMAT_UNIT			(0x04)
31 #define SCSI_INQUIRY				(0x12)
32 #define SCSI_START_STOP				(0x1B)
33 #define SCSI_MODE_SELECT			(0x55)
34 #define SCSI_MODE_SENSE				(0x5A)
35 #define SCSI_PREVENT_ALLOW			(0x1E)
36 #define SCSI_READ				(0x28)
37 #define SCSI_READ_12				(0xA8)
38 #define SCSI_READ_CAPACITY			(0x25)
39 #define SCSI_READ_FORMAT_CAP			(0x23)
40 #define SCSI_REQUEST_SENSE			(0x03)
41 #define SCSI_REZERO_UNIT			(0x01)
42 #define SCSI_SEEK				(0x2B)
43 #define SCSI_SEND_DIAGNOSTIC			(0x1D)
44 #define SCSI_TEST_UNIT_READY			(0x00)
45 #define SCSI_VERIFY				(0x2F)
46 #define SCSI_WRITE				(0x2A)
47 #define SCSI_WRITE_12				(0xAA)
48 #define SCSI_WRITE_VERIFY			(0x2E)
49 
50 #define SCSI_INQUIRY_DATA_LEN			(36)
51 #define SCSI_INQUIRY_CMD_LEN			(6)
52 
53 #define SCSI_MODE_SENSE_FLEX_DATA_LEN		(32)
54 #define SCSI_MODE_SENSE_CMD_LEN			(12)
55 
56 #define SCSI_READ_DATA_LEN			(0)
57 #define SCSI_READ_CMD_LEN			(10)
58 
59 #define SCSI_READ_CAPACITY_DATA_LEN		(8)
60 #define SCSI_READ_CAPACITY_CMD_LEN		(10)
61 
62 #define SCSI_TEST_DATA_LEN			(0)
63 #define SCSI_TEST_CMD_LEN			(6)
64 
65 #define SCSI_WRITE_DATA_LEN			(0)
66 #define SCSI_WRITE_CMD_LEN			(10)
67 
68 /* These macros are immune to unaligned access
69  * so they can be used on any address */
70 /* 1 Byte SCSI operation */
71 #define SCSI_WR1(base, offset, value)\
72 		(((uint8_t*)(base))[offset] = value)
73 #define SCSI_RD1(base, offset)\
74 		(((uint8_t*)(base))[offset])
75 #define SCSI_SET1(base, offset, value)\
76 		(((uint8_t*)(base))[offset] |= value)
77 /* 2 Byte SCSI operation */
78 #define SCSI_WR2(base, offset, value)\
79 		be16enc( &(((uint8_t*)(base))[offset]), value )
80 #define SCSI_RD2(base, offset)\
81 		be16dec( &(((uint8_t*)(base))[offset]) )
82 /* 4 Byte SCSI operation */
83 #define SCSI_WR4(base, offset, value)\
84 		be32enc( &(((uint8_t*)(base))[offset]), value )
85 #define SCSI_RD4(base, offset)\
86 		be32dec( &(((uint8_t*)(base))[offset]) )
87 
88 #define SCSI_SET_INQUIRY_OP_CODE(x)		SCSI_WR1((x), 0, SCSI_INQUIRY)
89 #define SCSI_SET_INQUIRY_EVPD(x)		SCSI_SET1((x), 1, 0x01)
90 #define SCSI_SET_INQUIRY_CMDDT(x)		SCSI_SET1((x), 1, 0x02)
91 #define SCSI_SET_INQUIRY_PAGE_CODE(x, code)	SCSI_WR1((x), 2, code)
92 #define SCSI_SET_INQUIRY_ALLOC_LEN(x, len)	SCSI_WR1((x), 4, len)
93 
94 #define SCSI_GET_INQUIRY_PERIPH_QUALIF(x)	((SCSI_RD1(x, 0) >> 5) & 0x7)
95 #define SCSI_GET_INQUIRY_VENDOR_NAME(x)		((const char *)(&((x)[8])))
96 #define SCSI_INQUIRY_VENDOR_NAME_LEN		(8)
97 #define SCSI_GET_INQUIRY_PRODUCT_NAME(x)	((const char *)(&((x)[16])))
98 #define SCSI_INQUIRY_PRODUCT_NAME_LEN		(16)
99 
100 #define SCSI_MODE_SENSE_FLEXIBLE_DISK_PAGE	(0x5)
101 #define SCSI_SET_MODE_SENSE_OP_CODE(x)		SCSI_WR1((x), 0, \
102 							SCSI_MODE_SENSE)
103 #define SCSI_SET_MODE_SENSE_PAGE_CODE(x, code)	SCSI_SET1((x), 2, \
104 							(code)&0x3F)
105 #define SCSI_GET_MODE_SENSE_CYLINDERS(x)	SCSI_RD2((x), 8)
106 #define SCSI_GET_MODE_SENSE_HEADS(x)		SCSI_RD1((x), 4)
107 #define SCSI_GET_MODE_SENSE_SECTORS(x)		SCSI_RD1((x), 5)
108 
109 #define SCSI_SET_READ_OP_CODE(x)		SCSI_WR1((x), 0, SCSI_READ)
110 #define SCSI_SET_READ_LBA(x, lba)		SCSI_WR4((x), 2, (lba))
111 #define SCSI_SET_READ_BLEN(x, len)		SCSI_WR2((x), 7, (len))
112 
113 #define SCSI_SET_READ_CAPACITY_OP_CODE(x)	SCSI_WR1((x), 0, \
114 							SCSI_READ_CAPACITY)
115 #define SCSI_SET_READ_CAPACITY_LBA(x, lba)	SCSI_WR4((x), 2, (lba))
116 #define SCSI_SET_READ_CAPACITY_PMI(x)		SCSI_SET1((x), 8, 0x01)
117 #define SCSI_GET_READ_CAPACITY_LBA(x)		SCSI_RD4((x), 0)
118 #define SCSI_GET_READ_CAPACITY_BLEN(x)		SCSI_RD4((x), 4)
119 
120 #define SCSI_SET_TEST_OP_CODE(x)		SCSI_WR1((x), 0, \
121 							SCSI_TEST_UNIT_READY)
122 
123 #define SCSI_SET_WRITE_OP_CODE(x)		SCSI_WR1((x), 0, SCSI_WRITE)
124 #define SCSI_SET_WRITE_LBA(x, lba)		SCSI_WR4((x), 2, (lba))
125 #define SCSI_SET_WRITE_BLEN(x, len)		SCSI_WR2((x), 7, (len))
126 
127 typedef struct scsi_transfer {
128 
129 	unsigned int lba;			/* logical block address */
130 	unsigned int length;			/* transfer length */
131 }
132 scsi_transfer;
133 
134 /*---------------------------*
135  *    declared functions     *
136  *---------------------------*/
137 int create_scsi_cmd(mass_storage_cbw *, int, struct scsi_transfer *);
138 int check_inquiry_reply(uint8_t *);
139 int check_read_capacity_reply(uint8_t *, uint32_t *, uint32_t *);
140 int check_mode_sense_reply(uint8_t *, unsigned *, unsigned *, unsigned *);
141 int check_csw(mass_storage_csw *, unsigned int);
142 
143 #endif /* !_SCSI_H_ */
144