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

« back to all changes in this revision

Viewing changes to driver/ndis.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:
25
25
#define MAX_ALLOCATED_NDIS_PACKETS TX_RING_SIZE
26
26
#define MAX_ALLOCATED_NDIS_BUFFERS TX_RING_SIZE
27
27
 
28
 
static void ndis_worker(struct work_struct *dummy);
29
28
static struct work_struct ndis_work;
30
29
static struct nt_list ndis_work_list;
31
30
static spinlock_t ndis_work_list_lock;
100
99
                        "pnp_event_notify", "shutdown",
101
100
                };
102
101
                func = (void **)&ndis_driver->mp.queryinfo;
103
 
                for (i = 0; i < (sizeof(mp_funcs) / sizeof(mp_funcs[0])); i++)
 
102
                for (i = 0; i < ARRAY_SIZE(mp_funcs); i++)
104
103
                        TRACE0("function '%s' is at %p", mp_funcs[i], func[i]);
105
104
        }
106
105
        EXIT1(return NDIS_STATUS_SUCCESS);
358
357
                ERROR("couldn't allocate memory");
359
358
                return NULL;
360
359
        }
361
 
        switch(type) {
 
360
        switch (type) {
362
361
        case NdisParameterInteger:
363
362
                param->data.integer = simple_strtol(setting->value, NULL, 0);
364
 
                TRACE2("0x%x", (ULONG)param->data.integer);
 
363
                TRACE2("0x%x", param->data.integer);
365
364
                break;
366
365
        case NdisParameterHexInteger:
367
366
                param->data.integer = simple_strtol(setting->value, NULL, 16);
368
 
                TRACE2("0x%x", (ULONG)param->data.integer);
 
367
                TRACE2("0x%x", param->data.integer);
369
368
                break;
370
369
        case NdisParameterString:
371
370
                RtlInitAnsiString(&ansi, setting->value);
378
377
                break;
379
378
        case NdisParameterBinary:
380
379
                param->data.integer = simple_strtol(setting->value, NULL, 2);
381
 
                TRACE2("0x%x", (ULONG)param->data.integer);
 
380
                TRACE2("0x%x", param->data.integer);
382
381
                break;
383
382
        default:
384
383
                ERROR("unknown type: %d", type);
402
401
                RtlFreeUnicodeString(&prev->data.string);
403
402
                setting->encoded = NULL;
404
403
        }
405
 
        switch(param->type) {
 
404
        switch (param->type) {
406
405
        case NdisParameterInteger:
407
 
                snprintf(setting->value, sizeof(u32), "%u",
 
406
                snprintf(setting->value, MAX_SETTING_VALUE_LEN, "%u",
408
407
                         param->data.integer);
409
 
                setting->value[sizeof(ULONG)] = 0;
410
408
                break;
411
409
        case NdisParameterHexInteger:
412
 
                snprintf(setting->value, sizeof(u32), "%x",
 
410
                snprintf(setting->value, MAX_SETTING_VALUE_LEN, "%x",
413
411
                         param->data.integer);
414
 
                setting->value[sizeof(ULONG)] = 0;
415
412
                break;
416
413
        case NdisParameterString:
417
414
                ansi.buf = setting->value;
425
422
                        ansi.length--;
426
423
                setting->value[ansi.length] = 0;
427
424
                break;
428
 
        case NdisParameterBinary:
429
 
                snprintf(setting->value, sizeof(u32), "%u",
430
 
                         param->data.integer);
431
 
                setting->value[sizeof(ULONG)] = 0;
432
 
                break;
433
425
        default:
434
426
                TRACE2("unknown setting type: %d", param->type);
435
427
                return -1;
444
436
                        enum ndis_parameter_type type)
445
437
{
446
438
        struct wrap_device_setting *setting;
447
 
        if (down_interruptible(&loader_mutex))
448
 
                WARNING("couldn't obtain loader_mutex");
 
439
        mutex_lock(&loader_mutex);
449
440
        nt_list_for_each_entry(setting, setting_list, list) {
450
441
                if (strnicmp(keyname, setting->name, length) == 0) {
451
442
                        TRACE2("setting %s='%s'", keyname, setting->value);
452
 
                        up(&loader_mutex);
 
443
                        mutex_unlock(&loader_mutex);
453
444
                        *param = ndis_encode_setting(setting, type);
454
445
                        if (*param)
455
446
                                EXIT2(return 0);
457
448
                                EXIT2(return -1);
458
449
                }
459
450
        }
460
 
        up(&loader_mutex);
 
451
        mutex_unlock(&loader_mutex);
461
452
        EXIT2(return -1);
462
453
}
463
454
 
509
500
        keyname = ansi.buf;
510
501
        TRACE2("%s", keyname);
511
502
 
512
 
        if (down_interruptible(&loader_mutex))
513
 
                WARNING("couldn't obtain loader_mutex");
 
503
        mutex_lock(&loader_mutex);
514
504
        nt_list_for_each_entry(setting, &nmb->wnd->wd->settings, list) {
515
505
                if (strnicmp(keyname, setting->name, ansi.length) == 0) {
516
 
                        up(&loader_mutex);
 
506
                        mutex_unlock(&loader_mutex);
517
507
                        if (ndis_decode_setting(setting, param))
518
508
                                *status = NDIS_STATUS_FAILURE;
519
509
                        else
522
512
                        EXIT2(return);
523
513
                }
524
514
        }
525
 
        up(&loader_mutex);
 
515
        mutex_unlock(&loader_mutex);
526
516
        setting = kzalloc(sizeof(*setting), GFP_KERNEL);
527
517
        if (setting) {
528
518
                if (ansi.length == ansi.max_length)
533
523
                        *status = NDIS_STATUS_FAILURE;
534
524
                else {
535
525
                        *status = NDIS_STATUS_SUCCESS;
536
 
                        if (down_interruptible(&loader_mutex))
537
 
                                WARNING("couldn't obtain loader_mutex");
 
526
                        mutex_lock(&loader_mutex);
538
527
                        InsertTailList(&nmb->wnd->wd->settings, &setting->list);
539
 
                        up(&loader_mutex);
 
528
                        mutex_unlock(&loader_mutex);
540
529
                }
541
530
        } else
542
531
                *status = NDIS_STATUS_RESOURCES;
686
675
{
687
676
        struct wrap_device *wd = nmb->wnd->wd;
688
677
        ULONG i;
 
678
        if (!wrap_is_pci_bus(wd->dev_bus)) {
 
679
                ERROR("used on a non-PCI device");
 
680
                return 0;
 
681
        }
689
682
        for (i = 0; i < len; i++)
690
683
                if (pci_read_config_byte(wd->pci.pdev, offset + i, &buf[i]) !=
691
684
                    PCIBIOS_SUCCESSFUL)
710
703
{
711
704
        struct wrap_device *wd = nmb->wnd->wd;
712
705
        ULONG i;
 
706
        if (!wrap_is_pci_bus(wd->dev_bus)) {
 
707
                ERROR("used on a non-PCI device");
 
708
                return 0;
 
709
        }
713
710
        for (i = 0; i < len; i++)
714
711
                if (pci_write_config_byte(wd->pci.pdev, offset + i, buf[i]) !=
715
712
                    PCIBIOS_SUCCESSFUL)
814
811
{
815
812
        struct ndis_device *wnd = nmb->wnd;
816
813
 
817
 
        ENTER2("%Lx, %d", phy_addr, len);
 
814
        ENTER2("%llx, %d", phy_addr, len);
818
815
        *virt = MmMapIoSpace(phy_addr, len, MmCached);
819
816
        if (*virt == NULL) {
820
817
                ERROR("ioremap failed");
938
935
        struct ndis_device *wnd = nmb->wnd;
939
936
 
940
937
        ENTER2("%p, %d %d %d %d", wnd, dmachan, dmasize, basemap, max_buf_size);
 
938
        if (!wrap_is_pci_bus(wnd->wd->dev_bus)) {
 
939
                ERROR("used on a non-PCI device");
 
940
                return NDIS_STATUS_NOT_SUPPORTED;
 
941
        }
941
942
        if (wnd->dma_map_count > 0) {
942
943
                WARNING("%s: map registers already allocated: %u",
943
944
                        wnd->net_dev->name, wnd->dma_map_count);
961
962
                else
962
963
                        wnd->net_dev->features |= NETIF_F_HIGHDMA;
963
964
#endif
 
965
        } else {
 
966
                ERROR("dmasize %d not supported", dmasize);
 
967
                EXIT2(return NDIS_STATUS_NOT_SUPPORTED);
964
968
        }
965
969
        /* since memory for buffer is allocated with kmalloc, buffer
966
970
         * is physically contiguous, so entire map will fit in one
974
978
//              EXIT2(return NDIS_STATUS_RESOURCES);
975
979
        }
976
980
 
977
 
        wnd->dma_map_addr = kmalloc(basemap * sizeof(*(wnd->dma_map_addr)),
 
981
        wnd->dma_map_addr = kzalloc(basemap * sizeof(*(wnd->dma_map_addr)),
978
982
                                    GFP_KERNEL);
979
983
        if (!wnd->dma_map_addr)
980
984
                EXIT2(return NDIS_STATUS_RESOURCES);
981
 
        memset(wnd->dma_map_addr, 0, basemap * sizeof(*(wnd->dma_map_addr)));
982
985
        wnd->dma_map_count = basemap;
983
986
        TRACE2("%u", wnd->dma_map_count);
984
987
        EXIT2(return NDIS_STATUS_SUCCESS);
1014
1017
        struct ndis_device *wnd = nmb->wnd;
1015
1018
 
1016
1019
        ENTER3("%p, %p, %u, %u", wnd, buf, index, wnd->dma_map_count);
 
1020
        if (!wrap_is_pci_bus(wnd->wd->dev_bus)) {
 
1021
                ERROR("used on a non-PCI device");
 
1022
                return;
 
1023
        }
1017
1024
        if (unlikely(wnd->sg_dma_size || !write_to_dev ||
1018
1025
                     index >= wnd->dma_map_count)) {
1019
1026
                WARNING("invalid request: %d, %d, %d, %d", wnd->sg_dma_size,
1024
1031
                return;
1025
1032
        }
1026
1033
        if (wnd->dma_map_addr[index]) {
1027
 
                TRACE2("buffer %p at %d is already mapped: %lx", buf, index,
1028
 
                       (unsigned long)wnd->dma_map_addr[index]);
 
1034
                TRACE2("buffer %p at %d is already mapped: %llx", buf, index,
 
1035
                       (unsigned long long)wnd->dma_map_addr[index]);
1029
1036
//              *array_size = 1;
1030
1037
                return;
1031
1038
        }
1041
1048
                                   MmGetMdlByteCount(buf), PCI_DMA_TODEVICE);
1042
1049
        phy_addr_array[0].phy_addr = wnd->dma_map_addr[index];
1043
1050
        phy_addr_array[0].length = MmGetMdlByteCount(buf);
1044
 
        TRACE4("%Lx, %d, %d", phy_addr_array[0].phy_addr,
 
1051
        TRACE4("%llx, %d, %d", phy_addr_array[0].phy_addr,
1045
1052
               phy_addr_array[0].length, index);
1046
1053
        *array_size = 1;
1047
1054
}
1053
1060
 
1054
1061
        ENTER3("%p, %p %u (%u)", wnd, buf, index, wnd->dma_map_count);
1055
1062
 
 
1063
        if (!wrap_is_pci_bus(wnd->wd->dev_bus)) {
 
1064
                ERROR("used on a non-PCI device");
 
1065
                return;
 
1066
        }
1056
1067
        if (unlikely(wnd->sg_dma_size))
1057
1068
                WARNING("buffer %p may have been unmapped already", buf);
1058
1069
        if (index >= wnd->dma_map_count) {
1060
1071
                      index, wnd->dma_map_count);
1061
1072
                return;
1062
1073
        }
1063
 
        TRACE4("%lx", (unsigned long)wnd->dma_map_addr[index]);
 
1074
        TRACE4("%llx", (unsigned long long)wnd->dma_map_addr[index]);
1064
1075
        if (wnd->dma_map_addr[index]) {
1065
1076
                PCI_DMA_UNMAP_SINGLE(wnd->wd->pci.pdev, wnd->dma_map_addr[index],
1066
1077
                                     MmGetMdlByteCount(buf), PCI_DMA_TODEVICE);
1077
1088
        struct wrap_device *wd = nmb->wnd->wd;
1078
1089
 
1079
1090
        ENTER3("size: %u, cached: %d", size, cached);
 
1091
        if (!wrap_is_pci_bus(wd->dev_bus)) {
 
1092
                ERROR("used on a non-PCI device");
 
1093
                return;
 
1094
        }
1080
1095
        *virt = PCI_DMA_ALLOC_COHERENT(wd->pci.pdev, size, &dma_addr);
1081
1096
        if (*virt)
1082
1097
                *phys = dma_addr;
1091
1106
         void *virt, NDIS_PHY_ADDRESS addr)
1092
1107
{
1093
1108
        struct wrap_device *wd = nmb->wnd->wd;
1094
 
        ENTER3("%p, %Lx, %u", virt, addr, size);
 
1109
        ENTER3("%p, %llx, %u", virt, addr, size);
 
1110
        if (!wrap_is_pci_bus(wd->dev_bus)) {
 
1111
                ERROR("used on a non-PCI device");
 
1112
                return;
 
1113
        }
1095
1114
        PCI_DMA_FREE_COHERENT(wd->pci.pdev, size, virt, addr);
1096
1115
        EXIT3(return);
1097
1116
}
1299
1318
        if (virt)
1300
1319
                *virt = MmGetSystemAddressForMdl(buffer);
1301
1320
        *length = MmGetMdlByteCount(buffer);
1302
 
        TRACE4("%p, %u", virt? *virt : NULL, *length);
 
1321
        TRACE4("%p, %u", virt ? *virt : NULL, *length);
1303
1322
        return;
1304
1323
}
1305
1324
 
1311
1330
        if (virt)
1312
1331
                *virt = MmGetSystemAddressForMdlSafe(buffer, priority);
1313
1332
        *length = MmGetMdlByteCount(buffer);
1314
 
        TRACE4("%p, %u", virt? *virt : NULL, *length);
 
1333
        TRACE4("%p, %u", virt ? *virt : NULL, *length);
1315
1334
}
1316
1335
 
1317
1336
wstdcall void *WIN_FUNC(NdisBufferVirtualAddress,1)
2147
2166
        struct ndis_device *wnd = nmb->wnd;
2148
2167
        ENTER2("%p", wnd);
2149
2168
        if (wnd->tx_ok)
2150
 
                schedule_wrapndis_work(&wnd->tx_work);
 
2169
                queue_work(wrapndis_wq, &wnd->tx_work);
2151
2170
}
2152
2171
 
2153
2172
/* called via function pointer */
2181
2200
                 */
2182
2201
                if (xchg(&wnd->tx_ok, 1) == 0) {
2183
2202
                        TRACE3("%d, %d", wnd->tx_ring_start, wnd->tx_ring_end);
2184
 
                        schedule_wrapndis_work(&wnd->tx_work);
 
2203
                        queue_work(wrapndis_wq, &wnd->tx_work);
2185
2204
                }
2186
2205
        }
2187
2206
        EXIT3(return);
2193
2212
        struct ndis_device *wnd = nmb->wnd;
2194
2213
        ENTER3("%d, %d", wnd->tx_ring_start, wnd->tx_ring_end);
2195
2214
        wnd->tx_ok = 1;
2196
 
        schedule_wrapndis_work(&wnd->tx_work);
 
2215
        queue_work(wrapndis_wq, &wnd->tx_work);
2197
2216
        EXIT3(return);
2198
2217
}
2199
2218
 
2246
2265
                                                 NormalPagePriority);
2247
2266
                TRACE3("%d, %d", length, total_length);
2248
2267
                oob_data = NDIS_PACKET_OOB_DATA(packet);
2249
 
                TRACE3("0x%x, 0x%x, %Lu", packet->private.flags,
 
2268
                TRACE3("0x%x, 0x%x, %llu", packet->private.flags,
2250
2269
                       packet->private.packet_flags, oob_data->time_rxed);
2251
2270
                skb = dev_alloc_skb(total_length);
2252
2271
                if (skb) {
2556
2575
        (LARGE_INTEGER *time)
2557
2576
{
2558
2577
        *time = ticks_1601();
2559
 
        TRACE5("%Lu, %lu", *time, jiffies);
 
2578
        TRACE5("%llu, %lu", *time, jiffies);
2560
2579
}
2561
2580
 
2562
2581
wstdcall LONG WIN_FUNC(NdisInterlockedDecrement,1)
2592
2611
}
2593
2612
 
2594
2613
wstdcall NDIS_STATUS WIN_FUNC(NdisMInitializeScatterGatherDma,3)
2595
 
        (struct ndis_mp_block *nmb, BOOLEAN dma_size, ULONG max_phy_map)
 
2614
        (struct ndis_mp_block *nmb, BOOLEAN dma64_supported, ULONG max_phy_map)
2596
2615
{
2597
2616
        struct ndis_device *wnd = nmb->wnd;
2598
 
        ENTER2("dma_size=%d, maxtransfer=%u", dma_size, max_phy_map);
 
2617
        ENTER2("dma64_supported=%d, maxtransfer=%u", dma64_supported,
 
2618
               max_phy_map);
 
2619
        if (!wrap_is_pci_bus(wnd->wd->dev_bus)) {
 
2620
                ERROR("used on a non-PCI device");
 
2621
                return NDIS_STATUS_NOT_SUPPORTED;
 
2622
        }
2599
2623
#ifdef CONFIG_X86_64
2600
 
        if (dma_size != NDIS_DMA_64BITS) {
2601
 
                TRACE1("DMA size is not 64-bits");
 
2624
        if (!dma64_supported) {
 
2625
                TRACE1("64-bit DMA size is not supported");
2602
2626
                if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_BIT_MASK(32)) ||
2603
2627
                    pci_set_consistent_dma_mask(wnd->wd->pci.pdev,
2604
2628
                                                DMA_BIT_MASK(32)))
2703
2727
        InsertTailList(&ndis_work_list, &ndis_work_item->list);
2704
2728
        spin_unlock_bh(&ndis_work_list_lock);
2705
2729
        WORKTRACE("scheduling %p", ndis_work_item);
2706
 
        schedule_ndis_work(&ndis_work);
 
2730
        queue_work(ndis_wq, &ndis_work);
2707
2731
        EXIT3(return NDIS_STATUS_SUCCESS);
2708
2732
}
2709
2733
 
2836
2860
        EXIT2(return NDIS_STATUS_SUCCESS);
2837
2861
}
2838
2862
 
2839
 
wstdcall void WIN_FUNC(NdisCompletePnPEvent,2)
 
2863
wstdcall void WIN_FUNC(NdisCompletePnPEvent,3)
2840
2864
        (NDIS_STATUS status, void *handle, struct net_pnp_event *event)
2841
2865
{
2842
2866
        ENTER2("%d, %p, %d", status, handle, event->code);
2883
2907
{
2884
2908
        int i;
2885
2909
        ENTER2("%p", name);
2886
 
        for (i = 0; i < sizeof(ndis_exports) / sizeof(ndis_exports[0]); i++) {
 
2910
        for (i = 0; i < ARRAY_SIZE(ndis_exports); i++) {
2887
2911
                if (strcmp(name, ndis_exports[i].name) == 0) {
2888
2912
                        TRACE2("%p", ndis_exports[i].func);
2889
2913
                        return ndis_exports[i].func;
2927
2951
{
2928
2952
        struct wrap_device_setting *setting;
2929
2953
        ENTER2("%p", wnd);
2930
 
        if (down_interruptible(&loader_mutex))
2931
 
                WARNING("couldn't obtain loader_mutex");
 
2954
        mutex_lock(&loader_mutex);
2932
2955
        nt_list_for_each_entry(setting, &wnd->wd->settings, list) {
2933
2956
                struct ndis_configuration_parameter *param;
2934
2957
                param = setting->encoded;
2939
2962
                        setting->encoded = NULL;
2940
2963
                }
2941
2964
        }
2942
 
        up(&loader_mutex);
 
2965
        mutex_unlock(&loader_mutex);
2943
2966
}
2944
2967
 
2945
2968
/* ndis_init is called once when module is loaded */
2947
2970
{
2948
2971
        InitializeListHead(&ndis_work_list);
2949
2972
        spin_lock_init(&ndis_work_list_lock);
2950
 
        initialize_work(&ndis_work, ndis_worker);
 
2973
        INIT_WORK(&ndis_work, ndis_worker);
2951
2974
 
2952
2975
        ndis_wq = create_singlethread_workqueue("ndis_wq");
2953
2976
        if (!ndis_wq) {