iPXE
Functions | Variables
netvsc.c File Reference

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

#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 52 of file netvsc.c.

53  {
54  uint64_t xid = ( NETVSC_BASE_XID + xrid );
55  unsigned int i;
56  int rc;
57 
58  /* Send control message */
59  if ( ( rc = vmbus_send_control ( netvsc->vmdev, xid, data, len ) ) !=0){
60  DBGC ( netvsc, "NETVSC %s could not send control message: %s\n",
61  netvsc->name, strerror ( rc ) );
62  return rc;
63  }
64 
65  /* Record transaction ID */
66  netvsc->wait_xrid = xrid;
67 
68  /* Wait for operation to complete */
69  for ( i = 0 ; i < NETVSC_MAX_WAIT_MS ; i++ ) {
70 
71  /* Check for completion */
72  if ( ! netvsc->wait_xrid )
73  return netvsc->wait_rc;
74 
75  /* Poll VMBus device */
76  vmbus_poll ( netvsc->vmdev );
77 
78  /* Delay for 1ms */
79  mdelay ( 1 );
80  }
81 
82  DBGC ( netvsc, "NETVSC %s timed out waiting for XRID %d\n",
83  netvsc->name, xrid );
84  vmbus_dump_channel ( netvsc->vmdev );
85  return -ETIMEDOUT;
86 }
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
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
uint32_t len
Length.
Definition: ena.h:14
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 96 of file netvsc.c.

97  {
98  return 0;
99 }

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 107 of file netvsc.c.

107  {
108  struct netvsc_init_message msg;
109  int rc;
110 
111  /* Construct message */
112  memset ( &msg, 0, sizeof ( msg ) );
113  msg.header.type = cpu_to_le32 ( NETVSC_INIT_MSG );
114  msg.min = cpu_to_le32 ( NETVSC_VERSION_1 );
115  msg.max = cpu_to_le32 ( NETVSC_VERSION_1 );
116 
117  /* Send message and wait for completion */
118  if ( ( rc = netvsc_control ( netvsc, NETVSC_INIT_XRID, &msg,
119  sizeof ( msg ) ) ) != 0 ) {
120  DBGC ( netvsc, "NETVSC %s could not initialise: %s\n",
121  netvsc->name, strerror ( rc ) );
122  return rc;
123  }
124 
125  return 0;
126 }
NetVSC initialisation message.
Definition: netvsc.h:83
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#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:52
#define NETVSC_INIT_MSG
NetVSC initialisation message.
Definition: netvsc.h:80
void * memset(void *dest, int character, size_t len) __nonnull
static void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: settings_ui.c:288

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 137 of file netvsc.c.

138  {
139  const struct netvsc_init_completion *cmplt = data;
140 
141  /* Check completion */
142  if ( len < sizeof ( *cmplt ) ) {
143  DBGC ( netvsc, "NETVSC %s underlength initialisation "
144  "completion (%zd bytes)\n", netvsc->name, len );
145  return -EINVAL;
146  }
147  if ( cmplt->header.type != cpu_to_le32 ( NETVSC_INIT_CMPLT ) ) {
148  DBGC ( netvsc, "NETVSC %s unexpected initialisation completion "
149  "type %d\n", netvsc->name,
150  le32_to_cpu ( cmplt->header.type ) );
151  return -EPROTO;
152  }
153  if ( cmplt->status != cpu_to_le32 ( NETVSC_OK ) ) {
154  DBGC ( netvsc, "NETVSC %s initialisation failure status %d\n",
155  netvsc->name, le32_to_cpu ( cmplt->status ) );
156  return -EPROTO;
157  }
158 
159  return 0;
160 }
#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
#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
uint32_t len
Length.
Definition: ena.h:14
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 168 of file netvsc.c.

