iPXE
Functions | Variables
netvsc.c File Reference

Hyper-V network virtual service client. More...

#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <byteswap.h>
#include <ipxe/umalloc.h>
#include <ipxe/rndis.h>
#include <ipxe/vmbus.h>
#include "netvsc.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static int netvsc_control (struct netvsc_device *netvsc, unsigned int xrid, const void *data, size_t len)
 Send control message and wait for completion. More...
 
static int netvsc_completed (struct netvsc_device *netvsc __unused, const void *data __unused, size_t len __unused)
 Handle generic completion. More...
 
static int netvsc_initialise (struct netvsc_device *netvsc)
 Initialise communication. More...
 
static int netvsc_initialised (struct netvsc_device *netvsc, const void *data, size_t len)
 Handle initialisation completion. More...
 
static int netvsc_ndis_version (struct netvsc_device *netvsc)
 Set NDIS version. More...
 
static int netvsc_establish_buffer (struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
 Establish data buffer. More...
 
static int netvsc_rx_established_buffer (struct netvsc_device *netvsc, const void *data, size_t len)
 Handle establish receive data buffer completion. More...
 
static int netvsc_revoke_buffer (struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
 Revoke data buffer. More...
 
static int netvsc_recv_control (struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
 Handle received control packet. More...
 
static int netvsc_recv_data (struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len, struct list_head *list)
 Handle received data packet. More...
 
static int netvsc_recv_completion (struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
 Handle received completion packet. More...
 
static int netvsc_recv_cancellation (struct vmbus_device *vmdev, uint64_t xid)
 Handle received cancellation packet. More...
 
static void netvsc_poll (struct rndis_device *rndis)
 Poll for completed and received packets. More...
 
static int netvsc_transmit (struct rndis_device *rndis, struct io_buffer *iobuf)
 Transmit packet. More...
 
static void netvsc_cancel_transmit (struct netvsc_device *netvsc, struct io_buffer *iobuf, unsigned int tx_id)
 Cancel transmission. More...
 
static int netvsc_create_ring (struct netvsc_device *netvsc __unused, struct netvsc_ring *ring)
 Create descriptor ring. More...
 
static void netvsc_destroy_ring (struct netvsc_device *netvsc, struct netvsc_ring *ring, void(*discard)(struct netvsc_device *, struct io_buffer *, unsigned int))
 Destroy descriptor ring. More...
 
static int netvsc_buffer_copy (struct vmbus_xfer_pages *pages, void *data, size_t offset, size_t len)
 Copy data from data buffer. More...
 
static int netvsc_create_buffer (struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
 Create data buffer. More...
 
static void netvsc_destroy_buffer (struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
 Destroy data buffer. More...
 
static int netvsc_open (struct rndis_device *rndis)
 Open device. More...
 
static void netvsc_close (struct rndis_device *rndis)
 Close device. More...
 
static int netvsc_probe (struct vmbus_device *vmdev)
 Probe device. More...
 
static int netvsc_reset (struct vmbus_device *vmdev)
 Reset device. More...
 
static void netvsc_remove (struct vmbus_device *vmdev)
 Remove device. More...
 

Variables

static struct vmbus_channel_operations netvsc_channel_operations
 VMBus channel operations. More...
 
static struct vmbus_xfer_pages_operations netvsc_xfer_pages_operations
 Transfer page set operations. More...
 
static struct rndis_operations netvsc_operations
 RNDIS operations. More...
 
struct vmbus_driver netvsc_driver __vmbus_driver
 NetVSC driver. More...
 

Detailed Description

Hyper-V network virtual service client.

The network virtual service client (NetVSC) connects to the network virtual service provider (NetVSP) via the Hyper-V virtual machine bus (VMBus). It provides a transport layer for RNDIS packets.

Definition in file netvsc.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ netvsc_control()

static int netvsc_control ( struct netvsc_device netvsc,
unsigned int  xrid,
const void *  data,
size_t  len 
)
static

Send control message and wait for completion.

Parameters
netvscNetVSC device
xridRelative transaction ID
dataData
lenLength of data
Return values
rcReturn status code

Definition at line 53 of file netvsc.c.

54  {
55  uint64_t xid = ( NETVSC_BASE_XID + xrid );
56  unsigned int i;
57  int rc;
58 
59  /* Send control message */
60  if ( ( rc = vmbus_send_control ( netvsc->vmdev, xid, data, len ) ) !=0){
61  DBGC ( netvsc, "NETVSC %s could not send control message: %s\n",
62  netvsc->name, strerror ( rc ) );
63  return rc;
64  }
65 
66  /* Record transaction ID */
67  netvsc->wait_xrid = xrid;
68 
69  /* Wait for operation to complete */
70  for ( i = 0 ; i < NETVSC_MAX_WAIT_MS ; i++ ) {
71 
72  /* Check for completion */
73  if ( ! netvsc->wait_xrid )
74  return netvsc->wait_rc;
75 
76  /* Poll VMBus device */
77  vmbus_poll ( netvsc->vmdev );
78 
79  /* Delay for 1ms */
80  mdelay ( 1 );
81  }
82 
83  DBGC ( netvsc, "NETVSC %s timed out waiting for XRID %d\n",
84  netvsc->name, xrid );
85  vmbus_dump_channel ( netvsc->vmdev );
86  return -ETIMEDOUT;
87 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
unsigned long long uint64_t
Definition: stdint.h:13
const char * name
Name.
Definition: netvsc.h:347
#define NETVSC_MAX_WAIT_MS
Maximum time to wait for a transaction to complete.
Definition: netvsc.h:19
ring len
Length.
Definition: dwmac.h:231
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
int vmbus_poll(struct vmbus_device *vmdev)
Poll ring buffer.
Definition: vmbus.c:972
unsigned int wait_xrid
Relative transaction ID for current blocking transaction.
Definition: netvsc.h:360
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:78
int vmbus_send_control(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
Send control packet via ring buffer.
Definition: vmbus.c:765
struct vmbus_device * vmdev
VMBus device.
Definition: netvsc.h:343
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define NETVSC_BASE_XID
Base transaction ID.
Definition: netvsc.h:45
void vmbus_dump_channel(struct vmbus_device *vmdev)
Dump channel status (for debugging)
Definition: vmbus.c:1089
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
int wait_rc
Return status code for current blocking transaction.
Definition: netvsc.h:362

References data, DBGC, ETIMEDOUT, len, mdelay(), netvsc_device::name, NETVSC_BASE_XID, NETVSC_MAX_WAIT_MS, rc, strerror(), vmbus_dump_channel(), vmbus_poll(), vmbus_send_control(), netvsc_device::vmdev, netvsc_device::wait_rc, and netvsc_device::wait_xrid.

Referenced by netvsc_establish_buffer(), netvsc_initialise(), netvsc_ndis_version(), and netvsc_revoke_buffer().

◆ netvsc_completed()

static int netvsc_completed ( struct netvsc_device *netvsc  __unused,
const void *data  __unused,
size_t len  __unused 
)
static

Handle generic completion.

Parameters
netvscNetVSC device
dataData
lenLength of data
Return values
rcReturn status code

Definition at line 97 of file netvsc.c.

98  {
99  return 0;
100 }

Referenced by netvsc_recv_completion().

◆ netvsc_initialise()

static int netvsc_initialise ( struct netvsc_device netvsc)
static

Initialise communication.

Parameters
netvscNetVSC device
Return values
rcReturn status code

Definition at line 108 of file netvsc.c.

108  {
109  struct netvsc_init_message msg;
110  int rc;
111 
112  /* Construct message */
113  memset ( &msg, 0, sizeof ( msg ) );
114  msg.header.type = cpu_to_le32 ( NETVSC_INIT_MSG );
115  msg.min = cpu_to_le32 ( NETVSC_VERSION_1 );
116  msg.max = cpu_to_le32 ( NETVSC_VERSION_1 );
117 
118  /* Send message and wait for completion */
119  if ( ( rc = netvsc_control ( netvsc, NETVSC_INIT_XRID, &msg,
120  sizeof ( msg ) ) ) != 0 ) {
121  DBGC ( netvsc, "NETVSC %s could not initialise: %s\n",
122  netvsc->name, strerror ( rc ) );
123  return rc;
124  }
125 
126  return 0;
127 }
NetVSC initialisation message.
Definition: netvsc.h:83
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: message.c:61
#define DBGC(...)
Definition: compiler.h:505
#define NETVSC_VERSION_1
Oldest known NetVSC protocol version.
Definition: netvsc.h:95
const char * name
Name.
Definition: netvsc.h:347
#define cpu_to_le32(value)
Definition: byteswap.h:107
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
Initialisation.
Definition: netvsc.h:52
static int netvsc_control(struct netvsc_device *netvsc, unsigned int xrid, const void *data, size_t len)
Send control message and wait for completion.
Definition: netvsc.c:53
#define NETVSC_INIT_MSG
NetVSC initialisation message.
Definition: netvsc.h:80
void * memset(void *dest, int character, size_t len) __nonnull

References cpu_to_le32, DBGC, memset(), msg(), netvsc_device::name, netvsc_control(), NETVSC_INIT_MSG, NETVSC_INIT_XRID, NETVSC_VERSION_1, rc, and strerror().

Referenced by netvsc_open().

◆ netvsc_initialised()

static int netvsc_initialised ( struct netvsc_device netvsc,
const void *  data,
size_t  len 
)
static

Handle initialisation completion.

Parameters
netvscNetVSC device
dataData
lenLength of data
Return values
rcReturn status code

Definition at line 138 of file netvsc.c.

139  {
140  const struct netvsc_init_completion *cmplt = data;
141 
142  /* Check completion */
143  if ( len < sizeof ( *cmplt ) ) {
144  DBGC ( netvsc, "NETVSC %s underlength initialisation "
145  "completion (%zd bytes)\n", netvsc->name, len );
146  return -EINVAL;
147  }
148  if ( cmplt->header.type != cpu_to_le32 ( NETVSC_INIT_CMPLT ) ) {
149  DBGC ( netvsc, "NETVSC %s unexpected initialisation completion "
150  "type %d\n", netvsc->name,
151  le32_to_cpu ( cmplt->header.type ) );
152  return -EPROTO;
153  }
154  if ( cmplt->status != cpu_to_le32 ( NETVSC_OK ) ) {
155  DBGC ( netvsc, "NETVSC %s initialisation failure status %d\n",
156  netvsc->name, le32_to_cpu ( cmplt->status ) );
157  return -EPROTO;
158  }
159 
160  return 0;
161 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
#define le32_to_cpu(value)
Definition: byteswap.h:113
#define DBGC(...)
Definition: compiler.h:505
const char * name
Name.
Definition: netvsc.h:347
struct netvsc_header header
Message header.
Definition: netvsc.h:103
ring len
Length.
Definition: dwmac.h:231
#define NETVSC_INIT_CMPLT
NetVSC initialisation completion.
Definition: netvsc.h:98
#define cpu_to_le32(value)
Definition: byteswap.h:107
#define EPROTO
Protocol error.
Definition: errno.h:624
uint32_t type
Type.
Definition: netvsc.h:76
uint32_t status
Status.
Definition: netvsc.h:109
uint8_t data[48]
Additional event data.
Definition: ena.h:22
NetVSC initialisation completion.
Definition: netvsc.h:101

References cpu_to_le32, data, DBGC, EINVAL, EPROTO, netvsc_init_completion::header, le32_to_cpu, len, netvsc_device::name, NETVSC_INIT_CMPLT, NETVSC_OK, netvsc_init_completion::status, and netvsc_header::type.

Referenced by netvsc_recv_completion().

◆ netvsc_ndis_version()

static int netvsc_ndis_version ( struct netvsc_device netvsc)
static

Set NDIS version.

Parameters
netvscNetVSC device
Return values
rcReturn status code

Definition at line 169 of file netvsc.c.

169  {
171  int rc;
172 
173  /* Construct message */
174  memset ( &msg, 0, sizeof ( msg ) );
175  msg.header.type = cpu_to_le32 ( NETVSC_NDIS_VERSION_MSG );
176  msg.major = cpu_to_le32 ( NETVSC_NDIS_MAJOR );
177  msg.minor = cpu_to_le32 ( NETVSC_NDIS_MINOR );
178 
179  /* Send message and wait for completion */
180  if ( ( rc = netvsc_control ( netvsc, NETVSC_NDIS_VERSION_XRID,
181  &msg, sizeof ( msg ) ) ) != 0 ) {
182  DBGC ( netvsc, "NETVSC %s could not set NDIS version: %s\n",
183  netvsc->name, strerror ( rc ) );
184  return rc;
185  }
186 
187  return 0;
188 }
NDIS version.
Definition: netvsc.h:54
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: message.c:61
#define DBGC(...)
Definition: compiler.h:505
const char * name
Name.
Definition: netvsc.h:347
#define NETVSC_NDIS_MINOR
NetVSC NDIS minor version.
Definition: netvsc.h:133
#define cpu_to_le32(value)
Definition: byteswap.h:107
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define NETVSC_NDIS_MAJOR
NetVSC NDIS major version.
Definition: netvsc.h:130
#define NETVSC_NDIS_VERSION_MSG
NetVSC NDIS version message.
Definition: netvsc.h:115
NetVSC NDIS version message.
Definition: netvsc.h:118
static int netvsc_control(struct netvsc_device *netvsc, unsigned int xrid, const void *data, size_t len)
Send control message and wait for completion.
Definition: netvsc.c:53
void * memset(void *dest, int character, size_t len) __nonnull

References cpu_to_le32, DBGC, memset(), msg(), netvsc_device::name, netvsc_control(), NETVSC_NDIS_MAJOR, NETVSC_NDIS_MINOR, NETVSC_NDIS_VERSION_MSG, NETVSC_NDIS_VERSION_XRID, rc, and strerror().

Referenced by netvsc_open().

◆ netvsc_establish_buffer()

static int netvsc_establish_buffer ( struct netvsc_device netvsc,
struct netvsc_buffer buffer 
)
static

Establish data buffer.

Parameters
netvscNetVSC device
bufferData buffer
Return values
rcReturn status code

Definition at line 197 of file netvsc.c.

198  {
200  int rc;
201 
202  /* Construct message */
203  memset ( &msg, 0, sizeof ( msg ) );
204  msg.header.type = cpu_to_le32 ( buffer->establish_type );
205  msg.gpadl = cpu_to_le32 ( buffer->gpadl );
206  msg.pageset = buffer->pages.pageset; /* Already protocol-endian */
207 
208  /* Send message and wait for completion */
209  if ( ( rc = netvsc_control ( netvsc, buffer->establish_xrid, &msg,
210  sizeof ( msg ) ) ) != 0 ) {
211  DBGC ( netvsc, "NETVSC %s could not establish buffer: %s\n",
212  netvsc->name, strerror ( rc ) );
213  return rc;
214  }
215 
216  return 0;
217 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: message.c:61
#define DBGC(...)
Definition: compiler.h:505
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
const char * name
Name.
Definition: netvsc.h:347
NetVSC establish data buffer message.
Definition: netvsc.h:154
#define cpu_to_le32(value)
Definition: byteswap.h:107
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static int netvsc_control(struct netvsc_device *netvsc, unsigned int xrid, const void *data, size_t len)
Send control message and wait for completion.
Definition: netvsc.c:53
void * memset(void *dest, int character, size_t len) __nonnull

References buffer, cpu_to_le32, DBGC, memset(), msg(), netvsc_device::name, netvsc_control(), rc, and strerror().

Referenced by netvsc_open().

◆ netvsc_rx_established_buffer()

static int netvsc_rx_established_buffer ( struct netvsc_device netvsc,
const void *  data,
size_t  len 
)
static

Handle establish receive data buffer completion.

Parameters
netvscNetVSC device
dataData
lenLength of data
Return values
rcReturn status code

Definition at line 227 of file netvsc.c.

228  {
229  const struct netvsc_rx_establish_buffer_completion *cmplt = data;
230 
231  /* Check completion */
232  if ( len < sizeof ( *cmplt ) ) {
233  DBGC ( netvsc, "NETVSC %s underlength buffer completion (%zd "
234  "bytes)\n", netvsc->name, len );
235  return -EINVAL;
236  }
237  if ( cmplt->header.type != cpu_to_le32 ( NETVSC_RX_ESTABLISH_CMPLT ) ) {
238  DBGC ( netvsc, "NETVSC %s unexpected buffer completion type "
239  "%d\n", netvsc->name, le32_to_cpu ( cmplt->header.type));
240  return -EPROTO;
241  }
242  if ( cmplt->status != cpu_to_le32 ( NETVSC_OK ) ) {
243  DBGC ( netvsc, "NETVSC %s buffer failure status %d\n",
244  netvsc->name, le32_to_cpu ( cmplt->status ) );
245  return -EPROTO;
246  }
247 
248  return 0;
249 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
#define NETVSC_RX_ESTABLISH_CMPLT
NetVSC establish receive data buffer completion.
Definition: netvsc.h:139
#define le32_to_cpu(value)
Definition: byteswap.h:113
#define DBGC(...)
Definition: compiler.h:505
const char * name
Name.
Definition: netvsc.h:347
NetVSC establish receive data buffer completion.
Definition: netvsc.h:178
ring len
Length.
Definition: dwmac.h:231
#define cpu_to_le32(value)
Definition: byteswap.h:107
#define EPROTO
Protocol error.
Definition: errno.h:624
uint32_t type
Type.
Definition: netvsc.h:76
uint8_t data[48]
Additional event data.
Definition: ena.h:22
struct netvsc_header header
Message header.
Definition: netvsc.h:180

References cpu_to_le32, data, DBGC, EINVAL, EPROTO, netvsc_rx_establish_buffer_completion::header, le32_to_cpu, len, netvsc_device::name, NETVSC_OK, NETVSC_RX_ESTABLISH_CMPLT, netvsc_rx_establish_buffer_completion::status, and netvsc_header::type.

Referenced by netvsc_recv_completion().

◆ netvsc_revoke_buffer()

static int netvsc_revoke_buffer ( struct netvsc_device netvsc,
struct netvsc_buffer buffer 
)
static

Revoke data buffer.

Parameters
netvscNetVSC device
bufferData buffer
Return values
rcReturn status code

Definition at line 258 of file netvsc.c.

259  {
261  int rc;
262 
263  /* If the buffer's GPADL is obsolete (i.e. was created before
264  * the most recent Hyper-V reset), then we will never receive
265  * a response to the revoke message. Since the GPADL is
266  * already destroyed as far as the hypervisor is concerned, no
267  * further action is required.
268  */
269  if ( netvsc_is_obsolete ( netvsc ) )
270  return 0;
271 
272  /* Construct message */
273  memset ( &msg, 0, sizeof ( msg ) );
274  msg.header.type = cpu_to_le32 ( buffer->revoke_type );
275  msg.pageset = buffer->pages.pageset; /* Already protocol-endian */
276 
277  /* Send message and wait for completion */
278  if ( ( rc = netvsc_control ( netvsc, buffer->revoke_xrid,
279  &msg, sizeof ( msg ) ) ) != 0 ) {
280  DBGC ( netvsc, "NETVSC %s could not revoke buffer: %s\n",
281  netvsc->name, strerror ( rc ) );
282  return rc;
283  }
284 
285  return 0;
286 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: message.c:61
#define DBGC(...)
Definition: compiler.h:505
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
const char * name
Name.
Definition: netvsc.h:347
#define cpu_to_le32(value)
Definition: byteswap.h:107
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static int netvsc_control(struct netvsc_device *netvsc, unsigned int xrid, const void *data, size_t len)
Send control message and wait for completion.
Definition: netvsc.c:53
NetVSC revoke data buffer message.
Definition: netvsc.h:200
void * memset(void *dest, int character, size_t len) __nonnull

References buffer, cpu_to_le32, DBGC, memset(), msg(), netvsc_device::name, netvsc_control(), rc, and strerror().

Referenced by netvsc_close(), and netvsc_open().

◆ netvsc_recv_control()

static int netvsc_recv_control ( struct vmbus_device vmdev,
uint64_t  xid,
const void *  data,
size_t  len 
)
static

Handle received control packet.

Parameters
vmdevVMBus device
xidTransaction ID
dataData
lenLength of data
Return values
rcReturn status code

Definition at line 297 of file netvsc.c.

298  {
299  struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
300  struct netvsc_device *netvsc = rndis->priv;
301 
302  DBGC ( netvsc, "NETVSC %s received unsupported control packet "
303  "(%08llx):\n", netvsc->name, xid );
304  DBGC_HDA ( netvsc, 0, data, len );
305  return -ENOTSUP;
306 }
#define DBGC(...)
Definition: compiler.h:505
const char * name
Name.
Definition: netvsc.h:347
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
#define DBGC_HDA(...)
Definition: compiler.h:506
ring len
Length.
Definition: dwmac.h:231
An RNDIS device.
Definition: rndis.h:317
A NetVSC device.
Definition: netvsc.h:341
static void * vmbus_get_drvdata(struct vmbus_device *vmdev)
Get VMBus device driver-private data.
Definition: vmbus.h:566
void * priv
Driver private data.
Definition: rndis.h:325
uint8_t data[48]
Additional event data.
Definition: ena.h:22
struct rndis_device * rndis
RNDIS device.
Definition: netvsc.h:345

References data, DBGC, DBGC_HDA, ENOTSUP, len, netvsc_device::name, rndis_device::priv, netvsc_device::rndis, and vmbus_get_drvdata().

◆ netvsc_recv_data()

static int netvsc_recv_data ( struct vmbus_device vmdev,
uint64_t  xid,
const void *  data,
size_t  len,
struct list_head list 
)
static

Handle received data packet.

Parameters
vmdevVMBus device
xidTransaction ID
dataData
lenLength of data
listList of I/O buffers
Return values
rcReturn status code

Definition at line 318 of file netvsc.c.

320  {
321  struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
322  struct netvsc_device *netvsc = rndis->priv;
323  const struct netvsc_rndis_message *msg = data;
324  struct io_buffer *iobuf;
325  struct io_buffer *tmp;
326  int rc;
327 
328  /* Sanity check */
329  if ( len < sizeof ( *msg ) ) {
330  DBGC ( netvsc, "NETVSC %s received underlength RNDIS packet "
331  "(%zd bytes)\n", netvsc->name, len );
332  rc = -EINVAL;
333  goto err_sanity;
334  }
335  if ( msg->header.type != cpu_to_le32 ( NETVSC_RNDIS_MSG ) ) {
336  DBGC ( netvsc, "NETVSC %s received unexpected RNDIS packet "
337  "type %d\n", netvsc->name,
338  le32_to_cpu ( msg->header.type ) );
339  rc = -EINVAL;
340  goto err_sanity;
341  }
342 
343  /* Send completion back to host */
344  if ( ( rc = vmbus_send_completion ( vmdev, xid, NULL, 0 ) ) != 0 ) {
345  DBGC ( netvsc, "NETVSC %s could not send completion: %s\n",
346  netvsc->name, strerror ( rc ) );
347  goto err_completion;
348  }
349 
350  /* Hand off to RNDIS */
351  list_for_each_entry_safe ( iobuf, tmp, list, list ) {
352  list_del ( &iobuf->list );
353  rndis_rx ( rndis, iob_disown ( iobuf ) );
354  }
355 
356  return 0;
357 
358  err_completion:
359  err_sanity:
360  list_for_each_entry_safe ( iobuf, tmp, list, list ) {
361  list_del ( &iobuf->list );
362  free_iob ( iobuf );
363  }
364  return rc;
365 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int vmbus_send_completion(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
Send completion packet via ring buffer.
Definition: vmbus.c:834
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: message.c:61
#define le32_to_cpu(value)
Definition: byteswap.h:113
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:152
NetVSC RNDIS message.
Definition: netvsc.h:213
#define DBGC(...)
Definition: compiler.h:505
#define NETVSC_RNDIS_MSG
NetVSC RNDIS message.
Definition: netvsc.h:210
const char * name
Name.
Definition: netvsc.h:347
unsigned long tmp
Definition: linux_pci.h:64
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:216
ring len
Length.
Definition: dwmac.h:231
An RNDIS device.
Definition: rndis.h:317
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:458
#define cpu_to_le32(value)
Definition: byteswap.h:107
A NetVSC device.
Definition: netvsc.h:341
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void * vmbus_get_drvdata(struct vmbus_device *vmdev)
Get VMBus device driver-private data.
Definition: vmbus.h:566
void rndis_rx(struct rndis_device *rndis, struct io_buffer *iobuf)
Receive packet from underlying transport layer.
Definition: rndis.c:829
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:44
void * priv
Driver private data.
Definition: rndis.h:325
uint8_t data[48]
Additional event data.
Definition: ena.h:22
struct rndis_device * rndis
RNDIS device.
Definition: netvsc.h:345
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
A persistent I/O buffer.
Definition: iobuf.h:37

References cpu_to_le32, data, DBGC, EINVAL, free_iob(), iob_disown, le32_to_cpu, len, io_buffer::list, list_del, list_for_each_entry_safe, msg(), netvsc_device::name, NETVSC_RNDIS_MSG, NULL, rndis_device::priv, rc, netvsc_device::rndis, rndis_rx(), strerror(), tmp, vmbus_get_drvdata(), and vmbus_send_completion().

◆ netvsc_recv_completion()

static int netvsc_recv_completion ( struct vmbus_device vmdev,
uint64_t  xid,
const void *  data,
size_t  len 
)
static

Handle received completion packet.

Parameters
vmdevVMBus device
xidTransaction ID
dataData
lenLength of data
Return values
rcReturn status code

Definition at line 376 of file netvsc.c.

377  {
378  struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
379  struct netvsc_device *netvsc = rndis->priv;
380  struct io_buffer *iobuf;
381  int ( * completion ) ( struct netvsc_device *netvsc,
382  const void *data, size_t len );
383  unsigned int xrid = ( xid - NETVSC_BASE_XID );
384  unsigned int tx_id;
385  int rc;
386 
387  /* Handle transmit completion, if applicable */
388  tx_id = ( xrid - NETVSC_TX_BASE_XRID );
389  if ( ( tx_id < NETVSC_TX_NUM_DESC ) &&
390  ( ( iobuf = netvsc->tx.iobufs[tx_id] ) != NULL ) ) {
391 
392  /* Free buffer ID */
393  netvsc->tx.iobufs[tx_id] = NULL;
394  netvsc->tx.ids[ ( netvsc->tx.id_cons++ ) &
395  ( netvsc->tx.count - 1 ) ] = tx_id;
396 
397  /* Hand back to RNDIS */
398  rndis_tx_complete ( rndis, iobuf );
399  return 0;
400  }
401 
402  /* Otherwise determine completion handler */
403  if ( xrid == NETVSC_INIT_XRID ) {
405  } else if ( xrid == NETVSC_RX_ESTABLISH_XRID ) {
407  } else if ( ( netvsc->wait_xrid != 0 ) &&
408  ( xrid == netvsc->wait_xrid ) ) {
410  } else {
411  DBGC ( netvsc, "NETVSC %s received unexpected completion "
412  "(%08llx)\n", netvsc->name, xid );
413  return -EPIPE;
414  }
415 
416  /* Hand off to completion handler */
417  rc = completion ( netvsc, data, len );
418 
419  /* Record completion handler result if applicable */
420  if ( xrid == netvsc->wait_xrid ) {
421  netvsc->wait_xrid = 0;
422  netvsc->wait_rc = rc;
423  }
424 
425  return rc;
426 }
unsigned int count
Number of descriptors.
Definition: netvsc.h:238
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
pseudo_bit_t completion[0x00001]
Definition: arbel.h:13
static void rndis_tx_complete(struct rndis_device *rndis, struct io_buffer *iobuf)
Complete message transmission.
Definition: rndis.h:364
#define EPIPE
Broken pipe.
Definition: errno.h:619
#define DBGC(...)
Definition: compiler.h:505
Establish receive buffer.
Definition: netvsc.h:56
unsigned int id_cons
Buffer ID consumer counter.
Definition: netvsc.h:246
const char * name
Name.
Definition: netvsc.h:347
struct io_buffer ** iobufs
I/O buffers, indexed by buffer ID.
Definition: netvsc.h:240
ring len
Length.
Definition: dwmac.h:231
An RNDIS device.
Definition: rndis.h:317
struct netvsc_ring tx
Transmit ring.
Definition: netvsc.h:350
A NetVSC device.
Definition: netvsc.h:341
static void * vmbus_get_drvdata(struct vmbus_device *vmdev)
Get VMBus device driver-private data.
Definition: vmbus.h:566
static int netvsc_completed(struct netvsc_device *netvsc __unused, const void *data __unused, size_t len __unused)
Handle generic completion.
Definition: netvsc.c:97
static int netvsc_rx_established_buffer(struct netvsc_device *netvsc, const void *data, size_t len)
Handle establish receive data buffer completion.
Definition: netvsc.c:227
#define NETVSC_TX_NUM_DESC
Number of transmit ring entries.
Definition: netvsc.h:27
unsigned int wait_xrid
Relative transaction ID for current blocking transaction.
Definition: netvsc.h:360
void * priv
Driver private data.
Definition: rndis.h:325
uint8_t data[48]
Additional event data.
Definition: ena.h:22
static int netvsc_initialised(struct netvsc_device *netvsc, const void *data, size_t len)
Handle initialisation completion.
Definition: netvsc.c:138
Initialisation.
Definition: netvsc.h:52
#define NETVSC_BASE_XID
Base transaction ID.
Definition: netvsc.h:45
Transmit descriptors (one per transmit buffer ID)
Definition: netvsc.h:50
struct rndis_device * rndis
RNDIS device.
Definition: netvsc.h:345
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
int wait_rc
Return status code for current blocking transaction.
Definition: netvsc.h:362
uint8_t * ids
Buffer ID ring.
Definition: netvsc.h:242
A persistent I/O buffer.
Definition: iobuf.h:37

References completion, netvsc_ring::count, data, DBGC, EPIPE, netvsc_ring::id_cons, netvsc_ring::ids, netvsc_ring::iobufs, len, netvsc_device::name, NETVSC_BASE_XID, netvsc_completed(), NETVSC_INIT_XRID, netvsc_initialised(), NETVSC_RX_ESTABLISH_XRID, netvsc_rx_established_buffer(), NETVSC_TX_BASE_XRID, NETVSC_TX_NUM_DESC, NULL, rndis_device::priv, rc, netvsc_device::rndis, rndis_tx_complete(), netvsc_device::tx, vmbus_get_drvdata(), netvsc_device::wait_rc, and netvsc_device::wait_xrid.

◆ netvsc_recv_cancellation()

static int netvsc_recv_cancellation ( struct vmbus_device vmdev,
uint64_t  xid 
)
static

Handle received cancellation packet.

Parameters
vmdevVMBus device
xidTransaction ID
Return values
rcReturn status code

Definition at line 435 of file netvsc.c.

436  {
437  struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
438  struct netvsc_device *netvsc = rndis->priv;
439 
440  DBGC ( netvsc, "NETVSC %s received unsupported cancellation packet "
441  "(%08llx):\n", netvsc->name, xid );
442  return -ENOTSUP;
443 }
#define DBGC(...)
Definition: compiler.h:505
const char * name
Name.
Definition: netvsc.h:347
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
An RNDIS device.
Definition: rndis.h:317
A NetVSC device.
Definition: netvsc.h:341
static void * vmbus_get_drvdata(struct vmbus_device *vmdev)
Get VMBus device driver-private data.
Definition: vmbus.h:566
void * priv
Driver private data.
Definition: rndis.h:325
struct rndis_device * rndis
RNDIS device.
Definition: netvsc.h:345

References DBGC, ENOTSUP, netvsc_device::name, rndis_device::priv, netvsc_device::rndis, and vmbus_get_drvdata().

◆ netvsc_poll()

static void netvsc_poll ( struct rndis_device rndis)
static

Poll for completed and received packets.

Parameters
rndisRNDIS device

Definition at line 458 of file netvsc.c.

458  {
459  struct netvsc_device *netvsc = rndis->priv;
460  struct vmbus_device *vmdev = netvsc->vmdev;
461 
462  /* Poll VMBus device */
463  while ( vmbus_has_data ( vmdev ) )
464  vmbus_poll ( vmdev );
465 }
static int vmbus_has_data(struct vmbus_device *vmdev)
Check if data is present in ring buffer.
Definition: vmbus.h:585
A VMBus device.
Definition: vmbus.h:475
A NetVSC device.
Definition: netvsc.h:341
int vmbus_poll(struct vmbus_device *vmdev)
Poll ring buffer.
Definition: vmbus.c:972
struct vmbus_device * vmdev
VMBus device.
Definition: netvsc.h:343
void * priv
Driver private data.
Definition: rndis.h:325
struct rndis_device * rndis
RNDIS device.
Definition: netvsc.h:345

References rndis_device::priv, netvsc_device::rndis, vmbus_has_data(), vmbus_poll(), and netvsc_device::vmdev.

◆ netvsc_transmit()

static int netvsc_transmit ( struct rndis_device rndis,
struct io_buffer iobuf 
)
static

Transmit packet.

Parameters
rndisRNDIS device
iobufI/O buffer
Return values
rcReturn status code

If this method returns success then the RNDIS device must eventually report completion via rndis_tx_complete().

Definition at line 477 of file netvsc.c.

478  {
479  struct netvsc_device *netvsc = rndis->priv;
480  struct rndis_header *header = iobuf->data;
481  struct netvsc_rndis_message msg;
482  unsigned int tx_id;
483  unsigned int xrid;
484  uint64_t xid;
485  int rc;
486 
487  /* If the device is obsolete (i.e. was opened before the most
488  * recent Hyper-V reset), then we will never receive transmit
489  * completions. Fail transmissions immediately to minimise
490  * the delay in closing and reopening the device.
491  */
492  if ( netvsc_is_obsolete ( netvsc ) )
493  return -EPIPE;
494 
495  /* Sanity check */
496  assert ( iob_len ( iobuf ) >= sizeof ( *header ) );
497  assert ( iob_len ( iobuf ) == le32_to_cpu ( header->len ) );
498 
499  /* Check that we have space in the transmit ring */
500  if ( netvsc_ring_is_full ( &netvsc->tx ) )
501  return rndis_tx_defer ( rndis, iobuf );
502 
503  /* Allocate buffer ID and calculate transaction ID */
504  tx_id = netvsc->tx.ids[ netvsc->tx.id_prod & ( netvsc->tx.count - 1 ) ];
505  assert ( netvsc->tx.iobufs[tx_id] == NULL );
506  xrid = ( NETVSC_TX_BASE_XRID + tx_id );
507  xid = ( NETVSC_BASE_XID + xrid );
508 
509  /* Construct message */
510  memset ( &msg, 0, sizeof ( msg ) );
511  msg.header.type = cpu_to_le32 ( NETVSC_RNDIS_MSG );
512  msg.channel = ( ( header->type == cpu_to_le32 ( RNDIS_PACKET_MSG ) ) ?
515 
516  /* Send message */
517  if ( ( rc = vmbus_send_data ( netvsc->vmdev, xid, &msg, sizeof ( msg ),
518  iobuf ) ) != 0 ) {
519  DBGC ( netvsc, "NETVSC %s could not send RNDIS message: %s\n",
520  netvsc->name, strerror ( rc ) );
521  return rc;
522  }
523 
524  /* Store I/O buffer and consume buffer ID */
525  netvsc->tx.iobufs[tx_id] = iobuf;
526  netvsc->tx.id_prod++;
527 
528  return 0;
529 }
unsigned int count
Number of descriptors.
Definition: netvsc.h:238
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define NETVSC_RNDIS_DATA
RNDIS data channel (for RNDIS_PACKET_MSG only)
Definition: netvsc.h:227
void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: message.c:61
#define le32_to_cpu(value)
Definition: byteswap.h:113
#define EPIPE
Broken pipe.
Definition: errno.h:619
NetVSC RNDIS message.
Definition: netvsc.h:213
#define DBGC(...)
Definition: compiler.h:505
unsigned long long uint64_t
Definition: stdint.h:13
#define NETVSC_RNDIS_MSG
NetVSC RNDIS message.
Definition: netvsc.h:210
const char * name
Name.
Definition: netvsc.h:347
struct io_buffer ** iobufs
I/O buffers, indexed by buffer ID.
Definition: netvsc.h:240
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
unsigned int id_prod
Buffer ID producer counter.
Definition: netvsc.h:244
#define NETVSC_RNDIS_NO_BUFFER
"No buffer used" index
Definition: netvsc.h:233
struct netvsc_ring tx
Transmit ring.
Definition: netvsc.h:350
#define cpu_to_le32(value)
Definition: byteswap.h:107
A NetVSC device.
Definition: netvsc.h:341
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
int rndis_tx_defer(struct rndis_device *rndis, struct io_buffer *iobuf)
Defer transmitted packet.
Definition: rndis.c:190
RNDIS message header.
Definition: rndis.h:23
struct vmbus_device * vmdev
VMBus device.
Definition: netvsc.h:343
void * data
Start of data.
Definition: iobuf.h:52
void * priv
Driver private data.
Definition: rndis.h:325
struct ena_llq_option header
Header locations.
Definition: ena.h:16
#define RNDIS_PACKET_MSG
RNDIS packet message.
Definition: rndis.h:219
#define NETVSC_BASE_XID
Base transaction ID.
Definition: netvsc.h:45
Transmit descriptors (one per transmit buffer ID)
Definition: netvsc.h:50
struct rndis_device * rndis
RNDIS device.
Definition: netvsc.h:345
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
int vmbus_send_data(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len, struct io_buffer *iobuf)
Send data packet via ring buffer.
Definition: vmbus.c:794
#define NETVSC_RNDIS_CONTROL
RNDIS control channel (for all other RNDIS messages)
Definition: netvsc.h:230
uint8_t * ids
Buffer ID ring.
Definition: netvsc.h:242
void * memset(void *dest, int character, size_t len) __nonnull

References assert(), netvsc_ring::count, cpu_to_le32, io_buffer::data, DBGC, EPIPE, header, netvsc_ring::id_prod, netvsc_ring::ids, iob_len(), netvsc_ring::iobufs, le32_to_cpu, memset(), msg(), netvsc_device::name, NETVSC_BASE_XID, NETVSC_RNDIS_CONTROL, NETVSC_RNDIS_DATA, NETVSC_RNDIS_MSG, NETVSC_RNDIS_NO_BUFFER, NETVSC_TX_BASE_XRID, NULL, rndis_device::priv, rc, netvsc_device::rndis, RNDIS_PACKET_MSG, rndis_tx_defer(), strerror(), netvsc_device::tx, vmbus_send_data(), and netvsc_device::vmdev.

◆ netvsc_cancel_transmit()

static void netvsc_cancel_transmit ( struct netvsc_device netvsc,
struct io_buffer iobuf,
unsigned int  tx_id 
)
static

Cancel transmission.

Parameters
netvscNetVSC device
iobufI/O buffer
tx_idTransmission ID

Definition at line 538 of file netvsc.c.

540  {
541  unsigned int xrid;
542  uint64_t xid;
543 
544  /* Send cancellation */
545  xrid = ( NETVSC_TX_BASE_XRID + tx_id );
546  xid = ( NETVSC_BASE_XID + xrid );
547  DBGC ( netvsc, "NETVSC %s cancelling transmission %#x\n",
548  netvsc->name, tx_id );
549  vmbus_send_cancellation ( netvsc->vmdev, xid );
550 
551  /* Report back to RNDIS */
552  rndis_tx_complete_err ( netvsc->rndis, iobuf, -ECANCELED );
553 }
#define DBGC(...)
Definition: compiler.h:505
unsigned long long uint64_t
Definition: stdint.h:13
const char * name
Name.
Definition: netvsc.h:347
#define ECANCELED
Operation canceled.
Definition: errno.h:343
int vmbus_send_cancellation(struct vmbus_device *vmdev, uint64_t xid)
Send cancellation packet via ring buffer.
Definition: vmbus.c:857
struct vmbus_device * vmdev
VMBus device.
Definition: netvsc.h:343
#define NETVSC_BASE_XID
Base transaction ID.
Definition: netvsc.h:45
Transmit descriptors (one per transmit buffer ID)
Definition: netvsc.h:50
struct rndis_device * rndis
RNDIS device.
Definition: netvsc.h:345
void rndis_tx_complete_err(struct rndis_device *rndis, struct io_buffer *iobuf, int rc)
Complete message transmission.
Definition: rndis.c:127

References DBGC, ECANCELED, netvsc_device::name, NETVSC_BASE_XID, NETVSC_TX_BASE_XRID, netvsc_device::rndis, rndis_tx_complete_err(), vmbus_send_cancellation(), and netvsc_device::vmdev.

Referenced by netvsc_close().

◆ netvsc_create_ring()

static int netvsc_create_ring ( struct netvsc_device *netvsc  __unused,
struct netvsc_ring ring 
)
static

Create descriptor ring.

Parameters
netvscNetVSC device
ringDescriptor ring
Return values
rcReturn status code

Definition at line 562 of file netvsc.c.

563  {
564  unsigned int i;
565 
566  /* Initialise buffer ID ring */
567  for ( i = 0 ; i < ring->count ; i++ ) {
568  ring->ids[i] = i;
569  assert ( ring->iobufs[i] == NULL );
570  }
571  ring->id_prod = 0;
572  ring->id_cons = 0;
573 
574  return 0;
575 }
unsigned int count
Number of descriptors.
Definition: netvsc.h:238
unsigned int id_cons
Buffer ID consumer counter.
Definition: netvsc.h:246
struct io_buffer ** iobufs
I/O buffers, indexed by buffer ID.
Definition: netvsc.h:240
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
unsigned int id_prod
Buffer ID producer counter.
Definition: netvsc.h:244
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
uint8_t * ids
Buffer ID ring.
Definition: netvsc.h:242

References assert(), netvsc_ring::count, netvsc_ring::id_cons, netvsc_ring::id_prod, netvsc_ring::ids, netvsc_ring::iobufs, and NULL.

Referenced by netvsc_open().

◆ netvsc_destroy_ring()

static void netvsc_destroy_ring ( struct netvsc_device netvsc,
struct netvsc_ring ring,
void(*)(struct netvsc_device *, struct io_buffer *, unsigned int)  discard 
)
static

Destroy descriptor ring.

Parameters
netvscNetVSC device
ringDescriptor ring
discardMethod used to discard outstanding buffer, or NULL

Definition at line 584 of file netvsc.c.

588  {
589  struct io_buffer *iobuf;
590  unsigned int i;
591 
592  /* Flush any outstanding buffers */
593  for ( i = 0 ; i < ring->count ; i++ ) {
594  iobuf = ring->iobufs[i];
595  if ( ! iobuf )
596  continue;
597  ring->iobufs[i] = NULL;
598  ring->ids[ ( ring->id_cons++ ) & ( ring->count - 1 ) ] = i;
599  if ( discard )
600  discard ( netvsc, iobuf, i );
601  }
602 
603  /* Sanity check */
604  assert ( netvsc_ring_is_empty ( ring ) );
605 }
unsigned int count
Number of descriptors.
Definition: netvsc.h:238
unsigned int id_cons
Buffer ID consumer counter.
Definition: netvsc.h:246
struct io_buffer ** iobufs
I/O buffers, indexed by buffer ID.
Definition: netvsc.h:240
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
uint8_t * ids
Buffer ID ring.
Definition: netvsc.h:242
A persistent I/O buffer.
Definition: iobuf.h:37

References assert(), netvsc_ring::count, netvsc_ring::id_cons, netvsc_ring::ids, netvsc_ring::iobufs, and NULL.

Referenced by netvsc_close(), and netvsc_open().

◆ netvsc_buffer_copy()

static int netvsc_buffer_copy ( struct vmbus_xfer_pages pages,
void *  data,
size_t  offset,
size_t  len 
)
static

Copy data from data buffer.

Parameters
pagesTransfer page set
dataData buffer
offsetOffset within page set
lenLength within page set
Return values
rcReturn status code

Definition at line 616 of file netvsc.c.

617  {
618  struct netvsc_buffer *buffer =
619  container_of ( pages, struct netvsc_buffer, pages );
620 
621  /* Sanity check */
622  if ( ( offset > buffer->len ) || ( len > ( buffer->len - offset ) ) )
623  return -ERANGE;
624 
625  /* Copy data from buffer */
626  memcpy ( data, ( buffer->data + offset ), len );
627 
628  return 0;
629 }
A NetVSC data buffer.
Definition: netvsc.h:294
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
ring len
Length.
Definition: dwmac.h:231
#define ERANGE
Result too large.
Definition: errno.h:639
struct vmbus_xfer_pages pages
Transfer page set.
Definition: netvsc.h:296
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint16_t offset
Offset to command line.
Definition: bzimage.h:8

References buffer, container_of, data, ERANGE, len, memcpy(), offset, and netvsc_buffer::pages.

◆ netvsc_create_buffer()

static int netvsc_create_buffer ( struct netvsc_device netvsc,
struct netvsc_buffer buffer 
)
static

Create data buffer.

Parameters
netvscNetVSC device
bufferData buffer
Return values
rcReturn status code

Definition at line 643 of file netvsc.c.

644  {
645  struct vmbus_device *vmdev = netvsc->vmdev;
646  int gpadl;
647  int rc;
648 
649  /* Allocate receive buffer */
650  buffer->data = umalloc ( buffer->len );
651  if ( ! buffer->data ) {
652  DBGC ( netvsc, "NETVSC %s could not allocate %zd-byte buffer\n",
653  netvsc->name, buffer->len );
654  rc = -ENOMEM;
655  goto err_alloc;
656  }
657 
658  /* Establish GPA descriptor list */
659  gpadl = vmbus_establish_gpadl ( vmdev, buffer->data, buffer->len );
660  if ( gpadl < 0 ) {
661  rc = gpadl;
662  DBGC ( netvsc, "NETVSC %s could not establish GPADL: %s\n",
663  netvsc->name, strerror ( rc ) );
664  goto err_establish_gpadl;
665  }
666  buffer->gpadl = gpadl;
667 
668  /* Register transfer page set */
669  if ( ( rc = vmbus_register_pages ( vmdev, &buffer->pages ) ) != 0 ) {
670  DBGC ( netvsc, "NETVSC %s could not register transfer pages: "
671  "%s\n", netvsc->name, strerror ( rc ) );
672  goto err_register_pages;
673  }
674 
675  return 0;
676 
677  vmbus_unregister_pages ( vmdev, &buffer->pages );
678  err_register_pages:
679  vmbus_gpadl_teardown ( vmdev, gpadl );
680  err_establish_gpadl:
681  ufree ( buffer->data );
682  err_alloc:
683  return rc;
684 }
static __always_inline void ufree(void *ptr)
Free external memory.
Definition: umalloc.h:67
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
A VMBus device.
Definition: vmbus.h:475
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
const char * name
Name.
Definition: netvsc.h:347
static int vmbus_register_pages(struct vmbus_device *vmdev, struct vmbus_xfer_pages *pages)
Register transfer page set.
Definition: vmbus.h:598
int vmbus_establish_gpadl(struct vmbus_device *vmdev, void *data, size_t len)
Establish GPA descriptor list.
Definition: vmbus.c:276
#define ENOMEM
Not enough space.
Definition: errno.h:534
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint32_t gpadl
GPADL ID.
Definition: netvsc.h:14
static void vmbus_unregister_pages(struct vmbus_device *vmdev, struct vmbus_xfer_pages *pages)
Unregister transfer page set.
Definition: vmbus.h:612
int vmbus_gpadl_teardown(struct vmbus_device *vmdev, unsigned int gpadl)
Tear down GPA descriptor list.
Definition: vmbus.c:347
struct vmbus_device * vmdev
VMBus device.
Definition: netvsc.h:343
static __always_inline void * umalloc(size_t size)
Allocate external memory.
Definition: umalloc.h:56

References buffer, DBGC, ENOMEM, gpadl, netvsc_device::name, rc, strerror(), ufree(), umalloc(), vmbus_establish_gpadl(), vmbus_gpadl_teardown(), vmbus_register_pages(), vmbus_unregister_pages(), and netvsc_device::vmdev.

Referenced by netvsc_open().

◆ netvsc_destroy_buffer()

static void netvsc_destroy_buffer ( struct netvsc_device netvsc,
struct netvsc_buffer buffer 
)
static

Destroy data buffer.

Parameters
netvscNetVSC device
bufferData buffer

Definition at line 692 of file netvsc.c.

693  {
694  struct vmbus_device *vmdev = netvsc->vmdev;
695  int rc;
696 
697  /* Unregister transfer pages */
698  vmbus_unregister_pages ( vmdev, &buffer->pages );
699 
700  /* Tear down GPA descriptor list */
701  if ( ( rc = vmbus_gpadl_teardown ( vmdev, buffer->gpadl ) ) != 0 ) {
702  DBGC ( netvsc, "NETVSC %s could not tear down GPADL: %s\n",
703  netvsc->name, strerror ( rc ) );
704  /* Death is imminent. The host may well continue to
705  * write to the data buffer. The best we can do is
706  * leak memory for now and hope that the host doesn't
707  * write to this region after we load an OS.
708  */
709  return;
710  }
711 
712  /* Free buffer */
713  ufree ( buffer->data );
714 }
static __always_inline void ufree(void *ptr)
Free external memory.
Definition: umalloc.h:67
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
A VMBus device.
Definition: vmbus.h:475
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
const char * name
Name.
Definition: netvsc.h:347
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void vmbus_unregister_pages(struct vmbus_device *vmdev, struct vmbus_xfer_pages *pages)
Unregister transfer page set.
Definition: vmbus.h:612
struct vmbus_device * vmdev
VMBus device.
Definition: netvsc.h:343
VMBus "GPADL teardown" message.
Definition: vmbus.h:193

References buffer, DBGC, netvsc_device::name, rc, strerror(), ufree(), vmbus_unregister_pages(), and netvsc_device::vmdev.

Referenced by netvsc_close(), and netvsc_open().

◆ netvsc_open()

static int netvsc_open ( struct rndis_device rndis)
static

Open device.

Parameters
rndisRNDIS device
Return values
rcReturn status code

Definition at line 722 of file netvsc.c.

722  {
723  struct netvsc_device *netvsc = rndis->priv;
724  int rc;
725 
726  /* Initialise receive buffer */
727  if ( ( rc = netvsc_create_buffer ( netvsc, &netvsc->rx ) ) != 0 )
728  goto err_create_rx;
729 
730  /* Open channel */
731  if ( ( rc = vmbus_open ( netvsc->vmdev, &netvsc_channel_operations,
732  PAGE_SIZE, PAGE_SIZE, NETVSC_MTU ) ) != 0 ) {
733  DBGC ( netvsc, "NETVSC %s could not open VMBus: %s\n",
734  netvsc->name, strerror ( rc ) );
735  goto err_vmbus_open;
736  }
737 
738  /* Initialise communication with NetVSP */
739  if ( ( rc = netvsc_initialise ( netvsc ) ) != 0 )
740  goto err_initialise;
741  if ( ( rc = netvsc_ndis_version ( netvsc ) ) != 0 )
742  goto err_ndis_version;
743 
744  /* Initialise transmit ring */
745  if ( ( rc = netvsc_create_ring ( netvsc, &netvsc->tx ) ) != 0 )
746  goto err_create_tx;
747 
748  /* Establish receive buffer */
749  if ( ( rc = netvsc_establish_buffer ( netvsc, &netvsc->rx ) ) != 0 )
750  goto err_establish_rx;
751 
752  return 0;
753 
754  netvsc_revoke_buffer ( netvsc, &netvsc->rx );
755  err_establish_rx:
756  netvsc_destroy_ring ( netvsc, &netvsc->tx, NULL );
757  err_create_tx:
758  err_ndis_version:
759  err_initialise:
760  vmbus_close ( netvsc->vmdev );
761  err_vmbus_open:
762  netvsc_destroy_buffer ( netvsc, &netvsc->rx );
763  err_create_rx:
764  return rc;
765 }
static int netvsc_create_ring(struct netvsc_device *netvsc __unused, struct netvsc_ring *ring)
Create descriptor ring.
Definition: netvsc.c:562
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static struct vmbus_channel_operations netvsc_channel_operations
VMBus channel operations.
Definition: netvsc.c:446
static void netvsc_destroy_ring(struct netvsc_device *netvsc, struct netvsc_ring *ring, void(*discard)(struct netvsc_device *, struct io_buffer *, unsigned int))
Destroy descriptor ring.
Definition: netvsc.c:584
int vmbus_open(struct vmbus_device *vmdev, struct vmbus_channel_operations *op, size_t out_len, size_t in_len, size_t mtu)
Open VMBus channel.
Definition: vmbus.c:403
#define DBGC(...)
Definition: compiler.h:505
static int netvsc_establish_buffer(struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
Establish data buffer.
Definition: netvsc.c:197
#define PAGE_SIZE
Page size.
Definition: io.h:27
const char * name
Name.
Definition: netvsc.h:347
static int netvsc_revoke_buffer(struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
Revoke data buffer.
Definition: netvsc.c:258
struct netvsc_ring tx
Transmit ring.
Definition: netvsc.h:350
A NetVSC device.
Definition: netvsc.h:341
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define NETVSC_MTU
Maximum supported NetVSC message length.
Definition: netvsc.h:13
static int netvsc_ndis_version(struct netvsc_device *netvsc)
Set NDIS version.
Definition: netvsc.c:169
struct vmbus_device * vmdev
VMBus device.
Definition: netvsc.h:343
static void netvsc_destroy_buffer(struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
Destroy data buffer.
Definition: netvsc.c:692
void * priv
Driver private data.
Definition: rndis.h:325
void vmbus_close(struct vmbus_device *vmdev)
Close VMBus channel.
Definition: vmbus.c:524
static int netvsc_initialise(struct netvsc_device *netvsc)
Initialise communication.
Definition: netvsc.c:108
struct rndis_device * rndis
RNDIS device.
Definition: netvsc.h:345
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct netvsc_buffer rx
Receive buffer.
Definition: netvsc.h:357
static int netvsc_create_buffer(struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
Create data buffer.
Definition: netvsc.c:643

References DBGC, netvsc_device::name, netvsc_channel_operations, netvsc_create_buffer(), netvsc_create_ring(), netvsc_destroy_buffer(), netvsc_destroy_ring(), netvsc_establish_buffer(), netvsc_initialise(), NETVSC_MTU, netvsc_ndis_version(), netvsc_revoke_buffer(), NULL, PAGE_SIZE, rndis_device::priv, rc, netvsc_device::rndis, netvsc_device::rx, strerror(), netvsc_device::tx, vmbus_close(), vmbus_open(), and netvsc_device::vmdev.

◆ netvsc_close()

static void netvsc_close ( struct rndis_device rndis)
static

Close device.

Parameters
rndisRNDIS device

Definition at line 772 of file netvsc.c.

772  {
773  struct netvsc_device *netvsc = rndis->priv;
774 
775  /* Revoke receive buffer */
776  netvsc_revoke_buffer ( netvsc, &netvsc->rx );
777 
778  /* Destroy transmit ring */
779  netvsc_destroy_ring ( netvsc, &netvsc->tx, netvsc_cancel_transmit );
780 
781  /* Close channel */
782  vmbus_close ( netvsc->vmdev );
783 
784  /* Destroy receive buffer */
785  netvsc_destroy_buffer ( netvsc, &netvsc->rx );
786 }
static void netvsc_cancel_transmit(struct netvsc_device *netvsc, struct io_buffer *iobuf, unsigned int tx_id)
Cancel transmission.
Definition: netvsc.c:538
static void netvsc_destroy_ring(struct netvsc_device *netvsc, struct netvsc_ring *ring, void(*discard)(struct netvsc_device *, struct io_buffer *, unsigned int))
Destroy descriptor ring.
Definition: netvsc.c:584
static int netvsc_revoke_buffer(struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
Revoke data buffer.
Definition: netvsc.c:258
struct netvsc_ring tx
Transmit ring.
Definition: netvsc.h:350
A NetVSC device.
Definition: netvsc.h:341
struct vmbus_device * vmdev
VMBus device.
Definition: netvsc.h:343
static void netvsc_destroy_buffer(struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
Destroy data buffer.
Definition: netvsc.c:692
void * priv
Driver private data.
Definition: rndis.h:325
void vmbus_close(struct vmbus_device *vmdev)
Close VMBus channel.
Definition: vmbus.c:524
struct rndis_device * rndis
RNDIS device.
Definition: netvsc.h:345
struct netvsc_buffer rx
Receive buffer.
Definition: netvsc.h:357

References netvsc_cancel_transmit(), netvsc_destroy_buffer(), netvsc_destroy_ring(), netvsc_revoke_buffer(), rndis_device::priv, netvsc_device::rndis, netvsc_device::rx, netvsc_device::tx, vmbus_close(), and netvsc_device::vmdev.

◆ netvsc_probe()

static int netvsc_probe ( struct vmbus_device vmdev)
static

Probe device.

Parameters
vmdevVMBus device
Return values
rcReturn status code

Definition at line 802 of file netvsc.c.

802  {
803  struct netvsc_device *netvsc;
804  struct rndis_device *rndis;
805  int rc;
806 
807  /* Allocate and initialise structure */
808  rndis = alloc_rndis ( sizeof ( *netvsc ) );
809  if ( ! rndis ) {
810  rc = -ENOMEM;
811  goto err_alloc;
812  }
813  rndis_init ( rndis, &netvsc_operations );
814  rndis->netdev->dev = &vmdev->dev;
815  netvsc = rndis->priv;
816  netvsc->vmdev = vmdev;
817  netvsc->rndis = rndis;
818  netvsc->name = vmdev->dev.name;
819  netvsc_init_ring ( &netvsc->tx, NETVSC_TX_NUM_DESC,
820  netvsc->tx_iobufs, netvsc->tx_ids );
821  netvsc_init_buffer ( &netvsc->rx, NETVSC_RX_BUF_PAGESET,
826  vmbus_set_drvdata ( vmdev, rndis );
827 
828  /* Register RNDIS device */
829  if ( ( rc = register_rndis ( rndis ) ) != 0 ) {
830  DBGC ( netvsc, "NETVSC %s could not register: %s\n",
831  netvsc->name, strerror ( rc ) );
832  goto err_register;
833  }
834 
835  return 0;
836 
837  unregister_rndis ( rndis );
838  err_register:
839  free_rndis ( rndis );
840  err_alloc:
841  return rc;
842 }
struct rndis_device * alloc_rndis(size_t priv_len)
Allocate RNDIS device.
Definition: rndis.c:1000
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct device dev
Generic iPXE device.
Definition: vmbus.h:477
void unregister_rndis(struct rndis_device *rndis)
Unregister RNDIS device.
Definition: rndis.c:1054
#define DBGC(...)
Definition: compiler.h:505
char name[40]
Name.
Definition: device.h:78
Establish receive buffer.
Definition: netvsc.h:56
const char * name
Name.
Definition: netvsc.h:347
#define NETVSC_RX_REVOKE_MSG
NetVSC revoke receive data buffer message.
Definition: netvsc.h:142
#define NETVSC_RX_BUF_PAGESET
RX data buffer page set ID.
Definition: netvsc.h:33
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct net_device * netdev
Network device.
Definition: rndis.h:319
#define NETVSC_RX_ESTABLISH_MSG
NetVSC establish receive data buffer message.
Definition: netvsc.h:136
An RNDIS device.
Definition: rndis.h:317
struct netvsc_ring tx
Transmit ring.
Definition: netvsc.h:350
static struct rndis_operations netvsc_operations
RNDIS operations.
Definition: netvsc.c:789
A NetVSC device.
Definition: netvsc.h:341
Revoke receive buffer.
Definition: netvsc.h:58
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
int register_rndis(struct rndis_device *rndis)
Register RNDIS device.
Definition: rndis.c:1026
static void rndis_init(struct rndis_device *rndis, struct rndis_operations *op)
Initialise an RNDIS device.
Definition: rndis.h:339
struct io_buffer * tx_iobufs[NETVSC_TX_NUM_DESC]
Transmit I/O buffers.
Definition: netvsc.h:354
#define NETVSC_TX_NUM_DESC
Number of transmit ring entries.
Definition: netvsc.h:27
struct device * dev
Underlying hardware device.
Definition: netdevice.h:364
uint8_t tx_ids[NETVSC_TX_NUM_DESC]
Transmit buffer IDs.
Definition: netvsc.h:352
struct vmbus_device * vmdev
VMBus device.
Definition: netvsc.h:343
void * priv
Driver private data.
Definition: rndis.h:325
#define NETVSC_RX_BUF_LEN
RX data buffer length.
Definition: netvsc.h:39
static void vmbus_set_drvdata(struct vmbus_device *vmdev, void *priv)
Set VMBus device driver-private data.
Definition: vmbus.h:556
static struct vmbus_xfer_pages_operations netvsc_xfer_pages_operations
Transfer page set operations.
Definition: netvsc.c:632
struct rndis_device * rndis
RNDIS device.
Definition: netvsc.h:345
void free_rndis(struct rndis_device *rndis)
Free RNDIS device.
Definition: rndis.c:1066
struct netvsc_buffer rx
Receive buffer.
Definition: netvsc.h:357

References alloc_rndis(), DBGC, net_device::dev, vmbus_device::dev, ENOMEM, free_rndis(), device::name, netvsc_device::name, rndis_device::netdev, netvsc_operations, NETVSC_RX_BUF_LEN, NETVSC_RX_BUF_PAGESET, NETVSC_RX_ESTABLISH_MSG, NETVSC_RX_ESTABLISH_XRID, NETVSC_RX_REVOKE_MSG, NETVSC_RX_REVOKE_XRID, NETVSC_TX_NUM_DESC, netvsc_xfer_pages_operations, rndis_device::priv, rc, register_rndis(), netvsc_device::rndis, rndis_init(), netvsc_device::rx, strerror(), netvsc_device::tx, netvsc_device::tx_ids, netvsc_device::tx_iobufs, unregister_rndis(), vmbus_set_drvdata(), and netvsc_device::vmdev.

◆ netvsc_reset()

static int netvsc_reset ( struct vmbus_device vmdev)
static

Reset device.

Parameters
vmdevVMBus device
Return values
rcReturn status code

Definition at line 850 of file netvsc.c.

850  {
851  struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
852  struct netvsc_device *netvsc = rndis->priv;
853  struct net_device *netdev = rndis->netdev;
854  int rc;
855 
856  /* A closed device holds no NetVSC (or RNDIS) state, so there
857  * is nothing to reset.
858  */
859  if ( ! netdev_is_open ( netdev ) )
860  return 0;
861 
862  /* Close and reopen device to reset any stale state */
863  netdev_close ( netdev );
864  if ( ( rc = netdev_open ( netdev ) ) != 0 ) {
865  DBGC ( netvsc, "NETVSC %s could not reopen: %s\n",
866  netvsc->name, strerror ( rc ) );
867  return rc;
868  }
869 
870  return 0;
871 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
const char * name
Name.
Definition: netvsc.h:347
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition: netdevice.h:661
struct net_device * netdev
Network device.
Definition: rndis.h:319
An RNDIS device.
Definition: rndis.h:317
static struct net_device * netdev
Definition: gdbudp.c:52
A NetVSC device.
Definition: netvsc.h:341
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void * vmbus_get_drvdata(struct vmbus_device *vmdev)
Get VMBus device driver-private data.
Definition: vmbus.h:566
A network device.
Definition: netdevice.h:352
void netdev_close(struct net_device *netdev)
Close network device.
Definition: netdevice.c:895
void * priv
Driver private data.
Definition: rndis.h:325
struct rndis_device * rndis
RNDIS device.
Definition: netvsc.h:345
int netdev_open(struct net_device *netdev)
Open network device.
Definition: netdevice.c:861

References DBGC, netvsc_device::name, netdev, rndis_device::netdev, netdev_close(), netdev_is_open(), netdev_open(), rndis_device::priv, rc, netvsc_device::rndis, strerror(), and vmbus_get_drvdata().

◆ netvsc_remove()

static void netvsc_remove ( struct vmbus_device vmdev)
static

Remove device.

Parameters
vmdevVMBus device

Definition at line 878 of file netvsc.c.

878  {
879  struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
880 
881  /* Unregister RNDIS device */
882  unregister_rndis ( rndis );
883 
884  /* Free RNDIS device */
885  free_rndis ( rndis );
886 }
void unregister_rndis(struct rndis_device *rndis)
Unregister RNDIS device.
Definition: rndis.c:1054
An RNDIS device.
Definition: rndis.h:317
static void * vmbus_get_drvdata(struct vmbus_device *vmdev)
Get VMBus device driver-private data.
Definition: vmbus.h:566
void free_rndis(struct rndis_device *rndis)
Free RNDIS device.
Definition: rndis.c:1066

References free_rndis(), unregister_rndis(), and vmbus_get_drvdata().

Variable Documentation

◆ netvsc_channel_operations

struct vmbus_channel_operations netvsc_channel_operations
static
Initial value:
= {
.recv_control = netvsc_recv_control,
.recv_data = netvsc_recv_data,
.recv_completion = netvsc_recv_completion,
.recv_cancellation = netvsc_recv_cancellation,
}
static int netvsc_recv_cancellation(struct vmbus_device *vmdev, uint64_t xid)
Handle received cancellation packet.
Definition: netvsc.c:435
static int netvsc_recv_completion(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
Handle received completion packet.
Definition: netvsc.c:376
static int netvsc_recv_control(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
Handle received control packet.
Definition: netvsc.c:297
static int netvsc_recv_data(struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len, struct list_head *list)
Handle received data packet.
Definition: netvsc.c:318

VMBus channel operations.

Definition at line 446 of file netvsc.c.

Referenced by netvsc_open().

◆ netvsc_xfer_pages_operations

struct vmbus_xfer_pages_operations netvsc_xfer_pages_operations
static
Initial value:
= {
}
static int netvsc_buffer_copy(struct vmbus_xfer_pages *pages, void *data, size_t offset, size_t len)
Copy data from data buffer.
Definition: netvsc.c:616

Transfer page set operations.

Definition at line 632 of file netvsc.c.

Referenced by netvsc_probe().

◆ netvsc_operations

struct rndis_operations netvsc_operations
static
Initial value:
= {
.open = netvsc_open,
.close = netvsc_close,
.transmit = netvsc_transmit,
.poll = netvsc_poll,
}
static int netvsc_transmit(struct rndis_device *rndis, struct io_buffer *iobuf)
Transmit packet.
Definition: netvsc.c:477
static void netvsc_poll(struct rndis_device *rndis)
Poll for completed and received packets.
Definition: netvsc.c:458
static void netvsc_close(struct rndis_device *rndis)
Close device.
Definition: netvsc.c:772
static int netvsc_open(struct rndis_device *rndis)
Open device.
Definition: netvsc.c:722

RNDIS operations.

Definition at line 789 of file netvsc.c.

Referenced by netvsc_probe().

◆ __vmbus_driver

struct vmbus_driver netvsc_driver __vmbus_driver
Initial value:
= {
.name = "netvsc",
.type = VMBUS_TYPE ( 0xf8615163, 0xdf3e, 0x46c5, 0x913f,
0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e ),
.probe = netvsc_probe,
.reset = netvsc_reset,
.remove = netvsc_remove,
}
static void netvsc_remove(struct vmbus_device *vmdev)
Remove device.
Definition: netvsc.c:878
#define VMBUS_TYPE(a, b, c, d, e0, e1, e2, e3, e4, e5)
Construct VMBus type.
Definition: vmbus.h:571
static int netvsc_reset(struct vmbus_device *vmdev)
Reset device.
Definition: netvsc.c:850
static int netvsc_probe(struct vmbus_device *vmdev)
Probe device.
Definition: netvsc.c:802

NetVSC driver.

Definition at line 889 of file netvsc.c.