xref: /minix/minix/drivers/usb/usb_storage/scsi.h (revision 2d64210c)
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_INQUIRY				(0x12)
31 #define SCSI_MODE_SENSE				(0x5A)
32 #define SCSI_READ				(0x28)
33 #define SCSI_READ_CAPACITY			(0x25)
34 #define SCSI_REQUEST_SENSE			(0x03)
35 #define SCSI_TEST_UNIT_READY			(0x00)
36 #define SCSI_WRITE				(0x2A)
37 
38 #define SCSI_INQUIRY_DATA_LEN			(36)
39 #define SCSI_INQUIRY_CMD_LEN			(6)
40 
41 #define SCSI_MODE_SENSE_FLEX_DATA_LEN		(32)
42 #define SCSI_MODE_SENSE_CMD_LEN			(12)
43 
44 #define SCSI_READ_DATA_LEN			(0)
45 #define SCSI_READ_CMD_LEN			(10)
46 
47 #define SCSI_READ_CAPACITY_DATA_LEN		(8)
48 #define SCSI_READ_CAPACITY_CMD_LEN		(10)
49 
50 #define SCSI_REQUEST_SENSE_DATA_LEN		(18)
51 #define SCSI_REQUEST_SENSE_CMD_LEN		(6)
52 
53 #define SCSI_TEST_DATA_LEN			(0)
54 #define SCSI_TEST_CMD_LEN			(6)
55 
56 #define SCSI_WRITE_DATA_LEN			(0)
57 #define SCSI_WRITE_CMD_LEN			(10)
58 
59 /* These macros are immune to unaligned access
60  * so they can be used on any address */
61 /* 1 Byte SCSI operation */
62 #define SCSI_WR1(base, offset, value)\
63 		(((uint8_t*)(base))[offset] = value)
64 #define SCSI_RD1(base, offset)\
65 		(((uint8_t*)(base))[offset])
66 #define SCSI_SET1(base, offset, value)\
67 		(((uint8_t*)(base))[offset] |= value)
68 /* 2 Byte SCSI operation */
69 #define SCSI_WR2(base, offset, value)\
70 		be16enc( &(((uint8_t*)(base))[offset]), value )
71 #define SCSI_RD2(base, offset)\
72 		be16dec( &(((uint8_t*)(base))[offset]) )
73 /* 4 Byte SCSI operation */
74 #define SCSI_WR4(base, offset, value)\
75 		be32enc( &(((uint8_t*)(base))[offset]), value )
76 #define SCSI_RD4(base, offset)\
77 		be32dec( &(((uint8_t*)(base))[offset]) )
78 
79 #define SCSI_SET_INQUIRY_OP_CODE(x)		SCSI_WR1((x), 0, SCSI_INQUIRY)
80 #define SCSI_SET_INQUIRY_EVPD(x)		SCSI_SET1((x), 1, 0x01)
81 #define SCSI_SET_INQUIRY_CMDDT(x)		SCSI_SET1((x), 1, 0x02)
82 #define SCSI_SET_INQUIRY_PAGE_CODE(x, code)	SCSI_WR1((x), 2, code)
83 #define SCSI_SET_INQUIRY_ALLOC_LEN(x, len)	SCSI_WR1((x), 4, len)
84 
85 #define SCSI_GET_INQUIRY_PERIPH_QUALIF(x)	((SCSI_RD1(x, 0) >> 5) & 0x7)
86 #define SCSI_GET_INQUIRY_VENDOR_NAME(x)		((const char *)(&((x)[8])))
87 #define SCSI_INQUIRY_VENDOR_NAME_LEN		(8)
88 #define SCSI_GET_INQUIRY_PRODUCT_NAME(x)	((const char *)(&((x)[16])))
89 #define SCSI_INQUIRY_PRODUCT_NAME_LEN		(16)
90 
91 #define SCSI_MODE_SENSE_FLEXIBLE_DISK_PAGE	(0x5)
92 #define SCSI_SET_MODE_SENSE_OP_CODE(x)		SCSI_WR1((x), 0, \
93 							SCSI_MODE_SENSE)
94 #define SCSI_SET_MODE_SENSE_PAGE_CODE(x, code)	SCSI_SET1((x), 2, \
95 							(code)&0x3F)
96 #define SCSI_GET_MODE_SENSE_CYLINDERS(x)	SCSI_RD2((x), 8)
97 #define SCSI_GET_MODE_SENSE_HEADS(x)		SCSI_RD1((x), 4)
98 #define SCSI_GET_MODE_SENSE_SECTORS(x)		SCSI_RD1((x), 5)
99 
100 #define SCSI_SET_READ_OP_CODE(x)		SCSI_WR1((x), 0, SCSI_READ)
101 #define SCSI_SET_READ_LBA(x, lba)		SCSI_WR4((x), 2, (lba))
102 #define SCSI_SET_READ_BLEN(x, len)		SCSI_WR2((x), 7, (len))
103 
104 #define SCSI_SET_READ_CAPACITY_OP_CODE(x)	SCSI_WR1((x), 0, \
105 							SCSI_READ_CAPACITY)
106 #define SCSI_SET_READ_CAPACITY_LBA(x, lba)	SCSI_WR4((x), 2, (lba))
107 #define SCSI_SET_READ_CAPACITY_PMI(x)		SCSI_SET1((x), 8, 0x01)
108 #define SCSI_GET_READ_CAPACITY_LBA(x)		SCSI_RD4((x), 0)
109 #define SCSI_GET_READ_CAPACITY_BLEN(x)		SCSI_RD4((x), 4)
110 
111 #define SCSI_SET_REQUEST_SENSE_OP_CODE(x)	SCSI_WR1((x), 0, \
112 							SCSI_REQUEST_SENSE)
113 #define SCSI_SET_REQUEST_SENSE_ALLOC(x, alloc)	SCSI_WR1((x), 4, (alloc))
114 
115 #define SCSI_SET_TEST_OP_CODE(x)		SCSI_WR1((x), 0, \
116 							SCSI_TEST_UNIT_READY)
117 
118 #define SCSI_SET_WRITE_OP_CODE(x)		SCSI_WR1((x), 0, SCSI_WRITE)
119 #define SCSI_SET_WRITE_LBA(x, lba)		SCSI_WR4((x), 2, (lba))
120 #define SCSI_SET_WRITE_BLEN(x, len)		SCSI_WR2((x), 7, (len))
121 
122 typedef struct scsi_transfer {
123 
124 	unsigned int lba;			/* logical block address */
125 	unsigned int length;			/* transfer length */
126 }
127 scsi_transfer;
128 
129 /*---------------------------*
130  *    declared functions     *
131  *---------------------------*/
132 int create_scsi_cmd(mass_storage_cbw *, int, struct scsi_transfer *);
133 int check_inquiry_reply(uint8_t *);
134 int check_read_capacity_reply(uint8_t *, uint32_t *, uint32_t *);
135 int check_mode_sense_reply(uint8_t *, unsigned *, unsigned *, unsigned *);
136 int check_csw(mass_storage_csw *, unsigned int);
137 
138 #endif /* !_SCSI_H_ */
139