168  {
170  int rc;
171 
172  /* Construct message */
173  memset ( &msg, 0, sizeof ( msg ) );
174  msg.header.type = cpu_to_le32 ( NETVSC_NDIS_VERSION_MSG );
175  msg.major = cpu_to_le32 ( NETVSC_NDIS_MAJOR );
176  msg.minor = cpu_to_le32 ( NETVSC_NDIS_MINOR );
177 
178  /* Send message and wait for completion */
179  if ( ( rc = netvsc_control ( netvsc, NETVSC_NDIS_VERSION_XRID,
180  &msg, sizeof ( msg ) ) ) != 0 ) {
181  DBGC ( netvsc, "NETVSC %s could not set NDIS version: %s\n",
182  netvsc->name, strerror ( rc ) );
183  return rc;
184  }
185 
186  return 0;
187 }
NDIS version.
Definition: netvsc.h:54
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#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:52
void * memset(void *dest, int character, size_t len) __nonnull
static void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: settings_ui.c:288

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 196 of file netvsc.c.

197  {
199  int rc;
200 
201  /* Construct message */
202  memset ( &msg, 0, sizeof ( msg ) );
203  msg.header.type = cpu_to_le32 ( buffer->establish_type );
204  msg.gpadl = cpu_to_le32 ( buffer->gpadl );
205  msg.pageset = buffer->pages.pageset; /* Already protocol-endian */
206 
207  /* Send message and wait for completion */
208  if ( ( rc = netvsc_control ( netvsc, buffer->establish_xrid, &msg,
209  sizeof ( msg ) ) ) != 0 ) {
210  DBGC ( netvsc, "NETVSC %s could not establish buffer: %s\n",
211  netvsc->name, strerror ( rc ) );
212  return rc;
213  }
214 
215  return 0;
216 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#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:52
void * memset(void *dest, int character, size_t len) __nonnull
static void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: settings_ui.c:288

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 226 of file netvsc.c.

227  {
228  const struct netvsc_rx_establish_buffer_completion *cmplt = data;
229 
230  /* Check completion */
231  if ( len < sizeof ( *cmplt ) ) {
232  DBGC ( netvsc, "NETVSC %s underlength buffer completion (%zd "
233  "bytes)\n", netvsc->name, len );
234  return -EINVAL;
235  }
236  if ( cmplt->header.type != cpu_to_le32 ( NETVSC_RX_ESTABLISH_CMPLT ) ) {
237  DBGC ( netvsc, "NETVSC %s unexpected buffer completion type "
238  "%d\n", netvsc->name, le32_to_cpu ( cmplt->header.type));
239  return -EPROTO;
240  }
241  if ( cmplt->status != cpu_to_le32 ( NETVSC_OK ) ) {
242  DBGC ( netvsc, "NETVSC %s buffer failure status %d\n",
243  netvsc->name, le32_to_cpu ( cmplt->status ) );
244  return -EPROTO;
245  }
246 
247  return 0;
248 }
#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
#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 len
Length.
Definition: ena.h:14
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 257 of file netvsc.c.

258  {
260  int rc;
261 
262  /* If the buffer's GPADL is obsolete (i.e. was created before
263  * the most recent Hyper-V reset), then we will never receive
264  * a response to the revoke message. Since the GPADL is
265  * already destroyed as far as the hypervisor is concerned, no
266  * further action is required.
267  */
268  if ( netvsc_is_obsolete ( netvsc ) )
269  return 0;
270 
271  /* Construct message */
272  memset ( &msg, 0, sizeof ( msg ) );
273  msg.header.type = cpu_to_le32 ( buffer->revoke_type );
274  msg.pageset = buffer->pages.pageset; /* Already protocol-endian */
275 
276  /* Send message and wait for completion */
277  if ( ( rc = netvsc_control ( netvsc, buffer->revoke_xrid,
278  &msg, sizeof ( msg ) ) ) != 0 ) {
279  DBGC ( netvsc, "NETVSC %s could not revoke buffer: %s\n",
280  netvsc->name, strerror ( rc ) );
281  return rc;
282  }
283 
284  return 0;
285 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#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:52
NetVSC revoke data buffer message.
Definition: netvsc.h:200
void * memset(void *dest, int character, size_t len) __nonnull
static void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: settings_ui.c:288

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 296 of file netvsc.c.

297  {
298  struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
299  struct netvsc_device *netvsc = rndis->priv;
300 
301  DBGC ( netvsc, "NETVSC %s received unsupported control packet "
302  "(%08llx):\n", netvsc->name, xid );
303  DBGC_HDA ( netvsc, 0, data, len );
304  return -ENOTSUP;
305 }
#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
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:567
uint32_t len
Length.
Definition: ena.h:14
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 317 of file netvsc.c.

319  {
320  struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
321  struct netvsc_device *netvsc = rndis->priv;
322  const struct netvsc_rndis_message *msg = data;
323  struct io_buffer *iobuf;
324  struct io_buffer *tmp;
325  int rc;
326 
327  /* Sanity check */
328  if ( len < sizeof ( *msg ) ) {
329  DBGC ( netvsc, "NETVSC %s received underlength RNDIS packet "
330  "(%zd bytes)\n", netvsc->name, len );
331  rc = -EINVAL;
332  goto err_sanity;
333  }
334  if ( msg->header.type != cpu_to_le32 ( NETVSC_RNDIS_MSG ) ) {
335  DBGC ( netvsc, "NETVSC %s received unexpected RNDIS packet "
336  "type %d\n", netvsc->name,
337  le32_to_cpu ( msg->header.type ) );
338  rc = -EINVAL;
339  goto err_sanity;
340  }
341 
342  /* Send completion back to host */
343  if ( ( rc = vmbus_send_completion ( vmdev, xid, NULL, 0 ) ) != 0 ) {
344  DBGC ( netvsc, "NETVSC %s could not send completion: %s\n",
345  netvsc->name, strerror ( rc ) );
346  goto err_completion;
347  }
348 
349  /* Hand off to RNDIS */
350  list_for_each_entry_safe ( iobuf, tmp, list, list ) {
351  list_del ( &iobuf->list );
352  rndis_rx ( rndis, iob_disown ( iobuf ) );
353  }
354 
355  return 0;
356 
357  err_completion:
358  err_sanity:
359  list_for_each_entry_safe ( iobuf, tmp, list, list ) {
360  list_del ( &iobuf->list );
361  free_iob ( iobuf );
362  }
363  return rc;
364 }
#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
#define le32_to_cpu(value)
Definition: byteswap.h:113
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
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:53
#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:212
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:567
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:40
uint32_t len
Length.
Definition: ena.h:14
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:33
static void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: settings_ui.c:288

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 375 of file netvsc.c.

376  {
377  struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
378  struct netvsc_device *netvsc = rndis->priv;
379  struct io_buffer *iobuf;
380  int ( * completion ) ( struct netvsc_device *netvsc,
381  const void *data, size_t len );
382  unsigned int xrid = ( xid - NETVSC_BASE_XID );
383  unsigned int tx_id;
384  int rc;
385 
386  /* Handle transmit completion, if applicable */
387  tx_id = ( xrid - NETVSC_TX_BASE_XRID );
388  if ( ( tx_id < NETVSC_TX_NUM_DESC ) &&
389  ( ( iobuf = netvsc->tx.iobufs[tx_id] ) != NULL ) ) {
390 
391  /* Free buffer ID */
392  netvsc->tx.iobufs[tx_id] = NULL;
393  netvsc->tx.ids[ ( netvsc->tx.id_cons++ ) &
394  ( netvsc->tx.count - 1 ) ] = tx_id;
395 
396  /* Hand back to RNDIS */
397  rndis_tx_complete ( rndis, iobuf );
398  return 0;
399  }
400 
401  /* Otherwise determine completion handler */
402  if ( xrid == NETVSC_INIT_XRID ) {
404  } else if ( xrid == NETVSC_RX_ESTABLISH_XRID ) {
406  } else if ( ( netvsc->wait_xrid != 0 ) &&
407  ( xrid == netvsc->wait_xrid ) ) {
409  } else {
410  DBGC ( netvsc, "NETVSC %s received unexpected completion "
411  "(%08llx)\n", netvsc->name, xid );
412  return -EPIPE;
413  }
414 
415  /* Hand off to completion handler */
416  rc = completion ( netvsc, data, len );
417 
418  /* Record completion handler result if applicable */
419  if ( xrid == netvsc->wait_xrid ) {
420  netvsc->wait_xrid = 0;
421  netvsc->wait_rc = rc;
422  }
423 
424  return rc;
425 }
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
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:567
static int netvsc_completed(struct netvsc_device *netvsc __unused, const void *data __unused, size_t len __unused)
Handle generic completion.
Definition: netvsc.c:96
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:226
#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
uint32_t len
Length.
Definition: ena.h:14
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:137
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:33

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 434 of file netvsc.c.

435  {
436  struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
437  struct netvsc_device *netvsc = rndis->priv;
438 
439  DBGC ( netvsc, "NETVSC %s received unsupported cancellation packet "
440  "(%08llx):\n", netvsc->name, xid );
441  return -ENOTSUP;
442 }
#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:567
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 457 of file netvsc.c.

457  {
458  struct netvsc_device *netvsc = rndis->priv;
459  struct vmbus_device *vmdev = netvsc->vmdev;
460 
461  /* Poll VMBus device */
462  while ( vmbus_has_data ( vmdev ) )
463  vmbus_poll ( vmdev );
464 }
static int vmbus_has_data(struct vmbus_device *vmdev)
Check if data is present in ring buffer.
Definition: vmbus.h:586
A VMBus device.
Definition: vmbus.h:476
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 476 of file netvsc.c.

477  {
478  struct netvsc_device *netvsc = rndis->priv;
479  struct rndis_header *header = iobuf->data;
480  struct netvsc_rndis_message msg;
481  unsigned int tx_id;
482  unsigned int xrid;
483  uint64_t xid;
484  int rc;
485 
486  /* If the device is obsolete (i.e. was opened before the most
487  * recent Hyper-V reset), then we will never receive transmit
488  * completions. Fail transmissions immediately to minimise
489  * the delay in closing and reopening the device.
490  */
491  if ( netvsc_is_obsolete ( netvsc ) )
492  return -EPIPE;
493 
494  /* Sanity check */
495  assert ( iob_len ( iobuf ) >= sizeof ( *header ) );
496  assert ( iob_len ( iobuf ) == le32_to_cpu ( header->len ) );
497 
498  /* Check that we have space in the transmit ring */
499  if ( netvsc_ring_is_full ( &netvsc->tx ) )
500  return rndis_tx_defer ( rndis, iobuf );
501 
502  /* Allocate buffer ID and calculate transaction ID */
503  tx_id = netvsc->tx.ids[ netvsc->tx.id_prod & ( netvsc->tx.count - 1 ) ];
504  assert ( netvsc->tx.iobufs[tx_id] == NULL );
505  xrid = ( NETVSC_TX_BASE_XRID + tx_id );
506  xid = ( NETVSC_BASE_XID + xrid );
507 
508  /* Construct message */
509  memset ( &msg, 0, sizeof ( msg ) );
510  msg.header.type = cpu_to_le32 ( NETVSC_RNDIS_MSG );
511  msg.channel = ( ( header->type == cpu_to_le32 ( RNDIS_PACKET_MSG ) ) ?
514 
515  /* Send message */
516  if ( ( rc = vmbus_send_data ( netvsc->vmdev, xid, &msg, sizeof ( msg ),
517  iobuf ) ) != 0 ) {
518  DBGC ( netvsc, "NETVSC %s could not send RNDIS message: %s\n",
519  netvsc->name, strerror ( rc ) );
520  return rc;
521  }
522 
523  /* Store I/O buffer and consume buffer ID */
524  netvsc->tx.iobufs[tx_id] = iobuf;
525  netvsc->tx.id_prod++;
526 
527  return 0;
528 }
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
#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:155
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:48
void * priv
Driver private data.
Definition: rndis.h:325
struct ena_aq_header header
Header.
Definition: ena.h:12
#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
static void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: settings_ui.c:288

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 537 of file netvsc.c.

539  {
540  unsigned int xrid;
541  uint64_t xid;
542 
543  /* Send cancellation */
544  xrid = ( NETVSC_TX_BASE_XRID + tx_id );
545  xid = ( NETVSC_BASE_XID + xrid );
546  DBGC ( netvsc, "NETVSC %s cancelling transmission %#x\n",
547  netvsc->name, tx_id );
548  vmbus_send_cancellation ( netvsc->vmdev, xid );
549 
550  /* Report back to RNDIS */
551  rndis_tx_complete_err ( netvsc->rndis, iobuf, -ECANCELED );
552 }
#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 561 of file netvsc.c.

562  {
563  unsigned int i;
564 
565  /* Initialise buffer ID ring */
566  for ( i = 0 ; i < ring->count ; i++ ) {
567  ring->ids[i] = i;
568  assert ( ring->iobufs[i] == NULL );
569  }
570  ring->id_prod = 0;
571  ring->id_cons = 0;
572 
573  return 0;
574 }
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 583 of file netvsc.c.

587  {
588  struct io_buffer *iobuf;
589  unsigned int i;
590 
591  /* Flush any outstanding buffers */
592  for ( i = 0 ; i < ring->count ; i++ ) {
593  iobuf = ring->iobufs[i];
594  if ( ! iobuf )
595  continue;
596  ring->iobufs[i] = NULL;
597  ring->ids[ ( ring->id_cons++ ) & ( ring->count - 1 ) ] = i;
598  if ( discard )
599  discard ( netvsc, iobuf, i );
600  }
601 
602  /* Sanity check */
603  assert ( netvsc_ring_is_empty ( ring ) );
604 }
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:33

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 615 of file netvsc.c.

616  {
617  struct netvsc_buffer *buffer =
618  container_of ( pages, struct netvsc_buffer, pages );
619 
620  /* Sanity check */
621  if ( ( offset > buffer->len ) || ( len > ( buffer->len - offset ) ) )
622  return -ERANGE;
623 
624  /* Copy data from buffer */
625  copy_from_user ( data, buffer->data, offset, len );
626 
627  return 0;
628 }
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
A NetVSC data buffer.
Definition: netvsc.h:294
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
#define ERANGE
Result too large.
Definition: errno.h:639
struct vmbus_xfer_pages pages
Transfer page set.
Definition: netvsc.h:296
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22

References buffer, container_of, copy_from_user(), data, ERANGE, len, 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 642 of file netvsc.c.

643  {
644  struct vmbus_device *vmdev = netvsc->vmdev;
645  int gpadl;
646  int rc;
647 
648  /* Allocate receive buffer */
649  buffer->data = umalloc ( buffer->len );
650  if ( ! buffer->data ) {
651  DBGC ( netvsc, "NETVSC %s could not allocate %zd-byte buffer\n",
652  netvsc->name, buffer->len );
653  rc = -ENOMEM;
654  goto err_alloc;
655  }
656 
657  /* Establish GPA descriptor list */
658  gpadl = vmbus_establish_gpadl ( vmdev, buffer->data, buffer->len );
659  if ( gpadl < 0 ) {
660  rc = gpadl;
661  DBGC ( netvsc, "NETVSC %s could not establish GPADL: %s\n",
662  netvsc->name, strerror ( rc ) );
663  goto err_establish_gpadl;
664  }
665  buffer->gpadl = gpadl;
666 
667  /* Register transfer page set */
668  if ( ( rc = vmbus_register_pages ( vmdev, &buffer->pages ) ) != 0 ) {
669  DBGC ( netvsc, "NETVSC %s could not register transfer pages: "
670  "%s\n", netvsc->name, strerror ( rc ) );
671  goto err_register_pages;
672  }
673 
674  return 0;
675 
676  vmbus_unregister_pages ( vmdev, &buffer->pages );
677  err_register_pages:
678  vmbus_gpadl_teardown ( vmdev, gpadl );
679  err_establish_gpadl:
680  ufree ( buffer->data );
681  err_alloc:
682  return rc;
683 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
A VMBus device.
Definition: vmbus.h:476
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:599
#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:613
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 ufree(userptr_t userptr)
Free external memory.
Definition: umalloc.h:65
static __always_inline userptr_t umalloc(size_t size)
Allocate external memory.
Definition: umalloc.h:54
int vmbus_establish_gpadl(struct vmbus_device *vmdev, userptr_t data, size_t len)
Establish GPA descriptor list.
Definition: vmbus.c:276

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 691 of file netvsc.c.

692  {
693  struct vmbus_device *vmdev = netvsc->vmdev;
694  int rc;
695 
696  /* Unregister transfer pages */
697  vmbus_unregister_pages ( vmdev, &buffer->pages );
698 
699  /* Tear down GPA descriptor list */
700  if ( ( rc = vmbus_gpadl_teardown ( vmdev, buffer->gpadl ) ) != 0 ) {
701  DBGC ( netvsc, "NETVSC %s could not tear down GPADL: %s\n",
702  netvsc->name, strerror ( rc ) );
703  /* Death is imminent. The host may well continue to
704  * write to the data buffer. The best we can do is
705  * leak memory for now and hope that the host doesn't
706  * write to this region after we load an OS.
707  */
708  return;
709  }
710 
711  /* Free buffer */
712  ufree ( buffer->data );
713 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
A VMBus device.
Definition: vmbus.h:476
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:613
struct vmbus_device * vmdev
VMBus device.
Definition: netvsc.h:343
static __always_inline void ufree(userptr_t userptr)
Free external memory.
Definition: umalloc.h:65
VMBus "GPADL teardown" message.
Definition: vmbus.h:194

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 721 of file netvsc.c.

721  {
722  struct netvsc_device *netvsc = rndis->priv;
723  int rc;
724 
725  /* Initialise receive buffer */
726  if ( ( rc = netvsc_create_buffer ( netvsc, &netvsc->rx ) ) != 0 )
727  goto err_create_rx;
728 
729  /* Open channel */
730  if ( ( rc = vmbus_open ( netvsc->vmdev, &netvsc_channel_operations,
731  PAGE_SIZE, PAGE_SIZE, NETVSC_MTU ) ) != 0 ) {
732  DBGC ( netvsc, "NETVSC %s could not open VMBus: %s\n",
733  netvsc->name, strerror ( rc ) );
734  goto err_vmbus_open;
735  }
736 
737  /* Initialise communication with NetVSP */
738  if ( ( rc = netvsc_initialise ( netvsc ) ) != 0 )
739  goto err_initialise;
740  if ( ( rc = netvsc_ndis_version ( netvsc ) ) != 0 )
741  goto err_ndis_version;
742 
743  /* Initialise transmit ring */
744  if ( ( rc = netvsc_create_ring ( netvsc, &netvsc->tx ) ) != 0 )
745  goto err_create_tx;
746 
747  /* Establish receive buffer */
748  if ( ( rc = netvsc_establish_buffer ( netvsc, &netvsc->rx ) ) != 0 )
749  goto err_establish_rx;
750 
751  return 0;
752 
753  netvsc_revoke_buffer ( netvsc, &netvsc->rx );
754  err_establish_rx:
755  netvsc_destroy_ring ( netvsc, &netvsc->tx, NULL );
756  err_create_tx:
757  err_ndis_version:
758  err_initialise:
759  vmbus_close ( netvsc->vmdev );
760  err_vmbus_open:
761  netvsc_destroy_buffer ( netvsc, &netvsc->rx );
762  err_create_rx:
763  return rc;
764 }
static int netvsc_create_ring(struct netvsc_device *netvsc __unused, struct netvsc_ring *ring)
Create descriptor ring.
Definition: netvsc.c:561
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static struct vmbus_channel_operations netvsc_channel_operations
VMBus channel operations.
Definition: netvsc.c:445
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:583
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:196
#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:257
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:168
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:691
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:107
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:642

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 771 of file netvsc.c.

771  {
772  struct netvsc_device *netvsc = rndis->priv;
773 
774  /* Revoke receive buffer */
775  netvsc_revoke_buffer ( netvsc, &netvsc->rx );
776 
777  /* Destroy transmit ring */
778  netvsc_destroy_ring ( netvsc, &netvsc->tx, netvsc_cancel_transmit );
779 
780  /* Close channel */
781  vmbus_close ( netvsc->vmdev );
782 
783  /* Destroy receive buffer */
784  netvsc_destroy_buffer ( netvsc, &netvsc->rx );
785 }
static void netvsc_cancel_transmit(struct netvsc_device *netvsc, struct io_buffer *iobuf, unsigned int tx_id)
Cancel transmission.
Definition: netvsc.c:537
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:583
static int netvsc_revoke_buffer(struct netvsc_device *netvsc, struct netvsc_buffer *buffer)
Revoke data buffer.
Definition: netvsc.c:257
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:691
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 801 of file netvsc.c.

801  {
802  struct netvsc_device *netvsc;
803  struct rndis_device *rndis;
804  int rc;
805 
806  /* Allocate and initialise structure */
807  rndis = alloc_rndis ( sizeof ( *netvsc ) );
808  if ( ! rndis ) {
809  rc = -ENOMEM;
810  goto err_alloc;
811  }
812  rndis_init ( rndis, &netvsc_operations );
813  rndis->netdev->dev = &vmdev->dev;
814  netvsc = rndis->priv;
815  netvsc->vmdev = vmdev;
816  netvsc->rndis = rndis;
817  netvsc->name = vmdev->dev.name;
818  netvsc_init_ring ( &netvsc->tx, NETVSC_TX_NUM_DESC,
819  netvsc->tx_iobufs, netvsc->tx_ids );
820  netvsc_init_buffer ( &netvsc->rx, NETVSC_RX_BUF_PAGESET,
825  vmbus_set_drvdata ( vmdev, rndis );
826 
827  /* Register RNDIS device */
828  if ( ( rc = register_rndis ( rndis ) ) != 0 ) {
829  DBGC ( netvsc, "NETVSC %s could not register: %s\n",
830  netvsc->name, strerror ( rc ) );
831  goto err_register;
832  }
833 
834  return 0;
835 
836  unregister_rndis ( rndis );
837  err_register:
838  free_rndis ( rndis );
839  err_alloc:
840  return rc;
841 }
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:478
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:75
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:788
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:557
static struct vmbus_xfer_pages_operations netvsc_xfer_pages_operations
Transfer page set operations.
Definition: netvsc.c:631
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 849 of file netvsc.c.

849  {
850  struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
851  struct netvsc_device *netvsc = rndis->priv;
852  struct net_device *netdev = rndis->netdev;
853  int rc;
854 
855  /* A closed device holds no NetVSC (or RNDIS) state, so there
856  * is nothing to reset.
857  */
858  if ( ! netdev_is_open ( netdev ) )
859  return 0;
860 
861  /* Close and reopen device to reset any stale state */
862  netdev_close ( netdev );
863  if ( ( rc = netdev_open ( netdev ) ) != 0 ) {
864  DBGC ( netvsc, "NETVSC %s could not reopen: %s\n",
865  netvsc->name, strerror ( rc ) );
866  return rc;
867  }
868 
869  return 0;
870 }
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:658
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:567
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 877 of file netvsc.c.

877  {
878  struct rndis_device *rndis = vmbus_get_drvdata ( vmdev );
879 
880  /* Unregister RNDIS device */
881  unregister_rndis ( rndis );
882 
883  /* Free RNDIS device */
884  free_rndis ( rndis );
885 }
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:567
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:434
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:375
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:296
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:317

VMBus channel operations.

Definition at line 445 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:615

Transfer page set operations.

Definition at line 631 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:476
static void netvsc_poll(struct rndis_device *rndis)
Poll for completed and received packets.
Definition: netvsc.c:457
static void netvsc_close(struct rndis_device *rndis)
Close device.
Definition: netvsc.c:771
static int netvsc_open(struct rndis_device *rndis)
Open device.
Definition: netvsc.c:721

RNDIS operations.

Definition at line 788 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:877
#define VMBUS_TYPE(a, b, c, d, e0, e1, e2, e3, e4, e5)
Construct VMBus type.
Definition: vmbus.h:572
static int netvsc_reset(struct vmbus_device *vmdev)
Reset device.
Definition: netvsc.c:849
static int netvsc_probe(struct vmbus_device *vmdev)
Probe device.
Definition: netvsc.c:801

NetVSC driver.

Definition at line 888 of file netvsc.c.