iPXE
acm.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <stdint.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <byteswap.h>
30 #include <ipxe/profile.h>
31 #include <ipxe/usb.h>
32 #include <ipxe/usbnet.h>
33 #include <ipxe/rndis.h>
34 #include "acm.h"
35 
36 /** @file
37  *
38  * USB RNDIS driver
39  *
40  */
41 
42 /** Interrupt completion profiler */
43 static struct profiler acm_intr_profiler __profiler =
44  { .name = "acm.intr" };
45 
46 /** Bulk IN completion profiler */
47 static struct profiler acm_in_profiler __profiler =
48  { .name = "acm.in" };
49 
50 /** Bulk OUT profiler */
51 static struct profiler acm_out_profiler __profiler =
52  { .name = "acm.out" };
53 
54 /******************************************************************************
55  *
56  * USB RNDIS communications interface
57  *
58  ******************************************************************************
59  */
60 
61 /**
62  * Complete interrupt transfer
63  *
64  * @v ep USB endpoint
65  * @v iobuf I/O buffer
66  * @v rc Completion status code
67  */
68 static void acm_intr_complete ( struct usb_endpoint *ep,
69  struct io_buffer *iobuf, int rc ) {
70  struct acm_device *acm = container_of ( ep, struct acm_device,
71  usbnet.intr );
72  struct rndis_device *rndis = acm->rndis;
73  struct usb_setup_packet *message;
74 
75  /* Profile completions */
76  profile_start ( &acm_intr_profiler );
77 
78  /* Ignore packets cancelled when the endpoint closes */
79  if ( ! ep->open )
80  goto ignore;
81 
82  /* Drop packets with errors */
83  if ( rc != 0 ) {
84  DBGC ( acm, "ACM %p interrupt failed: %s\n",
85  acm, strerror ( rc ) );
86  DBGC_HDA ( acm, 0, iobuf->data, iob_len ( iobuf ) );
87  goto error;
88  }
89 
90  /* Extract message header */
91  if ( iob_len ( iobuf ) < sizeof ( *message ) ) {
92  DBGC ( acm, "ACM %p underlength interrupt:\n", acm );
93  DBGC_HDA ( acm, 0, iobuf->data, iob_len ( iobuf ) );
94  rc = -EINVAL;
95  goto error;
96  }
97  message = iobuf->data;
98 
99  /* Parse message header */
100  switch ( message->request ) {
101 
103  case cpu_to_le16 ( 0x0001 ) : /* qemu seems to use this value */
104  acm->responded = 1;
105  break;
106 
107  default:
108  DBGC ( acm, "ACM %p unrecognised interrupt:\n", acm );
109  DBGC_HDA ( acm, 0, iobuf->data, iob_len ( iobuf ) );
110  rc = -ENOTSUP;
111  goto error;
112  }
113 
114  /* Free I/O buffer */
115  free_iob ( iobuf );
116  profile_stop ( &acm_intr_profiler );
117 
118  return;
119 
120  error:
121  rndis_rx_err ( rndis, iob_disown ( iobuf ), rc );
122  ignore:
123  free_iob ( iobuf );
124  return;
125 }
126 
127 /** Interrupt endpoint operations */
130 };
131 
132 /******************************************************************************
133  *
134  * USB RNDIS data interface
135  *
136  ******************************************************************************
137  */
138 
139 /**
140  * Complete bulk IN transfer
141  *
142  * @v ep USB endpoint
143  * @v iobuf I/O buffer
144  * @v rc Completion status code
145  */
146 static void acm_in_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
147  int rc ) {
148  struct acm_device *acm = container_of ( ep, struct acm_device,
149  usbnet.in );
150  struct rndis_device *rndis = acm->rndis;
151 
152  /* Profile receive completions */
153  profile_start ( &acm_in_profiler );
154 
155  /* Ignore packets cancelled when the endpoint closes */
156  if ( ! ep->open )
157  goto ignore;
158 
159  /* Record USB errors against the RNDIS device */
160  if ( rc != 0 ) {
161  DBGC ( acm, "ACM %p bulk IN failed: %s\n",
162  acm, strerror ( rc ) );
163  goto error;
164  }
165 
166  /* Hand off to RNDIS */
167  rndis_rx ( rndis, iob_disown ( iobuf ) );
168 
169  profile_stop ( &acm_in_profiler );
170  return;
171 
172  error:
173  rndis_rx_err ( rndis, iob_disown ( iobuf ), rc );
174  ignore:
175  free_iob ( iobuf );
176 }
177 
178 /** Bulk IN endpoint operations */
181 };
182 
183 /**
184  * Transmit packet
185  *
186  * @v acm USB RNDIS device
187  * @v iobuf I/O buffer
188  * @ret rc Return status code
189  */
190 static int acm_out_transmit ( struct acm_device *acm,
191  struct io_buffer *iobuf ) {
192  int rc;
193 
194  /* Profile transmissions */
195  profile_start ( &acm_out_profiler );
196 
197  /* Enqueue I/O buffer */
198  if ( ( rc = usb_stream ( &acm->usbnet.out, iobuf, 0 ) ) != 0 )
199  return rc;
200 
201  profile_stop ( &acm_out_profiler );
202  return 0;
203 }
204 
205 /**
206  * Complete bulk OUT transfer
207  *
208  * @v ep USB endpoint
209  * @v iobuf I/O buffer
210  * @v rc Completion status code
211  */
212 static void acm_out_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
213  int rc ) {
214  struct acm_device *acm = container_of ( ep, struct acm_device,
215  usbnet.out );
216  struct rndis_device *rndis = acm->rndis;
217 
218  /* Report TX completion */
219  rndis_tx_complete_err ( rndis, iobuf, rc );
220 }
221 
222 /** Bulk OUT endpoint operations */
225 };
226 
227 /******************************************************************************
228  *
229  * USB RNDIS control interface
230  *
231  ******************************************************************************
232  */
233 
234 /**
235  * Send control packet
236  *
237  * @v acm USB RNDIS device
238  * @v iobuf I/O buffer
239  * @ret rc Return status code
240  */
241 static int acm_control_transmit ( struct acm_device *acm,
242  struct io_buffer *iobuf ) {
243  struct rndis_device *rndis = acm->rndis;
244  struct usb_device *usb = acm->usb;
245  int rc;
246 
247  /* Send packet as an encapsulated command */
248  if ( ( rc = cdc_send_encapsulated_command ( usb, acm->usbnet.comms,
249  iobuf->data,
250  iob_len ( iobuf ) ) ) != 0){
251  DBGC ( acm, "ACM %p could not send encapsulated command: %s\n",
252  acm, strerror ( rc ) );
253  return rc;
254  }
255 
256  /* Complete packet immediately */
257  rndis_tx_complete ( rndis, iobuf );
258 
259  return 0;
260 }
261 
262 /**
263  * Receive control packet
264  *
265  * @v acm USB RNDIS device
266  * @ret rc Return status code
267  */
268 static int acm_control_receive ( struct acm_device *acm ) {
269  struct rndis_device *rndis = acm->rndis;
270  struct usb_device *usb = acm->usb;
271  struct io_buffer *iobuf;
272  struct rndis_header *header;
273  size_t mtu = ACM_RESPONSE_MTU;
274  size_t len;
275  int rc;
276 
277  /* Allocate I/O buffer */
278  iobuf = alloc_iob ( mtu );
279  if ( ! iobuf ) {
280  rc = -ENOMEM;
281  goto err_alloc;
282  }
283 
284  /* Get encapsulated response */
285  if ( ( rc = cdc_get_encapsulated_response ( usb, acm->usbnet.comms,
286  iobuf->data, mtu ) ) != 0 ){
287  DBGC ( acm, "ACM %p could not get encapsulated response: %s\n",
288  acm, strerror ( rc ) );
289  goto err_get_response;
290  }
291 
292  /* Fix up buffer length */
293  header = iobuf->data;
294  len = le32_to_cpu ( header->len );
295  if ( len > mtu ) {
296  DBGC ( acm, "ACM %p overlength encapsulated response\n", acm );
297  DBGC_HDA ( acm, 0, iobuf->data, mtu );
298  rc = -EPROTO;
299  goto err_len;
300  }
301  iob_put ( iobuf, len );
302 
303  /* Hand off to RNDIS */
304  rndis_rx ( rndis, iob_disown ( iobuf ) );
305 
306  return 0;
307 
308  err_len:
309  err_get_response:
310  free_iob ( iobuf );
311  err_alloc:
312  return rc;
313 }
314 
315 /******************************************************************************
316  *
317  * RNDIS interface
318  *
319  ******************************************************************************
320  */
321 
322 /**
323  * Open RNDIS device
324  *
325  * @v rndis RNDIS device
326  * @ret rc Return status code
327  */
328 static int acm_open ( struct rndis_device *rndis ) {
329  struct acm_device *acm = rndis->priv;
330  int rc;
331 
332  /* Open USB network device */
333  if ( ( rc = usbnet_open ( &acm->usbnet ) ) != 0 )
334  goto err_open;
335 
336  return 0;
337 
338  usbnet_close ( &acm->usbnet );
339  err_open:
340  return rc;
341 }
342 
343 /**
344  * Close RNDIS device
345  *
346  * @v rndis RNDIS device
347  */
348 static void acm_close ( struct rndis_device *rndis ) {
349  struct acm_device *acm = rndis->priv;
350 
351  /* Close USB network device */
352  usbnet_close ( &acm->usbnet );
353 }
354 
355 /**
356  * Transmit packet
357  *
358  * @v rndis RNDIS device
359  * @v iobuf I/O buffer
360  * @ret rc Return status code
361  */
362 static int acm_transmit ( struct rndis_device *rndis,
363  struct io_buffer *iobuf ) {
364  struct acm_device *acm = rndis->priv;
365  struct rndis_header *header = iobuf->data;
366 
367  /* Sanity check */
368  assert ( iob_len ( iobuf ) >= sizeof ( *header ) );
369  assert ( iob_len ( iobuf ) == le32_to_cpu ( header->len ) );
370 
371  /* Transmit packet via appropriate mechanism */
372  if ( header->type == cpu_to_le32 ( RNDIS_PACKET_MSG ) ) {
373  return acm_out_transmit ( acm, iobuf );
374  } else {
375  return acm_control_transmit ( acm, iobuf );
376  }
377 }
378 
379 /**
380  * Poll for completed and received packets
381  *
382  * @v rndis RNDIS device
383  */
384 static void acm_poll ( struct rndis_device *rndis ) {
385  struct acm_device *acm = rndis->priv;
386  int rc;
387 
388  /* Poll USB bus */
389  usb_poll ( acm->bus );
390 
391  /* Refill rings */
392  if ( ( rc = usbnet_refill ( &acm->usbnet ) ) != 0 )
393  rndis_rx_err ( rndis, NULL, rc );
394 
395  /* Retrieve encapsulated response, if applicable */
396  if ( acm->responded ) {
397 
398  /* Clear flag */
399  acm->responded = 0;
400 
401  /* Get encapsulated response */
402  if ( ( rc = acm_control_receive ( acm ) ) != 0 )
403  rndis_rx_err ( rndis, NULL, rc );
404  }
405 }
406 
407 /** USB RNDIS operations */
409  .open = acm_open,
410  .close = acm_close,
411  .transmit = acm_transmit,
412  .poll = acm_poll,
413 };
414 
415 /******************************************************************************
416  *
417  * USB interface
418  *
419  ******************************************************************************
420  */
421 
422 /**
423  * Probe device
424  *
425  * @v func USB function
426  * @v config Configuration descriptor
427  * @ret rc Return status code
428  */
429 static int acm_probe ( struct usb_function *func,
430  struct usb_configuration_descriptor *config ) {
431  struct usb_device *usb = func->usb;
432  struct rndis_device *rndis;
433  struct acm_device *acm;
434  int rc;
435 
436  /* Allocate and initialise structure */
437  rndis = alloc_rndis ( sizeof ( *acm ) );
438  if ( ! rndis ) {
439  rc = -ENOMEM;
440  goto err_alloc;
441  }
443  rndis->netdev->dev = &func->dev;
444  acm = rndis->priv;
445  acm->usb = usb;
446  acm->bus = usb->port->hub->bus;
447  acm->rndis = rndis;
448  usbnet_init ( &acm->usbnet, func, &acm_intr_operations,
450  usb_refill_init ( &acm->usbnet.intr, 0, 0, ACM_INTR_MAX_FILL );
452 
453  /* Describe USB network device */
454  if ( ( rc = usbnet_describe ( &acm->usbnet, config ) ) != 0 ) {
455  DBGC ( acm, "ACM %p could not describe: %s\n",
456  acm, strerror ( rc ) );
457  goto err_describe;
458  }
459 
460  /* Register RNDIS device */
461  if ( ( rc = register_rndis ( rndis ) ) != 0 )
462  goto err_register;
463 
464  usb_func_set_drvdata ( func, acm );
465  return 0;
466 
468  err_register:
469  err_describe:
470  free_rndis ( rndis );
471  err_alloc:
472  return rc;
473 }
474 
475 /**
476  * Remove device
477  *
478  * @v func USB function
479  */
480 static void acm_remove ( struct usb_function *func ) {
481  struct acm_device *acm = usb_func_get_drvdata ( func );
482  struct rndis_device *rndis = acm->rndis;
483 
484  /* Unregister RNDIS device */
485  unregister_rndis ( rndis );
486 
487  /* Free RNDIS device */
488  free_rndis ( rndis );
489 }
490 
491 /** USB CDC-ACM device IDs */
492 static struct usb_device_id cdc_acm_ids[] = {
493  {
494  .name = "cdc-acm",
495  .vendor = USB_ANY_ID,
496  .product = USB_ANY_ID,
497  },
498 };
499 
500 /** USB CDC-ACM driver */
501 struct usb_driver cdc_acm_driver __usb_driver = {
502  .ids = cdc_acm_ids,
503  .id_count = ( sizeof ( cdc_acm_ids ) / sizeof ( cdc_acm_ids[0] ) ),
506  .score = USB_SCORE_DEPRECATED,
507  .probe = acm_probe,
508  .remove = acm_remove,
509 };
510 
511 /** USB RF-RNDIS device IDs */
512 static struct usb_device_id rf_rndis_ids[] = {
513  {
514  .name = "rf-rndis",
515  .vendor = USB_ANY_ID,
516  .product = USB_ANY_ID,
517  },
518 };
519 
520 /** USB RF-RNDIS driver */
521 struct usb_driver rf_rndis_driver __usb_driver = {
522  .ids = rf_rndis_ids,
523  .id_count = ( sizeof ( rf_rndis_ids ) / sizeof ( rf_rndis_ids[0] ) ),
526  .score = USB_SCORE_DEPRECATED,
527  .probe = acm_probe,
528  .remove = acm_remove,
529 };
struct rndis_device * alloc_rndis(size_t priv_len)
Allocate RNDIS device.
Definition: rndis.c:1000
A USB driver.
Definition: usb.h:1381
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
A USB device ID.
Definition: usb.h:1335
static void acm_intr_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete interrupt transfer.
Definition: acm.c:68
struct usb_bus * bus
USB bus.
Definition: acm.h:35
#define ACM_RESPONSE_MTU
Encapsulated response buffer size.
Definition: acm.h:67
#define iob_put(iobuf, len)
Definition: iobuf.h:120
void(* complete)(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete transfer.
Definition: usb.h:481
int(* open)(struct rndis_device *rndis)
Open RNDIS device.
Definition: rndis.h:289
unsigned int comms
Communications interface.
Definition: usbnet.h:20
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
Definition: usb.h:703
static void acm_out_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk OUT transfer.
Definition: acm.c:212
#define le32_to_cpu(value)
Definition: byteswap.h:113
const char * name
Name.
Definition: usb.h:1337
Error codes.
static int acm_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
Definition: acm.c:429
#define CDC_RESPONSE_AVAILABLE
Response available.
Definition: cdc.h:44
Deprecated driver.
Definition: usb.h:1425
#define USB_SUBCLASS_CDC_ACM
CDC-ACM subclass.
Definition: acm.h:16
static void acm_in_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk IN transfer.
Definition: acm.c:146
static void rndis_tx_complete(struct rndis_device *rndis, struct io_buffer *iobuf)
Complete message transmission.
Definition: rndis.h:364
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
struct usbnet_device usbnet
USB network device.
Definition: acm.h:39
struct arbelprm_completion_with_error error
Definition: arbel.h:12
void unregister_rndis(struct rndis_device *rndis)
Unregister RNDIS device.
Definition: rndis.c:1054
#define ACM_IN_MAX_FILL
Bulk IN maximum fill level.
Definition: acm.h:55
int responded
An encapsulated response is available.
Definition: acm.h:42
#define DBGC(...)
Definition: compiler.h:505
static int acm_control_transmit(struct acm_device *acm, struct io_buffer *iobuf)
Send control packet.
Definition: acm.c:241
int usb_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int terminate)
Enqueue USB stream transfer.
Definition: usb.c:545
A data structure for storing profiling information.
Definition: profile.h:26
static struct usb_device_id rf_rndis_ids[]
USB RF-RNDIS device IDs.
Definition: acm.c:512
int open
Endpoint is open.
Definition: usb.h:404
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition: profile.h:171
static struct usb_device_id cdc_acm_ids[]
USB CDC-ACM device IDs.
Definition: acm.c:492
struct usb_endpoint intr
Interrupt endpoint.
Definition: usbnet.h:27
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:129
static struct rndis_operations acm_operations
USB RNDIS operations.
Definition: acm.c:408
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
#define USB_CLASS_WIRELESS
Class code for wireless devices.
Definition: acm.h:22
struct usb_endpoint out
Bulk OUT endpoint.
Definition: usbnet.h:31
#define USB_PROTOCOL_RADIO_RNDIS
Radio frequency RNDIS device protocol.
Definition: acm.h:28
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:212
A USB endpoint.
Definition: usb.h:389
const char * name
Name.
Definition: profile.h:28
static void acm_close(struct rndis_device *rndis)
Close RNDIS device.
Definition: acm.c:348
struct usb_port * port
USB port.
Definition: usb.h:712
static void acm_poll(struct rndis_device *rndis)
Poll for completed and received packets.
Definition: acm.c:384
static void acm_remove(struct usb_function *func)
Remove device.
Definition: acm.c:480
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
struct net_device * netdev
Network device.
Definition: rndis.h:319
static int cdc_get_encapsulated_response(struct usb_device *usb, unsigned int interface, void *data, size_t len)
Get encapsulated response.
Definition: cdc.h:97
#define DBGC_HDA(...)
Definition: compiler.h:506
An RNDIS device.
Definition: rndis.h:317
static void usb_refill_init(struct usb_endpoint *ep, size_t reserve, size_t len, unsigned int max)
Initialise USB endpoint refill.
Definition: usb.h:602
static int cdc_send_encapsulated_command(struct usb_device *usb, unsigned int interface, void *data, size_t len)
Send encapsulated command.
Definition: cdc.h:80
struct usb_device * usb
USB device.
Definition: acm.h:33
#define USB_SUBCLASS_WIRELESS_RADIO
Radio frequency device subclass.
Definition: acm.h:25
static void usb_func_set_drvdata(struct usb_function *func, void *priv)
Set USB function driver private data.
Definition: usb.h:692
static void profile_start(struct profiler *profiler)
Start profiling.
Definition: profile.h:158
USB RNDIS Ethernet driver.
Profiling.
void rndis_rx_err(struct rndis_device *rndis, struct io_buffer *iobuf, int rc)
Discard packet from underlying transport layer.
Definition: rndis.c:866
int usbnet_refill(struct usbnet_device *usbnet)
Refill USB network device bulk IN and interrupt endpoints.
Definition: usbnet.c:151
#define cpu_to_le32(value)
Definition: byteswap.h:107
A USB device.
Definition: usb.h:708
#define EPROTO
Protocol error.
Definition: errno.h:624
#define ACM_INTR_MAX_FILL
Interrupt maximum fill level.
Definition: acm.h:49
static void usb_poll(struct usb_bus *bus)
Poll USB bus.
Definition: usb.h:1051
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 size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
static struct usb_endpoint_driver_operations acm_out_operations
Bulk OUT endpoint operations.
Definition: acm.c:223
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
Definition: usb.h:1363
struct usb_endpoint in
Bulk IN endpoint.
Definition: usbnet.h:29
#define ACM_IN_MTU
Bulk IN buffer size.
Definition: acm.h:61
static struct usb_endpoint_driver_operations acm_in_operations
Bulk IN endpoint operations.
Definition: acm.c:179
Remote Network Driver Interface Specification.
A USB RNDIS network device.
Definition: acm.h:31
RNDIS device operations.
Definition: rndis.h:282
void rndis_rx(struct rndis_device *rndis, struct io_buffer *iobuf)
Receive packet from underlying transport layer.
Definition: rndis.c:829
struct usb_device * usb
USB device.
Definition: usb.h:663
static struct profiler acm_intr_profiler __profiler
Interrupt completion profiler.
Definition: acm.c:43
A USB setup data packet.
Definition: usb.h:68
static void rndis_init(struct rndis_device *rndis, struct rndis_operations *op)
Initialise an RNDIS device.
Definition: rndis.h:339
#define USB_CLASS_CDC
Class code for communications devices.
Definition: cdc.h:15
static int acm_open(struct rndis_device *rndis)
Open RNDIS device.
Definition: acm.c:328
struct device * dev
Underlying hardware device.
Definition: netdevice.h:364
static struct usb_endpoint_driver_operations acm_intr_operations
Interrupt endpoint operations.
Definition: acm.c:128
RNDIS message header.
Definition: rndis.h:23
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
USB network devices.
A USB configuration descriptor.
Definition: usb.h:195
uint32_t len
Length.
Definition: ena.h:14
#define USB_ANY_ID
Match-anything ID.
Definition: usb.h:1347
Universal Serial Bus (USB)
static int acm_transmit(struct rndis_device *rndis, struct io_buffer *iobuf)
Transmit packet.
Definition: acm.c:362
uint32_t mtu
Maximum MTU.
Definition: ena.h:28
static void usbnet_init(struct usbnet_device *usbnet, struct usb_function *func, struct usb_endpoint_driver_operations *intr, struct usb_endpoint_driver_operations *in, struct usb_endpoint_driver_operations *out)
Initialise USB network device.
Definition: usbnet.h:44
void * data
Start of data.
Definition: iobuf.h:48
struct usb_hub * hub
USB hub.
Definition: usb.h:800
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 USB_PROTOCOL_ACM_RNDIS
CDC-ACM RNDIS device protocol.
Definition: acm.h:19
#define cpu_to_le16(value)
Definition: byteswap.h:106
struct usb_driver cdc_acm_driver __usb_driver
USB CDC-ACM driver.
Definition: acm.c:501
int usbnet_describe(struct usbnet_device *usbnet, struct usb_configuration_descriptor *config)
Describe USB network device interfaces.
Definition: usbnet.c:277
char message[VMCONSOLE_BUFSIZE]
Definition: vmconsole.c:54
void usbnet_close(struct usbnet_device *usbnet)
Close USB network device.
Definition: usbnet.c:127
USB endpoint driver operations.
Definition: usb.h:474
struct device dev
Generic device.
Definition: usb.h:667
A USB function.
Definition: usb.h:659
static int acm_out_transmit(struct acm_device *acm, struct io_buffer *iobuf)
Transmit packet.
Definition: acm.c:190
struct usb_bus * bus
USB bus.
Definition: usb.h:830
static int acm_control_receive(struct acm_device *acm)
Receive control packet.
Definition: acm.c:268
void free_rndis(struct rndis_device *rndis)
Free RNDIS device.
Definition: rndis.c:1066
void rndis_tx_complete_err(struct rndis_device *rndis, struct io_buffer *iobuf, int rc)
Complete message transmission.
Definition: rndis.c:127
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
String functions.
struct rndis_device * rndis
RNDIS device.
Definition: acm.h:37
struct usb_device_id * ids
USB ID table.
Definition: usb.h:1383
A persistent I/O buffer.
Definition: iobuf.h:33
int usbnet_open(struct usbnet_device *usbnet)
Open USB network device.
Definition: usbnet.c:54