~ubuntu-branches/ubuntu/vivid/ndiswrapper/vivid

« back to all changes in this revision

Viewing changes to driver/usb.c

  • Committer: Package Import Robot
  • Author(s): Julian Andres Klode
  • Date: 2012-03-05 16:49:02 UTC
  • mfrom: (1.2.8)
  • Revision ID: package-import@ubuntu.com-20120305164902-rrir76um4yq4eimb
Tags: 1.57-1
* Imported Upstream version 1.57
  - Fixes build with kernel 3.2 (Closes: #655223, LP: #910597)
* Enable hardening build flags (Closes: #655249)
* patches/ndiswrapper-harden.patch: Use $(shell X) instead of `X`
* Update to Policy 3.9.3, copyright-format 1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
182
182
 
183
183
static void wrap_free_urb(struct urb *urb)
184
184
{
185
 
        struct irp *irp;
186
 
        struct wrap_urb *wrap_urb;
 
185
        struct wrap_urb *wrap_urb = urb->context;
 
186
        struct irp *irp = wrap_urb->irp;
 
187
        struct wrap_device *wd = IRP_WRAP_DEVICE(irp);
187
188
 
188
189
        USBTRACE("freeing urb: %p", urb);
189
 
        wrap_urb = urb->context;
190
 
        irp = wrap_urb->irp;
 
190
        irp->cancel_routine = NULL;
 
191
        IRP_WRAP_URB(irp) = NULL;
191
192
        if (wrap_urb->flags & WRAP_URB_COPY_BUFFER) {
192
193
                USBTRACE("freeing DMA buffer for URB: %p %p",
193
194
                         urb, urb->transfer_buffer);
194
 
                usb_free_coherent(IRP_WRAP_DEVICE(irp)->usb.udev,
195
 
                                urb->transfer_buffer_length,
196
 
                                urb->transfer_buffer, urb->transfer_dma);
 
195
                usb_free_coherent(wd->usb.udev, urb->transfer_buffer_length,
 
196
                                  urb->transfer_buffer, urb->transfer_dma);
197
197
        }
198
198
        kfree(urb->setup_packet);
199
 
        if (IRP_WRAP_DEVICE(irp)->usb.num_alloc_urbs > MAX_ALLOCATED_URBS) {
 
199
        if (wd->usb.num_alloc_urbs > MAX_ALLOCATED_URBS) {
200
200
                IoAcquireCancelSpinLock(&irp->cancel_irql);
201
201
                RemoveEntryList(&wrap_urb->list);
202
 
                IRP_WRAP_DEVICE(irp)->usb.num_alloc_urbs--;
 
202
                wd->usb.num_alloc_urbs--;
203
203
                IoReleaseCancelSpinLock(irp->cancel_irql);
204
204
                usb_free_urb(urb);
205
205
                kfree(wrap_urb);
226
226
wstdcall void wrap_cancel_irp(struct device_object *dev_obj, struct irp *irp)
227
227
{
228
228
        struct urb *urb;
 
229
        struct wrap_urb *wrap_urb = IRP_WRAP_URB(irp);
229
230
 
230
231
        /* NB: this function is called holding Cancel spinlock */
231
232
        USBENTER("irp: %p", irp);
232
 
        urb = IRP_WRAP_URB(irp)->urb;
 
233
        urb = wrap_urb->urb;
233
234
        USBTRACE("canceling urb %p", urb);
234
235
        if (wrap_cancel_urb(IRP_WRAP_URB(irp))) {
235
236
                irp->cancel = FALSE;
236
 
                ERROR("urb %p can't be canceled: %d", urb,
237
 
                      IRP_WRAP_URB(irp)->state);
 
237
                ERROR("urb %p can't be canceled: %d", urb, wrap_urb->state);
238
238
        } else
239
239
                USBTRACE("urb %p canceled", urb);
240
240
        IoReleaseCancelSpinLock(irp->cancel_irql);
252
252
 
253
253
        USBENTER("irp: %p", irp);
254
254
        wd = IRP_WRAP_DEVICE(irp);
 
255
 
 
256
        /* Don't interfere with URB cleanup by the kernel */
 
257
        if (test_bit(HW_DISABLED, &wd->hw_status))
 
258
                return NULL;
 
259
 
255
260
        alloc_flags = irql_gfp();
256
261
        IoAcquireCancelSpinLock(&irp->cancel_irql);
257
262
        urb = NULL;
259
264
                if (cmpxchg(&wrap_urb->state, URB_FREE,
260
265
                            URB_ALLOCATED) == URB_FREE) {
261
266
                        urb = wrap_urb->urb;
262
 
                        usb_init_urb(urb);
 
267
                        /* Clean URB but keep the refcount */
 
268
                        memset((char *)urb + sizeof(urb->kref), 0,
 
269
                               sizeof(*urb) - sizeof(urb->kref));
263
270
                        break;
264
271
                }
265
272
        }
308
315
                if (!urb->transfer_buffer) {
309
316
                        WARNING("couldn't allocate dma buf");
310
317
                        IoAcquireCancelSpinLock(&irp->cancel_irql);
 
318
                        irp->cancel_routine = NULL;
311
319
                        wrap_urb->state = URB_FREE;
312
320
                        wrap_urb->irp = NULL;
313
321
                        IRP_WRAP_URB(irp) = NULL;
328
336
static USBD_STATUS wrap_submit_urb(struct irp *irp)
329
337
{
330
338
        int ret;
331
 
        struct urb *urb;
332
 
        union nt_urb *nt_urb;
 
339
        struct wrap_urb *wrap_urb = IRP_WRAP_URB(irp);
 
340
        struct urb *urb = wrap_urb->urb;
 
341
        union nt_urb *nt_urb = IRP_URB(irp);
333
342
 
334
 
        urb = IRP_WRAP_URB(irp)->urb;
335
 
        nt_urb = IRP_URB(irp);
336
343
#ifdef USB_DEBUG
337
 
        if (IRP_WRAP_URB(irp)->state != URB_ALLOCATED) {
 
344
        if (wrap_urb->state != URB_ALLOCATED) {
338
345
                ERROR("urb %p is in wrong state: %d",
339
 
                      urb, IRP_WRAP_URB(irp)->state);
 
346
                      urb, wrap_urb->state);
340
347
                NT_URB_STATUS(nt_urb) = USBD_STATUS_REQUEST_FAILED;
341
348
                return NT_URB_STATUS(nt_urb);
342
349
        }
343
 
        IRP_WRAP_URB(irp)->id = pre_atomic_add(urb_id, 1);
 
350
        wrap_urb->id = pre_atomic_add(urb_id, 1);
344
351
#endif
345
352
        DUMP_WRAP_URB(IRP_WRAP_URB(irp), USB_DIR_OUT);
346
353
        irp->io_status.status = STATUS_PENDING;
349
356
        IoMarkIrpPending(irp);
350
357
        DUMP_URB_BUFFER(urb, USB_DIR_OUT);
351
358
        USBTRACE("%p", urb);
352
 
        IRP_WRAP_URB(irp)->state = URB_SUBMITTED;
 
359
        wrap_urb->state = URB_SUBMITTED;
353
360
        ret = usb_submit_urb(urb, irql_gfp());
354
361
        if (ret) {
355
362
                USBTRACE("ret: %d", ret);
383
390
        spin_lock(&wrap_urb_complete_list_lock);
384
391
        InsertTailList(&wrap_urb_complete_list, &wrap_urb->complete_list);
385
392
        spin_unlock(&wrap_urb_complete_list_lock);
386
 
        schedule_ntos_work(&wrap_urb_complete_work);
 
393
        queue_work(ntos_wq, &wrap_urb_complete_work);
387
394
}
388
395
 
389
396
/* one worker for all devices */
472
479
 
473
480
static USBD_STATUS wrap_bulk_or_intr_trans(struct irp *irp)
474
481
{
475
 
        usbd_pipe_handle pipe_handle;
 
482
        struct usb_endpoint_descriptor *pipe_handle;
476
483
        struct urb *urb;
477
484
        unsigned int pipe;
478
485
        struct usbd_bulk_or_intr_transfer *bulk_int_tx;
479
486
        USBD_STATUS status;
480
 
        struct usb_device *udev;
481
 
        union nt_urb *nt_urb;
 
487
        struct wrap_device *wd = IRP_WRAP_DEVICE(irp);
 
488
        struct usb_device *udev = wd->usb.udev;
 
489
        union nt_urb *nt_urb = IRP_URB(irp);
482
490
 
483
 
        nt_urb = IRP_URB(irp);
484
 
        udev = IRP_WRAP_DEVICE(irp)->usb.udev;
485
491
        bulk_int_tx = &nt_urb->bulk_int_transfer;
486
492
        pipe_handle = bulk_int_tx->pipe_handle;
487
493
        USBTRACE("flags: 0x%x, length: %u, buffer: %p, handle: %p",
542
548
        u8 req_type;
543
549
        unsigned int pipe;
544
550
        struct usbd_vendor_or_class_request *vc_req;
545
 
        struct usb_device *udev;
546
 
        union nt_urb *nt_urb;
547
551
        USBD_STATUS status;
548
552
        struct urb *urb;
549
553
        struct usb_ctrlrequest *dr;
 
554
        struct wrap_device *wd = IRP_WRAP_DEVICE(irp);
 
555
        struct usb_device *udev = wd->usb.udev;
 
556
        union nt_urb *nt_urb = IRP_URB(irp);
550
557
 
551
 
        nt_urb = IRP_URB(irp);
552
 
        udev = IRP_WRAP_DEVICE(irp)->usb.udev;
553
558
        vc_req = &nt_urb->vendor_class_request;
554
559
        USBTRACE("bits: %x, req: %x, val: %08x, index: %08x, flags: %x,"
555
560
                 "buf: %p, len: %d", vc_req->reserved_bits, vc_req->request,
613
618
                urb->transfer_flags |= URB_SHORT_NOT_OK;
614
619
        }
615
620
 
616
 
        dr = kzalloc(sizeof(*dr), GFP_ATOMIC);
 
621
        dr = kzalloc(sizeof(*dr), irql_gfp());
617
622
        if (!dr) {
618
623
                ERROR("couldn't allocate memory");
619
624
                wrap_free_urb(urb);
637
642
{
638
643
        int ret;
639
644
        union nt_urb *nt_urb;
640
 
        usbd_pipe_handle pipe_handle;
 
645
        struct usb_endpoint_descriptor *pipe_handle;
641
646
        unsigned int pipe1, pipe2;
642
647
 
643
648
        nt_urb = IRP_URB(irp);
669
674
static USBD_STATUS wrap_abort_pipe(struct usb_device *udev, struct irp *irp)
670
675
{
671
676
        union nt_urb *nt_urb;
672
 
        usbd_pipe_handle pipe_handle;
 
677
        struct usb_endpoint_descriptor *pipe_handle;
673
678
        struct wrap_urb *wrap_urb;
674
679
        struct wrap_device *wd;
675
680
        KIRQL irql;
716
721
                break;
717
722
        case URB_FUNCTION_SET_FEATURE_TO_INTERFACE:
718
723
                request = USB_REQ_SET_FEATURE;
719
 
                type =  USB_DT_INTERFACE;
 
724
                type = USB_DT_INTERFACE;
720
725
                break;
721
726
        case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT:
722
727
                request = USB_REQ_SET_FEATURE;
723
 
                type =  USB_DT_ENDPOINT;
 
728
                type = USB_DT_ENDPOINT;
724
729
                break;
725
730
        case URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE:
726
731
                request = USB_REQ_CLEAR_FEATURE;
727
 
                type =  USB_DT_DEVICE;
 
732
                type = USB_DT_DEVICE;
728
733
                break;
729
734
        case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE:
730
735
                request = USB_REQ_CLEAR_FEATURE;
731
 
                type =  USB_DT_INTERFACE;
 
736
                type = USB_DT_INTERFACE;
732
737
                break;
733
738
        case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT:
734
739
                request = USB_REQ_CLEAR_FEATURE;
735
 
                type =  USB_DT_ENDPOINT;
 
740
                type = USB_DT_ENDPOINT;
736
741
                break;
737
742
        default:
738
743
                WARNING("invalid function: %x", nt_urb->header.function);
998
1003
 
999
1004
static USBD_STATUS wrap_process_nt_urb(struct irp *irp)
1000
1005
{
1001
 
        union nt_urb *nt_urb;
1002
 
        struct usb_device *udev;
1003
1006
        USBD_STATUS status;
1004
 
        struct wrap_device *wd;
 
1007
        struct wrap_device *wd = IRP_WRAP_DEVICE(irp);
 
1008
        struct usb_device *udev = wd->usb.udev;
 
1009
        union nt_urb *nt_urb = IRP_URB(irp);
1005
1010
 
1006
 
        wd = IRP_WRAP_DEVICE(irp);
1007
 
        udev = wd->usb.udev;
1008
 
        nt_urb = IRP_URB(irp);
1009
1011
        USBENTER("nt_urb = %p, irp = %p, length = %d, function = %x",
1010
1012
                 nt_urb, irp, nt_urb->header.length, nt_urb->header.function);
1011
1013
 
 
1014
        if (test_bit(HW_DISABLED, &wd->hw_status)) {
 
1015
                status = USBD_STATUS_DEVICE_GONE;
 
1016
                NT_URB_STATUS(nt_urb) = status;
 
1017
                return status;
 
1018
        }
 
1019
 
1012
1020
        DUMP_IRP(irp);
1013
1021
        switch (nt_urb->header.function) {
1014
1022
                /* bulk/int and vendor/class urbs are submitted to
1319
1327
                                                   -1, -1, -1);
1320
1328
}
1321
1329
 
1322
 
wstdcall usb_common_descriptor_t *WIN_FUNC(USBD_ParseDescriptors,4)
1323
 
        (void *buf, ULONG length, void *start, LONG type)
 
1330
wstdcall struct usb_descriptor_header *WIN_FUNC(USBD_ParseDescriptors,4)
 
1331
        (void *buf, ULONG length, struct usb_descriptor_header *descr,
 
1332
         LONG type)
1324
1333
{
1325
 
        usb_common_descriptor_t *descr = start;
1326
 
 
1327
1334
        while ((void *)descr < buf + length) {
1328
1335
                if (descr->bDescriptorType == type)
1329
1336
                        return descr;
1427
1434
        USBEXIT(return STATUS_SUCCESS);
1428
1435
}
1429
1436
 
 
1437
NTSTATUS
 
1438
usb_query_interface(struct wrap_device *wd, struct io_stack_location *irp_sl)
 
1439
{
 
1440
        struct usbd_bus_interface_usbdi *intf =
 
1441
                (struct usbd_bus_interface_usbdi *)
 
1442
                irp_sl->params.query_intf.intf;
 
1443
 
 
1444
        TRACE2("type: %x, size: %d, version: %d",
 
1445
               irp_sl->params.query_intf.type->data1,
 
1446
               irp_sl->params.query_intf.size,
 
1447
               irp_sl->params.query_intf.version);
 
1448
        intf->Context = wd;
 
1449
        intf->InterfaceReference =
 
1450
                WIN_FUNC_PTR(USBD_InterfaceReference, 1);
 
1451
        intf->InterfaceDereference =
 
1452
                WIN_FUNC_PTR(USBD_InterfaceDereference, 1);
 
1453
        intf->GetUSBDIVersion =
 
1454
                WIN_FUNC_PTR(USBD_InterfaceGetUSBDIVersion, 3);
 
1455
        intf->QueryBusTime =
 
1456
                WIN_FUNC_PTR(USBD_InterfaceQueryBusTime, 2);
 
1457
        intf->SubmitIsoOutUrb =
 
1458
                WIN_FUNC_PTR(USBD_InterfaceSubmitIsoOutUrb, 2);
 
1459
        intf->QueryBusInformation =
 
1460
                WIN_FUNC_PTR(USBD_InterfaceQueryBusInformation, 5);
 
1461
        if (irp_sl->params.query_intf.version >= USB_BUSIF_USBDI_VERSION_1)
 
1462
                intf->IsDeviceHighSpeed =
 
1463
                        WIN_FUNC_PTR(USBD_InterfaceIsDeviceHighSpeed, 1);
 
1464
        if (irp_sl->params.query_intf.version >= USB_BUSIF_USBDI_VERSION_2)
 
1465
                intf->LogEntry = WIN_FUNC_PTR(USBD_InterfaceLogEntry, 5);
 
1466
        return STATUS_SUCCESS;
 
1467
}
 
1468
 
1430
1469
int usb_init(void)
1431
1470
{
1432
1471
        InitializeListHead(&wrap_urb_complete_list);
1433
1472
        spin_lock_init(&wrap_urb_complete_list_lock);
1434
 
        initialize_work(&wrap_urb_complete_work, wrap_urb_complete_worker);
 
1473
        INIT_WORK(&wrap_urb_complete_work, wrap_urb_complete_worker);
1435
1474
#ifdef USB_DEBUG
1436
1475
        urb_id = 0;
1437
1476
#endif