19
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
21
#define WRAP_ALLOC_URB(a, b) usb_alloc_urb(a)
22
#define WRAP_SUBMIT_URB(a, b) usb_submit_urb(a)
26
#define WRAP_ALLOC_URB(a, b) usb_alloc_urb(a, b)
27
#define WRAP_SUBMIT_URB(a, b) usb_submit_urb(a, b)
20
static unsigned int urb_id = 0;
23
#define DUMP_WRAP_URB(wrap_urb, dir) \
24
USBTRACE("urb %p (%d) %s: buf: %p, len: %d, pipe: %u", \
25
(wrap_urb)->urb, (wrap_urb)->id, \
26
(dir == 0) ? "going down" : "coming back", \
27
(wrap_urb)->urb->transfer_buffer, \
28
(wrap_urb)->urb->transfer_buffer_length, \
29
(wrap_urb)->urb->pipe)
31
#define DUMP_BUFFER(buf, len) \
32
while (debug >= 2) { \
34
char __msg[100], *__t; \
38
for (__i = 0; __i < len && \
39
__t < &__msg[sizeof(__msg) - 4]; __i++) { \
40
__t += sprintf(__t, "%02X ", \
41
(((UCHAR *)buf)[__i])); \
43
USBTRACE("%s", __msg); \
31
47
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,5)
32
48
#define CUR_ALT_SETTING(intf) (intf)->cur_altsetting
34
50
#define CUR_ALT_SETTING(intf) (intf)->altsetting[(intf)->act_altsetting]
37
static struct list_head completed_irps;
38
static KIRQL completed_irps_lock;
39
void usb_transfer_complete_tasklet(unsigned long dummy);
40
DECLARE_TASKLET(completed_irps_tasklet, usb_transfer_complete_tasklet, 0);
42
static struct list_head canceled_irps;
43
void usb_cancel_worker(void *dummy);
44
static struct work_struct cancel_usb_irp_work;
53
#ifndef USB_CTRL_SET_TIMEOUT
54
#define USB_CTRL_SET_TIMEOUT 5000
57
static int inline wrap_cancel_urb(struct urb *urb)
60
ret = usb_unlink_urb(urb);
61
if (ret != -EINPROGRESS) {
62
WARNING("unlink failed: %d", ret);
68
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
70
#define URB_NO_TRANSFER_DMA_MAP 0x0004
71
#define URB_STATUS(wrap_urb) (wrap_urb->urb_status)
73
static void *usb_buffer_alloc(struct usb_device *udev, size_t size,
74
unsigned mem_flags, dma_addr_t *dma)
76
return kmalloc(size, mem_flags);
79
static void usb_buffer_free(struct usb_device *udev, size_t size, void *addr,
85
static void usb_init_urb(struct urb *urb)
87
memset(urb, 0, sizeof(*urb));
92
#define URB_STATUS(wrap_urb) (wrap_urb->urb->status)
45
96
extern KSPIN_LOCK irp_cancel_lock;
48
#define DUMP_URB(urb) do { \
51
if ((urb)->pipe & USB_DIR_IN) \
52
USBTRACE("URB coming back"); \
54
USBTRACE("URB going down"); \
55
printk(KERN_DEBUG "length: %x", \
56
urb->transfer_buffer_length); \
58
for (i = 0; i < urb->transfer_buffer_length && \
59
t < &dbg[sizeof(dbg) - 2]; i++) \
60
t += sprintf(t, "%02X ", \
61
*(((UCHAR *)urb->transfer_buffer)+i)); \
62
dbg[sizeof(dbg)-1] = 0; \
63
printk(KERN_DEBUG "%s\n", dbg); \
69
static inline int wrap_submit_urb(struct urb *urb, int flags)
72
struct irp *irp = urb->context;
74
ret = WRAP_SUBMIT_URB(urb, flags);
76
ERROR("usb_submit_urb() = %d", ret);
78
if (IRP_DRIVER_CONTEXT(irp)[2])
79
kfree(IRP_DRIVER_CONTEXT(irp)[2]);
98
/* TODO: using a worker instead of tasklet is probably preferable,
99
* since we don't know if IoCompleteRequest can be called from atomic
100
* context, but with ZyDas driver the worker never gets executed, even
101
* though it gets scheduled */
102
static struct tasklet_struct irp_complete_work;
103
static struct nt_list irp_complete_list;
105
static STDCALL void wrap_cancel_irp(struct device_object *dev_obj,
107
static void irp_complete_worker(unsigned long data);
84
109
int usb_init(void)
86
kspin_lock_init(&completed_irps_lock);
87
INIT_LIST_HEAD(&canceled_irps);
88
INIT_LIST_HEAD(&completed_irps);
89
INIT_WORK(&cancel_usb_irp_work, usb_cancel_worker, NULL);
111
InitializeListHead(&irp_complete_list);
112
tasklet_init(&irp_complete_work, irp_complete_worker, 0);
93
119
void usb_exit(void)
98
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
99
void usb_transfer_complete(struct urb *urb, struct pt_regs *regs)
101
void usb_transfer_complete(struct urb *urb)
104
struct irp *irp = urb->context;
107
USBTRACEENTER("urb = %p", urb);
109
/* canceled via usb_unlink_urb? */
110
if ((urb->status == -ENOENT) || (urb->status == -ECONNRESET))
111
USBTRACEEXIT(return);
113
/* canceled but not yet unlinked? */
114
kspin_lock(&irp_cancel_lock);
115
irp->cancel_routine = NULL;
116
cancel = irp->cancel;
117
kspin_unlock(&irp_cancel_lock);
120
USBTRACEEXIT(return);
122
kspin_lock(&completed_irps_lock);
123
list_add_tail(&irp->completed_list, &completed_irps);
124
kspin_unlock(&completed_irps_lock);
126
tasklet_schedule(&completed_irps_tasklet);
127
USBTRACEEXIT(return);
130
void usb_transfer_complete_tasklet(unsigned long dummy)
134
struct io_stack_location *stack;
135
union nt_urb *nt_urb;
139
kspin_lock_irqsave(&completed_irps_lock, flags);
141
if (list_empty(&completed_irps)) {
142
kspin_unlock_irqrestore(&completed_irps_lock, flags);
143
USBTRACEEXIT(return);
145
irp = list_entry(completed_irps.next, struct irp,
147
list_del(&irp->completed_list);
149
kspin_unlock_irqrestore(&completed_irps_lock, flags);
151
urb = IRP_DRIVER_CONTEXT(irp)[3];
152
stack = IRP_CUR_STACK_LOC(irp) - 1;
153
nt_urb = stack->params.generic.arg1;
155
USBTRACE("irp = %p, urb = %p, status = %d", irp, urb,
158
if (urb->setup_packet)
159
kfree(urb->setup_packet);
161
irp->pending_returned = 1;
164
irp->io_status.status = STATUS_FAILURE;
121
tasklet_kill(&irp_complete_work);
125
int usb_init_device(struct wrapper_dev *wd)
127
InitializeListHead(&wd->dev.usb.wrap_urb_list);
128
wd->dev.usb.num_alloc_urbs = 0;
132
void usb_exit_device(struct wrapper_dev *wd)
135
struct wrap_urb *wrap_urb;
139
IoAcquireCancelSpinLock(&irql);
140
ent = RemoveHeadList(&wd->dev.usb.wrap_urb_list);
141
IoReleaseCancelSpinLock(irql);
144
wrap_urb = container_of(ent, struct wrap_urb, list);
145
if (wrap_urb->state == URB_SUBMITTED) {
146
WARNING("Windows driver %s didn't free urb: %p",
147
wd->driver->name, wrap_urb->urb);
148
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
149
wrap_cancel_urb(wrap_urb->urb);
151
usb_kill_urb(wrap_urb->urb);
153
wrap_urb->state = URB_FREE;
155
usb_free_urb(wrap_urb->urb);
158
wd->dev.usb.num_alloc_urbs = 0;
162
/* for a given Linux urb status code, return corresponding NT urb status */
163
static USBD_STATUS wrap_urb_status(int urb_status)
165
switch (urb_status) {
167
return USBD_STATUS_SUCCESS;
169
return USBD_STATUS_BTSTUFF;
171
return USBD_STATUS_CRC;
173
return USBD_STATUS_INVALID_PIPE_HANDLE;
175
return USBD_STATUS_DATA_OVERRUN;
177
return USBD_STATUS_DATA_UNDERRUN;
179
return USBD_STATUS_BABBLE_DETECTED;
181
return USBD_STATUS_ERROR_SHORT_TRANSFER;;
184
return USBD_STATUS_DEVICE_GONE;
186
return USBD_STATUS_NO_MEMORY;
188
return USBD_STATUS_NOT_SUPPORTED;
192
/* for a given USBD_STATUS, return its corresponding NTSTATUS (for irp) */
193
static NTSTATUS nt_urb_irp_status(USBD_STATUS nt_urb_status)
195
switch (nt_urb_status) {
196
case USBD_STATUS_SUCCESS:
197
return STATUS_SUCCESS;
198
case USBD_STATUS_DEVICE_GONE:
199
return STATUS_DEVICE_REMOVED;
200
case USBD_STATUS_PENDING:
201
return STATUS_PENDING;
202
case USBD_STATUS_NOT_SUPPORTED:
203
return STATUS_NOT_IMPLEMENTED;
204
case USBD_STATUS_NO_MEMORY:
205
return STATUS_NO_MEMORY;
207
return STATUS_FAILURE;
211
static void wrap_free_urb(struct urb *urb)
214
struct wrap_urb *wrap_urb;
215
struct wrapper_dev *wd;
217
USBTRACE("freeing urb: %p", urb);
218
wrap_urb = urb->context;
220
IoAcquireCancelSpinLock(&irp->cancel_irql);
222
irp->cancel_routine = NULL;
223
irp->wrap_urb = NULL;
224
if (urb->transfer_buffer &&
225
(wrap_urb->alloc_flags & URB_NO_TRANSFER_DMA_MAP)) {
226
USBTRACE("freeing DMA buffer for URB: %p %p",
227
urb, urb->transfer_buffer);
228
usb_buffer_free(irp->wd->dev.usb.udev,
229
urb->transfer_buffer_length,
230
urb->transfer_buffer, urb->transfer_dma);
232
if (urb->setup_packet)
233
kfree(urb->setup_packet);
234
if (wd->dev.usb.num_alloc_urbs > MAX_ALLOCATED_URBS) {
235
RemoveEntryList(&wrap_urb->list);
236
wd->dev.usb.num_alloc_urbs--;
240
wrap_urb->state = URB_FREE;
241
wrap_urb->alloc_flags = 0;
242
wrap_urb->irp = NULL;
244
if (wd->dev.usb.num_alloc_urbs < 0)
245
WARNING("num_allocated_urbs: %d",
246
wd->dev.usb.num_alloc_urbs);
247
IoReleaseCancelSpinLock(irp->cancel_irql);
251
void wrap_suspend_urbs(struct wrapper_dev *wd)
253
/* TODO: do we need to cancel urbs? */
256
void wrap_resume_urbs(struct wrapper_dev *wd)
258
/* TODO: do we need to resubmit urbs? */
261
static struct urb *wrap_alloc_urb(struct irp *irp, unsigned int pipe,
262
void *buf, unsigned int buf_len)
265
unsigned int alloc_flags;
266
struct wrap_urb *wrap_urb;
267
struct wrapper_dev *wd;
269
if (current_irql() < DISPATCH_LEVEL)
270
alloc_flags = GFP_KERNEL;
272
alloc_flags = GFP_ATOMIC;
274
IoAcquireCancelSpinLock(&irp->cancel_irql);
276
nt_list_for_each_entry(wrap_urb, &wd->dev.usb.wrap_urb_list, list) {
277
if (wrap_urb->state == URB_FREE) {
278
wrap_urb->state = URB_ALLOCATED;
286
IoReleaseCancelSpinLock(irp->cancel_irql);
287
wrap_urb = kmalloc(sizeof(*wrap_urb), alloc_flags);
289
WARNING("couldn't allocate memory");
292
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
293
urb = usb_alloc_urb(0, alloc_flags);
295
urb = usb_alloc_urb(0);
298
WARNING("couldn't allocate urb");
302
IoAcquireCancelSpinLock(&irp->cancel_irql);
303
memset(wrap_urb, 0, sizeof(*wrap_urb));
305
wrap_urb->state = URB_ALLOCATED;
306
InsertTailList(&wd->dev.usb.wrap_urb_list, &wrap_urb->list);
307
wd->dev.usb.num_alloc_urbs++;
310
#ifdef USB_ASYNC_UNLINK
311
urb->transfer_flags |= URB_ASYNC_UNLINK;
313
urb->context = wrap_urb;
315
wrap_urb->state = URB_ALLOCATED;
316
wrap_urb->pipe = pipe;
317
irp->wrap_urb = wrap_urb;
318
irp->cancel_routine = wrap_cancel_irp;
319
IoReleaseCancelSpinLock(irp->cancel_irql);
320
USBTRACE("allocated urb: %p", urb);
321
if (buf_len && buf) {
322
if (virt_addr_valid(buf))
323
urb->transfer_buffer = buf;
325
urb->transfer_buffer =
326
usb_buffer_alloc(irp->wd->dev.usb.udev,
327
buf_len, alloc_flags,
329
if (!urb->transfer_buffer) {
330
WARNING("couldn't allocate dma buf");
331
IoAcquireCancelSpinLock(&irp->cancel_irql);
332
wrap_urb->state = URB_FREE;
333
wrap_urb->irp = NULL;
334
irp->wrap_urb = NULL;
335
IoReleaseCancelSpinLock(irp->cancel_irql);
338
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
339
wrap_urb->alloc_flags |= URB_NO_TRANSFER_DMA_MAP;
340
if (usb_pipeout(pipe))
341
memcpy(urb->transfer_buffer, buf, buf_len);
342
USBTRACE("DMA buffer for urb %p is %p",
343
urb, urb->transfer_buffer);
346
urb->transfer_buffer = NULL;
347
urb->transfer_buffer_length = buf_len;
351
NTSTATUS wrap_submit_urb(struct irp *irp)
355
unsigned int alloc_flags;
357
union nt_urb *nt_urb;
359
if (current_irql() < DISPATCH_LEVEL)
360
alloc_flags = GFP_KERNEL;
362
alloc_flags = GFP_ATOMIC;
363
IoAcquireCancelSpinLock(&irp->cancel_irql);
364
urb = irp->wrap_urb->urb;
365
nt_urb = URB_FROM_IRP(irp);
366
if (irp->wrap_urb->state != URB_ALLOCATED) {
367
ERROR("urb %p is in wrong state: %d",
368
urb, irp->wrap_urb->state);
369
status = NT_URB_STATUS(nt_urb) = USBD_STATUS_REQUEST_FAILED;
370
irp->io_status.status = STATUS_NOT_SUPPORTED;
371
irp->io_status.status_info = 0;
372
IoReleaseCancelSpinLock(irp->cancel_irql);
375
irp->wrap_urb->state = URB_SUBMITTED;
377
irp->wrap_urb->id = urb_id++;
379
IoReleaseCancelSpinLock(irp->cancel_irql);
380
DUMP_WRAP_URB(irp->wrap_urb, 0);
381
irp->io_status.status = STATUS_PENDING;
382
irp->io_status.status_info = 0;
383
NT_URB_STATUS(nt_urb) = USBD_STATUS_PENDING;
384
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
385
ret = usb_submit_urb(urb, alloc_flags);
387
ret = usb_submit_urb(urb);
390
USBTRACE("ret: %d", ret);
392
irp->io_status.status = STATUS_NOT_SUPPORTED;
393
irp->io_status.status_info = 0;
394
NT_URB_STATUS(nt_urb) = USBD_STATUS_REQUEST_FAILED;
395
USBEXIT(return irp->io_status.status);
397
USBEXIT(return STATUS_PENDING);
400
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
401
static void wrap_urb_complete(struct urb *urb, struct pt_regs *regs)
403
static void wrap_urb_complete(struct urb *urb)
407
struct wrap_urb *wrap_urb;
409
wrap_urb = urb->context;
411
IoAcquireCancelSpinLock(&irp->cancel_irql);
412
DUMP_WRAP_URB(wrap_urb, 1);
413
irp->cancel_routine = NULL;
414
if (wrap_urb->state != URB_SUBMITTED &&
415
wrap_urb->state != URB_CANCELED)
416
WARNING("urb %p in wrong state: %d", urb, wrap_urb->state);
417
wrap_urb->state = URB_COMPLETED;
418
/* To prevent 2.4 kernels from resubmiting interrupt URBs
419
* (Windows driver also resubmits them); UHCI doesn't resubmit
420
* URB if status == -ENOENT */
421
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
422
if (usb_pipeint(urb->pipe)) {
423
wrap_urb->urb_status = urb->status;
424
urb->status = -ENOENT;
427
InsertTailList(&irp_complete_list, &irp->complete_list);
428
IoReleaseCancelSpinLock(irp->cancel_irql);
429
USBTRACE("urb %p (irp: %p) completed", urb, irp);
430
tasklet_schedule(&irp_complete_work);
433
/* one worker for all devices */
434
static void irp_complete_worker(unsigned long data)
438
struct usbd_bulk_or_intr_transfer *bulk_int_tx;
439
struct usbd_vendor_or_class_request *vc_req;
440
union nt_urb *nt_urb;
441
struct wrap_urb *wrap_urb;
446
IoAcquireCancelSpinLock(&irql);
447
ent = RemoveHeadList(&irp_complete_list);
448
IoReleaseCancelSpinLock(irql);
451
irp = container_of(ent, struct irp, complete_list);
453
wrap_urb = irp->wrap_urb;
455
if (wrap_urb->state != URB_COMPLETED)
456
WARNING("urb %p in wrong state: %d",
457
urb, wrap_urb->state);
458
nt_urb = URB_FROM_IRP(irp);
459
USBTRACE("urb: %p, nt_urb: %p, status: %d",
460
urb, nt_urb, URB_STATUS(wrap_urb));
461
switch (URB_STATUS(wrap_urb)) {
463
/* succesfully transferred */
464
NT_URB_STATUS(nt_urb) =
465
wrap_urb_status(URB_STATUS(wrap_urb));
166
466
irp->io_status.status = STATUS_SUCCESS;
167
irp->io_status.status_info = urb->actual_length;
169
/* also applies to ctrlDescReq or venClsReq */
170
nt_urb->bulkIntrTrans.transferBufLen = urb->actual_length;
174
if (IRP_DRIVER_CONTEXT(irp)[2]) {
175
if (urb->pipe & USB_DIR_IN) {
176
/* also applies to ctrlDescReq or venClsReq */
177
memcpy(nt_urb->bulkIntrTrans.transferBuf,
178
IRP_DRIVER_CONTEXT(irp)[2],
179
nt_urb->bulkIntrTrans.transferBufLen);
467
irp->io_status.status_info = urb->actual_length;
469
/* from WDM examples, it seems we don't need
470
* to update MDL's byte count if MDL is used */
471
switch (nt_urb->header.function) {
472
case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
473
bulk_int_tx = &nt_urb->bulk_int_transfer;
474
bulk_int_tx->transfer_buffer_length =
476
DUMP_BUFFER(urb->transfer_buffer,
478
if ((wrap_urb->alloc_flags &
479
URB_NO_TRANSFER_DMA_MAP) &&
480
usb_pipein(urb->pipe))
481
memcpy(bulk_int_tx->transfer_buffer,
482
urb->transfer_buffer,
485
case URB_FUNCTION_VENDOR_DEVICE:
486
case URB_FUNCTION_VENDOR_INTERFACE:
487
case URB_FUNCTION_VENDOR_ENDPOINT:
488
case URB_FUNCTION_VENDOR_OTHER:
489
case URB_FUNCTION_CLASS_DEVICE:
490
case URB_FUNCTION_CLASS_INTERFACE:
491
case URB_FUNCTION_CLASS_ENDPOINT:
492
case URB_FUNCTION_CLASS_OTHER:
493
vc_req = &nt_urb->vendor_class_request;
494
vc_req->transfer_buffer_length =
496
DUMP_BUFFER(urb->transfer_buffer,
498
DUMP_BUFFER(urb->setup_packet,
499
sizeof(struct usb_ctrlrequest));
500
if ((wrap_urb->alloc_flags &
501
URB_NO_TRANSFER_DMA_MAP) &&
502
usb_pipein(urb->pipe))
503
memcpy(vc_req->transfer_buffer,
504
urb->transfer_buffer,
508
ERROR("nt_urb type: %d unknown",
509
nt_urb->header.function);
181
kfree(IRP_DRIVER_CONTEXT(irp)[2]);
516
if (wrap_urb->state == URB_SUSPEND)
518
NT_URB_STATUS(nt_urb) = USBD_STATUS_CANCELLED;
519
irp->io_status.status = STATUS_CANCELLED;
520
irp->io_status.status_info = 0;
521
USBTRACE("irp %p canceled", irp);
524
NT_URB_STATUS(nt_urb) =
525
wrap_urb_status(URB_STATUS(wrap_urb));
526
irp->io_status.status =
527
nt_urb_irp_status(NT_URB_STATUS(nt_urb));
528
irp->io_status.status_info = 0;
529
USBTRACE("irp: %p, status: %d", irp,
530
URB_STATUS(wrap_urb));
184
IofCompleteRequest(FASTCALL_ARGS_2(irp, 0));
186
USBTRACE("freeing urb %p", urb);
534
IoCompleteRequest(irp, IO_NO_INCREMENT);
191
/* this is called holding irp_cancel_lock */
192
STDCALL void usb_cancel_transfer(struct device_object *dev_obj,
197
USBTRACEENTER("irp = %p", irp);
198
urb = IRP_DRIVER_CONTEXT(irp)[3];
199
USBTRACE("adding urb %p to cancel", urb);
201
/* while this function can run at DISPATCH_LEVEL,
202
* usb_unlink/kill_urb will only work successfully in
203
* schedulable context */
204
list_add_tail(&irp->cancel_list, &canceled_irps);
206
schedule_work(&cancel_usb_irp_work);
209
void usb_cancel_worker(void *dummy)
214
USBTRACEENTER("%s", "");
217
kspin_lock(&irp_cancel_lock);
219
if (list_empty(&canceled_irps)) {
220
kspin_unlock(&irp_cancel_lock);
221
USBTRACEEXIT(return);
223
irp = list_entry(canceled_irps.next, struct irp, cancel_list);
224
list_del(&irp->cancel_list);
226
kspin_unlock(&irp_cancel_lock);
228
urb = IRP_DRIVER_CONTEXT(irp)[3];
230
USBTRACE("freeing urb = %p", urb);
231
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)
234
if (usb_unlink_urb(urb) < 0)
235
USBTRACEEXIT(return);
237
if (urb->setup_packet)
238
kfree(urb->setup_packet);
241
if (IRP_DRIVER_CONTEXT(irp)[2])
242
kfree(IRP_DRIVER_CONTEXT(irp)[2]);
244
irp->io_status.status = STATUS_CANCELLED;
539
static STDCALL void wrap_cancel_irp(struct device_object *dev_obj,
544
/* NB: this function is called holding Cancel spinlock */
545
USBENTER("irp: %p", irp);
546
urb = irp->wrap_urb->urb;
547
USBTRACE("canceling urb %p", urb);
548
if (irp->wrap_urb->state == URB_SUBMITTED &&
549
wrap_cancel_urb(urb) == 0) {
550
USBTRACE("urb %p canceled", urb);
551
irp->wrap_urb->state = URB_CANCELED;
552
/* this IRP will be returned in urb's completion function */
553
IoReleaseCancelSpinLock(irp->cancel_irql);
555
union nt_urb *nt_urb;
556
nt_urb = URB_FROM_IRP(irp);
557
ERROR("urb %p not canceld: %d", urb, irp->wrap_urb->state);
558
NT_URB_STATUS(nt_urb) = USBD_STATUS_REQUEST_FAILED;
559
irp->io_status.status = STATUS_INVALID_PARAMETER;
245
560
irp->io_status.status_info = 0;
246
IofCompleteRequest(FASTCALL_ARGS_2(irp, 0));
561
IoReleaseCancelSpinLock(irp->cancel_irql);
563
IoCompleteRequest(irp, IO_NO_INCREMENT);
250
unsigned long usb_bulk_or_intr_trans(struct usb_device *dev,
251
union nt_urb *nt_urb, struct irp *irp)
567
static USBD_STATUS wrap_bulk_or_intr_trans(struct irp *irp)
253
union pipe_handle pipe_handle;
569
usbd_pipe_handle pipe_handle;
255
571
unsigned int pipe;
259
ASSERT(!nt_urb->bulkIntrTrans.transferBufMdl);
260
ASSERT(!nt_urb->bulkIntrTrans.urbLink);
261
USBTRACE("flags = %lX, length = %lu, buffer = %p",
262
nt_urb->bulkIntrTrans.transferFlags,
263
nt_urb->bulkIntrTrans.transferBufLen,
264
nt_urb->bulkIntrTrans.transferBuf);
266
/* FIXME: we should better check what GFP_ is required */
267
urb = WRAP_ALLOC_URB(0, GFP_ATOMIC);
271
/* store the linux-urb in the nt-irp and set the cancel routine */
272
IRP_DRIVER_CONTEXT(irp)[3] = urb;
273
irp->cancel_routine = usb_cancel_transfer;
275
pipe_handle = nt_urb->bulkIntrTrans.pipeHandle;
277
endpoint = pipe_handle.encoded.endpointAddr;
278
switch(pipe_handle.encoded.pipeType) {
279
case USB_ENDPOINT_XFER_CONTROL:
280
if (nt_urb->bulkIntrTrans.transferFlags &
281
USBD_TRANSFER_DIRECTION_IN)
282
pipe = usb_rcvctrlpipe(dev, endpoint);
284
pipe = usb_sndctrlpipe(dev, endpoint);
286
usb_fill_control_urb(urb, dev, pipe, urb->setup_packet,
287
nt_urb->bulkIntrTrans.transferBuf,
288
nt_urb->bulkIntrTrans.transferBufLen,
289
usb_transfer_complete, irp);
291
case USB_ENDPOINT_XFER_ISOC:
292
if (nt_urb->bulkIntrTrans.transferFlags &
293
USBD_TRANSFER_DIRECTION_IN)
294
pipe = usb_rcvisocpipe(dev, endpoint);
296
pipe = usb_sndisocpipe(dev, endpoint);
572
struct usbd_bulk_or_intr_transfer *bulk_int_tx;
574
struct usb_device *udev;
575
union nt_urb *nt_urb;
577
nt_urb = URB_FROM_IRP(irp);
578
udev = irp->wd->dev.usb.udev;
579
bulk_int_tx = &nt_urb->bulk_int_transfer;
580
USBTRACE("flags = %X, length = %u, buffer = %p",
581
bulk_int_tx->transfer_flags,
582
bulk_int_tx->transfer_buffer_length,
583
bulk_int_tx->transfer_buffer);
586
pipe_handle = bulk_int_tx->pipe_handle;
587
if (bulk_int_tx->transfer_flags & USBD_TRANSFER_DIRECTION_IN)
588
pipe = usb_rcvbulkpipe(udev, pipe_handle->bEndpointAddress);
590
pipe = usb_sndbulkpipe(udev, pipe_handle->bEndpointAddress);
592
if (unlikely(bulk_int_tx->transfer_buffer == NULL &&
593
bulk_int_tx->transfer_buffer_length > 0)) {
594
if (MmGetMdlByteCount(bulk_int_tx->mdl) !=
595
bulk_int_tx->transfer_buffer_length)
596
WARNING("mdl size %d != %d",
597
MmGetMdlByteCount(bulk_int_tx->mdl),
598
bulk_int_tx->transfer_buffer_length);
599
bulk_int_tx->transfer_buffer =
600
MmGetMdlVirtualAddress(bulk_int_tx->mdl);
603
urb = wrap_alloc_urb(irp, pipe, bulk_int_tx->transfer_buffer,
604
bulk_int_tx->transfer_buffer_length);
606
ERROR("couldn't allocate urb");
607
return USBD_STATUS_NO_MEMORY;
609
if (usb_pipein(pipe) &&
610
(!(bulk_int_tx->transfer_flags & USBD_SHORT_TRANSFER_OK))) {
611
USBTRACE("short not ok");
612
urb->transfer_flags |= URB_SHORT_NOT_OK;
615
switch(usb_pipetype(pipe)) {
298
616
case USB_ENDPOINT_XFER_BULK:
299
if (nt_urb->bulkIntrTrans.transferFlags &
300
USBD_TRANSFER_DIRECTION_IN)
301
pipe = usb_rcvbulkpipe(dev, endpoint);
303
pipe = usb_sndbulkpipe(dev, endpoint);
305
usb_fill_bulk_urb(urb, dev, pipe,
306
nt_urb->bulkIntrTrans.transferBuf,
307
nt_urb->bulkIntrTrans.transferBufLen,
308
usb_transfer_complete, irp);
617
usb_fill_bulk_urb(urb, udev, pipe, urb->transfer_buffer,
618
bulk_int_tx->transfer_buffer_length,
619
wrap_urb_complete, urb->context);
620
USBTRACE("submitting bulk urb %p on pipe %u",
621
urb, pipe_handle->bEndpointAddress);
622
status = USBD_STATUS_PENDING;
310
624
case USB_ENDPOINT_XFER_INT:
311
if (nt_urb->bulkIntrTrans.transferFlags &
312
USBD_TRANSFER_DIRECTION_IN)
313
pipe = usb_rcvintpipe(dev, endpoint);
315
pipe = usb_sndintpipe(dev, endpoint);
317
usb_fill_int_urb(urb, dev, pipe,
318
nt_urb->bulkIntrTrans.transferBuf,
319
nt_urb->bulkIntrTrans.transferBufLen,
320
usb_transfer_complete, irp,
321
pipe_handle.encoded.interval);
625
usb_fill_int_urb(urb, udev, pipe, urb->transfer_buffer,
626
bulk_int_tx->transfer_buffer_length,
627
wrap_urb_complete, urb->context,
628
pipe_handle->bInterval);
629
USBTRACE("submitting interrupt urb %p on pipe %u, intvl: %d",
630
urb, pipe_handle->bEndpointAddress,
631
pipe_handle->bInterval);
632
status = USBD_STATUS_PENDING;
324
ERROR("unknown pipe type: %d", pipe_handle.encoded.pipeType);
328
if ((nt_urb->venClsReq.transferFlags &
329
(USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK)) ==
330
USBD_TRANSFER_DIRECTION_IN)
331
urb->transfer_flags |= URB_SHORT_NOT_OK;
335
/* non-DMA-capable buffers have to be mirrored */
336
IRP_DRIVER_CONTEXT(irp)[2] = NULL;
337
if (!virt_addr_valid(nt_urb->bulkIntrTrans.transferBuf)) {
338
IRP_DRIVER_CONTEXT(irp)[2] =
339
kmalloc(nt_urb->bulkIntrTrans.transferBufLen,
341
if (!IRP_DRIVER_CONTEXT(irp)[2]) {
342
ERROR("%s", "kmalloc failed!");
347
if (!(pipe & USB_DIR_IN))
348
memcpy(IRP_DRIVER_CONTEXT(irp)[2],
349
nt_urb->bulkIntrTrans.transferBuf,
350
nt_urb->bulkIntrTrans.transferBufLen);
351
urb->transfer_buffer = IRP_DRIVER_CONTEXT(irp)[2];
352
USBTRACE("mirroring non-DMA buffer");
355
/* mark setup_packet as unused for cleanup procedure */
356
urb->setup_packet = NULL;
358
USBTRACE("submitting urb %p on pipe %p", urb, pipe_handle.handle);
359
/* FIXME: we should better check what GFP_ is required */
360
ret = wrap_submit_urb(urb, GFP_ATOMIC);
635
ERROR("unknown pipe type: %u", pipe_handle->bEndpointAddress);
636
status = USBD_STATUS_NOT_SUPPORTED;
639
USBEXIT(return status);
364
unsigned long usb_vendor_or_class_intf(struct usb_device *dev,
365
union nt_urb *nt_urb, struct irp *irp)
642
static USBD_STATUS wrap_vendor_or_class_req(struct irp *irp)
368
645
struct usb_ctrlrequest *dr;
370
647
unsigned int pipe;
373
ASSERT(!nt_urb->venClsReq.transferBufMdl);
374
ASSERT(!nt_urb->venClsReq.urbLink);
375
USBTRACE("reservedBits = %x, request = %x, "
376
"value = %d, index = %d, transferFlags = %lx, "
377
"transferBuf = %p, transferBufLen = %ld",
378
nt_urb->venClsReq.reservedBits,
379
nt_urb->venClsReq.request, nt_urb->venClsReq.value,
380
nt_urb->venClsReq.index, nt_urb->venClsReq.transferFlags,
381
nt_urb->venClsReq.transferBuf,
382
nt_urb->venClsReq.transferBufLen);
384
/* FIXME: we should better check what GFP_ is required */
385
urb = WRAP_ALLOC_URB(0, GFP_ATOMIC);
387
ERROR("%s", "usb_alloc_urb failed!");
391
req_type = USB_TYPE_VENDOR | USB_RECIP_DEVICE |
392
nt_urb->venClsReq.reservedBits;
394
if (nt_urb->venClsReq.transferFlags & USBD_TRANSFER_DIRECTION_IN) {
395
pipe = usb_rcvctrlpipe(dev, 0);
648
struct usbd_vendor_or_class_request *vc_req;
649
struct usb_device *udev;
650
union nt_urb *nt_urb;
653
nt_urb = URB_FROM_IRP(irp);
654
udev = irp->wd->dev.usb.udev;
655
vc_req = &nt_urb->vendor_class_request;
656
USBTRACE("bits = %x, req = %x, val = %08x, index = %08x, flags = %x,"
657
"tx_buf = %p, tx_buf_len = %d", vc_req->reserved_bits,
658
vc_req->request, vc_req->value, vc_req->index,
659
vc_req->transfer_flags, vc_req->transfer_buffer,
660
vc_req->transfer_buffer_length);
662
switch (nt_urb->header.function) {
663
case URB_FUNCTION_VENDOR_DEVICE:
664
req_type = USB_TYPE_VENDOR | USB_RECIP_DEVICE;
666
case URB_FUNCTION_VENDOR_INTERFACE:
667
req_type = USB_TYPE_VENDOR | USB_RECIP_INTERFACE;
669
case URB_FUNCTION_VENDOR_ENDPOINT:
670
req_type = USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
672
case URB_FUNCTION_VENDOR_OTHER:
673
req_type = USB_TYPE_VENDOR | USB_RECIP_OTHER;
675
case URB_FUNCTION_CLASS_DEVICE:
676
req_type = USB_TYPE_CLASS | USB_RECIP_DEVICE;
678
case URB_FUNCTION_CLASS_INTERFACE:
679
req_type = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
681
case URB_FUNCTION_CLASS_ENDPOINT:
682
req_type = USB_TYPE_CLASS | USB_RECIP_ENDPOINT;
684
case URB_FUNCTION_CLASS_OTHER:
685
req_type = USB_TYPE_CLASS | USB_RECIP_OTHER;
688
ERROR("unknown request type: %x", nt_urb->header.function);
693
req_type |= vc_req->reserved_bits;
694
USBTRACE("req type: %08x", req_type);
696
if (unlikely(vc_req->transfer_buffer == NULL &&
697
vc_req->transfer_buffer_length > 0)) {
698
if (MmGetMdlByteCount(vc_req->mdl) !=
699
vc_req->transfer_buffer_length)
700
WARNING("mdl size %d != %d",
701
MmGetMdlByteCount(vc_req->mdl),
702
vc_req->transfer_buffer_length);
703
vc_req->transfer_buffer = MmGetMdlVirtualAddress(vc_req->mdl);
706
if (vc_req->transfer_flags & USBD_TRANSFER_DIRECTION_IN) {
707
pipe = usb_rcvctrlpipe(udev, 0);
396
708
req_type |= USB_DIR_IN;
709
USBTRACE("pipe: %u, dir in", pipe);
398
pipe = usb_sndctrlpipe(dev, 0);
711
pipe = usb_sndctrlpipe(udev, 0);
399
712
req_type |= USB_DIR_OUT;
402
dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
713
USBTRACE("pipe: %u, dir out", pipe);
716
urb = wrap_alloc_urb(irp, pipe, vc_req->transfer_buffer,
717
vc_req->transfer_buffer_length);
719
ERROR("couldn't allocate urb");
720
return USBD_STATUS_NO_MEMORY;
723
if (usb_pipein(pipe) &&
724
(!(vc_req->transfer_flags & USBD_SHORT_TRANSFER_OK))) {
725
USBTRACE("short not ok");
726
urb->transfer_flags |= URB_SHORT_NOT_OK;
729
dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
404
ERROR("%s", "kmalloc failed!");
731
ERROR("couldn't allocate memory");
733
return USBD_STATUS_NO_MEMORY;
735
memset(dr, 0, sizeof(*dr));
409
736
dr->bRequestType = req_type;
410
dr->bRequest = nt_urb->venClsReq.request;
411
dr->wValue = nt_urb->venClsReq.value;
412
dr->wIndex = nt_urb->venClsReq.index;
413
dr->wLength = nt_urb->venClsReq.transferBufLen;
415
usb_fill_control_urb(urb, dev, pipe, (unsigned char *)dr,
416
nt_urb->venClsReq.transferBuf,
417
nt_urb->venClsReq.transferBufLen,
418
usb_transfer_complete, irp);
420
if ((nt_urb->venClsReq.transferFlags &
421
(USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK)) ==
422
USBD_TRANSFER_DIRECTION_IN)
423
urb->transfer_flags |= URB_SHORT_NOT_OK;
427
/* non-DMA-capable buffers have to be mirrored */
428
IRP_DRIVER_CONTEXT(irp)[2] = NULL;
429
if ((nt_urb->venClsReq.transferBufLen > 0) &&
430
!virt_addr_valid(nt_urb->venClsReq.transferBuf)) {
431
IRP_DRIVER_CONTEXT(irp)[2] =
432
kmalloc(nt_urb->venClsReq.transferBufLen, GFP_KERNEL);
433
if (!IRP_DRIVER_CONTEXT(irp)[2]) {
434
ERROR("%s", "kmalloc failed!");
440
if (!(pipe & USB_DIR_IN))
441
memcpy(IRP_DRIVER_CONTEXT(irp)[2],
442
nt_urb->venClsReq.transferBuf,
443
nt_urb->venClsReq.transferBufLen);
444
urb->transfer_buffer = IRP_DRIVER_CONTEXT(irp)[2];
445
USBTRACE("mirroring non-DMA buffer");
737
dr->bRequest = vc_req->request;
738
dr->wValue = cpu_to_le16(vc_req->value);
739
dr->wIndex = cpu_to_le16(vc_req->index);
740
dr->wLength = cpu_to_le16(vc_req->transfer_buffer_length);
742
usb_fill_control_urb(urb, udev, pipe, (unsigned char *)dr,
743
urb->transfer_buffer,
744
vc_req->transfer_buffer_length,
745
wrap_urb_complete, urb->context);
747
status = USBD_STATUS_PENDING;
748
USBEXIT(return status);
751
static USBD_STATUS wrap_reset_pipe(struct usb_device *udev, struct irp *irp)
753
unsigned int pipe1, pipe2;
755
union nt_urb *nt_urb;
756
usbd_pipe_handle pipe_handle;
757
enum pipe_type pipe_type;
759
USBTRACE("irp = %p", irp);
760
nt_urb = URB_FROM_IRP(irp);
762
pipe_handle = nt_urb->pipe_req.pipe_handle;
763
pipe_type = pipe_handle->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
764
/* TODO: not clear if both directions should be cleared? */
765
if (pipe_type == USB_ENDPOINT_XFER_BULK) {
766
pipe1 = usb_rcvbulkpipe(udev, pipe_handle->bEndpointAddress);
767
pipe2 = usb_sndbulkpipe(udev, pipe_handle->bEndpointAddress);
768
} else if (pipe_type == USB_ENDPOINT_XFER_INT) {
769
pipe1 = usb_rcvintpipe(udev, pipe_handle->bEndpointAddress);
770
/* no outgoing interrupt pipes */
772
} else if (pipe_type == USB_ENDPOINT_XFER_CONTROL) {
773
pipe1 = usb_rcvctrlpipe(udev, pipe_handle->bEndpointAddress);
774
pipe2 = usb_sndctrlpipe(udev, pipe_handle->bEndpointAddress);
776
WARNING("pipe type %d not handled", pipe_type);
777
return USBD_STATUS_SUCCESS;
448
/* store the linux-urb in the nt-irp and set the cancel routine */
449
IRP_DRIVER_CONTEXT(irp)[3] = urb;
450
irp->cancel_routine = usb_cancel_transfer;
452
USBTRACE("submitting urb %p on control pipe", urb);
453
/* FIXME: we should better check what GFP_ is required */
454
ret = wrap_submit_urb(urb, GFP_ATOMIC);
779
ret = usb_clear_halt(udev, pipe1);
460
unsigned long usb_reset_pipe(struct usb_device *dev,
461
union pipe_handle pipe_handle)
466
USBTRACE("pipe = %p", pipe_handle.handle);
467
endpoint = pipe_handle.encoded.endpointAddr;
468
switch (pipe_handle.encoded.pipeType) {
469
case USB_ENDPOINT_XFER_CONTROL:
470
if (pipe_handle.encoded.endpointAddr & USB_ENDPOINT_DIR_MASK)
471
pipe = usb_rcvctrlpipe(dev, endpoint);
473
pipe = usb_sndctrlpipe(dev, endpoint);
476
case USB_ENDPOINT_XFER_ISOC:
477
if (pipe_handle.encoded.endpointAddr & USB_ENDPOINT_DIR_MASK)
478
pipe = usb_rcvisocpipe(dev, endpoint);
480
pipe = usb_sndisocpipe(dev, endpoint);
483
case USB_ENDPOINT_XFER_BULK:
484
if (pipe_handle.encoded.endpointAddr & USB_ENDPOINT_DIR_MASK)
485
pipe = usb_rcvbulkpipe(dev, endpoint);
487
pipe = usb_sndbulkpipe(dev, endpoint);
490
default: /* USB_ENDPOINT_XFER_INT */
491
if (pipe_handle.encoded.endpointAddr & USB_ENDPOINT_DIR_MASK)
492
pipe = usb_rcvbulkpipe(dev, endpoint);
494
pipe = usb_sndbulkpipe(dev, endpoint);
498
return usb_clear_halt(dev, pipe);
501
unsigned long usb_select_configuration(struct usb_device *dev,
502
union nt_urb *nt_urb, struct irp *irp)
504
struct usb_interface *intf;
505
struct usbd_pipe_information *pipe_info;
507
struct usb_endpoint_descriptor *desc;
509
ASSERT(nt_urb->selConf.config->bNumInterfaces == 1);
510
USBTRACE("intf.intfNum = %d, intf.altSet = %d",
511
nt_urb->selConf.intf.intfNum, nt_urb->selConf.intf.altSet);
513
ret = usb_set_interface(dev, nt_urb->selConf.intf.intfNum,
514
nt_urb->selConf.intf.altSet);
781
WARNING("resetting pipe %d failed: %d", pipe_type, ret);
782
if (pipe2 != pipe1) {
783
ret = usb_clear_halt(udev, pipe2);
785
WARNING("resetting pipe %d failed: %d",
788
return USBD_STATUS_SUCCESS;
791
static USBD_STATUS wrap_abort_pipe(struct usb_device *udev, struct irp *irp)
793
union nt_urb *nt_urb;
794
usbd_pipe_handle pipe_handle;
797
struct wrap_urb *wrap_urb;
798
struct wrapper_dev *wd;
800
USBENTER("irp = %p", irp);
802
nt_urb = URB_FROM_IRP(irp);
803
pipe_handle = nt_urb->pipe_req.pipe_handle;
805
nt_urb = URB_FROM_IRP(irp);
807
kspin_lock_irqsave(&irp_cancel_lock, flags);
809
nt_list_for_each_entry(wrap_urb, &wd->dev.usb.wrap_urb_list,
811
if (wrap_urb->state == URB_SUBMITTED &&
812
(usb_pipeendpoint(wrap_urb->pipe) ==
813
pipe_handle->bEndpointAddress)) {
814
wrap_urb->state = URB_CANCELED;
819
kspin_unlock_irqrestore(&irp_cancel_lock, flags);
821
wrap_cancel_urb(urb);
822
USBTRACE("canceled urb: %p", urb);
826
USBEXIT(return USBD_STATUS_SUCCESS);
829
static USBD_STATUS wrap_select_configuration(struct wrapper_dev *wd,
830
union nt_urb *nt_urb,
833
struct usbd_pipe_information *pipe;
834
int i, n, ret, pipe_num;
835
struct usb_endpoint_descriptor *ep;
836
struct usbd_select_configuration *sel_conf;
837
struct usb_device *udev;
838
struct usbd_interface_information *intf;
839
struct usb_config_descriptor *config;
840
struct usb_interface *usb_intf;
842
udev = wd->dev.usb.udev;
843
sel_conf = &nt_urb->select_conf;
844
config = sel_conf->config;
845
if (config == NULL) {
846
/* TODO: set to unconfigured state (configuration 0):
847
* is this correctt? */
848
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
849
USB_REQ_SET_CONFIGURATION, 0,
850
0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
851
return wrap_urb_status(ret);
854
USBTRACE("conf: %d, type: %d, length: %d, numif: %d, attr: %08x",
855
config->bConfigurationValue, config->bDescriptorType,
856
config->wTotalLength, config->bNumInterfaces,
857
config->bmAttributes);
859
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
860
USB_REQ_SET_CONFIGURATION, 0,
861
config->bConfigurationValue, 0,
862
NULL, 0, USB_CTRL_SET_TIMEOUT);
516
ERROR("usb_set_interface() = %d", ret);
517
USBTRACEEXIT(return ret);
520
intf = usb_ifnum_to_if(dev, nt_urb->selConf.intf.intfNum);
522
ERROR("usb_ifnum_to_if() = %d", ret);
523
USBTRACEEXIT(return ret);
864
ERROR("ret: %d", ret);
865
return wrap_urb_status(ret);
869
intf = &sel_conf->intf;
870
for (n = 0; n < config->bNumInterfaces && intf->bLength > 0;
871
n++, intf = (((void *)intf) + intf->bLength)) {
873
USBTRACE("intf: %d, alt setting: %d",
874
intf->bInterfaceNumber, intf->bAlternateSetting);
875
ret = usb_set_interface(udev, intf->bInterfaceNumber,
876
intf->bAlternateSetting);
878
ERROR("failed with %d", ret);
879
return wrap_urb_status(ret);
881
usb_intf = usb_ifnum_to_if(udev, intf->bInterfaceNumber);
883
ERROR("couldn't obtain ifnum");
884
return USBD_STATUS_REQUEST_FAILED;
886
USBTRACE("intf: %p, num ep: %d", intf, intf->bNumEndpoints);
526
888
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
527
for (i = 0; i < CUR_ALT_SETTING(intf)->desc.bNumEndpoints; i++) {
528
desc = &(CUR_ALT_SETTING(intf)->endpoint + i)->desc;
889
for (i = 0; i < CUR_ALT_SETTING(usb_intf)->desc.bNumEndpoints;
891
ep = &(CUR_ALT_SETTING(usb_intf)->endpoint + i)->desc;
530
for (i = 0; i < CUR_ALT_SETTING(intf).bNumEndpoints; i++) {
531
desc = &((CUR_ALT_SETTING(intf)).endpoint[i]);
893
for (i = 0; i < CUR_ALT_SETTING(usb_intf).bNumEndpoints;
895
ep = &((CUR_ALT_SETTING(usb_intf)).endpoint[i]);
533
pipe_info = &nt_urb->selConf.intf.pipes[i];
535
pipe_info->maxPacketSize = desc->wMaxPacketSize;
536
pipe_info->endpointAddr = desc->bEndpointAddress;
537
pipe_info->interval = desc->bInterval;
538
pipe_info->pipeType = desc->bmAttributes;
540
pipe_info->pipeHandle.encoded.endpointAddr =
541
desc->bEndpointAddress;
542
pipe_info->pipeHandle.encoded.pipeType =
543
desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
544
pipe_info->pipeHandle.encoded.interval =
545
(dev->speed == USB_SPEED_HIGH) ?
546
desc->bInterval + 3 : desc->bInterval;
547
pipe_info->pipeHandle.encoded.fill = 0;
549
USBTRACE("%i: Addr %X, Type %d, PkSz %d, "
550
"Intv %d, Handle %p", i, desc->bEndpointAddress,
551
desc->bmAttributes, desc->wMaxPacketSize,
552
desc->bInterval, pipe_info->pipeHandle.handle);
554
USBTRACEEXIT(return 0);
557
unsigned long usb_submit_nt_urb(struct usb_device *dev, union nt_urb *nt_urb,
562
USBTRACEENTER("nt_urb = %p, irp = %p, length = %d, function = %x",
563
nt_urb, irp, nt_urb->header.length,
564
nt_urb->header.function);
566
nt_urb->header.status = USB_STATUS_SUCCESS;
897
if (i >= intf->bNumEndpoints) {
898
ERROR("intf %p has only %d endpoints, "
899
"ignoring endpoints above %d",
900
intf, intf->bNumEndpoints, i);
903
pipe = &intf->pipes[i];
905
if (pipe->flags & USBD_PF_CHANGE_MAX_PACKET)
906
WARNING("pkt_sz: %d: %d", pipe->wMaxPacketSize,
908
USBTRACE("driver wants max_tx_size to %d",
911
pipe->wMaxPacketSize = ep->wMaxPacketSize;
912
pipe->bEndpointAddress = ep->bEndpointAddress;
913
pipe->bInterval = ep->bInterval;
915
ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
918
USBTRACE("%d: addr %X, type %d, pkt_sz %d, intv %d,"
919
"handle %p", i, ep->bEndpointAddress,
920
ep->bmAttributes, ep->wMaxPacketSize,
921
ep->bInterval, pipe->handle);
924
return USBD_STATUS_SUCCESS;
927
static USBD_STATUS wrap_get_descriptor(struct wrapper_dev *wd,
928
union nt_urb *nt_urb, struct irp *irp)
930
struct usbd_control_descriptor_request *ctrl_req;
932
struct usb_device *udev;
934
udev = wd->dev.usb.udev;
935
ctrl_req = &nt_urb->control_request;
936
USBTRACE("desctype = %d, descindex = %d, transfer_buffer = %p,"
937
"transfer_buffer_length = %d", ctrl_req->desc_type,
938
ctrl_req->index, ctrl_req->transfer_buffer,
939
ctrl_req->transfer_buffer_length);
941
if (ctrl_req->desc_type == USB_DT_STRING) {
942
USBTRACE("langid: %d", ctrl_req->language_id);
943
ret = usb_get_string(udev, ctrl_req->language_id,
945
ctrl_req->transfer_buffer,
946
ctrl_req->transfer_buffer_length);
948
ret = usb_get_descriptor(udev, ctrl_req->desc_type,
950
ctrl_req->transfer_buffer,
951
ctrl_req->transfer_buffer_length);
954
WARNING("request %d failed with %d", ctrl_req->desc_type, ret);
955
ctrl_req->transfer_buffer_length = 0;
956
return USBD_STATUS_REQUEST_FAILED;
958
USBTRACE("ret: %08x", ret);
959
DUMP_BUFFER(ctrl_req->transfer_buffer, ret);
960
ctrl_req->transfer_buffer_length = ret;
961
irp->io_status.status_info = ret;
962
return USBD_STATUS_SUCCESS;
966
static USBD_STATUS wrap_process_nt_urb(struct irp *irp)
968
union nt_urb *nt_urb;
969
struct usb_device *udev;
971
struct wrapper_dev *wd;
974
udev = wd->dev.usb.udev;
975
nt_urb = URB_FROM_IRP(irp);
976
USBENTER("nt_urb = %p, irp = %p, length = %d, function = %x",
977
nt_urb, irp, nt_urb->header.length, nt_urb->header.function);
568
980
switch (nt_urb->header.function) {
981
/* bulk/int and vendor/class urbs are submitted
982
* asynchronously later by pdoDispatchDeviceControl */
983
case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
984
USBTRACE("submitting bulk/int irp: %p", irp);
985
status = wrap_bulk_or_intr_trans(irp);
988
case URB_FUNCTION_VENDOR_DEVICE:
989
case URB_FUNCTION_VENDOR_INTERFACE:
990
case URB_FUNCTION_VENDOR_ENDPOINT:
991
case URB_FUNCTION_VENDOR_OTHER:
992
case URB_FUNCTION_CLASS_DEVICE:
993
case URB_FUNCTION_CLASS_INTERFACE:
994
case URB_FUNCTION_CLASS_ENDPOINT:
995
case URB_FUNCTION_CLASS_OTHER:
996
USBTRACE("submitting vendor/class irp: %p", irp);
997
status = wrap_vendor_or_class_req(irp);
1000
/* rest are synchronous */
569
1001
case URB_FUNCTION_SELECT_CONFIGURATION:
570
usb_select_configuration(dev, nt_urb, irp);
571
USBTRACEEXIT(return STATUS_SUCCESS);
573
case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
574
ret = usb_bulk_or_intr_trans(dev, nt_urb, irp);
577
USBTRACEEXIT(return STATUS_PENDING);
1002
status = wrap_select_configuration(wd, nt_urb, irp);
1003
NT_URB_STATUS(nt_urb) = status;
579
1006
case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
580
ASSERT(!nt_urb->ctrlDescReq.transferBufMdl);
581
ASSERT(!nt_urb->ctrlDescReq.urbLink);
582
USBTRACE("desctype = %d, descindex = %d, "
583
"transferBuf = %p, transferBufLen = %ld",
584
nt_urb->ctrlDescReq.desctype,
585
nt_urb->ctrlDescReq.descindex,
586
nt_urb->ctrlDescReq.transferBuf,
587
nt_urb->ctrlDescReq.transferBufLen);
589
ret = usb_get_descriptor(dev, nt_urb->ctrlDescReq.desctype,
590
nt_urb->ctrlDescReq.descindex,
591
nt_urb->ctrlDescReq.transferBuf,
592
nt_urb->ctrlDescReq.transferBufLen);
594
ERROR("usb_get_descriptor() = %d", ret);
597
nt_urb->ctrlDescReq.transferBufLen = ret;
598
USBTRACEEXIT(return STATUS_SUCCESS);
600
case URB_FUNCTION_VENDOR_DEVICE:
601
case URB_FUNCTION_VENDOR_INTERFACE:
602
case URB_FUNCTION_CLASS_INTERFACE:
603
USBTRACE("func: %d", nt_urb->header.function);
604
ret = usb_vendor_or_class_intf(dev, nt_urb, irp);
607
USBTRACEEXIT(return STATUS_PENDING);
1007
status = wrap_get_descriptor(wd, nt_urb, irp);
1008
NT_URB_STATUS(nt_urb) = status;
609
1011
case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:
610
ret = usb_reset_pipe(dev, nt_urb->pipeReq.pipeHandle);
612
ERROR("usb_reset_pipe() = %d", ret);
615
USBTRACEEXIT(return STATUS_SUCCESS);
1012
status = wrap_reset_pipe(udev, irp);
1013
NT_URB_STATUS(nt_urb) = status;
1016
case URB_FUNCTION_ABORT_PIPE:
1017
status = wrap_abort_pipe(udev, irp);
1018
NT_URB_STATUS(nt_urb) = status;
618
ERROR("function %X NOT IMPLEMENTED!\n",
619
nt_urb->header.function);
1022
ERROR("function %x not implemented", nt_urb->header.function);
1023
status = NT_URB_STATUS(nt_urb) = USBD_STATUS_NOT_SUPPORTED;
621
nt_urb->header.status = USB_STATUS_ERROR;
622
USBTRACEEXIT(return STATUS_FAILURE);
1026
USBTRACE("status: %08X", status);
625
unsigned long usb_reset_port(struct usb_device *dev)
1030
static USBD_STATUS wrap_reset_port(struct irp *irp)
629
USBTRACEENTER("%s", "");
631
ret = usb_reset_device(dev);
633
ERROR("usb_reset_device() = %d", ret);
634
USBTRACEEXIT(return STATUS_FAILURE);
637
USBTRACEEXIT(return STATUS_SUCCESS);
640
STDCALL union nt_urb *WRAP_EXPORT(USBD_CreateConfigurationRequest)
641
(struct usb_config_descriptor *config, unsigned short *urb_size)
644
struct usb_interface_descriptor *intf_desc;
645
struct usbd_interface_information *intf_info;
646
char *pos = (char *)config;
647
int cfg_size = config->wTotalLength;
650
USBTRACEENTER("config = %p, urb_size = %p", config, urb_size);
651
ASSERT(config->bNumInterfaces < 2);
653
while ((char *)pos - (char *)config < cfg_size) {
654
intf_desc = (struct usb_interface_descriptor *)pos;
655
pos = pos + intf_desc->bLength;
657
if (intf_desc->bDescriptorType != USB_DT_INTERFACE)
660
USBTRACE("selected interface = %p", intf_desc);
665
USBTRACEEXIT(return NULL);
667
*urb_size = sizeof(union nt_urb) +
668
sizeof(struct usbd_pipe_information) *
669
(intf_desc->bNumEndpoints - 1);
670
/* FIXME: we should better check what GFP_ is required */
671
urb = kmalloc(*urb_size, GFP_ATOMIC);
674
urb->selConf.header.length = *urb_size;
675
urb->selConf.header.function =
676
URB_FUNCTION_SELECT_CONFIGURATION;
677
urb->selConf.config = config;
679
intf_info = &urb->selConf.intf;
680
intf_info->length = sizeof(struct usbd_interface_information)+
681
sizeof(struct usbd_pipe_information) *
682
(intf_desc->bNumEndpoints - 1);
683
intf_info->intfNum = intf_desc->bInterfaceNumber;
684
intf_info->altSet = intf_desc->bAlternateSetting;
685
intf_info->class = intf_desc->bInterfaceClass;
686
intf_info->subClass = intf_desc->bInterfaceSubClass;
687
intf_info->proto = intf_desc->bInterfaceProtocol;
688
intf_info->pipeNum = intf_desc->bNumEndpoints;
691
USBTRACEEXIT(return urb);
694
STDCALL union nt_urb * WRAP_EXPORT(USBD_CreateConfigurationRequestEx)
1033
struct wrapper_dev *wd;
1036
USBENTER("%p, %p", wd, wd->dev.usb.udev);
1038
ret = usb_reset_device(wd->dev.usb.udev);
1040
WARNING("reset failed: %d", ret);
1041
return USBD_STATUS_SUCCESS;
1044
static USBD_STATUS wrap_get_port_status(struct irp *irp)
1046
struct wrapper_dev *wd;
1050
USBENTER("%p, %p", wd, wd->dev.usb.udev);
1051
status = IoGetCurrentIrpStackLocation(irp)->params.others.arg1;
1052
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
1054
enum usb_device_state state;
1055
state = wd->dev.usb.udev->state;
1056
if (state != USB_STATE_NOTATTACHED &&
1057
state != USB_STATE_SUSPENDED) {
1058
*status |= USBD_PORT_CONNECTED;
1059
if (state == USB_STATE_CONFIGURED)
1060
*status |= USBD_PORT_ENABLED;
1065
/* TODO: how to get current status? */
1066
*status = USBD_PORT_CONNECTED | USBD_PORT_ENABLED;
1069
return USBD_STATUS_SUCCESS;
1072
NTSTATUS wrap_submit_irp(struct device_object *pdo, struct irp *irp)
1074
struct io_stack_location *irp_sl;
1075
struct wrapper_dev *wd;
1078
irp_sl = IoGetCurrentIrpStackLocation(irp);
1081
if (unlikely(wd->dev.usb.intf == NULL)) {
1082
irp->io_status.status = STATUS_DEVICE_REMOVED;
1083
irp->io_status.status_info = 0;
1084
return irp->io_status.status;
1088
switch (irp_sl->params.ioctl.code) {
1089
case IOCTL_INTERNAL_USB_SUBMIT_URB:
1090
status = wrap_process_nt_urb(irp);
1092
case IOCTL_INTERNAL_USB_RESET_PORT:
1093
status = wrap_reset_port(irp);
1095
case IOCTL_INTERNAL_USB_GET_PORT_STATUS:
1096
status = wrap_get_port_status(irp);
1099
ERROR("ioctl %08X NOT IMPLEMENTED", irp_sl->params.ioctl.code);
1100
status = USBD_STATUS_NOT_SUPPORTED;
1104
USBTRACE("status: %08X", status);
1105
if (status == USBD_STATUS_PENDING)
1106
return STATUS_PENDING;
1107
irp->io_status.status = nt_urb_irp_status(status);
1108
if (status != USBD_STATUS_SUCCESS)
1109
irp->io_status.status_info = 0;
1110
USBEXIT(return irp->io_status.status);
1113
/* TODO: The example on msdn in reference section suggests that second
1114
* argument should be an array of usbd_interface_information, but
1115
* description and examples elsewhere suggest that it should be
1116
* usbd_interface_list_entry structre. Which is correct? */
1118
STDCALL union nt_urb *WRAP_EXPORT(USBD_CreateConfigurationRequestEx)
695
1119
(struct usb_config_descriptor *config,
696
struct usbd_interface_list_entry *intfList)
1120
struct usbd_interface_list_entry *intf_list)
1123
struct usbd_interface_information *intf;
1124
struct usbd_pipe_information *pipe;
700
1125
struct usb_interface_descriptor *intf_desc;
701
struct usbd_interface_information *intf_info;
704
* Note: This function is more or less a hack - due to a lack
705
* of understanding of the underlying USB details. It only
706
* sets up an URB with one interface inside. This is what the
707
* WUSB54G driver requests or what the WUSB54G device
708
* provides. However, this function warns if the assumption is
712
USBTRACEENTER("config = %p, intfList = %p", config, intfList);
713
ASSERT(config->bNumInterfaces < 2);
715
intf_desc = intfList->intfDesc;
716
urb_size = sizeof(union nt_urb) +
717
sizeof(struct usbd_pipe_information) *
718
(intf_desc->bNumEndpoints - 1);
719
/* FIXME: we should better check what GFP_ is required */
720
urb = kmalloc(urb_size, GFP_ATOMIC);
723
urb->selConf.header.length = urb_size;
724
urb->selConf.header.function =
725
URB_FUNCTION_SELECT_CONFIGURATION;
726
urb->selConf.config = config;
728
intf_info = &urb->selConf.intf;
729
intfList->intf = intf_info;
730
intf_info->length = sizeof(struct usbd_interface_information)+
731
sizeof(struct usbd_pipe_information) *
732
(intf_desc->bNumEndpoints - 1);
733
intf_info->intfNum = intf_desc->bInterfaceNumber;
734
intf_info->altSet = intf_desc->bAlternateSetting;
735
intf_info->class = intf_desc->bInterfaceClass;
736
intf_info->subClass = intf_desc->bInterfaceSubClass;
737
intf_info->proto = intf_desc->bInterfaceProtocol;
738
intf_info->pipeNum = intf_desc->bNumEndpoints;
740
ASSERT(!(intfList+1)->intfDesc);
743
USBTRACEEXIT(return urb);
1126
struct usbd_select_configuration *select_conf;
1128
USBENTER("config = %p, intf_list = %p", config, intf_list);
1130
/* calculate size required; select_conf already has space for
1131
* one intf structure */
1132
size = sizeof(*select_conf) - sizeof(*intf);
1133
for (n = 0; n < config->bNumInterfaces; n++) {
1134
i = intf_list[n].intf_desc->bNumEndpoints;
1135
/* intf already has space for one pipe */
1136
size += sizeof(*intf) + (i - 1) * sizeof(*pipe);
1138
/* don't use kmalloc - driver frees it with ExFreePool */
1139
select_conf = ExAllocatePoolWithTag(NonPagedPool, size,
1140
POOL_TAG('L', 'U', 'S', 'B'));
1142
WARNING("couldn't allocate memory");
1145
memset(select_conf, 0, size);
1146
intf = &select_conf->intf;
1147
/* handle points to beginning of interface information */
1148
select_conf->handle = intf;
1149
for (n = 0; n < config->bNumInterfaces && intf_list[n].intf_desc;
1151
/* initialize 'intf' fields in intf_list so they point
1152
* to appropriate entry; these may be read/written by
1153
* driver after this function returns */
1154
intf_list[n].intf = intf;
1155
intf_desc = intf_list[n].intf_desc;
1157
i = intf_desc->bNumEndpoints;
1158
intf->bLength = sizeof(*intf) + (i - 1) * sizeof(*pipe);
1160
intf->bInterfaceNumber = intf_desc->bInterfaceNumber;
1161
intf->bAlternateSetting = intf_desc->bAlternateSetting;
1162
intf->bInterfaceClass = intf_desc->bInterfaceClass;
1163
intf->bInterfaceSubClass = intf_desc->bInterfaceSubClass;
1164
intf->bInterfaceProtocol = intf_desc->bInterfaceProtocol;
1165
intf->bNumEndpoints = intf_desc->bNumEndpoints;
1167
pipe = &intf->pipes[0];
1168
for (i = 0; i < intf->bNumEndpoints; i++) {
1169
memset(&pipe[i], 0, sizeof(*pipe));
1170
pipe[i].max_tx_size =
1171
USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;
1173
intf = (((void *)intf) + intf->bLength);
1175
select_conf->header.function = URB_FUNCTION_SELECT_CONFIGURATION;
1176
select_conf->header.length = size;
1177
select_conf->config = config;
1178
USBEXIT(return (union nt_urb *)select_conf);
745
1181
WRAP_EXPORT_MAP("_USBD_CreateConfigurationRequestEx@8", USBD_CreateConfigurationRequestEx);
747
1183
STDCALL struct usb_interface_descriptor *
748
WRAP_EXPORT(USBD_ParseConfigurationDescriptorEx)
749
(struct usb_config_descriptor *config,
750
void *startPos, LONG intfNum, LONG altSet,
751
LONG intfClass, LONG intfSubClass, LONG intfProto)
1184
WRAP_EXPORT(USBD_ParseConfigurationDescriptorEx)
1185
(struct usb_config_descriptor *config, void *start,
1186
LONG bInterfaceNumber, LONG bAlternateSetting, LONG bInterfaceClass,
1187
LONG bInterfaceSubClass, LONG bInterfaceProtocol)
753
int size = config->wTotalLength;
754
char *pos = startPos;
755
1190
struct usb_interface_descriptor *intf;
757
USBTRACEENTER("config = %p, startPos = %p, intfNum = %d, altSet = %d,"
758
" intfClass = %d, intfSubClass = %d, intfProto = %d",
759
config, startPos, intfNum, altSet, intfClass, intfSubClass,
762
while ((char *)pos - (char *)config < size) {
763
intf = (struct usb_interface_descriptor *)pos;
764
pos = pos + intf->bLength;
766
if (intf->bDescriptorType != USB_DT_INTERFACE)
768
if ((intfNum != -1) && (intf->bInterfaceNumber != intfNum))
770
if ((altSet != -1) && (intf->bAlternateSetting != altSet))
772
if ((intfClass != -1) && (intf->bInterfaceClass != intfClass))
774
if ((intfSubClass != -1) &&
775
(intf->bInterfaceSubClass != intfSubClass))
777
if ((intfProto != -1) &&
778
(intf->bInterfaceProtocol != intfProto))
781
USBTRACE("selected interface = %p", intf);
782
USBTRACEEXIT(return intf);
1192
USBENTER("config = %p, start = %p, ifnum = %d, alt_setting = %d,"
1193
" class = %d, subclass = %d, proto = %d", config, start,
1194
bInterfaceNumber, bAlternateSetting,
1195
bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol);
1197
for (pos = start; pos < ((void *)config + config->wTotalLength);
1198
pos += intf->bLength) {
1202
if ((intf->bDescriptorType == USB_DT_INTERFACE) &&
1203
((bInterfaceNumber == -1) ||
1204
(intf->bInterfaceNumber == bInterfaceNumber)) &&
1205
((bAlternateSetting == -1) ||
1206
(intf->bAlternateSetting == bAlternateSetting)) &&
1207
((bInterfaceClass == -1) ||
1208
(intf->bInterfaceClass == bInterfaceClass)) &&
1209
((bInterfaceSubClass == -1) ||
1210
(intf->bInterfaceSubClass == bInterfaceSubClass)) &&
1211
((bInterfaceProtocol == -1) ||
1212
(intf->bInterfaceProtocol == bInterfaceProtocol))) {
1213
USBTRACE("selected interface = %p", intf);
1214
USBEXIT(return intf);
785
USBTRACEEXIT(return NULL);
1217
USBEXIT(return NULL);
787
1220
WRAP_EXPORT_MAP("_USBD_ParseConfigurationDescriptorEx@28", USBD_ParseConfigurationDescriptorEx);
1222
STDCALL union nt_urb *WRAP_EXPORT(USBD_CreateConfigurationRequest)
1223
(struct usb_config_descriptor *config, USHORT *size)
1225
union nt_urb *nt_urb;
1226
struct usbd_interface_list_entry intf_list[2];
1227
struct usb_interface_descriptor *intf_desc;
1229
USBENTER("config = %p, urb_size = %p", config, size);
1231
intf_desc = USBD_ParseConfigurationDescriptorEx(config, config, -1, -1,
1233
intf_list[0].intf_desc = intf_desc;
1234
intf_list[0].intf = NULL;
1235
intf_list[1].intf_desc = NULL;
1236
intf_list[1].intf = NULL;
1237
nt_urb = USBD_CreateConfigurationRequestEx(config, intf_list);
1241
*size = nt_urb->select_conf.header.length;
1242
USBEXIT(return nt_urb);
789
1245
STDCALL struct usb_interface_descriptor *
790
WRAP_EXPORT(USBD_ParseConfigurationDescriptor)
791
(struct usb_config_descriptor *config,
792
unsigned char intfNum, unsigned char altSet)
1246
WRAP_EXPORT(USBD_ParseConfigurationDescriptor)
1247
(struct usb_config_descriptor *config, UCHAR bInterfaceNumber,
1248
UCHAR bAlternateSetting)
794
1250
return USBD_ParseConfigurationDescriptorEx(config, config,