48
52
INIT_WORK(&ndis_work, &ndis_worker, NULL);
49
53
INIT_LIST_HEAD(&ndis_work_list);
50
54
INIT_LIST_HEAD(&handle_ctx_list);
51
wrap_spin_lock_init(&ndis_work_list_lock);
53
wrap_spin_lock_init(&atomic_lock);
54
wrap_spin_lock_init(&cancel_lock);
55
kspin_lock_init(&ndis_work_list_lock);
56
packet_cache = kmem_cache_create("ndis_packet",
57
sizeof(struct ndis_packet), 0, 0,
60
ERROR("couldn't allocate packet cache");
66
/* ndis_exit is called once when module is removed */
69
if (packet_cache && kmem_cache_destroy(packet_cache))
70
ERROR("A Windows driver didn't free all packet(s);"
58
75
/* ndis_exit_handle is called for each handle */
59
76
void ndis_exit_handle(struct ndis_handle *handle)
61
struct miniport_char *miniport = &handle->driver->miniport_char;
63
78
/* TI driver doesn't call NdisMDeregisterInterrupt during halt! */
64
if (handle->ndis_irq) {
67
spin_lock_irqsave(K_SPINLOCK(&(handle->ndis_irq->lock)), flags);
68
if (miniport->disable_interrupts)
69
miniport->disable_interrupts(handle->adapter_ctx);
70
spin_unlock_irqrestore(K_SPINLOCK(&(handle->ndis_irq->lock)),
72
80
NdisMDeregisterInterrupt(handle->ndis_irq);
74
wrap_free_timers(handle);
75
81
free_handle_ctx(handle);
78
/* ndis_exit is called once when module is removed */
84
static void wrap_free_timers(struct ndis_handle *handle)
87
/* Cancel any timers left by bugyy windows driver
88
* Also free the memory for timers
91
struct wrapper_timer *timer;
92
wrap_spin_lock(&handle->timers_lock, DISPATCH_LEVEL);
93
if (list_empty(&handle->timers)) {
94
wrap_spin_unlock(&handle->timers_lock);
98
timer = (struct wrapper_timer *)handle->timers.next;
99
list_del(&timer->list);
100
wrap_spin_unlock(&handle->timers_lock);
102
DBGTRACE1("fixing up timer %p, timer->list %p",
103
timer, &timer->list);
104
wrapper_cancel_timer(timer, &canceled);
82
if (handle->pci_resources)
83
vfree(handle->pci_resources);
109
86
/* remove all 'handle X ctx' pairs for the given handle */
110
87
static void free_handle_ctx(struct ndis_handle *handle)
112
struct list_head *curr, *tmp;
89
struct list_head *cur, *tmp;
114
wrap_spin_lock(&atomic_lock, PASSIVE_LEVEL);
115
list_for_each_safe(curr, tmp, &handle_ctx_list) {
91
kspin_lock(&ntoskernel_lock);
92
list_for_each_safe(cur, tmp, &handle_ctx_list) {
116
93
struct handle_ctx_entry *handle_ctx =
117
(struct handle_ctx_entry *)curr;
94
list_entry(cur, struct handle_ctx_entry, list);
118
95
if (handle_ctx->handle == handle) {
119
96
list_del(&handle_ctx->list);
120
97
kfree(handle_ctx);
123
wrap_spin_unlock(&atomic_lock);
100
kspin_unlock(&ntoskernel_lock);
127
104
/* Called from the driver entry. */
128
STDCALL static void WRAP_EXPORT(NdisInitializeWrapper)
105
STDCALL void WRAP_EXPORT(NdisInitializeWrapper)
129
106
(struct ndis_handle **ndis_handle, void *SystemSpecific1,
130
107
void *SystemSpecific2, void *SystemSpecific3)
821
846
TRACEEXIT2(return);
824
STDCALL static NDIS_STATUS WRAP_EXPORT(NdisMMapIoSpace)
849
STDCALL NDIS_STATUS WRAP_EXPORT(NdisMPciAssignResources)
850
(struct ndis_handle *handle, ULONG slot_number,
851
struct ndis_resource_list **resources)
856
size = sizeof(struct ndis_resource_list) +
857
sizeof(struct ndis_resource_entry) * 20;
858
handle->pci_resources = vmalloc(size);
859
if (!handle->resources) {
860
ERROR("couldn't allocate memory");
861
TRACEEXIT2(return NDIS_STATUS_SUCCESS);
863
NdisMQueryAdapterResources(&status, handle, handle->pci_resources,
865
*resources = handle->pci_resources;
866
TRACEEXIT2(return NDIS_STATUS_SUCCESS);
869
STDCALL NDIS_STATUS WRAP_EXPORT(NdisMMapIoSpace)
825
870
(void **virt, struct ndis_handle *handle,
826
871
NDIS_PHY_ADDRESS phy_addr, UINT len)
830
addr = (ULONG_PTR)phy_addr.quad;
832
TRACEENTER2("%p, %u", (void *)addr, len);
833
*virt = ioremap(addr, len);
873
TRACEENTER2("%016llx, %d", phy_addr, len);
874
*virt = ioremap(phy_addr, len);
834
875
if (*virt == NULL) {
835
876
ERROR("%s", "ioremap failed");
836
877
TRACEEXIT2(return NDIS_STATUS_FAILURE);
839
handle->mem_start = addr;
840
handle->mem_end = addr + len -1;
880
handle->mem_start = phy_addr;
881
handle->mem_end = phy_addr + len -1;
841
883
DBGTRACE2("ioremap successful %p", *virt);
842
884
TRACEEXIT2(return NDIS_STATUS_SUCCESS);
845
STDCALL static void WRAP_EXPORT(NdisMUnmapIoSpace)
887
STDCALL void WRAP_EXPORT(NdisMUnmapIoSpace)
846
888
(struct ndis_handle *handle, void *virtaddr, UINT len)
848
890
TRACEENTER2("%p, %d", virtaddr, len);
849
891
iounmap(virtaddr);
852
STDCALL static void WRAP_EXPORT(NdisAllocateSpinLock)
853
(struct ndis_spinlock *lock)
855
TRACEENTER4("lock %p", lock);
857
#ifdef CONFIG_DEBUG_SPINLOCK
858
lock->lock = wrap_kmalloc(sizeof(struct wrap_spinlock), GFP_ATOMIC);
860
ERROR("coudln't allocate memory");
864
wrap_spin_lock_init(NDIS_SPINLOCK(lock));
869
STDCALL static void WRAP_EXPORT(NdisFreeSpinLock)
870
(struct ndis_spinlock *lock)
872
TRACEENTER4("lock %p", lock);
873
lock->use_bh = PASSIVE_LEVEL;
878
STDCALL static void WRAP_EXPORT(NdisAcquireSpinLock)
879
(struct ndis_spinlock *lock)
881
TRACEENTER5("lock %p", lock);
882
/* TI ACX 100 driver doesn't call NdisAllocateSpinLock before
883
* calling NdisAcquireSpinLock and in those cases, lock seems
884
* to be set to 0, so check if that is the case and initialize
886
if (NDIS_SPINLOCK(lock) == 0) {
887
WARNING("Windows driver is using uninitialized spinlock %p",
889
NdisAllocateSpinLock(lock);
891
wrap_spin_lock(NDIS_SPINLOCK(lock), PASSIVE_LEVEL);
895
STDCALL static void WRAP_EXPORT(NdisReleaseSpinLock)
896
(struct ndis_spinlock *lock)
898
TRACEENTER5("lock %p", lock);
899
wrap_spin_unlock(NDIS_SPINLOCK(lock));
903
STDCALL static void WRAP_EXPORT(NdisDprAcquireSpinLock)
904
(struct ndis_spinlock *lock)
906
TRACEENTER5("lock %p", lock);
907
/* we use PASSIVE_LEVEL here because this function is not
908
* supposed to change IRQL */
909
wrap_spin_lock(NDIS_SPINLOCK(lock), PASSIVE_LEVEL);
913
STDCALL static void WRAP_EXPORT(NdisDprReleaseSpinLock)
914
(struct ndis_spinlock *lock)
916
TRACEENTER5("lock %p", lock);
917
wrap_spin_unlock(NDIS_SPINLOCK(lock));
921
STDCALL static NDIS_STATUS WRAP_EXPORT(NdisMAllocateMapRegisters)
894
STDCALL void WRAP_EXPORT(NdisAllocateSpinLock)
895
(struct ndis_spinlock *lock)
897
TRACEENTER4("lock %p", lock);
899
KeInitializeSpinLock(&lock->klock);
904
STDCALL void WRAP_EXPORT(NdisFreeSpinLock)
905
(struct ndis_spinlock *lock)
907
TRACEENTER4("lock %p", lock);
911
STDCALL void WRAP_EXPORT(NdisAcquireSpinLock)
912
(struct ndis_spinlock *lock)
914
TRACEENTER5("lock %p", lock);
915
lock->irql = kspin_lock_irql(&lock->klock, DISPATCH_LEVEL);
919
STDCALL void WRAP_EXPORT(NdisReleaseSpinLock)
920
(struct ndis_spinlock *lock)
922
TRACEENTER5("lock %p", lock);
923
kspin_unlock_irql(&lock->klock, lock->irql);
927
STDCALL void WRAP_EXPORT(NdisDprAcquireSpinLock)
928
(struct ndis_spinlock *lock)
930
TRACEENTER5("lock %p", lock);
931
kspin_lock(&lock->klock);
935
STDCALL void WRAP_EXPORT(NdisDprReleaseSpinLock)
936
(struct ndis_spinlock *lock)
938
TRACEENTER5("lock %p", lock);
939
kspin_unlock(&lock->klock);
943
STDCALL void WRAP_EXPORT(NdisInitializeReadWriteLock)
944
(struct ndis_rw_lock *rw_lock)
946
memset(rw_lock, 0, sizeof(*rw_lock));
947
KeInitializeSpinLock(&rw_lock->u.s.klock);
951
STDCALL NDIS_STATUS WRAP_EXPORT(NdisMAllocateMapRegisters)
922
952
(struct ndis_handle *handle, UINT dmachan,
923
953
NDIS_DMA_SIZE dmasize, ULONG basemap, ULONG size)
1003
1030
alloc_mem->cached = cached;
1004
1031
alloc_mem->ctx = ctx;
1006
wrap_spin_lock(&ndis_work_list_lock, DISPATCH_LEVEL);
1033
irql = kspin_lock_irql(&ndis_work_list_lock, DISPATCH_LEVEL);
1007
1034
list_add_tail(&ndis_work_entry->list, &ndis_work_list);
1008
wrap_spin_unlock(&ndis_work_list_lock);
1035
kspin_unlock_irql(&ndis_work_list_lock, irql);
1010
1037
schedule_work(&ndis_work);
1011
1038
TRACEEXIT3(return NDIS_STATUS_PENDING);
1014
STDCALL static void WRAP_EXPORT(NdisMFreeSharedMemory)
1041
STDCALL void WRAP_EXPORT(NdisMFreeSharedMemory)
1015
1042
(struct ndis_handle *handle, ULONG size, BOOLEAN cached,
1016
1043
void *virt, NDIS_PHY_ADDRESS addr)
1018
1045
TRACEENTER3("%s", "");
1019
1046
/* FIXME: do USB drivers call this? */
1020
#ifdef CONFIG_X86_64
1021
PCI_DMA_FREE_COHERENT(handle->dev.pci, size, virt, addr.quad);
1023
PCI_DMA_FREE_COHERENT(handle->dev.pci, size, virt, addr.s.low);
1047
PCI_DMA_FREE_COHERENT(handle->dev.pci, size, virt, addr);
1025
1048
TRACEEXIT3(return);
1028
STDCALL static void WRAP_EXPORT(NdisAllocateBufferPool)
1029
(NDIS_STATUS *status, void *poolhandle, UINT size)
1051
/* Some drivers allocate NDIS_BUFFER (aka MDL) very often; instead of
1052
* allocating and freeing with kernel functions, we chain them into
1053
* ndis_buffer_pool. When an MDL is freed, it is added to the list of
1054
* free MDLs. When allocated, we first check if there is one in free
1055
* list and if so just return it; otherwise, we allocate a new one and
1056
* return that. This reduces memory fragmentation. Windows DDK says
1057
* that the driver itself shouldn't check what is returned in
1058
* pool_handle, presumably because buffer pools are not used in
1059
* XP. However, as long as driver follows rest of the semantics - that
1060
* it should indicate maximum number of MDLs used with num_descr and
1061
* pass the same pool_handle in other buffer functions, this should
1062
* work. Sadly, though, NdisFreeBuffer doesn't pass the pool_handle,
1063
* so we use 'process' field of MDL to store pool_handle. */
1064
STDCALL void WRAP_EXPORT(NdisAllocateBufferPool)
1065
(NDIS_STATUS *status, struct ndis_buffer_pool **pool_handle,
1031
TRACEENTER4("%s", "");
1068
struct ndis_buffer_pool *pool;
1070
TRACEENTER3("buffers: %d", num_descr);
1071
pool = kmalloc(sizeof(*pool), GFP_ATOMIC);
1073
*status = NDIS_STATUS_RESOURCES;
1076
kspin_lock_init(&pool->lock);
1077
pool->max_descr = num_descr;
1078
pool->num_allocated_descr = 0;
1079
pool->free_descr = NULL;
1080
*pool_handle = pool;
1032
1081
*status = NDIS_STATUS_SUCCESS;
1035
STDCALL static void WRAP_EXPORT(NdisFreeBufferPool)
1038
TRACEENTER4("%s", "");
1043
STDCALL static void WRAP_EXPORT(NdisAllocateBuffer)
1044
(NDIS_STATUS *status, struct ndis_buffer **buffer,
1045
void *poolhandle, void *virt, UINT len)
1047
struct ndis_buffer *ndis_buffer = kmalloc(sizeof(struct ndis_buffer),
1049
TRACEENTER4("%s", "");
1051
ERROR("%s", "Couldn't allocate memory");
1085
STDCALL void WRAP_EXPORT(NdisAllocateBuffer)
1086
(NDIS_STATUS *status, ndis_buffer **buffer,
1087
struct ndis_buffer_pool *pool, void *virt, UINT length)
1092
TRACEENTER3("pool: %p, allocated: %d",
1093
pool, pool->num_allocated_descr);
1052
1095
*status = NDIS_STATUS_FAILURE;
1053
1096
TRACEEXIT4(return);
1056
memset(ndis_buffer, 0, sizeof(struct ndis_buffer));
1058
ndis_buffer->data = virt;
1059
ndis_buffer->next = 0;
1060
ndis_buffer->len = len;
1062
*buffer = ndis_buffer;
1064
DBGTRACE4("allocated buffer: %p", buffer);
1065
*status = NDIS_STATUS_SUCCESS;
1069
STDCALL static void WRAP_EXPORT(NdisFreeBuffer)
1070
(struct ndis_buffer *buffer)
1098
irql = kspin_lock_irql(&pool->lock, DISPATCH_LEVEL);
1099
if (pool->num_allocated_descr < pool->max_descr) {
1100
if (pool->free_descr) {
1101
descr = pool->free_descr;
1102
pool->free_descr = descr->next;
1103
memset(descr, 0, sizeof(*descr));
1104
MmInitializeMdl(descr, virt, length);
1106
descr = allocate_init_mdl(virt, length);
1111
/* NdisFreeBuffer doesn't pass pool, so we store pool
1112
* in unused field 'process' */
1113
descr->process = pool;
1114
pool->num_allocated_descr++;
1115
*status = NDIS_STATUS_SUCCESS;
1116
DBGTRACE3("allocated buffer %p for %p", descr, virt);
1118
*status = NDIS_STATUS_FAILURE;
1121
kspin_unlock_irql(&pool->lock, irql);
1125
STDCALL void WRAP_EXPORT(NdisFreeBuffer)
1126
(ndis_buffer *descr)
1128
struct ndis_buffer_pool *pool;
1131
TRACEENTER3("buffer: %p", descr);
1132
pool = descr->process;
1134
ERROR("pool for descriptor %p is invalid", descr);
1137
irql = kspin_lock_irql(&pool->lock, DISPATCH_LEVEL);
1138
descr->next = pool->free_descr;
1139
pool->free_descr = descr;
1140
pool->num_allocated_descr--;
1141
kspin_unlock_irql(&pool->lock, irql);
1145
STDCALL void WRAP_EXPORT(NdisFreeBufferPool)
1146
(struct ndis_buffer_pool *pool)
1148
ndis_buffer *cur, *prev;
1151
TRACEENTER3("pool: %p", pool);
1152
irql = kspin_lock_irql(&pool->lock, DISPATCH_LEVEL);
1153
cur = pool->free_descr;
1157
prev->process = NULL;
1160
kspin_unlock_irql(&pool->lock, irql);
1165
STDCALL void WRAP_EXPORT(NdisAdjustBufferLength)
1166
(ndis_buffer *buffer, UINT length)
1072
1168
TRACEENTER4("%p", buffer);
1079
STDCALL static void WRAP_EXPORT(NdisAdjustBufferLength)
1080
(struct ndis_buffer *buf, UINT len)
1082
TRACEENTER4("%s", "");
1086
STDCALL static void WRAP_EXPORT(NdisQueryBuffer)
1087
(struct ndis_buffer *buf, void **adr, UINT *len)
1089
TRACEENTER3("%s", "");
1096
STDCALL static void WRAP_EXPORT(NdisQueryBufferSafe)
1097
(struct ndis_buffer *buf, void **adr,
1098
UINT *len, enum mm_page_priority priority)
1100
TRACEENTER3("%p, %p, %p", buf, adr, len);
1107
STDCALL static void *WRAP_EXPORT(NdisBufferVirtualAddress)
1108
(struct ndis_buffer *buf)
1110
TRACEENTER3("%s", "");
1114
STDCALL static ULONG WRAP_EXPORT(NdisBufferLength)
1115
(struct ndis_buffer *buf)
1117
TRACEENTER3("%s", "");
1121
STDCALL static void WRAP_EXPORT(NdisAllocatePacketPool)
1122
(NDIS_STATUS *status, unsigned int *poolhandle,
1123
UINT size, UINT rsvlen)
1125
TRACEENTER3("size=%d", size);
1126
*poolhandle = 0xa000fff4;
1169
buffer->bytecount = length;
1172
STDCALL void WRAP_EXPORT(NdisQueryBuffer)
1173
(ndis_buffer *buffer, void **virt, UINT *length)
1175
TRACEENTER3("buffer: %p", buffer);
1177
*virt = MmGetMdlVirtualAddress(buffer);
1179
*length = MmGetMdlByteCount(buffer);
1183
STDCALL void WRAP_EXPORT(NdisQueryBufferSafe)
1184
(ndis_buffer *buffer, void **virt, UINT *length,
1185
enum mm_page_priority priority)
1187
TRACEENTER3("%p, %p, %p", buffer, virt, length);
1189
*virt = MmGetMdlVirtualAddress(buffer);
1191
*length = MmGetMdlByteCount(buffer);
1194
STDCALL void *WRAP_EXPORT(NdisBufferVirtualAddress)
1195
(ndis_buffer *buffer)
1197
TRACEENTER3("%p", buffer);
1198
return MmGetMdlVirtualAddress(buffer);
1201
STDCALL ULONG WRAP_EXPORT(NdisBufferLength)
1202
(ndis_buffer *buffer)
1204
TRACEENTER3("%p", buffer);
1205
return MmGetMdlByteCount(buffer);
1208
STDCALL void WRAP_EXPORT(NdisAllocatePacketPool)
1209
(NDIS_STATUS *status, struct ndis_packet_pool **pool_handle,
1210
UINT num_descr, UINT rsvlen)
1212
struct ndis_packet_pool *pool;
1214
TRACEENTER3("buffers: %d", num_descr);
1215
pool = kmalloc(sizeof(*pool), GFP_ATOMIC);
1217
*status = NDIS_STATUS_RESOURCES;
1220
kspin_lock_init(&pool->lock);
1221
pool->max_descr = num_descr;
1222
pool->num_allocated_descr = 0;
1223
pool->free_descr = NULL;
1224
*pool_handle = pool;
1127
1225
*status = NDIS_STATUS_SUCCESS;
1130
STDCALL static void WRAP_EXPORT(NdisAllocatePacketPoolEx)
1131
(NDIS_STATUS *status, unsigned int *poolhandle,
1132
UINT size, UINT overflowsize, UINT rsvlen)
1134
TRACEENTER3("%s", "");
1135
NdisAllocatePacketPool(status, poolhandle, size, rsvlen);
1139
STDCALL static UINT WRAP_EXPORT(NdisPacketPoolUsage)
1146
STDCALL static void WRAP_EXPORT(NdisFreePacketPool)
1149
TRACEENTER3("handle: %p", poolhandle);
1152
STDCALL static void WRAP_EXPORT(NdisAllocatePacket)
1153
(NDIS_STATUS *status, struct ndis_packet **packet_out,
1229
STDCALL void WRAP_EXPORT(NdisAllocatePacketPoolEx)
1230
(NDIS_STATUS *status, struct ndis_packet_pool **pool_handle,
1231
UINT num_descr, UINT overflowsize, UINT rsvlen)
1234
NdisAllocatePacketPool(status, pool_handle, num_descr, rsvlen);
1238
STDCALL UINT WRAP_EXPORT(NdisPacketPoolUsage)
1239
(struct ndis_packet_pool *pool)
1244
irql = kspin_lock_irql(&pool->lock, DISPATCH_LEVEL);
1245
i = pool->num_allocated_descr;
1246
kspin_unlock_irql(&pool->lock, irql);
1250
struct ndis_packet *allocate_ndis_packet(void)
1156
1252
struct ndis_packet *packet;
1158
TRACEENTER3("%s", "");
1159
packet = kmalloc(sizeof(struct ndis_packet), GFP_ATOMIC);
1161
ERROR("%s", "Couldn't allocate memory");
1163
*status = NDIS_STATUS_FAILURE;
1166
memset(packet, 0, sizeof(struct ndis_packet));
1167
packet->private.oob_offset = offsetof(struct ndis_packet, oob_tx);
1168
packet->private.pool = (void *)0xa000fff4;
1169
packet->private.packet_flags = 0xc0;
1171
/* See comment in wrapper.c/send_one about this */
1175
/* Poision extra packet info */
1176
int *x = (int*) &packet->ext1;
1177
for (i = 0; i <= 12; i++)
1180
packet->mediaspecific_size = 0x100;
1181
packet->mediaspecific = (void*) 0x0001f00;
1186
*packet_out = packet;
1187
*status = NDIS_STATUS_SUCCESS;
1191
STDCALL static void WRAP_EXPORT(NdisFreePacket)
1194
TRACEENTER3("%s", "");
1253
packet = kmem_cache_alloc(packet_cache, GFP_ATOMIC);
1196
memset(packet, 0, sizeof(struct ndis_packet));
1202
STDCALL static void WRAP_EXPORT(NdisMInitializeTimer)
1255
memset(packet, 0, sizeof(*packet));
1256
packet->private.oob_offset =
1257
offsetof(struct ndis_packet, oob_data);
1258
packet->private.packet_flags = fPACKET_ALLOCATED_BY_NDIS;
1263
void free_ndis_packet(struct ndis_packet *packet)
1265
kmem_cache_free(packet_cache, packet);
1268
STDCALL void WRAP_EXPORT(NdisAllocatePacket)
1269
(NDIS_STATUS *status, struct ndis_packet **packet,
1270
struct ndis_packet_pool *pool)
1272
struct ndis_packet *descr;
1275
TRACEENTER3("pool: %p", pool);
1277
*status = NDIS_STATUS_RESOURCES;
1280
irql = kspin_lock_irql(&pool->lock, DISPATCH_LEVEL);
1281
if (pool->num_allocated_descr < pool->max_descr) {
1282
if (pool->free_descr) {
1283
descr = pool->free_descr;
1284
pool->free_descr = descr->next;
1285
memset(descr, 0, sizeof(*descr));
1286
descr->private.oob_offset =
1287
offsetof(struct ndis_packet, oob_data);
1288
descr->private.packet_flags =
1289
fPACKET_ALLOCATED_BY_NDIS;
1291
descr = allocate_ndis_packet();
1296
pool->num_allocated_descr++;
1297
descr->private.pool = pool;
1298
*status = NDIS_STATUS_SUCCESS;
1300
*status = NDIS_STATUS_RESOURCES;
1302
kspin_unlock_irql(&pool->lock, irql);
1303
DBGTRACE3("packet: %p, pool: %p", descr, pool);
1307
STDCALL void WRAP_EXPORT(NdisDprAllocatePacket)
1308
(NDIS_STATUS *status, struct ndis_packet **packet,
1309
struct ndis_packet_pool *pool)
1311
NdisAllocatePacket(status, packet, pool);
1314
STDCALL void WRAP_EXPORT(NdisFreePacket)
1315
(struct ndis_packet *descr)
1317
struct ndis_packet_pool *pool;
1320
TRACEENTER3("packet: %p, pool: %p", descr, descr->private.pool);
1321
pool = descr->private.pool;
1323
ERROR("pool for descriptor %p is invalid", descr);
1326
irql = kspin_lock_irql(&pool->lock, DISPATCH_LEVEL);
1327
descr->next = pool->free_descr;
1328
pool->free_descr = descr;
1329
pool->num_allocated_descr--;
1330
kspin_unlock_irql(&pool->lock, irql);
1334
STDCALL void WRAP_EXPORT(NdisFreePacketPool)
1335
(struct ndis_packet_pool *pool)
1337
struct ndis_packet *cur, *prev;
1340
TRACEENTER3("pool: %p", pool);
1341
irql = kspin_lock_irql(&pool->lock, DISPATCH_LEVEL);
1342
cur = pool->free_descr;
1346
free_ndis_packet(prev);
1348
kspin_unlock_irql(&pool->lock, irql);
1353
STDCALL void WRAP_EXPORT(NdisSend)
1354
(NDIS_STATUS *status, struct ndis_handle *handle,
1355
struct ndis_packet *packet)
1358
struct miniport_char *miniport = &handle->driver->miniport_char;
1360
if (miniport->send_packets) {
1361
struct ndis_packet *packets[1];
1363
packets[0] = packet;
1364
irql = raise_irql(DISPATCH_LEVEL);
1365
LIN2WIN3(miniport->send_packets, handle->adapter_ctx,
1368
if (test_bit(ATTR_SERIALIZED, &handle->attributes)) {
1369
*status = packet->oob_data.status;
1371
case NDIS_STATUS_SUCCESS:
1372
sendpacket_done(handle, packet);
1374
case NDIS_STATUS_PENDING:
1376
case NDIS_STATUS_RESOURCES:
1377
handle->send_ok = 0;
1379
case NDIS_STATUS_FAILURE:
1384
*status = NDIS_STATUS_PENDING;
1387
irql = raise_irql(DISPATCH_LEVEL);
1388
*status = LIN2WIN3(miniport->send, handle->adapter_ctx,
1392
case NDIS_STATUS_SUCCESS:
1393
sendpacket_done(handle, packet);
1395
case NDIS_STATUS_PENDING:
1397
case NDIS_STATUS_RESOURCES:
1398
handle->send_ok = 0;
1400
case NDIS_STATUS_FAILURE:
1407
STDCALL void WRAP_EXPORT(NdisMInitializeTimer)
1203
1408
(struct ndis_miniport_timer *timer_handle, struct ndis_handle *handle,
1204
1409
void *func, void *ctx)
2199
2413
ndis_work_entry->type = NDIS_SCHED_WORK_ITEM;
2200
2414
ndis_work_entry->entry.sched_work_item = ndis_sched_work_item;
2202
wrap_spin_lock(&ndis_work_list_lock, DISPATCH_LEVEL);
2416
irql = kspin_lock_irql(&ndis_work_list_lock, DISPATCH_LEVEL);
2203
2417
list_add_tail(&ndis_work_entry->list, &ndis_work_list);
2204
wrap_spin_unlock(&ndis_work_list_lock);
2418
kspin_unlock_irql(&ndis_work_list_lock, irql);
2206
2420
schedule_work(&ndis_work);
2207
2421
TRACEEXIT3(return NDIS_STATUS_SUCCESS);
2210
STDCALL static void WRAP_EXPORT(NdisUnchainBufferAtBack)
2211
(struct ndis_packet *packet, struct ndis_buffer **buffer)
2424
STDCALL void WRAP_EXPORT(NdisUnchainBufferAtBack)
2425
(struct ndis_packet *packet, ndis_buffer **buffer)
2213
struct ndis_buffer *b = packet->private.buffer_head;
2214
struct ndis_buffer *btail = packet->private.buffer_tail;
2427
ndis_buffer *b, *btail;
2216
TRACEENTER3("%p", b);
2429
TRACEENTER3("%p", packet);
2430
if (packet == NULL || buffer == NULL)
2432
b = packet->private.buffer_head;
2218
/* No buffer in packet */
2434
/* no buffer in packet */
2219
2435
*buffer = NULL;
2220
2436
TRACEEXIT3(return);
2438
btail = packet->private.buffer_tail;
2440
packet->private.valid_counts = FALSE;
2223
2441
if (b == btail) {
2224
/* Only buffer in packet */
2442
/* one buffer in packet */
2225
2443
packet->private.buffer_head = NULL;
2226
2444
packet->private.buffer_tail = NULL;
2228
2446
while (b->next != btail)
2230
2448
packet->private.buffer_tail = b;
2233
packet->private.valid_counts = 0;
2235
2451
TRACEEXIT3(return);
2238
STDCALL static void WRAP_EXPORT(NdisUnchainBufferAtFront)
2239
(struct ndis_packet *packet, struct ndis_buffer **buffer)
2454
STDCALL void WRAP_EXPORT(NdisUnchainBufferAtFront)
2455
(struct ndis_packet *packet, ndis_buffer **buffer)
2241
struct ndis_buffer *b = packet->private.buffer_head;
2243
TRACEENTER3("%p", b);
2245
/* No buffer in packet */
2457
TRACEENTER3("%p", packet);
2460
if (packet == NULL) {
2461
/* no buffer in packet */
2246
2462
*buffer = NULL;
2247
2463
TRACEEXIT3(return);
2250
if (b == packet->private.buffer_tail) {
2251
/* Only buffer in packet */
2466
packet->private.valid_counts = FALSE;
2467
*buffer = packet->private.buffer_head;
2468
if (packet->private.buffer_head == packet->private.buffer_tail) {
2469
/* one buffer in packet */
2252
2470
packet->private.buffer_head = NULL;
2253
2471
packet->private.buffer_tail = NULL;
2255
packet->private.buffer_head = b->next;
2258
packet->private.valid_counts = 0;
2473
packet->private.buffer_head = (*buffer)->next;
2261
2475
TRACEEXIT3(return);
2264
STDCALL static void WRAP_EXPORT(NdisGetFirstBufferFromPacketSafe)
2265
(struct ndis_packet *packet, struct ndis_buffer **buffer, void **virt,
2266
UINT *len, UINT *totlen, enum mm_page_priority priority)
2478
STDCALL void WRAP_EXPORT(NdisGetFirstBufferFromPacketSafe)
2479
(struct ndis_packet *packet, ndis_buffer **first_buffer,
2480
void **first_buffer_va, UINT *first_buffer_length,
2481
UINT *total_buffer_length, enum mm_page_priority priority)
2268
struct ndis_buffer *b = packet->private.buffer_head;
2483
ndis_buffer *b = packet->private.buffer_head;
2270
2485
TRACEENTER3("%p", b);
2275
*totlen = packet->private.len;
2278
STDCALL static void WRAP_EXPORT(NdisMStartBufferPhysicalMapping)
2279
(struct ndis_handle *handle, struct ndis_buffer *buf,
2488
*first_buffer_va = MmGetMdlVirtualAddress(b);
2489
*first_buffer_length = *total_buffer_length =
2490
MmGetMdlByteCount(b);
2491
for (b = b->next; b != NULL; b = b->next)
2492
*total_buffer_length += MmGetMdlByteCount(b);
2494
*first_buffer_va = NULL;
2495
*first_buffer_length = 0;
2496
*total_buffer_length = 0;
2500
STDCALL void WRAP_EXPORT(NdisCopyFromPacketToPacketSafe)
2501
(struct ndis_packet *dst, UINT dst_offset, UINT num_to_copy,
2502
struct ndis_packet *src, UINT src_offset, UINT *num_copied,
2503
enum mm_page_priority priority)
2505
UINT dst_left, src_left, left, done;
2506
ndis_buffer *dst_buf;
2507
ndis_buffer *src_buf;
2515
dst_buf = dst->private.buffer_head;
2516
src_buf = src->private.buffer_head;
2518
if (!dst_buf || !src_buf) {
2522
dst_left = MmGetMdlByteCount(dst_buf) - dst_offset;
2523
src_left = MmGetMdlByteCount(src_buf) - src_offset;
2525
left = min(src_left, dst_left);
2526
left = min(left, num_to_copy);
2527
memcpy(MmGetMdlVirtualAddress(dst_buf) + dst_offset,
2528
MmGetMdlVirtualAddress(src_buf) + src_offset, left);
2530
done = num_to_copy - left;
2532
if (left == dst_left) {
2533
dst_buf = dst_buf->next;
2536
dst_left = MmGetMdlByteCount(dst_buf);
2539
if (left == src_left) {
2540
src_buf = src_buf->next;
2543
src_left = MmGetMdlByteCount(src_buf);
2547
left = min(src_left, dst_left);
2548
left = min(left, done);
2549
memcpy(MmGetMdlVirtualAddress(dst_buf),
2550
MmGetMdlVirtualAddress(src_buf), left);
2553
*num_copied = num_to_copy - done;
2557
STDCALL void WRAP_EXPORT(NdisCopyFromPacketToPacket)
2558
(struct ndis_packet *dst, UINT dst_offset, UINT num_to_copy,
2559
struct ndis_packet *src, UINT src_offset, UINT *num_copied)
2561
NdisCopyFromPacketToPacketSafe(dst, dst_offset, num_to_copy,
2562
src, src_offset, num_copied,
2563
NormalPagePriority);
2567
STDCALL void WRAP_EXPORT(NdisMStartBufferPhysicalMapping)
2568
(struct ndis_handle *handle, ndis_buffer *buf,
2280
2569
ULONG phy_map_reg, BOOLEAN write_to_dev,
2281
2570
struct ndis_phy_addr_unit *phy_addr_array, UINT *array_size)
2283
dma_addr_t dma_addr;
2284
2572
TRACEENTER3("phy_map_reg: %u", phy_map_reg);
2285
2574
if (!write_to_dev) {
2286
2575
ERROR( "dma from device not supported (%d)", write_to_dev);
2287
2576
*array_size = 0;