|
@@ -126,7 +126,8 @@ int ecm_fetch_mac ( struct usb_device *usb,
|
126
|
126
|
*/
|
127
|
127
|
static void ecm_intr_complete ( struct usb_endpoint *ep,
|
128
|
128
|
struct io_buffer *iobuf, int rc ) {
|
129
|
|
- struct ecm_device *ecm = container_of ( ep, struct ecm_device, intr );
|
|
129
|
+ struct ecm_device *ecm = container_of ( ep, struct ecm_device,
|
|
130
|
+ usbnet.intr );
|
130
|
131
|
struct net_device *netdev = ecm->netdev;
|
131
|
132
|
struct usb_setup_packet *message;
|
132
|
133
|
size_t len = iob_len ( iobuf );
|
|
@@ -197,43 +198,6 @@ static struct usb_endpoint_driver_operations ecm_intr_operations = {
|
197
|
198
|
.complete = ecm_intr_complete,
|
198
|
199
|
};
|
199
|
200
|
|
200
|
|
-/**
|
201
|
|
- * Open communications interface
|
202
|
|
- *
|
203
|
|
- * @v ecm CDC-ECM device
|
204
|
|
- * @ret rc Return status code
|
205
|
|
- */
|
206
|
|
-static int ecm_comms_open ( struct ecm_device *ecm ) {
|
207
|
|
- int rc;
|
208
|
|
-
|
209
|
|
- /* Open interrupt endpoint */
|
210
|
|
- if ( ( rc = usb_endpoint_open ( &ecm->intr ) ) != 0 ) {
|
211
|
|
- DBGC ( ecm, "ECM %p could not open interrupt: %s\n",
|
212
|
|
- ecm, strerror ( rc ) );
|
213
|
|
- goto err_open;
|
214
|
|
- }
|
215
|
|
-
|
216
|
|
- /* Refill interrupt endpoint */
|
217
|
|
- usb_refill ( &ecm->intr );
|
218
|
|
-
|
219
|
|
- return 0;
|
220
|
|
-
|
221
|
|
- usb_endpoint_close ( &ecm->intr );
|
222
|
|
- err_open:
|
223
|
|
- return rc;
|
224
|
|
-}
|
225
|
|
-
|
226
|
|
-/**
|
227
|
|
- * Close communications interface
|
228
|
|
- *
|
229
|
|
- * @v ecm CDC-ECM device
|
230
|
|
- */
|
231
|
|
-static void ecm_comms_close ( struct ecm_device *ecm ) {
|
232
|
|
-
|
233
|
|
- /* Close interrupt endpoint */
|
234
|
|
- usb_endpoint_close ( &ecm->intr );
|
235
|
|
-}
|
236
|
|
-
|
237
|
201
|
/******************************************************************************
|
238
|
202
|
*
|
239
|
203
|
* CDC-ECM data interface
|
|
@@ -250,7 +214,8 @@ static void ecm_comms_close ( struct ecm_device *ecm ) {
|
250
|
214
|
*/
|
251
|
215
|
static void ecm_in_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
|
252
|
216
|
int rc ) {
|
253
|
|
- struct ecm_device *ecm = container_of ( ep, struct ecm_device, in );
|
|
217
|
+ struct ecm_device *ecm = container_of ( ep, struct ecm_device,
|
|
218
|
+ usbnet.in );
|
254
|
219
|
struct net_device *netdev = ecm->netdev;
|
255
|
220
|
|
256
|
221
|
/* Profile receive completions */
|
|
@@ -299,7 +264,7 @@ static int ecm_out_transmit ( struct ecm_device *ecm,
|
299
|
264
|
profile_start ( &ecm_out_profiler );
|
300
|
265
|
|
301
|
266
|
/* Enqueue I/O buffer */
|
302
|
|
- if ( ( rc = usb_stream ( &ecm->out, iobuf, 1 ) ) != 0 )
|
|
267
|
+ if ( ( rc = usb_stream ( &ecm->usbnet.out, iobuf, 1 ) ) != 0 )
|
303
|
268
|
return rc;
|
304
|
269
|
|
305
|
270
|
profile_stop ( &ecm_out_profiler );
|
|
@@ -315,7 +280,8 @@ static int ecm_out_transmit ( struct ecm_device *ecm,
|
315
|
280
|
*/
|
316
|
281
|
static void ecm_out_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
|
317
|
282
|
int rc ) {
|
318
|
|
- struct ecm_device *ecm = container_of ( ep, struct ecm_device, out );
|
|
283
|
+ struct ecm_device *ecm = container_of ( ep, struct ecm_device,
|
|
284
|
+ usbnet.out );
|
319
|
285
|
struct net_device *netdev = ecm->netdev;
|
320
|
286
|
|
321
|
287
|
/* Report TX completion */
|
|
@@ -327,68 +293,6 @@ static struct usb_endpoint_driver_operations ecm_out_operations = {
|
327
|
293
|
.complete = ecm_out_complete,
|
328
|
294
|
};
|
329
|
295
|
|
330
|
|
-/**
|
331
|
|
- * Open data interface
|
332
|
|
- *
|
333
|
|
- * @v ecm CDC-ECM device
|
334
|
|
- * @ret rc Return status code
|
335
|
|
- */
|
336
|
|
-static int ecm_data_open ( struct ecm_device *ecm ) {
|
337
|
|
- struct usb_device *usb = ecm->usb;
|
338
|
|
- int rc;
|
339
|
|
-
|
340
|
|
- /* Select alternate setting for data interface */
|
341
|
|
- if ( ( rc = usb_set_interface ( usb, ecm->data,
|
342
|
|
- ECM_DATA_ALTERNATE ) ) != 0 ) {
|
343
|
|
- DBGC ( ecm, "ECM %p could not set alternate interface: %s\n",
|
344
|
|
- ecm, strerror ( rc ) );
|
345
|
|
- goto err_set_interface;
|
346
|
|
- }
|
347
|
|
-
|
348
|
|
- /* Open bulk IN endpoint */
|
349
|
|
- if ( ( rc = usb_endpoint_open ( &ecm->in ) ) != 0 ) {
|
350
|
|
- DBGC ( ecm, "ECM %p could not open bulk IN: %s\n",
|
351
|
|
- ecm, strerror ( rc ) );
|
352
|
|
- goto err_open_in;
|
353
|
|
- }
|
354
|
|
-
|
355
|
|
- /* Open bulk OUT endpoint */
|
356
|
|
- if ( ( rc = usb_endpoint_open ( &ecm->out ) ) != 0 ) {
|
357
|
|
- DBGC ( ecm, "ECM %p could not open bulk OUT: %s\n",
|
358
|
|
- ecm, strerror ( rc ) );
|
359
|
|
- goto err_open_out;
|
360
|
|
- }
|
361
|
|
-
|
362
|
|
- /* Refill bulk IN endpoint */
|
363
|
|
- usb_refill ( &ecm->in );
|
364
|
|
-
|
365
|
|
- return 0;
|
366
|
|
-
|
367
|
|
- usb_endpoint_close ( &ecm->out );
|
368
|
|
- err_open_out:
|
369
|
|
- usb_endpoint_close ( &ecm->in );
|
370
|
|
- err_open_in:
|
371
|
|
- usb_set_interface ( usb, ecm->data, 0 );
|
372
|
|
- err_set_interface:
|
373
|
|
- return rc;
|
374
|
|
-}
|
375
|
|
-
|
376
|
|
-/**
|
377
|
|
- * Close data interface
|
378
|
|
- *
|
379
|
|
- * @v ecm CDC-ECM device
|
380
|
|
- */
|
381
|
|
-static void ecm_data_close ( struct ecm_device *ecm ) {
|
382
|
|
- struct usb_device *usb = ecm->usb;
|
383
|
|
-
|
384
|
|
- /* Close endpoints */
|
385
|
|
- usb_endpoint_close ( &ecm->out );
|
386
|
|
- usb_endpoint_close ( &ecm->in );
|
387
|
|
-
|
388
|
|
- /* Reset data interface */
|
389
|
|
- usb_set_interface ( usb, ecm->data, 0 );
|
390
|
|
-}
|
391
|
|
-
|
392
|
296
|
/******************************************************************************
|
393
|
297
|
*
|
394
|
298
|
* Network device interface
|
|
@@ -408,13 +312,12 @@ static int ecm_open ( struct net_device *netdev ) {
|
408
|
312
|
unsigned int filter;
|
409
|
313
|
int rc;
|
410
|
314
|
|
411
|
|
- /* Open communications interface */
|
412
|
|
- if ( ( rc = ecm_comms_open ( ecm ) ) != 0 )
|
413
|
|
- goto err_comms_open;
|
414
|
|
-
|
415
|
|
- /* Open data interface */
|
416
|
|
- if ( ( rc = ecm_data_open ( ecm ) ) != 0 )
|
417
|
|
- goto err_data_open;
|
|
315
|
+ /* Open USB network device */
|
|
316
|
+ if ( ( rc = usbnet_open ( &ecm->usbnet ) ) != 0 ) {
|
|
317
|
+ DBGC ( ecm, "ECM %p could not open: %s\n",
|
|
318
|
+ ecm, strerror ( rc ) );
|
|
319
|
+ goto err_open;
|
|
320
|
+ }
|
418
|
321
|
|
419
|
322
|
/* Set packet filter */
|
420
|
323
|
filter = ( ECM_PACKET_TYPE_PROMISCUOUS |
|
|
@@ -422,7 +325,7 @@ static int ecm_open ( struct net_device *netdev ) {
|
422
|
325
|
ECM_PACKET_TYPE_DIRECTED |
|
423
|
326
|
ECM_PACKET_TYPE_BROADCAST );
|
424
|
327
|
if ( ( rc = usb_control ( usb, ECM_SET_ETHERNET_PACKET_FILTER,
|
425
|
|
- filter, ecm->comms, NULL, 0 ) ) != 0 ) {
|
|
328
|
+ filter, ecm->usbnet.comms, NULL, 0 ) ) != 0 ){
|
426
|
329
|
DBGC ( ecm, "ECM %p could not set packet filter: %s\n",
|
427
|
330
|
ecm, strerror ( rc ) );
|
428
|
331
|
goto err_set_filter;
|
|
@@ -431,10 +334,8 @@ static int ecm_open ( struct net_device *netdev ) {
|
431
|
334
|
return 0;
|
432
|
335
|
|
433
|
336
|
err_set_filter:
|
434
|
|
- ecm_data_close ( ecm );
|
435
|
|
- err_data_open:
|
436
|
|
- ecm_comms_close ( ecm );
|
437
|
|
- err_comms_open:
|
|
337
|
+ usbnet_close ( &ecm->usbnet );
|
|
338
|
+ err_open:
|
438
|
339
|
return rc;
|
439
|
340
|
}
|
440
|
341
|
|
|
@@ -446,11 +347,8 @@ static int ecm_open ( struct net_device *netdev ) {
|
446
|
347
|
static void ecm_close ( struct net_device *netdev ) {
|
447
|
348
|
struct ecm_device *ecm = netdev->priv;
|
448
|
349
|
|
449
|
|
- /* Close data interface */
|
450
|
|
- ecm_data_close ( ecm );
|
451
|
|
-
|
452
|
|
- /* Close communications interface */
|
453
|
|
- ecm_comms_close ( ecm );
|
|
350
|
+ /* Close USB network device */
|
|
351
|
+ usbnet_close ( &ecm->usbnet );
|
454
|
352
|
}
|
455
|
353
|
|
456
|
354
|
/**
|
|
@@ -484,12 +382,8 @@ static void ecm_poll ( struct net_device *netdev ) {
|
484
|
382
|
/* Poll USB bus */
|
485
|
383
|
usb_poll ( ecm->bus );
|
486
|
384
|
|
487
|
|
- /* Refill interrupt endpoint */
|
488
|
|
- if ( ( rc = usb_refill ( &ecm->intr ) ) != 0 )
|
489
|
|
- netdev_rx_err ( netdev, NULL, rc );
|
490
|
|
-
|
491
|
|
- /* Refill bulk IN endpoint */
|
492
|
|
- if ( ( rc = usb_refill ( &ecm->in ) ) != 0 )
|
|
385
|
+ /* Refill endpoints */
|
|
386
|
+ if ( ( rc = usbnet_refill ( &ecm->usbnet ) ) != 0 )
|
493
|
387
|
netdev_rx_err ( netdev, NULL, rc );
|
494
|
388
|
}
|
495
|
389
|
|
|
@@ -521,7 +415,6 @@ static int ecm_probe ( struct usb_function *func,
|
521
|
415
|
struct net_device *netdev;
|
522
|
416
|
struct ecm_device *ecm;
|
523
|
417
|
struct usb_interface_descriptor *comms;
|
524
|
|
- struct usb_interface_descriptor *data;
|
525
|
418
|
struct ecm_ethernet_descriptor *ethernet;
|
526
|
419
|
int rc;
|
527
|
420
|
|
|
@@ -538,65 +431,22 @@ static int ecm_probe ( struct usb_function *func,
|
538
|
431
|
ecm->usb = usb;
|
539
|
432
|
ecm->bus = usb->port->hub->bus;
|
540
|
433
|
ecm->netdev = netdev;
|
541
|
|
- usb_endpoint_init ( &ecm->intr, usb, &ecm_intr_operations );
|
542
|
|
- usb_endpoint_init ( &ecm->in, usb, &ecm_in_operations );
|
543
|
|
- usb_endpoint_init ( &ecm->out, usb, &ecm_out_operations );
|
544
|
|
- usb_refill_init ( &ecm->intr, 0, ECM_INTR_MAX_FILL );
|
545
|
|
- usb_refill_init ( &ecm->in, ECM_IN_MTU, ECM_IN_MAX_FILL );
|
|
434
|
+ usbnet_init ( &ecm->usbnet, func, &ecm_intr_operations,
|
|
435
|
+ &ecm_in_operations, &ecm_out_operations );
|
|
436
|
+ usb_refill_init ( &ecm->usbnet.intr, 0, ECM_INTR_MAX_FILL );
|
|
437
|
+ usb_refill_init ( &ecm->usbnet.in, ECM_IN_MTU, ECM_IN_MAX_FILL );
|
546
|
438
|
DBGC ( ecm, "ECM %p on %s\n", ecm, func->name );
|
547
|
439
|
|
548
|
|
- /* Identify interfaces */
|
549
|
|
- if ( func->count < ECM_INTERFACE_COUNT ) {
|
550
|
|
- DBGC ( ecm, "ECM %p has only %d interfaces\n",
|
551
|
|
- ecm, func->count );
|
552
|
|
- rc = -EINVAL;
|
553
|
|
- goto err_count;
|
554
|
|
- }
|
555
|
|
- ecm->comms = func->interface[ECM_INTERFACE_COMMS];
|
556
|
|
- ecm->data = func->interface[ECM_INTERFACE_DATA];
|
557
|
|
-
|
558
|
|
- /* Locate communications interface descriptor */
|
559
|
|
- comms = usb_interface_descriptor ( config, ecm->comms, 0 );
|
560
|
|
- if ( ! comms ) {
|
561
|
|
- DBGC ( ecm, "ECM %p has no communications interface\n", ecm );
|
562
|
|
- rc = -EINVAL;
|
563
|
|
- goto err_comms;
|
564
|
|
- }
|
565
|
|
-
|
566
|
|
- /* Locate data interface descriptor */
|
567
|
|
- data = usb_interface_descriptor ( config, ecm->data,
|
568
|
|
- ECM_DATA_ALTERNATE );
|
569
|
|
- if ( ! data ) {
|
570
|
|
- DBGC ( ecm, "ECM %p has no data interface\n", ecm );
|
571
|
|
- rc = -EINVAL;
|
572
|
|
- goto err_data;
|
573
|
|
- }
|
574
|
|
-
|
575
|
|
- /* Describe interrupt endpoint */
|
576
|
|
- if ( ( rc = usb_endpoint_described ( &ecm->intr, config, comms,
|
577
|
|
- USB_INTERRUPT, 0 ) ) != 0 ) {
|
578
|
|
- DBGC ( ecm, "ECM %p could not describe interrupt endpoint: "
|
579
|
|
- "%s\n", ecm, strerror ( rc ) );
|
580
|
|
- goto err_interrupt;
|
581
|
|
- }
|
582
|
|
-
|
583
|
|
- /* Describe bulk IN endpoint */
|
584
|
|
- if ( ( rc = usb_endpoint_described ( &ecm->in, config, data,
|
585
|
|
- USB_BULK_IN, 0 ) ) != 0 ) {
|
586
|
|
- DBGC ( ecm, "ECM %p could not describe bulk IN endpoint: "
|
587
|
|
- "%s\n", ecm, strerror ( rc ) );
|
588
|
|
- goto err_bulk_in;
|
589
|
|
- }
|
590
|
|
-
|
591
|
|
- /* Describe bulk OUT endpoint */
|
592
|
|
- if ( ( rc = usb_endpoint_described ( &ecm->out, config, data,
|
593
|
|
- USB_BULK_OUT, 0 ) ) != 0 ) {
|
594
|
|
- DBGC ( ecm, "ECM %p could not describe bulk OUT endpoint: "
|
595
|
|
- "%s\n", ecm, strerror ( rc ) );
|
596
|
|
- goto err_bulk_out;
|
|
440
|
+ /* Describe USB network device */
|
|
441
|
+ if ( ( rc = usbnet_describe ( &ecm->usbnet, config ) ) != 0 ) {
|
|
442
|
+ DBGC ( ecm, "ECM %p could not describe: %s\n",
|
|
443
|
+ ecm, strerror ( rc ) );
|
|
444
|
+ goto err_describe;
|
597
|
445
|
}
|
598
|
446
|
|
599
|
447
|
/* Locate Ethernet descriptor */
|
|
448
|
+ comms = usb_interface_descriptor ( config, ecm->usbnet.comms, 0 );
|
|
449
|
+ assert ( comms != NULL );
|
600
|
450
|
ethernet = ecm_ethernet_descriptor ( config, comms );
|
601
|
451
|
if ( ! ethernet ) {
|
602
|
452
|
DBGC ( ecm, "ECM %p has no Ethernet descriptor\n", ecm );
|
|
@@ -622,12 +472,7 @@ static int ecm_probe ( struct usb_function *func,
|
622
|
472
|
err_register:
|
623
|
473
|
err_fetch_mac:
|
624
|
474
|
err_ethernet:
|
625
|
|
- err_bulk_out:
|
626
|
|
- err_bulk_in:
|
627
|
|
- err_interrupt:
|
628
|
|
- err_data:
|
629
|
|
- err_comms:
|
630
|
|
- err_count:
|
|
475
|
+ err_describe:
|
631
|
476
|
netdev_nullify ( netdev );
|
632
|
477
|
netdev_put ( netdev );
|
633
|
478
|
err_alloc:
|