|
@@ -1,5 +1,4 @@
|
|
|
/*
|
|
|
- *
|
|
|
* Copyright (c) 2009, Microsoft Corporation.
|
|
|
*
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
@@ -18,20 +17,15 @@
|
|
|
* Authors:
|
|
|
* Haiyang Zhang <haiyangz@microsoft.com>
|
|
|
* Hank Janssen <hjanssen@microsoft.com>
|
|
|
- *
|
|
|
*/
|
|
|
-
|
|
|
#include <linux/kernel.h>
|
|
|
#include <linux/highmem.h>
|
|
|
-#include <asm/kmap_types.h>
|
|
|
-#include <asm/io.h>
|
|
|
-
|
|
|
+#include <linux/io.h>
|
|
|
#include "osd.h"
|
|
|
#include "logging.h"
|
|
|
#include "NetVscApi.h"
|
|
|
#include "RndisFilter.h"
|
|
|
|
|
|
-
|
|
|
/* Data types */
|
|
|
struct rndis_filter_driver_object {
|
|
|
/* The original driver */
|
|
@@ -46,25 +40,27 @@ enum rndis_device_state {
|
|
|
};
|
|
|
|
|
|
struct rndis_device {
|
|
|
- struct NETVSC_DEVICE *NetDevice;
|
|
|
+ struct NETVSC_DEVICE *NetDevice;
|
|
|
|
|
|
enum rndis_device_state State;
|
|
|
- u32 LinkStatus;
|
|
|
+ u32 LinkStatus;
|
|
|
atomic_t NewRequestId;
|
|
|
|
|
|
spinlock_t request_lock;
|
|
|
- LIST_ENTRY RequestList;
|
|
|
+ LIST_ENTRY RequestList;
|
|
|
|
|
|
- unsigned char HwMacAddr[HW_MACADDR_LEN];
|
|
|
+ unsigned char HwMacAddr[HW_MACADDR_LEN];
|
|
|
};
|
|
|
|
|
|
-
|
|
|
struct rndis_request {
|
|
|
- LIST_ENTRY ListEntry;
|
|
|
+ LIST_ENTRY ListEntry;
|
|
|
struct osd_waitevent *WaitEvent;
|
|
|
|
|
|
- /* FIXME: We assumed a fixed size response here. If we do ever need to handle a bigger response, */
|
|
|
- /* we can either define a max response message or add a response buffer variable above this field */
|
|
|
+ /*
|
|
|
+ * FIXME: We assumed a fixed size response here. If we do ever need to
|
|
|
+ * handle a bigger response, we can either define a max response
|
|
|
+ * message or add a response buffer variable above this field
|
|
|
+ */
|
|
|
struct rndis_message ResponseMessage;
|
|
|
|
|
|
/* Simplify allocation by having a netvsc packet inline */
|
|
@@ -76,133 +72,41 @@ struct rndis_request {
|
|
|
|
|
|
|
|
|
struct rndis_filter_packet {
|
|
|
- void *CompletionContext;
|
|
|
- PFN_ON_SENDRECVCOMPLETION OnCompletion;
|
|
|
-
|
|
|
+ void *CompletionContext;
|
|
|
+ PFN_ON_SENDRECVCOMPLETION OnCompletion;
|
|
|
struct rndis_message Message;
|
|
|
};
|
|
|
|
|
|
|
|
|
-/* Internal routines */
|
|
|
+static int RndisFilterOnDeviceAdd(struct hv_device *Device,
|
|
|
+ void *AdditionalInfo);
|
|
|
|
|
|
-static int
|
|
|
-RndisFilterSendRequest(
|
|
|
- struct rndis_device *Device,
|
|
|
- struct rndis_request *Request
|
|
|
- );
|
|
|
+static int RndisFilterOnDeviceRemove(struct hv_device *Device);
|
|
|
|
|
|
-static void RndisFilterReceiveResponse(struct rndis_device *Device,
|
|
|
- struct rndis_message *Response);
|
|
|
+static void RndisFilterOnCleanup(struct hv_driver *Driver);
|
|
|
|
|
|
-static void RndisFilterReceiveIndicateStatus(struct rndis_device *Device,
|
|
|
- struct rndis_message *Response);
|
|
|
+static int RndisFilterOnOpen(struct hv_device *Device);
|
|
|
|
|
|
-static void RndisFilterReceiveData(struct rndis_device *Device,
|
|
|
- struct rndis_message *Message,
|
|
|
- struct hv_netvsc_packet *Packet);
|
|
|
-
|
|
|
-static int RndisFilterOnReceive(
|
|
|
- struct hv_device *Device,
|
|
|
- struct hv_netvsc_packet *Packet
|
|
|
- );
|
|
|
-
|
|
|
-static int
|
|
|
-RndisFilterQueryDevice(
|
|
|
- struct rndis_device *Device,
|
|
|
- u32 Oid,
|
|
|
- void *Result,
|
|
|
- u32 *ResultSize
|
|
|
- );
|
|
|
-
|
|
|
-static inline int
|
|
|
-RndisFilterQueryDeviceMac(
|
|
|
- struct rndis_device *Device
|
|
|
- );
|
|
|
-
|
|
|
-static inline int
|
|
|
-RndisFilterQueryDeviceLinkStatus(
|
|
|
- struct rndis_device *Device
|
|
|
- );
|
|
|
-
|
|
|
-static int
|
|
|
-RndisFilterSetPacketFilter(
|
|
|
- struct rndis_device *Device,
|
|
|
- u32 NewFilter
|
|
|
- );
|
|
|
-
|
|
|
-static int
|
|
|
-RndisFilterInitDevice(
|
|
|
- struct rndis_device *Device
|
|
|
- );
|
|
|
-
|
|
|
-static int
|
|
|
-RndisFilterOpenDevice(
|
|
|
- struct rndis_device *Device
|
|
|
- );
|
|
|
-
|
|
|
-static int
|
|
|
-RndisFilterCloseDevice(
|
|
|
- struct rndis_device *Device
|
|
|
- );
|
|
|
-
|
|
|
-static int
|
|
|
-RndisFilterOnDeviceAdd(
|
|
|
- struct hv_device *Device,
|
|
|
- void *AdditionalInfo
|
|
|
- );
|
|
|
-
|
|
|
-static int
|
|
|
-RndisFilterOnDeviceRemove(
|
|
|
- struct hv_device *Device
|
|
|
- );
|
|
|
-
|
|
|
-static void
|
|
|
-RndisFilterOnCleanup(
|
|
|
- struct hv_driver *Driver
|
|
|
- );
|
|
|
-
|
|
|
-static int
|
|
|
-RndisFilterOnOpen(
|
|
|
- struct hv_device *Device
|
|
|
- );
|
|
|
-
|
|
|
-static int
|
|
|
-RndisFilterOnClose(
|
|
|
- struct hv_device *Device
|
|
|
- );
|
|
|
-
|
|
|
-static int
|
|
|
-RndisFilterOnSend(
|
|
|
- struct hv_device *Device,
|
|
|
- struct hv_netvsc_packet *Packet
|
|
|
- );
|
|
|
-
|
|
|
-static void
|
|
|
-RndisFilterOnSendCompletion(
|
|
|
- void *Context
|
|
|
- );
|
|
|
-
|
|
|
-static void
|
|
|
-RndisFilterOnSendRequestCompletion(
|
|
|
- void *Context
|
|
|
- );
|
|
|
-
|
|
|
-
|
|
|
-/* Global var */
|
|
|
+static int RndisFilterOnClose(struct hv_device *Device);
|
|
|
+
|
|
|
+static int RndisFilterOnSend(struct hv_device *Device,
|
|
|
+ struct hv_netvsc_packet *Packet);
|
|
|
+
|
|
|
+static void RndisFilterOnSendCompletion(void *Context);
|
|
|
+
|
|
|
+static void RndisFilterOnSendRequestCompletion(void *Context);
|
|
|
|
|
|
|
|
|
/* The one and only */
|
|
|
static struct rndis_filter_driver_object gRndisFilter;
|
|
|
|
|
|
-static inline struct rndis_device *GetRndisDevice(void)
|
|
|
+static struct rndis_device *GetRndisDevice(void)
|
|
|
{
|
|
|
struct rndis_device *device;
|
|
|
|
|
|
device = kzalloc(sizeof(struct rndis_device), GFP_KERNEL);
|
|
|
if (!device)
|
|
|
- {
|
|
|
return NULL;
|
|
|
- }
|
|
|
|
|
|
spin_lock_init(&device->request_lock);
|
|
|
|
|
@@ -213,12 +117,9 @@ static inline struct rndis_device *GetRndisDevice(void)
|
|
|
return device;
|
|
|
}
|
|
|
|
|
|
-static inline void PutRndisDevice(struct rndis_device *Device)
|
|
|
-{
|
|
|
- kfree(Device);
|
|
|
-}
|
|
|
-
|
|
|
-static inline struct rndis_request *GetRndisRequest(struct rndis_device *Device, u32 MessageType, u32 MessageLength)
|
|
|
+static struct rndis_request *GetRndisRequest(struct rndis_device *Device,
|
|
|
+ u32 MessageType,
|
|
|
+ u32 MessageLength)
|
|
|
{
|
|
|
struct rndis_request *request;
|
|
|
struct rndis_message *rndisMessage;
|
|
@@ -227,13 +128,10 @@ static inline struct rndis_request *GetRndisRequest(struct rndis_device *Device,
|
|
|
|
|
|
request = kzalloc(sizeof(struct rndis_request), GFP_KERNEL);
|
|
|
if (!request)
|
|
|
- {
|
|
|
return NULL;
|
|
|
- }
|
|
|
|
|
|
request->WaitEvent = osd_WaitEventCreate();
|
|
|
- if (!request->WaitEvent)
|
|
|
- {
|
|
|
+ if (!request->WaitEvent) {
|
|
|
kfree(request);
|
|
|
return NULL;
|
|
|
}
|
|
@@ -242,8 +140,11 @@ static inline struct rndis_request *GetRndisRequest(struct rndis_device *Device,
|
|
|
rndisMessage->NdisMessageType = MessageType;
|
|
|
rndisMessage->MessageLength = MessageLength;
|
|
|
|
|
|
- /* Set the request id. This field is always after the rndis header for request/response packet types so */
|
|
|
- /* we just used the SetRequest as a template */
|
|
|
+ /*
|
|
|
+ * Set the request id. This field is always after the rndis header for
|
|
|
+ * request/response packet types so we just used the SetRequest as a
|
|
|
+ * template
|
|
|
+ */
|
|
|
set = &rndisMessage->Message.SetRequest;
|
|
|
set->RequestId = atomic_inc_return(&Device->NewRequestId);
|
|
|
|
|
@@ -255,7 +156,8 @@ static inline struct rndis_request *GetRndisRequest(struct rndis_device *Device,
|
|
|
return request;
|
|
|
}
|
|
|
|
|
|
-static inline void PutRndisRequest(struct rndis_device *Device, struct rndis_request *Request)
|
|
|
+static void PutRndisRequest(struct rndis_device *Device,
|
|
|
+ struct rndis_request *Request)
|
|
|
{
|
|
|
unsigned long flags;
|
|
|
|
|
@@ -267,24 +169,29 @@ static inline void PutRndisRequest(struct rndis_device *Device, struct rndis_req
|
|
|
kfree(Request);
|
|
|
}
|
|
|
|
|
|
-static inline void DumpRndisMessage(struct rndis_message *RndisMessage)
|
|
|
+static void DumpRndisMessage(struct rndis_message *RndisMessage)
|
|
|
{
|
|
|
- switch (RndisMessage->NdisMessageType)
|
|
|
- {
|
|
|
+ switch (RndisMessage->NdisMessageType) {
|
|
|
case REMOTE_NDIS_PACKET_MSG:
|
|
|
- DPRINT_DBG(NETVSC, "REMOTE_NDIS_PACKET_MSG (len %u, data offset %u data len %u, # oob %u, oob offset %u, oob len %u, pkt offset %u, pkt len %u",
|
|
|
- RndisMessage->MessageLength,
|
|
|
- RndisMessage->Message.Packet.DataOffset,
|
|
|
- RndisMessage->Message.Packet.DataLength,
|
|
|
- RndisMessage->Message.Packet.NumOOBDataElements,
|
|
|
- RndisMessage->Message.Packet.OOBDataOffset,
|
|
|
- RndisMessage->Message.Packet.OOBDataLength,
|
|
|
- RndisMessage->Message.Packet.PerPacketInfoOffset,
|
|
|
- RndisMessage->Message.Packet.PerPacketInfoLength);
|
|
|
+ DPRINT_DBG(NETVSC, "REMOTE_NDIS_PACKET_MSG (len %u, "
|
|
|
+ "data offset %u data len %u, # oob %u, "
|
|
|
+ "oob offset %u, oob len %u, pkt offset %u, "
|
|
|
+ "pkt len %u",
|
|
|
+ RndisMessage->MessageLength,
|
|
|
+ RndisMessage->Message.Packet.DataOffset,
|
|
|
+ RndisMessage->Message.Packet.DataLength,
|
|
|
+ RndisMessage->Message.Packet.NumOOBDataElements,
|
|
|
+ RndisMessage->Message.Packet.OOBDataOffset,
|
|
|
+ RndisMessage->Message.Packet.OOBDataLength,
|
|
|
+ RndisMessage->Message.Packet.PerPacketInfoOffset,
|
|
|
+ RndisMessage->Message.Packet.PerPacketInfoLength);
|
|
|
break;
|
|
|
|
|
|
case REMOTE_NDIS_INITIALIZE_CMPLT:
|
|
|
- DPRINT_DBG(NETVSC, "REMOTE_NDIS_INITIALIZE_CMPLT (len %u, id 0x%x, status 0x%x, major %d, minor %d, device flags %d, max xfer size 0x%x, max pkts %u, pkt aligned %u)",
|
|
|
+ DPRINT_DBG(NETVSC, "REMOTE_NDIS_INITIALIZE_CMPLT "
|
|
|
+ "(len %u, id 0x%x, status 0x%x, major %d, minor %d, "
|
|
|
+ "device flags %d, max xfer size 0x%x, max pkts %u, "
|
|
|
+ "pkt aligned %u)",
|
|
|
RndisMessage->MessageLength,
|
|
|
RndisMessage->Message.InitializeComplete.RequestId,
|
|
|
RndisMessage->Message.InitializeComplete.Status,
|
|
@@ -297,7 +204,9 @@ static inline void DumpRndisMessage(struct rndis_message *RndisMessage)
|
|
|
break;
|
|
|
|
|
|
case REMOTE_NDIS_QUERY_CMPLT:
|
|
|
- DPRINT_DBG(NETVSC, "REMOTE_NDIS_QUERY_CMPLT (len %u, id 0x%x, status 0x%x, buf len %u, buf offset %u)",
|
|
|
+ DPRINT_DBG(NETVSC, "REMOTE_NDIS_QUERY_CMPLT "
|
|
|
+ "(len %u, id 0x%x, status 0x%x, buf len %u, "
|
|
|
+ "buf offset %u)",
|
|
|
RndisMessage->MessageLength,
|
|
|
RndisMessage->Message.QueryComplete.RequestId,
|
|
|
RndisMessage->Message.QueryComplete.Status,
|
|
@@ -306,14 +215,16 @@ static inline void DumpRndisMessage(struct rndis_message *RndisMessage)
|
|
|
break;
|
|
|
|
|
|
case REMOTE_NDIS_SET_CMPLT:
|
|
|
- DPRINT_DBG(NETVSC, "REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)",
|
|
|
+ DPRINT_DBG(NETVSC,
|
|
|
+ "REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)",
|
|
|
RndisMessage->MessageLength,
|
|
|
RndisMessage->Message.SetComplete.RequestId,
|
|
|
RndisMessage->Message.SetComplete.Status);
|
|
|
break;
|
|
|
|
|
|
case REMOTE_NDIS_INDICATE_STATUS_MSG:
|
|
|
- DPRINT_DBG(NETVSC, "REMOTE_NDIS_INDICATE_STATUS_MSG (len %u, status 0x%x, buf len %u, buf offset %u)",
|
|
|
+ DPRINT_DBG(NETVSC, "REMOTE_NDIS_INDICATE_STATUS_MSG "
|
|
|
+ "(len %u, status 0x%x, buf len %u, buf offset %u)",
|
|
|
RndisMessage->MessageLength,
|
|
|
RndisMessage->Message.IndicateStatus.Status,
|
|
|
RndisMessage->Message.IndicateStatus.StatusBufferLength,
|
|
@@ -328,13 +239,10 @@ static inline void DumpRndisMessage(struct rndis_message *RndisMessage)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static int
|
|
|
-RndisFilterSendRequest(
|
|
|
- struct rndis_device *Device,
|
|
|
- struct rndis_request *Request
|
|
|
- )
|
|
|
+static int RndisFilterSendRequest(struct rndis_device *Device,
|
|
|
+ struct rndis_request *Request)
|
|
|
{
|
|
|
- int ret=0;
|
|
|
+ int ret;
|
|
|
struct hv_netvsc_packet *packet;
|
|
|
|
|
|
DPRINT_ENTER(NETVSC);
|
|
@@ -346,12 +254,15 @@ RndisFilterSendRequest(
|
|
|
packet->TotalDataBufferLength = Request->RequestMessage.MessageLength;
|
|
|
packet->PageBufferCount = 1;
|
|
|
|
|
|
- packet->PageBuffers[0].Pfn = virt_to_phys(&Request->RequestMessage) >> PAGE_SHIFT;
|
|
|
+ packet->PageBuffers[0].Pfn = virt_to_phys(&Request->RequestMessage) >>
|
|
|
+ PAGE_SHIFT;
|
|
|
packet->PageBuffers[0].Length = Request->RequestMessage.MessageLength;
|
|
|
- packet->PageBuffers[0].Offset = (unsigned long)&Request->RequestMessage & (PAGE_SIZE -1);
|
|
|
+ packet->PageBuffers[0].Offset =
|
|
|
+ (unsigned long)&Request->RequestMessage & (PAGE_SIZE - 1);
|
|
|
|
|
|
packet->Completion.Send.SendCompletionContext = Request;/* packet; */
|
|
|
- packet->Completion.Send.OnSendCompletion = RndisFilterOnSendRequestCompletion;
|
|
|
+ packet->Completion.Send.OnSendCompletion =
|
|
|
+ RndisFilterOnSendRequestCompletion;
|
|
|
packet->Completion.Send.SendCompletionTid = (unsigned long)Device;
|
|
|
|
|
|
ret = gRndisFilter.InnerDriver.OnSend(Device->NetDevice->Device, packet);
|
|
@@ -359,7 +270,6 @@ RndisFilterSendRequest(
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
static void RndisFilterReceiveResponse(struct rndis_device *Device,
|
|
|
struct rndis_message *Response)
|
|
|
{
|
|
@@ -372,15 +282,22 @@ static void RndisFilterReceiveResponse(struct rndis_device *Device,
|
|
|
DPRINT_ENTER(NETVSC);
|
|
|
|
|
|
spin_lock_irqsave(&Device->request_lock, flags);
|
|
|
- ITERATE_LIST_ENTRIES(anchor, curr, &Device->RequestList)
|
|
|
- {
|
|
|
- request = CONTAINING_RECORD(curr, struct rndis_request, ListEntry);
|
|
|
-
|
|
|
- /* All request/response message contains RequestId as the 1st field */
|
|
|
- if (request->RequestMessage.Message.InitializeRequest.RequestId == Response->Message.InitializeComplete.RequestId)
|
|
|
- {
|
|
|
- DPRINT_DBG(NETVSC, "found rndis request for this response (id 0x%x req type 0x%x res type 0x%x)",
|
|
|
- request->RequestMessage.Message.InitializeRequest.RequestId, request->RequestMessage.NdisMessageType, Response->NdisMessageType);
|
|
|
+ ITERATE_LIST_ENTRIES(anchor, curr, &Device->RequestList) {
|
|
|
+ request = CONTAINING_RECORD(curr, struct rndis_request,
|
|
|
+ ListEntry);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * All request/response message contains RequestId as the 1st
|
|
|
+ * field
|
|
|
+ */
|
|
|
+ if (request->RequestMessage.Message.InitializeRequest.RequestId
|
|
|
+ == Response->Message.InitializeComplete.RequestId) {
|
|
|
+ DPRINT_DBG(NETVSC, "found rndis request for "
|
|
|
+ "this response (id 0x%x req type 0x%x res "
|
|
|
+ "type 0x%x)",
|
|
|
+ request->RequestMessage.Message.InitializeRequest.RequestId,
|
|
|
+ request->RequestMessage.NdisMessageType,
|
|
|
+ Response->NdisMessageType);
|
|
|
|
|
|
found = true;
|
|
|
break;
|
|
@@ -388,32 +305,31 @@ static void RndisFilterReceiveResponse(struct rndis_device *Device,
|
|
|
}
|
|
|
spin_unlock_irqrestore(&Device->request_lock, flags);
|
|
|
|
|
|
- if (found)
|
|
|
- {
|
|
|
- if (Response->MessageLength <= sizeof(struct rndis_message))
|
|
|
- {
|
|
|
- memcpy(&request->ResponseMessage, Response, Response->MessageLength);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- DPRINT_ERR(NETVSC, "rndis response buffer overflow detected (size %u max %zu)", Response->MessageLength, sizeof(struct rndis_filter_packet));
|
|
|
-
|
|
|
- if (Response->NdisMessageType == REMOTE_NDIS_RESET_CMPLT) /* does not have a request id field */
|
|
|
- {
|
|
|
+ if (found) {
|
|
|
+ if (Response->MessageLength <= sizeof(struct rndis_message)) {
|
|
|
+ memcpy(&request->ResponseMessage, Response,
|
|
|
+ Response->MessageLength);
|
|
|
+ } else {
|
|
|
+ DPRINT_ERR(NETVSC, "rndis response buffer overflow "
|
|
|
+ "detected (size %u max %zu)",
|
|
|
+ Response->MessageLength,
|
|
|
+ sizeof(struct rndis_filter_packet));
|
|
|
+
|
|
|
+ if (Response->NdisMessageType ==
|
|
|
+ REMOTE_NDIS_RESET_CMPLT) {
|
|
|
+ /* does not have a request id field */
|
|
|
request->ResponseMessage.Message.ResetComplete.Status = STATUS_BUFFER_OVERFLOW;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
+ } else {
|
|
|
request->ResponseMessage.Message.InitializeComplete.Status = STATUS_BUFFER_OVERFLOW;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
osd_WaitEventSet(request->WaitEvent);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- DPRINT_ERR(NETVSC, "no rndis request found for this response (id 0x%x res type 0x%x)",
|
|
|
- Response->Message.InitializeComplete.RequestId, Response->NdisMessageType);
|
|
|
+ } else {
|
|
|
+ DPRINT_ERR(NETVSC, "no rndis request found for this response "
|
|
|
+ "(id 0x%x res type 0x%x)",
|
|
|
+ Response->Message.InitializeComplete.RequestId,
|
|
|
+ Response->NdisMessageType);
|
|
|
}
|
|
|
|
|
|
DPRINT_EXIT(NETVSC);
|
|
@@ -422,19 +338,17 @@ static void RndisFilterReceiveResponse(struct rndis_device *Device,
|
|
|
static void RndisFilterReceiveIndicateStatus(struct rndis_device *Device,
|
|
|
struct rndis_message *Response)
|
|
|
{
|
|
|
- struct rndis_indicate_status *indicate = &Response->Message.IndicateStatus;
|
|
|
+ struct rndis_indicate_status *indicate =
|
|
|
+ &Response->Message.IndicateStatus;
|
|
|
|
|
|
- if (indicate->Status == RNDIS_STATUS_MEDIA_CONNECT)
|
|
|
- {
|
|
|
+ if (indicate->Status == RNDIS_STATUS_MEDIA_CONNECT) {
|
|
|
gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 1);
|
|
|
- }
|
|
|
- else if (indicate->Status == RNDIS_STATUS_MEDIA_DISCONNECT)
|
|
|
- {
|
|
|
+ } else if (indicate->Status == RNDIS_STATUS_MEDIA_DISCONNECT) {
|
|
|
gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 0);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- /* TODO: */
|
|
|
+ } else {
|
|
|
+ /*
|
|
|
+ * TODO:
|
|
|
+ */
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -448,12 +362,15 @@ static void RndisFilterReceiveData(struct rndis_device *Device,
|
|
|
DPRINT_ENTER(NETVSC);
|
|
|
|
|
|
/* empty ethernet frame ?? */
|
|
|
- ASSERT(Packet->PageBuffers[0].Length > RNDIS_MESSAGE_SIZE(struct rndis_packet));
|
|
|
+ ASSERT(Packet->PageBuffers[0].Length >
|
|
|
+ RNDIS_MESSAGE_SIZE(struct rndis_packet));
|
|
|
|
|
|
rndisPacket = &Message->Message.Packet;
|
|
|
|
|
|
- /* FIXME: Handle multiple rndis pkt msgs that maybe enclosed in this */
|
|
|
- /* netvsc packet (ie TotalDataBufferLength != MessageLength) */
|
|
|
+ /*
|
|
|
+ * FIXME: Handle multiple rndis pkt msgs that maybe enclosed in this
|
|
|
+ * netvsc packet (ie TotalDataBufferLength != MessageLength)
|
|
|
+ */
|
|
|
|
|
|
/* Remove the rndis header and pass it back up the stack */
|
|
|
dataOffset = RNDIS_HEADER_SIZE + rndisPacket->DataOffset;
|
|
@@ -464,18 +381,16 @@ static void RndisFilterReceiveData(struct rndis_device *Device,
|
|
|
|
|
|
Packet->IsDataPacket = true;
|
|
|
|
|
|
- gRndisFilter.InnerDriver.OnReceiveCallback(Device->NetDevice->Device, Packet);
|
|
|
+ gRndisFilter.InnerDriver.OnReceiveCallback(Device->NetDevice->Device,
|
|
|
+ Packet);
|
|
|
|
|
|
DPRINT_EXIT(NETVSC);
|
|
|
}
|
|
|
|
|
|
-static int
|
|
|
-RndisFilterOnReceive(
|
|
|
- struct hv_device *Device,
|
|
|
- struct hv_netvsc_packet *Packet
|
|
|
- )
|
|
|
+static int RndisFilterOnReceive(struct hv_device *Device,
|
|
|
+ struct hv_netvsc_packet *Packet)
|
|
|
{
|
|
|
- struct NETVSC_DEVICE *netDevice = (struct NETVSC_DEVICE*)Device->Extension;
|
|
|
+ struct NETVSC_DEVICE *netDevice = Device->Extension;
|
|
|
struct rndis_device *rndisDevice;
|
|
|
struct rndis_message rndisMessage;
|
|
|
struct rndis_message *rndisHeader;
|
|
@@ -484,74 +399,87 @@ RndisFilterOnReceive(
|
|
|
|
|
|
ASSERT(netDevice);
|
|
|
/* Make sure the rndis device state is initialized */
|
|
|
- if (!netDevice->Extension)
|
|
|
- {
|
|
|
- DPRINT_ERR(NETVSC, "got rndis message but no rndis device...dropping this message!");
|
|
|
+ if (!netDevice->Extension) {
|
|
|
+ DPRINT_ERR(NETVSC, "got rndis message but no rndis device..."
|
|
|
+ "dropping this message!");
|
|
|
DPRINT_EXIT(NETVSC);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- rndisDevice = (struct rndis_device*)netDevice->Extension;
|
|
|
- if (rndisDevice->State == RNDIS_DEV_UNINITIALIZED)
|
|
|
- {
|
|
|
- DPRINT_ERR(NETVSC, "got rndis message but rndis device uninitialized...dropping this message!");
|
|
|
+ rndisDevice = (struct rndis_device *)netDevice->Extension;
|
|
|
+ if (rndisDevice->State == RNDIS_DEV_UNINITIALIZED) {
|
|
|
+ DPRINT_ERR(NETVSC, "got rndis message but rndis device "
|
|
|
+ "uninitialized...dropping this message!");
|
|
|
DPRINT_EXIT(NETVSC);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- rndisHeader = (struct rndis_message *)kmap_atomic(pfn_to_page(Packet->PageBuffers[0].Pfn), KM_IRQ0);
|
|
|
+ rndisHeader = (struct rndis_message *)kmap_atomic(
|
|
|
+ pfn_to_page(Packet->PageBuffers[0].Pfn), KM_IRQ0);
|
|
|
|
|
|
- rndisHeader = (void*)((unsigned long)rndisHeader + Packet->PageBuffers[0].Offset);
|
|
|
+ rndisHeader = (void *)((unsigned long)rndisHeader +
|
|
|
+ Packet->PageBuffers[0].Offset);
|
|
|
|
|
|
/* Make sure we got a valid rndis message */
|
|
|
- /* FIXME: There seems to be a bug in set completion msg where its MessageLength is 16 bytes but */
|
|
|
- /* the ByteCount field in the xfer page range shows 52 bytes */
|
|
|
+ /*
|
|
|
+ * FIXME: There seems to be a bug in set completion msg where its
|
|
|
+ * MessageLength is 16 bytes but the ByteCount field in the xfer page
|
|
|
+ * range shows 52 bytes
|
|
|
+ * */
|
|
|
#if 0
|
|
|
- if ( Packet->TotalDataBufferLength != rndisHeader->MessageLength )
|
|
|
- {
|
|
|
- kunmap_atomic(rndisHeader - Packet->PageBuffers[0].Offset, KM_IRQ0);
|
|
|
-
|
|
|
- DPRINT_ERR(NETVSC, "invalid rndis message? (expected %u bytes got %u)...dropping this message!",
|
|
|
- rndisHeader->MessageLength, Packet->TotalDataBufferLength);
|
|
|
+ if (Packet->TotalDataBufferLength != rndisHeader->MessageLength) {
|
|
|
+ kunmap_atomic(rndisHeader - Packet->PageBuffers[0].Offset,
|
|
|
+ KM_IRQ0);
|
|
|
+
|
|
|
+ DPRINT_ERR(NETVSC, "invalid rndis message? (expected %u "
|
|
|
+ "bytes got %u)...dropping this message!",
|
|
|
+ rndisHeader->MessageLength,
|
|
|
+ Packet->TotalDataBufferLength);
|
|
|
DPRINT_EXIT(NETVSC);
|
|
|
return -1;
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
- if ((rndisHeader->NdisMessageType != REMOTE_NDIS_PACKET_MSG) && (rndisHeader->MessageLength > sizeof(struct rndis_message)))
|
|
|
- {
|
|
|
- DPRINT_ERR(NETVSC, "incoming rndis message buffer overflow detected (got %u, max %zu)...marking it an error!",
|
|
|
- rndisHeader->MessageLength, sizeof(struct rndis_message));
|
|
|
+ if ((rndisHeader->NdisMessageType != REMOTE_NDIS_PACKET_MSG) &&
|
|
|
+ (rndisHeader->MessageLength > sizeof(struct rndis_message))) {
|
|
|
+ DPRINT_ERR(NETVSC, "incoming rndis message buffer overflow "
|
|
|
+ "detected (got %u, max %zu)...marking it an error!",
|
|
|
+ rndisHeader->MessageLength,
|
|
|
+ sizeof(struct rndis_message));
|
|
|
}
|
|
|
|
|
|
- memcpy(&rndisMessage, rndisHeader, (rndisHeader->MessageLength > sizeof(struct rndis_message))?sizeof(struct rndis_message):rndisHeader->MessageLength);
|
|
|
+ memcpy(&rndisMessage, rndisHeader,
|
|
|
+ (rndisHeader->MessageLength > sizeof(struct rndis_message)) ?
|
|
|
+ sizeof(struct rndis_message) :
|
|
|
+ rndisHeader->MessageLength);
|
|
|
|
|
|
kunmap_atomic(rndisHeader - Packet->PageBuffers[0].Offset, KM_IRQ0);
|
|
|
|
|
|
DumpRndisMessage(&rndisMessage);
|
|
|
|
|
|
- switch (rndisMessage.NdisMessageType)
|
|
|
- {
|
|
|
- /* data msg */
|
|
|
+ switch (rndisMessage.NdisMessageType) {
|
|
|
case REMOTE_NDIS_PACKET_MSG:
|
|
|
+ /* data msg */
|
|
|
RndisFilterReceiveData(rndisDevice, &rndisMessage, Packet);
|
|
|
break;
|
|
|
|
|
|
- /* completion msgs */
|
|
|
case REMOTE_NDIS_INITIALIZE_CMPLT:
|
|
|
case REMOTE_NDIS_QUERY_CMPLT:
|
|
|
case REMOTE_NDIS_SET_CMPLT:
|
|
|
/* case REMOTE_NDIS_RESET_CMPLT: */
|
|
|
/* case REMOTE_NDIS_KEEPALIVE_CMPLT: */
|
|
|
+ /* completion msgs */
|
|
|
RndisFilterReceiveResponse(rndisDevice, &rndisMessage);
|
|
|
break;
|
|
|
|
|
|
- /* notification msgs */
|
|
|
case REMOTE_NDIS_INDICATE_STATUS_MSG:
|
|
|
+ /* notification msgs */
|
|
|
RndisFilterReceiveIndicateStatus(rndisDevice, &rndisMessage);
|
|
|
break;
|
|
|
default:
|
|
|
- DPRINT_ERR(NETVSC, "unhandled rndis message (type %u len %u)", rndisMessage.NdisMessageType, rndisMessage.MessageLength);
|
|
|
+ DPRINT_ERR(NETVSC, "unhandled rndis message (type %u len %u)",
|
|
|
+ rndisMessage.NdisMessageType,
|
|
|
+ rndisMessage.MessageLength);
|
|
|
break;
|
|
|
}
|
|
|
|
|
@@ -559,29 +487,23 @@ RndisFilterOnReceive(
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-static int
|
|
|
-RndisFilterQueryDevice(
|
|
|
- struct rndis_device *Device,
|
|
|
- u32 Oid,
|
|
|
- void *Result,
|
|
|
- u32 *ResultSize
|
|
|
- )
|
|
|
+static int RndisFilterQueryDevice(struct rndis_device *Device, u32 Oid,
|
|
|
+ void *Result, u32 *ResultSize)
|
|
|
{
|
|
|
struct rndis_request *request;
|
|
|
u32 inresultSize = *ResultSize;
|
|
|
struct rndis_query_request *query;
|
|
|
struct rndis_query_complete *queryComplete;
|
|
|
- int ret=0;
|
|
|
+ int ret = 0;
|
|
|
|
|
|
DPRINT_ENTER(NETVSC);
|
|
|
|
|
|
ASSERT(Result);
|
|
|
|
|
|
*ResultSize = 0;
|
|
|
- request = GetRndisRequest(Device, REMOTE_NDIS_QUERY_MSG, RNDIS_MESSAGE_SIZE(struct rndis_query_request));
|
|
|
- if (!request)
|
|
|
- {
|
|
|
+ request = GetRndisRequest(Device, REMOTE_NDIS_QUERY_MSG,
|
|
|
+ RNDIS_MESSAGE_SIZE(struct rndis_query_request));
|
|
|
+ if (!request) {
|
|
|
ret = -1;
|
|
|
goto Cleanup;
|
|
|
}
|
|
@@ -595,62 +517,53 @@ RndisFilterQueryDevice(
|
|
|
|
|
|
ret = RndisFilterSendRequest(Device, request);
|
|
|
if (ret != 0)
|
|
|
- {
|
|
|
goto Cleanup;
|
|
|
- }
|
|
|
|
|
|
osd_WaitEventWait(request->WaitEvent);
|
|
|
|
|
|
/* Copy the response back */
|
|
|
queryComplete = &request->ResponseMessage.Message.QueryComplete;
|
|
|
|
|
|
- if (queryComplete->InformationBufferLength > inresultSize)
|
|
|
- {
|
|
|
+ if (queryComplete->InformationBufferLength > inresultSize) {
|
|
|
ret = -1;
|
|
|
goto Cleanup;
|
|
|
}
|
|
|
|
|
|
memcpy(Result,
|
|
|
- (void*)((unsigned long)queryComplete + queryComplete->InformationBufferOffset),
|
|
|
- queryComplete->InformationBufferLength);
|
|
|
+ (void *)((unsigned long)queryComplete +
|
|
|
+ queryComplete->InformationBufferOffset),
|
|
|
+ queryComplete->InformationBufferLength);
|
|
|
|
|
|
*ResultSize = queryComplete->InformationBufferLength;
|
|
|
|
|
|
Cleanup:
|
|
|
if (request)
|
|
|
- {
|
|
|
PutRndisRequest(Device, request);
|
|
|
- }
|
|
|
DPRINT_EXIT(NETVSC);
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static inline int RndisFilterQueryDeviceMac(struct rndis_device *Device)
|
|
|
+static int RndisFilterQueryDeviceMac(struct rndis_device *Device)
|
|
|
{
|
|
|
- u32 size=HW_MACADDR_LEN;
|
|
|
+ u32 size = HW_MACADDR_LEN;
|
|
|
|
|
|
return RndisFilterQueryDevice(Device,
|
|
|
- RNDIS_OID_802_3_PERMANENT_ADDRESS,
|
|
|
- Device->HwMacAddr,
|
|
|
- &size);
|
|
|
+ RNDIS_OID_802_3_PERMANENT_ADDRESS,
|
|
|
+ Device->HwMacAddr, &size);
|
|
|
}
|
|
|
|
|
|
-static inline int RndisFilterQueryDeviceLinkStatus(struct rndis_device *Device)
|
|
|
+static int RndisFilterQueryDeviceLinkStatus(struct rndis_device *Device)
|
|
|
{
|
|
|
- u32 size=sizeof(u32);
|
|
|
+ u32 size = sizeof(u32);
|
|
|
|
|
|
return RndisFilterQueryDevice(Device,
|
|
|
- RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
|
|
|
- &Device->LinkStatus,
|
|
|
- &size);
|
|
|
+ RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
|
|
|
+ &Device->LinkStatus, &size);
|
|
|
}
|
|
|
|
|
|
-static int
|
|
|
-RndisFilterSetPacketFilter(
|
|
|
- struct rndis_device *Device,
|
|
|
- u32 NewFilter
|
|
|
- )
|
|
|
+static int RndisFilterSetPacketFilter(struct rndis_device *Device,
|
|
|
+ u32 NewFilter)
|
|
|
{
|
|
|
struct rndis_request *request;
|
|
|
struct rndis_set_request *set;
|
|
@@ -660,11 +573,13 @@ RndisFilterSetPacketFilter(
|
|
|
|
|
|
DPRINT_ENTER(NETVSC);
|
|
|
|
|
|
- ASSERT(RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32) <= sizeof(struct rndis_message));
|
|
|
+ ASSERT(RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32) <=
|
|
|
+ sizeof(struct rndis_message));
|
|
|
|
|
|
- request = GetRndisRequest(Device, REMOTE_NDIS_SET_MSG, RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32));
|
|
|
- if (!request)
|
|
|
- {
|
|
|
+ request = GetRndisRequest(Device, REMOTE_NDIS_SET_MSG,
|
|
|
+ RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
|
|
|
+ sizeof(u32));
|
|
|
+ if (!request) {
|
|
|
ret = -1;
|
|
|
goto Cleanup;
|
|
|
}
|
|
@@ -675,37 +590,32 @@ RndisFilterSetPacketFilter(
|
|
|
set->InformationBufferLength = sizeof(u32);
|
|
|
set->InformationBufferOffset = sizeof(struct rndis_set_request);
|
|
|
|
|
|
- memcpy((void*)(unsigned long)set + sizeof(struct rndis_set_request), &NewFilter, sizeof(u32));
|
|
|
+ memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request),
|
|
|
+ &NewFilter, sizeof(u32));
|
|
|
|
|
|
ret = RndisFilterSendRequest(Device, request);
|
|
|
if (ret != 0)
|
|
|
- {
|
|
|
goto Cleanup;
|
|
|
- }
|
|
|
|
|
|
ret = osd_WaitEventWaitEx(request->WaitEvent, 2000/*2sec*/);
|
|
|
- if (!ret)
|
|
|
- {
|
|
|
+ if (!ret) {
|
|
|
ret = -1;
|
|
|
DPRINT_ERR(NETVSC, "timeout before we got a set response...");
|
|
|
- /* We cant deallocate the request since we may still receive a send completion for it. */
|
|
|
+ /*
|
|
|
+ * We cant deallocate the request since we may still receive a
|
|
|
+ * send completion for it.
|
|
|
+ */
|
|
|
goto Exit;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
+ } else {
|
|
|
if (ret > 0)
|
|
|
- {
|
|
|
ret = 0;
|
|
|
- }
|
|
|
setComplete = &request->ResponseMessage.Message.SetComplete;
|
|
|
status = setComplete->Status;
|
|
|
}
|
|
|
|
|
|
Cleanup:
|
|
|
if (request)
|
|
|
- {
|
|
|
PutRndisRequest(Device, request);
|
|
|
- }
|
|
|
Exit:
|
|
|
DPRINT_EXIT(NETVSC);
|
|
|
|
|
@@ -716,7 +626,8 @@ int RndisFilterInit(struct netvsc_driver *Driver)
|
|
|
{
|
|
|
DPRINT_ENTER(NETVSC);
|
|
|
|
|
|
- DPRINT_DBG(NETVSC, "sizeof(struct rndis_filter_packet) == %zd", sizeof(struct rndis_filter_packet));
|
|
|
+ DPRINT_DBG(NETVSC, "sizeof(struct rndis_filter_packet) == %zd",
|
|
|
+ sizeof(struct rndis_filter_packet));
|
|
|
|
|
|
Driver->RequestExtSize = sizeof(struct rndis_filter_packet);
|
|
|
Driver->AdditionalRequestPageBufferCount = 1; /* For rndis header */
|
|
@@ -732,14 +643,16 @@ int RndisFilterInit(struct netvsc_driver *Driver)
|
|
|
|
|
|
/* Save the original dispatch handlers before we override it */
|
|
|
gRndisFilter.InnerDriver.Base.OnDeviceAdd = Driver->Base.OnDeviceAdd;
|
|
|
- gRndisFilter.InnerDriver.Base.OnDeviceRemove = Driver->Base.OnDeviceRemove;
|
|
|
+ gRndisFilter.InnerDriver.Base.OnDeviceRemove =
|
|
|
+ Driver->Base.OnDeviceRemove;
|
|
|
gRndisFilter.InnerDriver.Base.OnCleanup = Driver->Base.OnCleanup;
|
|
|
|
|
|
ASSERT(Driver->OnSend);
|
|
|
ASSERT(Driver->OnReceiveCallback);
|
|
|
gRndisFilter.InnerDriver.OnSend = Driver->OnSend;
|
|
|
gRndisFilter.InnerDriver.OnReceiveCallback = Driver->OnReceiveCallback;
|
|
|
- gRndisFilter.InnerDriver.OnLinkStatusChanged = Driver->OnLinkStatusChanged;
|
|
|
+ gRndisFilter.InnerDriver.OnLinkStatusChanged =
|
|
|
+ Driver->OnLinkStatusChanged;
|
|
|
|
|
|
/* Override */
|
|
|
Driver->Base.OnDeviceAdd = RndisFilterOnDeviceAdd;
|
|
@@ -766,9 +679,9 @@ static int RndisFilterInitDevice(struct rndis_device *Device)
|
|
|
|
|
|
DPRINT_ENTER(NETVSC);
|
|
|
|
|
|
- request = GetRndisRequest(Device, REMOTE_NDIS_INITIALIZE_MSG, RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
|
|
|
- if (!request)
|
|
|
- {
|
|
|
+ request = GetRndisRequest(Device, REMOTE_NDIS_INITIALIZE_MSG,
|
|
|
+ RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
|
|
|
+ if (!request) {
|
|
|
ret = -1;
|
|
|
goto Cleanup;
|
|
|
}
|
|
@@ -777,13 +690,13 @@ static int RndisFilterInitDevice(struct rndis_device *Device)
|
|
|
init = &request->RequestMessage.Message.InitializeRequest;
|
|
|
init->MajorVersion = RNDIS_MAJOR_VERSION;
|
|
|
init->MinorVersion = RNDIS_MINOR_VERSION;
|
|
|
- init->MaxTransferSize = 2048; /* FIXME: Use 1536 - rounded ethernet frame size */
|
|
|
+ /* FIXME: Use 1536 - rounded ethernet frame size */
|
|
|
+ init->MaxTransferSize = 2048;
|
|
|
|
|
|
Device->State = RNDIS_DEV_INITIALIZING;
|
|
|
|
|
|
ret = RndisFilterSendRequest(Device, request);
|
|
|
- if (ret != 0)
|
|
|
- {
|
|
|
+ if (ret != 0) {
|
|
|
Device->State = RNDIS_DEV_UNINITIALIZED;
|
|
|
goto Cleanup;
|
|
|
}
|
|
@@ -792,22 +705,17 @@ static int RndisFilterInitDevice(struct rndis_device *Device)
|
|
|
|
|
|
initComplete = &request->ResponseMessage.Message.InitializeComplete;
|
|
|
status = initComplete->Status;
|
|
|
- if (status == RNDIS_STATUS_SUCCESS)
|
|
|
- {
|
|
|
+ if (status == RNDIS_STATUS_SUCCESS) {
|
|
|
Device->State = RNDIS_DEV_INITIALIZED;
|
|
|
ret = 0;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
+ } else {
|
|
|
Device->State = RNDIS_DEV_UNINITIALIZED;
|
|
|
ret = -1;
|
|
|
}
|
|
|
|
|
|
Cleanup:
|
|
|
if (request)
|
|
|
- {
|
|
|
PutRndisRequest(Device, request);
|
|
|
- }
|
|
|
DPRINT_EXIT(NETVSC);
|
|
|
|
|
|
return ret;
|
|
@@ -821,11 +729,10 @@ static void RndisFilterHaltDevice(struct rndis_device *Device)
|
|
|
DPRINT_ENTER(NETVSC);
|
|
|
|
|
|
/* Attempt to do a rndis device halt */
|
|
|
- request = GetRndisRequest(Device, REMOTE_NDIS_HALT_MSG, RNDIS_MESSAGE_SIZE(struct rndis_halt_request));
|
|
|
+ request = GetRndisRequest(Device, REMOTE_NDIS_HALT_MSG,
|
|
|
+ RNDIS_MESSAGE_SIZE(struct rndis_halt_request));
|
|
|
if (!request)
|
|
|
- {
|
|
|
goto Cleanup;
|
|
|
- }
|
|
|
|
|
|
/* Setup the rndis set */
|
|
|
halt = &request->RequestMessage.Message.HaltRequest;
|
|
@@ -838,28 +745,25 @@ static void RndisFilterHaltDevice(struct rndis_device *Device)
|
|
|
|
|
|
Cleanup:
|
|
|
if (request)
|
|
|
- {
|
|
|
PutRndisRequest(Device, request);
|
|
|
- }
|
|
|
DPRINT_EXIT(NETVSC);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
static int RndisFilterOpenDevice(struct rndis_device *Device)
|
|
|
{
|
|
|
- int ret=0;
|
|
|
+ int ret;
|
|
|
|
|
|
DPRINT_ENTER(NETVSC);
|
|
|
|
|
|
if (Device->State != RNDIS_DEV_INITIALIZED)
|
|
|
return 0;
|
|
|
|
|
|
- ret = RndisFilterSetPacketFilter(Device, NDIS_PACKET_TYPE_BROADCAST|NDIS_PACKET_TYPE_DIRECTED);
|
|
|
+ ret = RndisFilterSetPacketFilter(Device,
|
|
|
+ NDIS_PACKET_TYPE_BROADCAST |
|
|
|
+ NDIS_PACKET_TYPE_DIRECTED);
|
|
|
if (ret == 0)
|
|
|
- {
|
|
|
Device->State = RNDIS_DEV_DATAINITIALIZED;
|
|
|
- }
|
|
|
|
|
|
DPRINT_EXIT(NETVSC);
|
|
|
return ret;
|
|
@@ -876,53 +780,46 @@ static int RndisFilterCloseDevice(struct rndis_device *Device)
|
|
|
|
|
|
ret = RndisFilterSetPacketFilter(Device, 0);
|
|
|
if (ret == 0)
|
|
|
- {
|
|
|
Device->State = RNDIS_DEV_INITIALIZED;
|
|
|
- }
|
|
|
|
|
|
DPRINT_EXIT(NETVSC);
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-static int
|
|
|
-RndisFilterOnDeviceAdd(
|
|
|
- struct hv_device *Device,
|
|
|
- void *AdditionalInfo
|
|
|
- )
|
|
|
+static int RndisFilterOnDeviceAdd(struct hv_device *Device,
|
|
|
+ void *AdditionalInfo)
|
|
|
{
|
|
|
int ret;
|
|
|
struct NETVSC_DEVICE *netDevice;
|
|
|
struct rndis_device *rndisDevice;
|
|
|
- struct netvsc_device_info *deviceInfo = (struct netvsc_device_info *)AdditionalInfo;
|
|
|
+ struct netvsc_device_info *deviceInfo = AdditionalInfo;
|
|
|
|
|
|
DPRINT_ENTER(NETVSC);
|
|
|
|
|
|
rndisDevice = GetRndisDevice();
|
|
|
- if (!rndisDevice)
|
|
|
- {
|
|
|
+ if (!rndisDevice) {
|
|
|
DPRINT_EXIT(NETVSC);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
DPRINT_DBG(NETVSC, "rndis device object allocated - %p", rndisDevice);
|
|
|
|
|
|
- /* Let the inner driver handle this first to create the netvsc channel */
|
|
|
- /* NOTE! Once the channel is created, we may get a receive callback */
|
|
|
- /* (RndisFilterOnReceive()) before this call is completed */
|
|
|
+ /*
|
|
|
+ * Let the inner driver handle this first to create the netvsc channel
|
|
|
+ * NOTE! Once the channel is created, we may get a receive callback
|
|
|
+ * (RndisFilterOnReceive()) before this call is completed
|
|
|
+ */
|
|
|
ret = gRndisFilter.InnerDriver.Base.OnDeviceAdd(Device, AdditionalInfo);
|
|
|
- if (ret != 0)
|
|
|
- {
|
|
|
- PutRndisDevice(rndisDevice);
|
|
|
+ if (ret != 0) {
|
|
|
+ kfree(rndisDevice);
|
|
|
DPRINT_EXIT(NETVSC);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
|
|
|
/* Initialize the rndis device */
|
|
|
-
|
|
|
- netDevice = (struct NETVSC_DEVICE*)Device->Extension;
|
|
|
+ netDevice = Device->Extension;
|
|
|
ASSERT(netDevice);
|
|
|
ASSERT(netDevice->Device);
|
|
|
|
|
@@ -931,54 +828,54 @@ RndisFilterOnDeviceAdd(
|
|
|
|
|
|
/* Send the rndis initialization message */
|
|
|
ret = RndisFilterInitDevice(rndisDevice);
|
|
|
- if (ret != 0)
|
|
|
- {
|
|
|
- /* TODO: If rndis init failed, we will need to shut down the channel */
|
|
|
+ if (ret != 0) {
|
|
|
+ /*
|
|
|
+ * TODO: If rndis init failed, we will need to shut down the
|
|
|
+ * channel
|
|
|
+ */
|
|
|
}
|
|
|
|
|
|
/* Get the mac address */
|
|
|
ret = RndisFilterQueryDeviceMac(rndisDevice);
|
|
|
- if (ret != 0)
|
|
|
- {
|
|
|
- /* TODO: shutdown rndis device and the channel */
|
|
|
+ if (ret != 0) {
|
|
|
+ /*
|
|
|
+ * TODO: shutdown rndis device and the channel
|
|
|
+ */
|
|
|
}
|
|
|
|
|
|
DPRINT_INFO(NETVSC, "Device 0x%p mac addr %02x%02x%02x%02x%02x%02x",
|
|
|
- rndisDevice,
|
|
|
- rndisDevice->HwMacAddr[0],
|
|
|
- rndisDevice->HwMacAddr[1],
|
|
|
- rndisDevice->HwMacAddr[2],
|
|
|
- rndisDevice->HwMacAddr[3],
|
|
|
- rndisDevice->HwMacAddr[4],
|
|
|
- rndisDevice->HwMacAddr[5]);
|
|
|
+ rndisDevice,
|
|
|
+ rndisDevice->HwMacAddr[0],
|
|
|
+ rndisDevice->HwMacAddr[1],
|
|
|
+ rndisDevice->HwMacAddr[2],
|
|
|
+ rndisDevice->HwMacAddr[3],
|
|
|
+ rndisDevice->HwMacAddr[4],
|
|
|
+ rndisDevice->HwMacAddr[5]);
|
|
|
|
|
|
memcpy(deviceInfo->MacAddr, rndisDevice->HwMacAddr, HW_MACADDR_LEN);
|
|
|
|
|
|
RndisFilterQueryDeviceLinkStatus(rndisDevice);
|
|
|
|
|
|
deviceInfo->LinkState = rndisDevice->LinkStatus;
|
|
|
- DPRINT_INFO(NETVSC, "Device 0x%p link state %s", rndisDevice, ((deviceInfo->LinkState)?("down"):("up")));
|
|
|
+ DPRINT_INFO(NETVSC, "Device 0x%p link state %s", rndisDevice,
|
|
|
+ ((deviceInfo->LinkState) ? ("down") : ("up")));
|
|
|
|
|
|
DPRINT_EXIT(NETVSC);
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-static int
|
|
|
-RndisFilterOnDeviceRemove(
|
|
|
- struct hv_device *Device
|
|
|
- )
|
|
|
+static int RndisFilterOnDeviceRemove(struct hv_device *Device)
|
|
|
{
|
|
|
- struct NETVSC_DEVICE *netDevice = (struct NETVSC_DEVICE*)Device->Extension;
|
|
|
- struct rndis_device *rndisDevice = (struct rndis_device *)netDevice->Extension;
|
|
|
+ struct NETVSC_DEVICE *netDevice = Device->Extension;
|
|
|
+ struct rndis_device *rndisDevice = netDevice->Extension;
|
|
|
|
|
|
DPRINT_ENTER(NETVSC);
|
|
|
|
|
|
/* Halt and release the rndis device */
|
|
|
RndisFilterHaltDevice(rndisDevice);
|
|
|
|
|
|
- PutRndisDevice(rndisDevice);
|
|
|
+ kfree(rndisDevice);
|
|
|
netDevice->Extension = NULL;
|
|
|
|
|
|
/* Pass control to inner driver to remove the device */
|
|
@@ -989,61 +886,47 @@ RndisFilterOnDeviceRemove(
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-static void
|
|
|
-RndisFilterOnCleanup(
|
|
|
- struct hv_driver *Driver
|
|
|
- )
|
|
|
+static void RndisFilterOnCleanup(struct hv_driver *Driver)
|
|
|
{
|
|
|
DPRINT_ENTER(NETVSC);
|
|
|
|
|
|
DPRINT_EXIT(NETVSC);
|
|
|
}
|
|
|
|
|
|
-static int
|
|
|
-RndisFilterOnOpen(
|
|
|
- struct hv_device *Device
|
|
|
- )
|
|
|
+static int RndisFilterOnOpen(struct hv_device *Device)
|
|
|
{
|
|
|
int ret;
|
|
|
- struct NETVSC_DEVICE *netDevice = (struct NETVSC_DEVICE*)Device->Extension;
|
|
|
+ struct NETVSC_DEVICE *netDevice = Device->Extension;
|
|
|
|
|
|
DPRINT_ENTER(NETVSC);
|
|
|
|
|
|
ASSERT(netDevice);
|
|
|
- ret = RndisFilterOpenDevice((struct rndis_device *)netDevice->Extension);
|
|
|
+ ret = RndisFilterOpenDevice(netDevice->Extension);
|
|
|
|
|
|
DPRINT_EXIT(NETVSC);
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static int
|
|
|
-RndisFilterOnClose(
|
|
|
- struct hv_device *Device
|
|
|
- )
|
|
|
+static int RndisFilterOnClose(struct hv_device *Device)
|
|
|
{
|
|
|
int ret;
|
|
|
- struct NETVSC_DEVICE *netDevice = (struct NETVSC_DEVICE*)Device->Extension;
|
|
|
+ struct NETVSC_DEVICE *netDevice = Device->Extension;
|
|
|
|
|
|
DPRINT_ENTER(NETVSC);
|
|
|
|
|
|
ASSERT(netDevice);
|
|
|
- ret = RndisFilterCloseDevice((struct rndis_device *)netDevice->Extension);
|
|
|
+ ret = RndisFilterCloseDevice(netDevice->Extension);
|
|
|
|
|
|
DPRINT_EXIT(NETVSC);
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-static int
|
|
|
-RndisFilterOnSend(
|
|
|
- struct hv_device *Device,
|
|
|
- struct hv_netvsc_packet *Packet
|
|
|
- )
|
|
|
+static int RndisFilterOnSend(struct hv_device *Device,
|
|
|
+ struct hv_netvsc_packet *Packet)
|
|
|
{
|
|
|
- int ret=0;
|
|
|
+ int ret;
|
|
|
struct rndis_filter_packet *filterPacket;
|
|
|
struct rndis_message *rndisMessage;
|
|
|
struct rndis_packet *rndisPacket;
|
|
@@ -1061,31 +944,38 @@ RndisFilterOnSend(
|
|
|
rndisMessageSize = RNDIS_MESSAGE_SIZE(struct rndis_packet);
|
|
|
|
|
|
rndisMessage->NdisMessageType = REMOTE_NDIS_PACKET_MSG;
|
|
|
- rndisMessage->MessageLength = Packet->TotalDataBufferLength + rndisMessageSize;
|
|
|
+ rndisMessage->MessageLength = Packet->TotalDataBufferLength +
|
|
|
+ rndisMessageSize;
|
|
|
|
|
|
rndisPacket = &rndisMessage->Message.Packet;
|
|
|
rndisPacket->DataOffset = sizeof(struct rndis_packet);
|
|
|
rndisPacket->DataLength = Packet->TotalDataBufferLength;
|
|
|
|
|
|
Packet->IsDataPacket = true;
|
|
|
- Packet->PageBuffers[0].Pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT;
|
|
|
- Packet->PageBuffers[0].Offset = (unsigned long)rndisMessage & (PAGE_SIZE-1);
|
|
|
- Packet->PageBuffers[0].Length = rndisMessageSize;
|
|
|
+ Packet->PageBuffers[0].Pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT;
|
|
|
+ Packet->PageBuffers[0].Offset =
|
|
|
+ (unsigned long)rndisMessage & (PAGE_SIZE-1);
|
|
|
+ Packet->PageBuffers[0].Length = rndisMessageSize;
|
|
|
|
|
|
/* Save the packet send completion and context */
|
|
|
filterPacket->OnCompletion = Packet->Completion.Send.OnSendCompletion;
|
|
|
- filterPacket->CompletionContext = Packet->Completion.Send.SendCompletionContext;
|
|
|
+ filterPacket->CompletionContext =
|
|
|
+ Packet->Completion.Send.SendCompletionContext;
|
|
|
|
|
|
/* Use ours */
|
|
|
Packet->Completion.Send.OnSendCompletion = RndisFilterOnSendCompletion;
|
|
|
Packet->Completion.Send.SendCompletionContext = filterPacket;
|
|
|
|
|
|
ret = gRndisFilter.InnerDriver.OnSend(Device, Packet);
|
|
|
- if (ret != 0)
|
|
|
- {
|
|
|
- /* Reset the completion to originals to allow retries from above */
|
|
|
- Packet->Completion.Send.OnSendCompletion = filterPacket->OnCompletion;
|
|
|
- Packet->Completion.Send.SendCompletionContext = filterPacket->CompletionContext;
|
|
|
+ if (ret != 0) {
|
|
|
+ /*
|
|
|
+ * Reset the completion to originals to allow retries from
|
|
|
+ * above
|
|
|
+ */
|
|
|
+ Packet->Completion.Send.OnSendCompletion =
|
|
|
+ filterPacket->OnCompletion;
|
|
|
+ Packet->Completion.Send.SendCompletionContext =
|
|
|
+ filterPacket->CompletionContext;
|
|
|
}
|
|
|
|
|
|
DPRINT_EXIT(NETVSC);
|
|
@@ -1093,11 +983,9 @@ RndisFilterOnSend(
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static void
|
|
|
-RndisFilterOnSendCompletion(
|
|
|
- void *Context)
|
|
|
+static void RndisFilterOnSendCompletion(void *Context)
|
|
|
{
|
|
|
- struct rndis_filter_packet *filterPacket = (struct rndis_filter_packet *)Context;
|
|
|
+ struct rndis_filter_packet *filterPacket = Context;
|
|
|
|
|
|
DPRINT_ENTER(NETVSC);
|
|
|
|
|
@@ -1108,10 +996,7 @@ RndisFilterOnSendCompletion(
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void
|
|
|
-RndisFilterOnSendRequestCompletion(
|
|
|
- void *Context
|
|
|
- )
|
|
|
+static void RndisFilterOnSendRequestCompletion(void *Context)
|
|
|
{
|
|
|
DPRINT_ENTER(NETVSC);
|
|
|
|