win-pvdrivers

changeset 22:2e1ad5552529

xennet: get mac from backend; watch backend for state changes
author Andy Grover <andy@groveronline.com>
date Fri Nov 30 10:21:12 2007 -0800 (2007-11-30)
parents e2d29b60b744
children e4f0a0a21488
files xennet/xennet.c
line diff
     1.1 --- a/xennet/xennet.c	Thu Nov 29 16:06:20 2007 -0800
     1.2 +++ b/xennet/xennet.c	Fri Nov 30 10:21:12 2007 -0800
     1.3 @@ -18,6 +18,8 @@ along with this program; if not, write t
     1.4  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     1.5  */
     1.6  
     1.7 +#include <stdlib.h>
     1.8 +#include <io/xenbus.h>
     1.9  #include "xennet.h"
    1.10  
    1.11  #if !defined (NDIS51_MINIPORT)
    1.12 @@ -41,8 +43,8 @@ struct xennet_info
    1.13    WCHAR name[NAME_SIZE];
    1.14    NDIS_HANDLE adapter_handle;
    1.15    ULONG packet_filter;
    1.16 -  UCHAR perm_mac_addr[ETH_ALEN];
    1.17 -  UCHAR curr_mac_addr[ETH_ALEN];
    1.18 +  UINT8 perm_mac_addr[ETH_ALEN];
    1.19 +  UINT8 curr_mac_addr[ETH_ALEN];
    1.20  
    1.21    char Path[128];
    1.22    char BackendPath[128];
    1.23 @@ -74,6 +76,36 @@ typedef struct _wdf_device_info
    1.24  
    1.25  WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(wdf_device_info, GetWdfDeviceInfo)
    1.26  
    1.27 +/* This function copied from linux's lib/vsprintf.c, see it for attribution */
    1.28 +static unsigned long
    1.29 +simple_strtoul(const char *cp,char **endp,unsigned int base)
    1.30 +{
    1.31 +  unsigned long result = 0,value;
    1.32 +
    1.33 +  if (!base) {
    1.34 +    base = 10;
    1.35 +    if (*cp == '0') {
    1.36 +      base = 8;
    1.37 +      cp++;
    1.38 +      if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
    1.39 +        cp++;
    1.40 +        base = 16;
    1.41 +      }
    1.42 +    }
    1.43 +  } else if (base == 16) {
    1.44 +    if (cp[0] == '0' && toupper(cp[1]) == 'X')
    1.45 +    cp += 2;
    1.46 +  }
    1.47 +  while (isxdigit(*cp) &&
    1.48 +  (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
    1.49 +    result = result*base + value;
    1.50 +    cp++;
    1.51 +  }
    1.52 +  if (endp)
    1.53 +  *endp = (char *)cp;
    1.54 +  return result;
    1.55 + }
    1.56 +
    1.57  static PMDL
    1.58  AllocatePages(int Pages)
    1.59  {
    1.60 @@ -124,6 +156,65 @@ XenNet_Interrupt(
    1.61    return TRUE;
    1.62  }
    1.63  
    1.64 +static VOID
    1.65 +XenNet_BackEndStateHandler(char *Path, PVOID Data)
    1.66 +{
    1.67 +  struct xennet_info *xi = Data;
    1.68 +  char *Value;
    1.69 +  int be_state;
    1.70 +
    1.71 +  xi->XenBusInterface.Read(xi->XenBusInterface.InterfaceHeader.Context,
    1.72 +    XBT_NIL, Path, &Value);
    1.73 +  be_state = atoi(Value);
    1.74 +  ExFreePool(Value);
    1.75 +
    1.76 +  switch (be_state)
    1.77 +  {
    1.78 +  case XenbusStateUnknown:
    1.79 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Unknown\n"));  
    1.80 +    break;
    1.81 +
    1.82 +  case XenbusStateInitialising:
    1.83 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialising\n"));  
    1.84 +    break;
    1.85 +
    1.86 +  case XenbusStateInitWait:
    1.87 +    KdPrint((__DRIVER_NAME "     Backend State Changed to InitWait\n"));  
    1.88 +
    1.89 +    /* do stuff here */
    1.90 +
    1.91 +    KdPrint((__DRIVER_NAME "     Set Frontend state to Initialised\n"));
    1.92 +    break;
    1.93 +
    1.94 +  case XenbusStateInitialised:
    1.95 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialised\n"));
    1.96 +    // create the device
    1.97 +    break;
    1.98 +
    1.99 +  case XenbusStateConnected:
   1.100 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Connected\n"));  
   1.101 +
   1.102 +    /* do more stuff here */
   1.103 +
   1.104 +    KdPrint((__DRIVER_NAME "     Set Frontend state to Connected\n"));
   1.105 +    break;
   1.106 +
   1.107 +  case XenbusStateClosing:
   1.108 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Closing\n"));  
   1.109 +    break;
   1.110 +
   1.111 +  case XenbusStateClosed:
   1.112 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Closed\n"));  
   1.113 +    break;
   1.114 +
   1.115 +  default:
   1.116 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Undefined = %d\n", be_state));
   1.117 +    break;
   1.118 +  }
   1.119 +
   1.120 +}
   1.121 +
   1.122 +
   1.123  VOID
   1.124  XenNet_Halt(
   1.125    IN NDIS_HANDLE MiniportAdapterContext
   1.126 @@ -304,7 +395,7 @@ XenNet_Init(
   1.127        XBT_NIL, TmpPath, &Value);
   1.128      if (!Value)
   1.129      {
   1.130 -      KdPrint((__DRIVER_NAME "     Read Failed\n"));
   1.131 +      KdPrint((__DRIVER_NAME "    backend Read Failed\n"));
   1.132      }
   1.133      else
   1.134      {
   1.135 @@ -313,6 +404,41 @@ XenNet_Init(
   1.136      }
   1.137      ExFreePool(Value);
   1.138  
   1.139 +    /* Add watch on backend state */
   1.140 +    RtlStringCbCopyA(TmpPath, ARRAY_SIZE(TmpPath), xi->BackendPath);
   1.141 +    RtlStringCbCatA(TmpPath, ARRAY_SIZE(TmpPath), "/state");
   1.142 +    xi->XenBusInterface.AddWatch(xi->XenBusInterface.InterfaceHeader.Context,
   1.143 +      XBT_NIL, TmpPath, XenNet_BackEndStateHandler, xi);
   1.144 +
   1.145 +    /* get mac address */
   1.146 +    RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath), "%s/mac", xi->Path);
   1.147 +    xi->XenBusInterface.Read(xi->XenBusInterface.InterfaceHeader.Context,
   1.148 +      XBT_NIL, TmpPath, &Value);
   1.149 +    if (!Value)
   1.150 +    {
   1.151 +      KdPrint((__DRIVER_NAME "    mac Read Failed\n"));
   1.152 +    }
   1.153 +    else
   1.154 +    {
   1.155 +      char *s, *e;
   1.156 +      int i;
   1.157 +
   1.158 +      s = Value;
   1.159 +
   1.160 +      for (i = 0; i < ETH_ALEN; i++) {
   1.161 +        xi->perm_mac_addr[i] = (UINT8)simple_strtoul(s, &e, 16);
   1.162 +        if ((s == e) || (*e != ((i == ETH_ALEN-1) ? '\0' : ':'))) {
   1.163 +          KdPrint((__DRIVER_NAME "Error parsing MAC address\n"));
   1.164 +          ExFreePool(Value);
   1.165 +          ExFreePool(vif_devs);
   1.166 +          status = NDIS_STATUS_FAILURE;
   1.167 +          goto err;
   1.168 +        }
   1.169 +        s = e + 1;
   1.170 +      }
   1.171 +    }
   1.172 +    ExFreePool(Value);
   1.173 +
   1.174      //XenVbd_HotPlugHandler(buffer, NULL);
   1.175      //ExFreePoolWithTag(bdDevices[i], XENPCI_POOL_TAG);
   1.176    }