|  | @@ -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:
 |