win-pvdrivers
changeset 1017:9b6213b6be25
Fix problem with stopping xennet
author | James Harper <james.harper@bendigoit.com.au> |
---|---|
date | Tue Feb 12 20:44:22 2013 +1100 (2013-02-12) |
parents | 9dbd45b40726 |
children | 9c6af8d0bdb6 |
files | xennet/xennet_common.c xennet/xennet_rx.c |
line diff
1.1 --- a/xennet/xennet_common.c Tue Feb 12 20:22:42 2013 +1100 1.2 +++ b/xennet/xennet_common.c Tue Feb 12 20:44:22 2013 +1100 1.3 @@ -381,51 +381,55 @@ XenNet_Connect(PVOID context, BOOLEAN su 1.4 /* continue with setup so all the flags and capabilities are correct */ 1.5 } 1.6 1.7 - for (i = 0; i <= 5 && xi->backend_state != XenbusStateInitialising && xi->backend_state != XenbusStateInitWait && xi->backend_state != XenbusStateInitialised; i++) { 1.8 - FUNCTION_MSG("Waiting for XenbusStateInitXxx\n"); 1.9 - KeWaitForSingleObject(&xi->backend_event, Executive, KernelMode, FALSE, NULL); 1.10 - } 1.11 - if (xi->backend_state != XenbusStateInitialising && xi->backend_state != XenbusStateInitWait && xi->backend_state != XenbusStateInitialised) { 1.12 - FUNCTION_MSG("Backend state timeout\n"); 1.13 - return STATUS_UNSUCCESSFUL; 1.14 - } 1.15 - if (!NT_SUCCESS(status = XnBindEvent(xi->handle, &xi->event_channel, XenNet_HandleEvent_DIRQL, xi))) { 1.16 - FUNCTION_MSG("Cannot allocate event channel\n"); 1.17 - return STATUS_UNSUCCESSFUL; 1.18 - } 1.19 - FUNCTION_MSG("event_channel = %d\n", xi->event_channel); 1.20 - status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "event-channel", xi->event_channel); 1.21 - xi->tx_sring = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENNET_POOL_TAG); 1.22 - if (!xi->tx_sring) { 1.23 - FUNCTION_MSG("Cannot allocate tx_sring\n"); 1.24 - return STATUS_UNSUCCESSFUL; 1.25 + if (xi->device_state != DEVICE_STATE_INACTIVE) { 1.26 + for (i = 0; i <= 5 && xi->backend_state != XenbusStateInitialising && xi->backend_state != XenbusStateInitWait && xi->backend_state != XenbusStateInitialised; i++) { 1.27 + FUNCTION_MSG("Waiting for XenbusStateInitXxx\n"); 1.28 + if (xi->backend_state == XenbusStateClosed) { 1.29 + status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "state", XenbusStateInitialising); 1.30 + } 1.31 + KeWaitForSingleObject(&xi->backend_event, Executive, KernelMode, FALSE, NULL); 1.32 + } 1.33 + if (xi->backend_state != XenbusStateInitialising && xi->backend_state != XenbusStateInitWait && xi->backend_state != XenbusStateInitialised) { 1.34 + FUNCTION_MSG("Backend state timeout\n"); 1.35 + return STATUS_UNSUCCESSFUL; 1.36 + } 1.37 + if (!NT_SUCCESS(status = XnBindEvent(xi->handle, &xi->event_channel, XenNet_HandleEvent_DIRQL, xi))) { 1.38 + FUNCTION_MSG("Cannot allocate event channel\n"); 1.39 + return STATUS_UNSUCCESSFUL; 1.40 + } 1.41 + FUNCTION_MSG("event_channel = %d\n", xi->event_channel); 1.42 + status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "event-channel", xi->event_channel); 1.43 + xi->tx_sring = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENNET_POOL_TAG); 1.44 + if (!xi->tx_sring) { 1.45 + FUNCTION_MSG("Cannot allocate tx_sring\n"); 1.46 + return STATUS_UNSUCCESSFUL; 1.47 + } 1.48 + SHARED_RING_INIT(xi->tx_sring); 1.49 + FRONT_RING_INIT(&xi->tx_ring, xi->tx_sring, PAGE_SIZE); 1.50 + pfn = (PFN_NUMBER)(MmGetPhysicalAddress(xi->tx_sring).QuadPart >> PAGE_SHIFT); 1.51 + FUNCTION_MSG("tx sring pfn = %d\n", (ULONG)pfn); 1.52 + xi->tx_sring_gref = XnGrantAccess(xi->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, XENNET_POOL_TAG); 1.53 + FUNCTION_MSG("tx sring_gref = %d\n", xi->tx_sring_gref); 1.54 + status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "tx-ring-ref", xi->tx_sring_gref); 1.55 + xi->rx_sring = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENNET_POOL_TAG); 1.56 + if (!xi->rx_sring) { 1.57 + FUNCTION_MSG("Cannot allocate rx_sring\n"); 1.58 + return STATUS_UNSUCCESSFUL; 1.59 + } 1.60 + SHARED_RING_INIT(xi->rx_sring); 1.61 + FRONT_RING_INIT(&xi->rx_ring, xi->rx_sring, PAGE_SIZE); 1.62 + pfn = (PFN_NUMBER)(MmGetPhysicalAddress(xi->rx_sring).QuadPart >> PAGE_SHIFT); 1.63 + FUNCTION_MSG("rx sring pfn = %d\n", (ULONG)pfn); 1.64 + xi->rx_sring_gref = XnGrantAccess(xi->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, XENNET_POOL_TAG); 1.65 + FUNCTION_MSG("rx sring_gref = %d\n", xi->rx_sring_gref); 1.66 + status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "rx-ring-ref", xi->rx_sring_gref); 1.67 + 1.68 + status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "request-rx-copy", 1); 1.69 + status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "request-rx-notify", 1); 1.70 + status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-no-csum-offload", !xi->frontend_csum_supported); 1.71 + status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-sg", (int)xi->frontend_sg_supported); 1.72 + status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-gso-tcpv4", !!xi->frontend_gso_value); 1.73 } 1.74 - SHARED_RING_INIT(xi->tx_sring); 1.75 - FRONT_RING_INIT(&xi->tx_ring, xi->tx_sring, PAGE_SIZE); 1.76 - pfn = (PFN_NUMBER)(MmGetPhysicalAddress(xi->tx_sring).QuadPart >> PAGE_SHIFT); 1.77 - FUNCTION_MSG("tx sring pfn = %d\n", (ULONG)pfn); 1.78 - xi->tx_sring_gref = XnGrantAccess(xi->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, XENNET_POOL_TAG); 1.79 - FUNCTION_MSG("tx sring_gref = %d\n", xi->tx_sring_gref); 1.80 - status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "tx-ring-ref", xi->tx_sring_gref); 1.81 - xi->rx_sring = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENNET_POOL_TAG); 1.82 - if (!xi->rx_sring) { 1.83 - FUNCTION_MSG("Cannot allocate rx_sring\n"); 1.84 - return STATUS_UNSUCCESSFUL; 1.85 - } 1.86 - SHARED_RING_INIT(xi->rx_sring); 1.87 - FRONT_RING_INIT(&xi->rx_ring, xi->rx_sring, PAGE_SIZE); 1.88 - pfn = (PFN_NUMBER)(MmGetPhysicalAddress(xi->rx_sring).QuadPart >> PAGE_SHIFT); 1.89 - FUNCTION_MSG("rx sring pfn = %d\n", (ULONG)pfn); 1.90 - xi->rx_sring_gref = XnGrantAccess(xi->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, XENNET_POOL_TAG); 1.91 - FUNCTION_MSG("rx sring_gref = %d\n", xi->rx_sring_gref); 1.92 - status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "rx-ring-ref", xi->rx_sring_gref); 1.93 - 1.94 - status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "request-rx-copy", 1); 1.95 - status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "request-rx-notify", 1); 1.96 - status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-no-csum-offload", !xi->frontend_csum_supported); 1.97 - status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-sg", (int)xi->frontend_sg_supported); 1.98 - status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "feature-gso-tcpv4", !!xi->frontend_gso_value); 1.99 - 1.100 status = XnReadInt32(xi->handle, XN_BASE_BACKEND, "feature-sg", &tmp_ulong); 1.101 if (tmp_ulong) { 1.102 xi->backend_sg_supported = TRUE; 1.103 @@ -482,18 +486,20 @@ XenNet_Connect(PVOID context, BOOLEAN su 1.104 xi->curr_mac_addr[0], xi->curr_mac_addr[1], xi->curr_mac_addr[2], 1.105 xi->curr_mac_addr[3], xi->curr_mac_addr[4], xi->curr_mac_addr[5]); 1.106 1.107 - status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "state", XenbusStateConnected); 1.108 + if (xi->device_state != DEVICE_STATE_INACTIVE) { 1.109 + status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "state", XenbusStateConnected); 1.110 1.111 - for (i = 0; i <= 5 && xi->backend_state != XenbusStateConnected; i++) { 1.112 - FUNCTION_MSG("Waiting for XenbusStateConnected\n"); 1.113 - KeWaitForSingleObject(&xi->backend_event, Executive, KernelMode, FALSE, NULL); 1.114 + for (i = 0; i <= 5 && xi->backend_state != XenbusStateConnected; i++) { 1.115 + FUNCTION_MSG("Waiting for XenbusStateConnected\n"); 1.116 + KeWaitForSingleObject(&xi->backend_event, Executive, KernelMode, FALSE, NULL); 1.117 + } 1.118 + if (xi->backend_state != XenbusStateConnected) { 1.119 + FUNCTION_MSG("Backend state timeout\n"); 1.120 + return STATUS_UNSUCCESSFUL; 1.121 + } 1.122 + XenNet_TxInit(xi); 1.123 + XenNet_RxInit(xi); 1.124 } 1.125 - if (xi->backend_state != XenbusStateConnected) { 1.126 - FUNCTION_MSG("Backend state timeout\n"); 1.127 - return STATUS_UNSUCCESSFUL; 1.128 - } 1.129 - XenNet_TxInit(xi); 1.130 - XenNet_RxInit(xi); 1.131 1.132 /* we don't set device_state = DEVICE_STATE_ACTIVE here - has to be done during init once ndis is ready */ 1.133 1.134 @@ -506,35 +512,35 @@ XenNet_Disconnect(PVOID context, BOOLEAN 1.135 //PFN_NUMBER pfn; 1.136 NTSTATUS status; 1.137 1.138 - if (xi->device_state != DEVICE_STATE_ACTIVE) { 1.139 - FUNCTION_MSG("state not DEVICE_STATE_ACTIVE, is %d instead\n", xi->device_state); 1.140 + if (xi->device_state != DEVICE_STATE_ACTIVE && xi->device_state != DEVICE_STATE_INACTIVE) { 1.141 + FUNCTION_MSG("state not DEVICE_STATE_(IN)ACTIVE, is %d instead\n", xi->device_state); 1.142 FUNCTION_EXIT(); 1.143 return STATUS_SUCCESS; 1.144 } 1.145 - xi->device_state = DEVICE_STATE_DISCONNECTING; 1.146 - status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "state", XenbusStateClosing); 1.147 - while (xi->backend_state != XenbusStateClosing && xi->backend_state != XenbusStateClosed) { 1.148 - FUNCTION_MSG("Waiting for XenbusStateClosing/Closed\n"); 1.149 - KeWaitForSingleObject(&xi->backend_event, Executive, KernelMode, FALSE, NULL); 1.150 - } 1.151 - status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "state", XenbusStateClosed); 1.152 - while (xi->backend_state != XenbusStateClosed) { 1.153 - FUNCTION_MSG("Waiting for XenbusStateClosed\n"); 1.154 - KeWaitForSingleObject(&xi->backend_event, Executive, KernelMode, FALSE, NULL); 1.155 + if (xi->device_state != DEVICE_STATE_INACTIVE) { 1.156 + xi->device_state = DEVICE_STATE_DISCONNECTING; 1.157 + status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "state", XenbusStateClosing); 1.158 + while (xi->backend_state != XenbusStateClosing && xi->backend_state != XenbusStateClosed) { 1.159 + FUNCTION_MSG("Waiting for XenbusStateClosing/Closed\n"); 1.160 + KeWaitForSingleObject(&xi->backend_event, Executive, KernelMode, FALSE, NULL); 1.161 + } 1.162 + status = XnWriteInt32(xi->handle, XN_BASE_FRONTEND, "state", XenbusStateClosed); 1.163 + while (xi->backend_state != XenbusStateClosed) { 1.164 + FUNCTION_MSG("Waiting for XenbusStateClosed\n"); 1.165 + KeWaitForSingleObject(&xi->backend_event, Executive, KernelMode, FALSE, NULL); 1.166 + } 1.167 + XnUnbindEvent(xi->handle, xi->event_channel); 1.168 + 1.169 + #if NTDDI_VERSION < WINXP 1.170 + KeFlushQueuedDpcs(); 1.171 + #endif 1.172 + XenNet_TxShutdown(xi); 1.173 + XenNet_RxShutdown(xi); 1.174 + XnEndAccess(xi->handle, xi->rx_sring_gref, FALSE, XENNET_POOL_TAG); 1.175 + ExFreePoolWithTag(xi->rx_sring, XENNET_POOL_TAG); 1.176 + XnEndAccess(xi->handle, xi->tx_sring_gref, FALSE, XENNET_POOL_TAG); 1.177 + ExFreePoolWithTag(xi->tx_sring, XENNET_POOL_TAG); 1.178 } 1.179 - XnUnbindEvent(xi->handle, xi->event_channel); 1.180 - 1.181 -#if NTDDI_VERSION < WINXP 1.182 - KeFlushQueuedDpcs(); 1.183 -#endif 1.184 - XenNet_TxShutdown(xi); 1.185 - XenNet_RxShutdown(xi); 1.186 - //pfn = (PFN_NUMBER)(MmGetPhysicalAddress(xi->rx_sring).QuadPart >> PAGE_SHIFT); 1.187 - XnEndAccess(xi->handle, xi->rx_sring_gref, FALSE, XENNET_POOL_TAG); 1.188 - ExFreePoolWithTag(xi->rx_sring, XENNET_POOL_TAG); 1.189 - //pfn = (PFN_NUMBER)(MmGetPhysicalAddress(xi->tx_sring).QuadPart >> PAGE_SHIFT); 1.190 - XnEndAccess(xi->handle, xi->tx_sring_gref, FALSE, XENNET_POOL_TAG); 1.191 - ExFreePoolWithTag(xi->tx_sring, XENNET_POOL_TAG); 1.192 if (!suspend) { 1.193 XnCloseDevice(xi->handle); 1.194 } 1.195 @@ -565,8 +571,11 @@ XenNet_DeviceCallback(PVOID context, ULO 1.196 break; 1.197 case XN_DEVICE_CALLBACK_RESUME: 1.198 FUNCTION_MSG("XN_DEVICE_CALLBACK_RESUME"); 1.199 + xi->device_state = DEVICE_STATE_INITIALISING; 1.200 XenNet_Connect(xi, TRUE); 1.201 - //xi->device_state = DEVICE_STATE_ACTIVE; 1.202 + if (xi->device_state != DEVICE_STATE_INACTIVE) { 1.203 + xi->device_state = DEVICE_STATE_ACTIVE; 1.204 + } 1.205 KeInsertQueueDpc(&xi->rxtx_dpc, NULL, NULL); 1.206 break; 1.207 }
2.1 --- a/xennet/xennet_rx.c Tue Feb 12 20:22:42 2013 +1100 2.2 +++ b/xennet/xennet_rx.c Tue Feb 12 20:44:22 2013 +1100 2.3 @@ -710,8 +710,6 @@ done: 2.4 return; 2.5 } 2.6 2.7 -ULONG outstanding1 = 0, outstanding2 = 0, outstanding3 = 0; 2.8 - 2.9 #if NTDDI_VERSION < NTDDI_VISTA 2.10 /* called at DISPATCH_LEVEL */ 2.11 /* it's okay for return packet to be called while resume_state != RUNNING as the packet will simply be added back to the freelist, the grants will be fixed later */ 2.12 @@ -741,8 +739,7 @@ XenNet_ReturnPacket(NDIS_HANDLE adapter_ 2.13 } 2.14 2.15 NdisFreePacket(packet); 2.16 - outstanding1--; 2.17 - outstanding3--; 2.18 + InterlockedDecrement(&xi->rx_outstanding); 2.19 if (!xi->rx_outstanding && xi->device_state != DEVICE_STATE_ACTIVE) 2.20 KeSetEvent(&xi->rx_idle_event, IO_NO_INCREMENT, FALSE); 2.21 //FUNCTION_EXIT(); 2.22 @@ -1077,17 +1074,12 @@ XenNet_RxBufferCheck(struct xennet_info 2.23 last_header_only_packet = packet; 2.24 PACKET_NEXT_PACKET(packet) = NULL; 2.25 } 2.26 - outstanding1++; 2.27 - if (status == NDIS_STATUS_RESOURCES) 2.28 - outstanding2++; 2.29 packets[packet_count++] = packet; 2.30 - InterlockedIncrement(&xi->rx_outstanding); 2.31 /* if we indicate a packet with NDIS_STATUS_RESOURCES then any following packet can't be NDIS_STATUS_SUCCESS */ 2.32 if (packet_count == MAXIMUM_PACKETS_PER_INDICATE || !rc.first_packet 2.33 || (NDIS_GET_PACKET_STATUS(rc.first_packet) == NDIS_STATUS_SUCCESS 2.34 && status == NDIS_STATUS_RESOURCES)) { 2.35 NdisMIndicateReceivePacket(xi->adapter_handle, packets, packet_count); 2.36 - outstanding3 += packet_count; 2.37 packet_count = 0; 2.38 } 2.39 } 2.40 @@ -1096,7 +1088,6 @@ XenNet_RxBufferCheck(struct xennet_info 2.41 PNDIS_PACKET packet = first_header_only_packet; 2.42 first_header_only_packet = PACKET_NEXT_PACKET(packet); 2.43 XenNet_ReturnPacket(xi, packet); 2.44 - outstanding2--; 2.45 } 2.46 #else 2.47 if (rc.first_nbl) { 2.48 @@ -1225,33 +1216,26 @@ XenNet_RxInit(xennet_info_t *xi) { 2.49 VOID 2.50 XenNet_RxShutdown(xennet_info_t *xi) { 2.51 KIRQL old_irql; 2.52 - UNREFERENCED_PARAMETER(xi); 2.53 + UNREFERENCED_PARAMETER(xi); 2.54 2.55 FUNCTION_ENTER(); 2.56 2.57 KeAcquireSpinLock(&xi->rx_lock, &old_irql); 2.58 while (xi->rx_outstanding) { 2.59 - FUNCTION_MSG("Waiting for all packets to be returned\n"); 2.60 + FUNCTION_MSG("Waiting for %d packets to be returned\n", xi->rx_outstanding); 2.61 KeReleaseSpinLock(&xi->rx_lock, old_irql); 2.62 -FUNCTION_MSG("AAA\n"); 2.63 KeWaitForSingleObject(&xi->rx_idle_event, Executive, KernelMode, FALSE, NULL); 2.64 -FUNCTION_MSG("BBB\n"); 2.65 KeAcquireSpinLock(&xi->rx_lock, &old_irql); 2.66 -FUNCTION_MSG("CCC\n"); 2.67 } 2.68 KeReleaseSpinLock(&xi->rx_lock, old_irql); 2.69 -FUNCTION_MSG("DDD\n"); 2.70 2.71 XenNet_BufferFree(xi); 2.72 -FUNCTION_MSG("EEE\n"); 2.73 2.74 stack_delete(xi->rx_pb_stack, NULL, NULL); 2.75 stack_delete(xi->rx_hb_stack, NULL, NULL); 2.76 2.77 -FUNCTION_MSG("FFF\n"); 2.78 2.79 ExFreePoolWithTag(xi->rxpi, XENNET_POOL_TAG); 2.80 -FUNCTION_MSG("GGG\n"); 2.81 2.82 #if NTDDI_VERSION < NTDDI_VISTA 2.83 NdisFreePacketPool(xi->rx_packet_pool);