Sync with trunk head
[reactos.git] / drivers / usb / nt4compat / usbdriver / umss.h
1 #ifndef __UMSS_H__
2 #define __UMSS_H__
3
4 #define MAX_BULK_TRANSFER_LENGTH 0x100000
5
6 #define PROTOCOL_CBI 0x00
7 #define PROTOCOL_CB 0x01
8 #define PROTOCOL_BULKONLY 0x50
9
10 #define PROTOCOL_UNDEFINED 0xFF // Not in spec
11
12 #define UMSS_SUBCLASS_RBC 0x01
13 #define UMSS_SUBCLASS_SFF8020I 0X02
14 #define UMSS_SUBCLASS_QIC157 0x03
15 #define UMSS_SUBCLASS_UFI 0x04
16 #define UMSS_SUBCLASS_SFF8070I 0x05
17 #define UMSS_SUBCLASS_SCSI_TCS 0x06
18
19 #define ACCEPT_DEVICE_SPECIFIC_COMMAND 0
20
21 #define BULK_ONLY_MASS_STORAGE_RESET 0xFF
22 #define BULK_ONLY_GET_MAX_LUN 0xFE
23
24 #define CBW_SIGNATURE 0x43425355L
25 #define CSW_SIGNATURE 0x53425355L
26 #define CSW_OLYMPUS_SIGNATURE 0x55425355L
27
28 #define CSW_STATUS_PASSED 0x00
29 #define CSW_STATUS_FAILED 0x01
30 #define CSW_STATUS_PHASE_ERROR 0x02
31
32 #define IOCTL_UMSS_SUBMIT_CDB CTL_CODE( FILE_USB_DEV_TYPE, 4200, METHOD_BUFFERED, FILE_ANY_ACCESS )
33 // for request with no other input and output
34 // input buffer is a _USER_IO_PACKET and input_buffer_length is length of the _USER_IO_PACKET
35 // output_buffer is NULL, and output_buffer_length is zero
36
37 #define IOCTL_UMSS_SUBMIT_CDB_IN CTL_CODE( FILE_USB_DEV_TYPE, 4201, METHOD_IN_DIRECT, FILE_ANY_ACCESS )
38 // for request to read in data
39 // input_buffer is a _USER_IO_PACKET and input_buffer_length is length to the _USER_IO_PACKET
40 // output_buffer is a buffer to receive the data from dev, and
41 // output_buffer_length is the size of the buffer
42
43 #define IOCTL_UMSS_SUBMIT_CDB_OUT CTL_CODE( FILE_USB_DEV_TYPE, 4202, METHOD_OUT_DIRECT, FILE_ANY_ACCESS )
44 // for request to write data to device
45 // input_buffer is a _USER_IO_PACKET and input_buffer_length is length to the _USER_IO_PACKET
46 // output_buffer is data to send to the device, and
47 // output_buffer_length is the size of the buffer
48
49 #define IOCTL_REGISTER_DRIVER CTL_CODE( FILE_USB_DEV_TYPE, 4203, METHOD_BUFFERED, FILE_ANY_ACCESS )
50 // input_buffer is a CLASS_DRV_REG_INFO, and input_buffer_length is equal to or greater than
51 // sizeof( CLASS_DRV_REG_INFO ); the output_buffer is null and no output_buffer_length,
52 // only the following fields in urb can be accessed, others must be zeroed.
53
54 #define IOCTL_REVOKE_DRIVER CTL_CODE( FILE_USB_DEV_TYPE, 4204, METHOD_BUFFERED, FILE_ANY_ACCESS )
55 // tell the umss driver to clear the information in the drivers registry
56 // no other parameters
57
58 #define IOCTL_UMSS_SUBMIT_SRB CTL_CODE( FILE_USB_DEV_TYPE, 4205, METHOD_BUFFERED, FILE_ANY_ACCESS )
59 // irpStack->Parameters.Scsi.Srb points to an Srb structure and all the data buffer and buffer
60 // size are stored in the srb
61
62
63 #define IOCTL_UMSS_SET_FDO CTL_CODE( FILE_USB_DEV_TYPE, 4206, METHOD_BUFFERED, FILE_ANY_ACCESS )
64 // input_buffer is a pointer to PDEVICE_OBJECT, and input_buffer_length should be
65 // no less than sizeof( PDEVICE_OBJECT )
66 // output buffer is NULL, and output_buffer_length is zero
67 // if the deivce is accessable, the fdo is set, else, the fdo is not set and return
68 // STATUS_DEVICE_DOES_NOT_EXIST
69
70 #define SFF_FORMAT_UNIT 0x04
71 #define SFF_INQUIRY 0x12
72 #define SFF_MODE_SELECT 0x55
73 #define SFF_MODE_SENSE 0x5a
74 #define SFF_ALLOW_REMOVE 0x1e
75 #define SFF_READ10 0x28
76 #define SFF_READ12 0xa8
77 #define SFF_READ_CAPACITY 0x25
78 #define SFF_REQUEST_SENSEE 0x03
79 #define SFF_SEEK 0x2b
80 #define SFF_START_STOP 0x1b
81 #define SFF_TUR 0x00
82 #define SFF_VERIFY 0x2f
83 #define SFF_WRITE10 0x2a
84 #define SFF_WRITE12 0xaa
85 #define SFF_READ_FMT_CAPACITY 0x23
86 #define SFF_WRITE_VERIFY 0x2e
87
88 #define MAX_CDB_LENGTH 0x10
89
90 typedef struct _USER_IO_PACKET
91 {
92 UCHAR sub_class;
93 UCHAR lun;
94 UCHAR cdb_length;
95 UCHAR cdb[ MAX_CDB_LENGTH ];
96
97 } USER_IO_PACKET, *PUSER_IO_PACKET;
98
99 //flags for IO_PACKET::flags
100 #define IOP_FLAG_REQ_SENSE 0x80000000 // sense data would be fetched if error occurs
101 #define IOP_FLAG_SRB_TRANSFER 0x40000000 // current tranfer is initiated by an srb request, the srb is held by the irp
102 #define IOP_FLAG_SCSI_CTRL_TRANSFER 0x20000000 // current transfer is initiated by an scsi ioctrl request
103
104 #define IOP_FLAG_DIR_IN USB_DIR_IN
105 #define IOP_FLAG_STAGE_MASK 0x03
106 #define IOP_FLAG_STAGE_NORMAL 0x00
107 #define IOP_FLAG_STAGE_SENSE 0x01
108
109 typedef struct _IO_PACKET
110 {
111 ULONG flags;
112 UCHAR cdb_length;
113 UCHAR cdb[ MAX_CDB_LENGTH ];
114 UCHAR lun;
115 PVOID data_buffer;
116 ULONG data_length;
117 PVOID sense_data;
118 ULONG sense_data_length;
119 PIRP pirp;
120
121 } IO_PACKET, *PIO_PACKET;
122
123 #pragma pack( 1 )
124
125 typedef struct _COMMAND_BLOCK_WRAPPER
126 {
127 ULONG dCBWSignature;
128 ULONG dCBWTag;
129 ULONG dCBWDataTransferLength;
130 UCHAR bmCBWFlags;
131 UCHAR bCBWLun;
132 UCHAR bCBWLength;
133 UCHAR CBWCB[ MAX_CDB_LENGTH ];
134
135 } COMMAND_BLOCK_WRAPPER, *PCOMMAND_BLOCK_WRAPPER;
136
137 typedef struct _COMMAND_STATUS_WRAPPER
138 {
139 ULONG dCSWSignature;
140 ULONG dCSWTag;
141 ULONG dCSWDataResidue;
142 UCHAR bCSWStatus;
143
144 } COMMAND_STATUS_WRAPPER, *PCOMMAND_STATUS_WRAPPER;
145
146
147 typedef struct _INTERRUPT_DATA_BLOCK
148 {
149 UCHAR bType;
150 UCHAR bValue;
151
152 } INTERRUPT_DATA_BLOCK, *PINTERRUPT_DATA_BLOCK;
153
154 #pragma pack()
155
156 #define UMSS_PNPMSG_STOP 0x01
157 #define UMSS_PNPMSG_DISCONNECT 0x02
158
159 typedef NTSTATUS ( *PCLASS_DRVR_PNP_DISP )( PDEVICE_OBJECT pdo, ULONG ctrl_code, PVOID context );
160 // pdo is the device object umss created
161
162 typedef PDEVICE_OBJECT ( *PCLASS_DRIVER_ADD_DEV )( PDRIVER_OBJECT fdo_drvr, PDEVICE_OBJECT pdo );
163 // if the return value is not zero, it is a pointer to the
164 // fdo sitting over the pdo of this driver. if it is null,
165 // the add_device failed, and initialization process should
166 // stall.
167
168 typedef struct _CLASS_DRV_REGISTRY_INFO
169 {
170 // class driver will pass this structure to umss port
171 // driver after loaded
172 PDRIVER_OBJECT fdo_driver;
173 PCLASS_DRIVER_ADD_DEV add_device;
174 PCLASS_DRVR_PNP_DISP pnp_dispatch;
175
176 } CLASS_DRV_REG_INFO, *PCLASS_DRV_REG_INFO;
177
178 typedef struct _UMSS_PORT_DEVICE_EXTENSION
179 {
180 // this structure is the device extension for port dev_obj
181 // it is used to has class driver pass CLASS_DRV_REG_INFO
182 // to our umss driver.
183 DEVEXT_HEADER dev_ext_hdr;
184 PUSB_DRIVER pdriver;
185
186 } UMSS_PORT_DEV_EXT, *PUMSS_PORT_DEV_EXT;
187
188 typedef struct _UMSS_DRVR_EXTENSION
189 {
190 LIST_HEAD dev_list;
191 FAST_MUTEX dev_list_mutex;
192 UCHAR dev_count;
193 CLASS_DRV_REG_INFO class_driver_info;
194 PDEVICE_OBJECT port_dev_obj; // we use this obj as a connection point for class driver, its name usbPort0
195
196 } UMSS_DRVR_EXTENSION, *PUMSS_DRVR_EXTENSION;
197
198 #define UMSS_DEV_FLAG_IF_DEV 0x01
199 #define UMSS_DEV_FLAG_OLYMPUS_DEV 0x02
200
201 #define UMSS_OLYMPUS_VENDOR_ID 0x07b4
202
203 typedef struct _UMSS_DEVICE_EXTENSION
204 {
205 //this structure is the device extension for dev_obj
206 //created for the device.
207 DEVEXT_HEADER dev_ext_hdr;
208
209 ULONG flags;
210 LIST_ENTRY dev_obj_link; // this link is used by the driver object to track the existing dev_objs
211
212 PDEVICE_OBJECT pdo; // this is the pdo
213 PDEVICE_OBJECT fdo; // driver object for the dev_obj
214
215 DEV_HANDLE dev_handle; // handle to the usb_dev under
216
217 PUCHAR desc_buf;
218 UCHAR umss_dev_id; // used to build symbolic link
219
220 PUSB_INTERFACE_DESC pif_desc;
221 PUSB_ENDPOINT_DESC pout_endp_desc, pin_endp_desc, pint_endp_desc;
222 UCHAR if_idx, out_endp_idx, in_endp_idx, int_endp_idx;
223
224 struct _USB_DEV_MANAGER *dev_mgr;
225
226 //working data
227 COMMAND_BLOCK_WRAPPER cbw;
228 union
229 {
230 INTERRUPT_DATA_BLOCK idb;
231 COMMAND_STATUS_WRAPPER csw;
232 };
233
234 KEVENT sync_event; //for umss_sync_submit_urb
235 KSPIN_LOCK dev_lock;
236 IO_PACKET io_packet;
237 BOOLEAN retry;
238
239 PUSB_DRIVER pdriver; //used by umss_delete_device
240 NTSTATUS reset_pipe_status;
241 } UMSS_DEVICE_EXTENSION, *PUMSS_DEVICE_EXTENSION;
242
243 // for device creation workitem
244 typedef struct _UMSS_CREATE_DATA
245 {
246 DEV_HANDLE dev_handle;
247 PUCHAR desc_buf;
248 PUSB_DEV_MANAGER dev_mgr;
249 PUSB_DRIVER pdriver;
250
251 } UMSS_CREATE_DATA, *PUMSS_CREATE_DATA;
252
253 // for reset pipe item
254 //typedef void ( _stdcall *COMPLETION_HANDLER )( PVOID );
255 typedef void ( *UMSS_WORKER_ROUTINE )( PVOID );
256
257 typedef struct _UMSS_WORKER_PACKET
258 {
259 UMSS_WORKER_ROUTINE completion;
260 PVOID context;
261 PUSB_DEV_MANAGER dev_mgr;
262 PVOID pdev;
263
264 } UMSS_WORKER_PACKET, *PUMSS_WORKER_PACKET;
265
266 BOOLEAN
267 umss_driver_init(
268 PUSB_DEV_MANAGER dev_mgr,
269 PUSB_DRIVER pdriver
270 );
271
272 BOOLEAN
273 umss_if_driver_init(
274 PUSB_DEV_MANAGER dev_mgr,
275 PUSB_DRIVER pdriver
276 );
277
278 BOOLEAN
279 umss_driver_destroy(
280 PUSB_DEV_MANAGER dev_mgr,
281 PUSB_DRIVER pdriver
282 );
283
284 #define umss_if_driver_destroy umss_driver_destroy
285
286 BOOLEAN
287 umss_if_driver_destroy(
288 PUSB_DEV_MANAGER dev_mgr,
289 PUSB_DRIVER pdriver
290 );
291
292 VOID
293 umss_complete_request(
294 PUMSS_DEVICE_EXTENSION pdev_ext,
295 NTSTATUS status
296 );
297
298 NTSTATUS
299 umss_reset_pipe(
300 PUMSS_DEVICE_EXTENSION pdev_ext,
301 DEV_HANDLE endp_handle
302 );
303
304 PVOID
305 umss_get_buffer(
306 PUMSS_DEVICE_EXTENSION pdev_ext,
307 ULONG* buf_length
308 );
309
310 NTSTATUS
311 umss_bulk_transfer(
312 IN PUMSS_DEVICE_EXTENSION pdev_ext,
313 IN UCHAR trans_dir,
314 IN PVOID buf,
315 IN ULONG buf_length,
316 IN PURBCOMPLETION completion
317 );
318
319 BOOLEAN
320 umss_schedule_workitem(
321 PVOID context,
322 UMSS_WORKER_ROUTINE completion,
323 PUSB_DEV_MANAGER dev_mgr,
324 DEV_HANDLE dev_handle
325 );
326
327 NTSTATUS
328 umss_bulkonly_startio(
329 IN PUMSS_DEVICE_EXTENSION pdev_ext,
330 IN PIO_PACKET io_packet
331 );
332
333 NTSTATUS
334 umss_cbi_startio(
335 IN PUMSS_DEVICE_EXTENSION pdev_ext,
336 IN PIO_PACKET io_packet
337 );
338
339 #define UMSS_FORGE_GOOD_SENSE( sense_BUF ) \
340 {\
341 int i;\
342 PUCHAR buf = ( PUCHAR )( sense_BUF ); \
343 for( i = 0; i < 18; i++)\
344 {\
345 buf[i] = 0;\
346 }\
347 buf[7] = 10;\
348 }
349
350 #endif