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);