1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * f_phonet.c -- USB CDC Phonet function 4 * 5 * Copyright (C) 2007-2008 Nokia Corporation. All rights reserved. 6 * 7 * Author: Rémi Denis-Courmont 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License 11 * version 2 as published by the Free Software Foundation. 12 */ 13 14 #include <linux/mm.h> 15 #include <linux/slab.h> 16 #include <linux/kernel.h> 17 #include <linux/module.h> 18 #include <linux/device.h> 19 20 #include <linux/netdevice.h> 21 #include <linux/if_ether.h> 22 #include <linux/if_phonet.h> 23 #include <linux/if_arp.h> 24 25 #include <linux/usb/ch9.h> 26 #include <linux/usb/cdc.h> 27 #include <linux/usb/composite.h> 28 29 #include "u_phonet.h" 30 #include "u_ether.h" 31 32 #define PN_MEDIA_USB 0x1B 33 #define MAXPACKET 512 34 #if (PAGE_SIZE % MAXPACKET) 35 #error MAXPACKET must divide PAGE_SIZE! 36 #endif 37 38 /*-------------------------------------------------------------------------*/ 39 40 struct phonet_port { 41 struct f_phonet *usb; 42 spinlock_t lock; 43 }; 44 45 struct f_phonet { 46 struct usb_function function; 47 struct { 48 struct sk_buff *skb; 49 spinlock_t lock; 50 } rx; 51 struct net_device *dev; 52 struct usb_ep *in_ep, *out_ep; 53 54 struct usb_request *in_req; 55 struct usb_request *out_reqv[0]; 56 }; 57 58 static int phonet_rxq_size = 17; 59 60 static inline struct f_phonet *func_to_pn(struct usb_function *f) 61 { 62 return container_of(f, struct f_phonet, function); 63 } 64 65 /*-------------------------------------------------------------------------*/ 66 67 #define USB_CDC_SUBCLASS_PHONET 0xfe 68 #define USB_CDC_PHONET_TYPE 0xab 69 70 static struct usb_interface_descriptor 71 pn_control_intf_desc = { 72 .bLength = sizeof pn_control_intf_desc, 73 .bDescriptorType = USB_DT_INTERFACE, 74 75 /* .bInterfaceNumber = DYNAMIC, */ 76 .bInterfaceClass = USB_CLASS_COMM, 77 .bInterfaceSubClass = USB_CDC_SUBCLASS_PHONET, 78 }; 79 80 static const struct usb_cdc_header_desc 81 pn_header_desc = { 82 .bLength = sizeof pn_header_desc, 83 .bDescriptorType = USB_DT_CS_INTERFACE, 84 .bDescriptorSubType = USB_CDC_HEADER_TYPE, 85 .bcdCDC = cpu_to_le16(0x0110), 86 }; 87 88 static const struct usb_cdc_header_desc 89 pn_phonet_desc = { 90 .bLength = sizeof pn_phonet_desc, 91 .bDescriptorType = USB_DT_CS_INTERFACE, 92 .bDescriptorSubType = USB_CDC_PHONET_TYPE, 93 .bcdCDC = cpu_to_le16(0x1505), /* ??? */ 94 }; 95 96 static struct usb_cdc_union_desc 97 pn_union_desc = { 98 .bLength = sizeof pn_union_desc, 99 .bDescriptorType = USB_DT_CS_INTERFACE, 100 .bDescriptorSubType = USB_CDC_UNION_TYPE, 101 102 /* .bMasterInterface0 = DYNAMIC, */ 103 /* .bSlaveInterface0 = DYNAMIC, */ 104 }; 105 106 static struct usb_interface_descriptor 107 pn_data_nop_intf_desc = { 108 .bLength = sizeof pn_data_nop_intf_desc, 109 .bDescriptorType = USB_DT_INTERFACE, 110 111 /* .bInterfaceNumber = DYNAMIC, */ 112 .bAlternateSetting = 0, 113 .bNumEndpoints = 0, 114 .bInterfaceClass = USB_CLASS_CDC_DATA, 115 }; 116 117 static struct usb_interface_descriptor 118 pn_data_intf_desc = { 119 .bLength = sizeof pn_data_intf_desc, 120 .bDescriptorType = USB_DT_INTERFACE, 121 122 /* .bInterfaceNumber = DYNAMIC, */ 123 .bAlternateSetting = 1, 124 .bNumEndpoints = 2, 125 .bInterfaceClass = USB_CLASS_CDC_DATA, 126 }; 127 128 static struct usb_endpoint_descriptor 129 pn_fs_sink_desc = { 130 .bLength = USB_DT_ENDPOINT_SIZE, 131 .bDescriptorType = USB_DT_ENDPOINT, 132 133 .bEndpointAddress = USB_DIR_OUT, 134 .bmAttributes = USB_ENDPOINT_XFER_BULK, 135 }; 136 137 static struct usb_endpoint_descriptor 138 pn_hs_sink_desc = { 139 .bLength = USB_DT_ENDPOINT_SIZE, 140 .bDescriptorType = USB_DT_ENDPOINT, 141 142 .bEndpointAddress = USB_DIR_OUT, 143 .bmAttributes = USB_ENDPOINT_XFER_BULK, 144 .wMaxPacketSize = cpu_to_le16(MAXPACKET), 145 }; 146 147 static struct usb_endpoint_descriptor 148 pn_fs_source_desc = { 149 .bLength = USB_DT_ENDPOINT_SIZE, 150 .bDescriptorType = USB_DT_ENDPOINT, 151 152 .bEndpointAddress = USB_DIR_IN, 153 .bmAttributes = USB_ENDPOINT_XFER_BULK, 154 }; 155 156 static struct usb_endpoint_descriptor 157 pn_hs_source_desc = { 158 .bLength = USB_DT_ENDPOINT_SIZE, 159 .bDescriptorType = USB_DT_ENDPOINT, 160 161 .bEndpointAddress = USB_DIR_IN, 162 .bmAttributes = USB_ENDPOINT_XFER_BULK, 163 .wMaxPacketSize = cpu_to_le16(512), 164 }; 165 166 static struct usb_descriptor_header *fs_pn_function[] = { 167 (struct usb_descriptor_header *) &pn_control_intf_desc, 168 (struct usb_descriptor_header *) &pn_header_desc, 169 (struct usb_descriptor_header *) &pn_phonet_desc, 170 (struct usb_descriptor_header *) &pn_union_desc, 171 (struct usb_descriptor_header *) &pn_data_nop_intf_desc, 172 (struct usb_descriptor_header *) &pn_data_intf_desc, 173 (struct usb_descriptor_header *) &pn_fs_sink_desc, 174 (struct usb_descriptor_header *) &pn_fs_source_desc, 175 NULL, 176 }; 177 178 static struct usb_descriptor_header *hs_pn_function[] = { 179 (struct usb_descriptor_header *) &pn_control_intf_desc, 180 (struct usb_descriptor_header *) &pn_header_desc, 181 (struct usb_descriptor_header *) &pn_phonet_desc, 182 (struct usb_descriptor_header *) &pn_union_desc, 183 (struct usb_descriptor_header *) &pn_data_nop_intf_desc, 184 (struct usb_descriptor_header *) &pn_data_intf_desc, 185 (struct usb_descriptor_header *) &pn_hs_sink_desc, 186 (struct usb_descriptor_header *) &pn_hs_source_desc, 187 NULL, 188 }; 189 190 /*-------------------------------------------------------------------------*/ 191 192 static int pn_net_open(struct net_device *dev) 193 { 194 netif_wake_queue(dev); 195 return 0; 196 } 197 198 static int pn_net_close(struct net_device *dev) 199 { 200 netif_stop_queue(dev); 201 return 0; 202 } 203 204 static void pn_tx_complete(struct usb_ep *ep, struct usb_request *req) 205 { 206 struct f_phonet *fp = ep->driver_data; 207 struct net_device *dev = fp->dev; 208 struct sk_buff *skb = req->context; 209 210 switch (req->status) { 211 case 0: 212 dev->stats.tx_packets++; 213 dev->stats.tx_bytes += skb->len; 214 break; 215 216 case -ESHUTDOWN: /* disconnected */ 217 case -ECONNRESET: /* disabled */ 218 dev->stats.tx_aborted_errors++; 219 /* fall through */ 220 default: 221 dev->stats.tx_errors++; 222 } 223 224 dev_kfree_skb_any(skb); 225 netif_wake_queue(dev); 226 } 227 228 static int pn_net_xmit(struct sk_buff *skb, struct net_device *dev) 229 { 230 struct phonet_port *port = netdev_priv(dev); 231 struct f_phonet *fp; 232 struct usb_request *req; 233 unsigned long flags; 234 235 if (skb->protocol != htons(ETH_P_PHONET)) 236 goto out; 237 238 spin_lock_irqsave(&port->lock, flags); 239 fp = port->usb; 240 if (unlikely(!fp)) /* race with carrier loss */ 241 goto out_unlock; 242 243 req = fp->in_req; 244 req->buf = skb->data; 245 req->length = skb->len; 246 req->complete = pn_tx_complete; 247 req->zero = 1; 248 req->context = skb; 249 250 if (unlikely(usb_ep_queue(fp->in_ep, req, GFP_ATOMIC))) 251 goto out_unlock; 252 253 netif_stop_queue(dev); 254 skb = NULL; 255 256 out_unlock: 257 spin_unlock_irqrestore(&port->lock, flags); 258 out: 259 if (unlikely(skb)) { 260 dev_kfree_skb(skb); 261 dev->stats.tx_dropped++; 262 } 263 return NETDEV_TX_OK; 264 } 265 266 static const struct net_device_ops pn_netdev_ops = { 267 .ndo_open = pn_net_open, 268 .ndo_stop = pn_net_close, 269 .ndo_start_xmit = pn_net_xmit, 270 }; 271 272 static void pn_net_setup(struct net_device *dev) 273 { 274 dev->features = 0; 275 dev->type = ARPHRD_PHONET; 276 dev->flags = IFF_POINTOPOINT | IFF_NOARP; 277 dev->mtu = PHONET_DEV_MTU; 278 dev->min_mtu = PHONET_MIN_MTU; 279 dev->max_mtu = PHONET_MAX_MTU; 280 dev->hard_header_len = 1; 281 dev->dev_addr[0] = PN_MEDIA_USB; 282 dev->addr_len = 1; 283 dev->tx_queue_len = 1; 284 285 dev->netdev_ops = &pn_netdev_ops; 286 dev->needs_free_netdev = true; 287 dev->header_ops = &phonet_header_ops; 288 } 289 290 /*-------------------------------------------------------------------------*/ 291 292 /* 293 * Queue buffer for data from the host 294 */ 295 static int 296 pn_rx_submit(struct f_phonet *fp, struct usb_request *req, gfp_t gfp_flags) 297 { 298 struct page *page; 299 int err; 300 301 page = __dev_alloc_page(gfp_flags | __GFP_NOMEMALLOC); 302 if (!page) 303 return -ENOMEM; 304 305 req->buf = page_address(page); 306 req->length = PAGE_SIZE; 307 req->context = page; 308 309 err = usb_ep_queue(fp->out_ep, req, gfp_flags); 310 if (unlikely(err)) 311 put_page(page); 312 return err; 313 } 314 315 static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req) 316 { 317 struct f_phonet *fp = ep->driver_data; 318 struct net_device *dev = fp->dev; 319 struct page *page = req->context; 320 struct sk_buff *skb; 321 unsigned long flags; 322 int status = req->status; 323 324 switch (status) { 325 case 0: 326 spin_lock_irqsave(&fp->rx.lock, flags); 327 skb = fp->rx.skb; 328 if (!skb) 329 skb = fp->rx.skb = netdev_alloc_skb(dev, 12); 330 if (req->actual < req->length) /* Last fragment */ 331 fp->rx.skb = NULL; 332 spin_unlock_irqrestore(&fp->rx.lock, flags); 333 334 if (unlikely(!skb)) 335 break; 336 337 if (skb->len == 0) { /* First fragment */ 338 skb->protocol = htons(ETH_P_PHONET); 339 skb_reset_mac_header(skb); 340 /* Can't use pskb_pull() on page in IRQ */ 341 skb_put_data(skb, page_address(page), 1); 342 } 343 344 skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, 345 skb->len <= 1, req->actual, PAGE_SIZE); 346 page = NULL; 347 348 if (req->actual < req->length) { /* Last fragment */ 349 skb->dev = dev; 350 dev->stats.rx_packets++; 351 dev->stats.rx_bytes += skb->len; 352 353 netif_rx(skb); 354 } 355 break; 356 357 /* Do not resubmit in these cases: */ 358 case -ESHUTDOWN: /* disconnect */ 359 case -ECONNABORTED: /* hw reset */ 360 case -ECONNRESET: /* dequeued (unlink or netif down) */ 361 req = NULL; 362 break; 363 364 /* Do resubmit in these cases: */ 365 case -EOVERFLOW: /* request buffer overflow */ 366 dev->stats.rx_over_errors++; 367 /* fall through */ 368 default: 369 dev->stats.rx_errors++; 370 break; 371 } 372 373 if (page) 374 put_page(page); 375 if (req) 376 pn_rx_submit(fp, req, GFP_ATOMIC); 377 } 378 379 /*-------------------------------------------------------------------------*/ 380 381 static void __pn_reset(struct usb_function *f) 382 { 383 struct f_phonet *fp = func_to_pn(f); 384 struct net_device *dev = fp->dev; 385 struct phonet_port *port = netdev_priv(dev); 386 387 netif_carrier_off(dev); 388 port->usb = NULL; 389 390 usb_ep_disable(fp->out_ep); 391 usb_ep_disable(fp->in_ep); 392 if (fp->rx.skb) { 393 dev_kfree_skb_irq(fp->rx.skb); 394 fp->rx.skb = NULL; 395 } 396 } 397 398 static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt) 399 { 400 struct f_phonet *fp = func_to_pn(f); 401 struct usb_gadget *gadget = fp->function.config->cdev->gadget; 402 403 if (intf == pn_control_intf_desc.bInterfaceNumber) 404 /* control interface, no altsetting */ 405 return (alt > 0) ? -EINVAL : 0; 406 407 if (intf == pn_data_intf_desc.bInterfaceNumber) { 408 struct net_device *dev = fp->dev; 409 struct phonet_port *port = netdev_priv(dev); 410 411 /* data intf (0: inactive, 1: active) */ 412 if (alt > 1) 413 return -EINVAL; 414 415 spin_lock(&port->lock); 416 417 if (fp->in_ep->enabled) 418 __pn_reset(f); 419 420 if (alt == 1) { 421 int i; 422 423 if (config_ep_by_speed(gadget, f, fp->in_ep) || 424 config_ep_by_speed(gadget, f, fp->out_ep)) { 425 fp->in_ep->desc = NULL; 426 fp->out_ep->desc = NULL; 427 spin_unlock(&port->lock); 428 return -EINVAL; 429 } 430 usb_ep_enable(fp->out_ep); 431 usb_ep_enable(fp->in_ep); 432 433 port->usb = fp; 434 fp->out_ep->driver_data = fp; 435 fp->in_ep->driver_data = fp; 436 437 netif_carrier_on(dev); 438 for (i = 0; i < phonet_rxq_size; i++) 439 pn_rx_submit(fp, fp->out_reqv[i], GFP_ATOMIC); 440 } 441 spin_unlock(&port->lock); 442 return 0; 443 } 444 445 return -EINVAL; 446 } 447 448 static int pn_get_alt(struct usb_function *f, unsigned intf) 449 { 450 struct f_phonet *fp = func_to_pn(f); 451 452 if (intf == pn_control_intf_desc.bInterfaceNumber) 453 return 0; 454 455 if (intf == pn_data_intf_desc.bInterfaceNumber) { 456 struct phonet_port *port = netdev_priv(fp->dev); 457 u8 alt; 458 459 spin_lock(&port->lock); 460 alt = port->usb != NULL; 461 spin_unlock(&port->lock); 462 return alt; 463 } 464 465 return -EINVAL; 466 } 467 468 static void pn_disconnect(struct usb_function *f) 469 { 470 struct f_phonet *fp = func_to_pn(f); 471 struct phonet_port *port = netdev_priv(fp->dev); 472 unsigned long flags; 473 474 /* remain disabled until set_alt */ 475 spin_lock_irqsave(&port->lock, flags); 476 __pn_reset(f); 477 spin_unlock_irqrestore(&port->lock, flags); 478 } 479 480 /*-------------------------------------------------------------------------*/ 481 482 static int pn_bind(struct usb_configuration *c, struct usb_function *f) 483 { 484 struct usb_composite_dev *cdev = c->cdev; 485 struct usb_gadget *gadget = cdev->gadget; 486 struct f_phonet *fp = func_to_pn(f); 487 struct usb_ep *ep; 488 int status, i; 489 490 struct f_phonet_opts *phonet_opts; 491 492 phonet_opts = container_of(f->fi, struct f_phonet_opts, func_inst); 493 494 /* 495 * in drivers/usb/gadget/configfs.c:configfs_composite_bind() 496 * configurations are bound in sequence with list_for_each_entry, 497 * in each configuration its functions are bound in sequence 498 * with list_for_each_entry, so we assume no race condition 499 * with regard to phonet_opts->bound access 500 */ 501 if (!phonet_opts->bound) { 502 gphonet_set_gadget(phonet_opts->net, gadget); 503 status = gphonet_register_netdev(phonet_opts->net); 504 if (status) 505 return status; 506 phonet_opts->bound = true; 507 } 508 509 /* Reserve interface IDs */ 510 status = usb_interface_id(c, f); 511 if (status < 0) 512 goto err; 513 pn_control_intf_desc.bInterfaceNumber = status; 514 pn_union_desc.bMasterInterface0 = status; 515 516 status = usb_interface_id(c, f); 517 if (status < 0) 518 goto err; 519 pn_data_nop_intf_desc.bInterfaceNumber = status; 520 pn_data_intf_desc.bInterfaceNumber = status; 521 pn_union_desc.bSlaveInterface0 = status; 522 523 /* Reserve endpoints */ 524 status = -ENODEV; 525 ep = usb_ep_autoconfig(gadget, &pn_fs_sink_desc); 526 if (!ep) 527 goto err; 528 fp->out_ep = ep; 529 530 ep = usb_ep_autoconfig(gadget, &pn_fs_source_desc); 531 if (!ep) 532 goto err; 533 fp->in_ep = ep; 534 535 pn_hs_sink_desc.bEndpointAddress = pn_fs_sink_desc.bEndpointAddress; 536 pn_hs_source_desc.bEndpointAddress = pn_fs_source_desc.bEndpointAddress; 537 538 /* Do not try to bind Phonet twice... */ 539 status = usb_assign_descriptors(f, fs_pn_function, hs_pn_function, 540 NULL, NULL); 541 if (status) 542 goto err; 543 544 /* Incoming USB requests */ 545 status = -ENOMEM; 546 for (i = 0; i < phonet_rxq_size; i++) { 547 struct usb_request *req; 548 549 req = usb_ep_alloc_request(fp->out_ep, GFP_KERNEL); 550 if (!req) 551 goto err_req; 552 553 req->complete = pn_rx_complete; 554 fp->out_reqv[i] = req; 555 } 556 557 /* Outgoing USB requests */ 558 fp->in_req = usb_ep_alloc_request(fp->in_ep, GFP_KERNEL); 559 if (!fp->in_req) 560 goto err_req; 561 562 INFO(cdev, "USB CDC Phonet function\n"); 563 INFO(cdev, "using %s, OUT %s, IN %s\n", cdev->gadget->name, 564 fp->out_ep->name, fp->in_ep->name); 565 return 0; 566 567 err_req: 568 for (i = 0; i < phonet_rxq_size && fp->out_reqv[i]; i++) 569 usb_ep_free_request(fp->out_ep, fp->out_reqv[i]); 570 usb_free_all_descriptors(f); 571 err: 572 ERROR(cdev, "USB CDC Phonet: cannot autoconfigure\n"); 573 return status; 574 } 575 576 static inline struct f_phonet_opts *to_f_phonet_opts(struct config_item *item) 577 { 578 return container_of(to_config_group(item), struct f_phonet_opts, 579 func_inst.group); 580 } 581 582 static void phonet_attr_release(struct config_item *item) 583 { 584 struct f_phonet_opts *opts = to_f_phonet_opts(item); 585 586 usb_put_function_instance(&opts->func_inst); 587 } 588 589 static struct configfs_item_operations phonet_item_ops = { 590 .release = phonet_attr_release, 591 }; 592 593 static ssize_t f_phonet_ifname_show(struct config_item *item, char *page) 594 { 595 return gether_get_ifname(to_f_phonet_opts(item)->net, page, PAGE_SIZE); 596 } 597 598 CONFIGFS_ATTR_RO(f_phonet_, ifname); 599 600 static struct configfs_attribute *phonet_attrs[] = { 601 &f_phonet_attr_ifname, 602 NULL, 603 }; 604 605 static struct config_item_type phonet_func_type = { 606 .ct_item_ops = &phonet_item_ops, 607 .ct_attrs = phonet_attrs, 608 .ct_owner = THIS_MODULE, 609 }; 610 611 static void phonet_free_inst(struct usb_function_instance *f) 612 { 613 struct f_phonet_opts *opts; 614 615 opts = container_of(f, struct f_phonet_opts, func_inst); 616 if (opts->bound) 617 gphonet_cleanup(opts->net); 618 else 619 free_netdev(opts->net); 620 kfree(opts); 621 } 622 623 static struct usb_function_instance *phonet_alloc_inst(void) 624 { 625 struct f_phonet_opts *opts; 626 627 opts = kzalloc(sizeof(*opts), GFP_KERNEL); 628 if (!opts) 629 return ERR_PTR(-ENOMEM); 630 631 opts->func_inst.free_func_inst = phonet_free_inst; 632 opts->net = gphonet_setup_default(); 633 if (IS_ERR(opts->net)) { 634 struct net_device *net = opts->net; 635 kfree(opts); 636 return ERR_CAST(net); 637 } 638 639 config_group_init_type_name(&opts->func_inst.group, "", 640 &phonet_func_type); 641 642 return &opts->func_inst; 643 } 644 645 static void phonet_free(struct usb_function *f) 646 { 647 struct f_phonet *phonet; 648 649 phonet = func_to_pn(f); 650 kfree(phonet); 651 } 652 653 static void pn_unbind(struct usb_configuration *c, struct usb_function *f) 654 { 655 struct f_phonet *fp = func_to_pn(f); 656 int i; 657 658 /* We are already disconnected */ 659 if (fp->in_req) 660 usb_ep_free_request(fp->in_ep, fp->in_req); 661 for (i = 0; i < phonet_rxq_size; i++) 662 if (fp->out_reqv[i]) 663 usb_ep_free_request(fp->out_ep, fp->out_reqv[i]); 664 665 usb_free_all_descriptors(f); 666 } 667 668 static struct usb_function *phonet_alloc(struct usb_function_instance *fi) 669 { 670 struct f_phonet *fp; 671 struct f_phonet_opts *opts; 672 int size; 673 674 size = sizeof(*fp) + (phonet_rxq_size * sizeof(struct usb_request *)); 675 fp = kzalloc(size, GFP_KERNEL); 676 if (!fp) 677 return ERR_PTR(-ENOMEM); 678 679 opts = container_of(fi, struct f_phonet_opts, func_inst); 680 681 fp->dev = opts->net; 682 fp->function.name = "phonet"; 683 fp->function.bind = pn_bind; 684 fp->function.unbind = pn_unbind; 685 fp->function.set_alt = pn_set_alt; 686 fp->function.get_alt = pn_get_alt; 687 fp->function.disable = pn_disconnect; 688 fp->function.free_func = phonet_free; 689 spin_lock_init(&fp->rx.lock); 690 691 return &fp->function; 692 } 693 694 struct net_device *gphonet_setup_default(void) 695 { 696 struct net_device *dev; 697 struct phonet_port *port; 698 699 /* Create net device */ 700 dev = alloc_netdev(sizeof(*port), "upnlink%d", NET_NAME_UNKNOWN, 701 pn_net_setup); 702 if (!dev) 703 return ERR_PTR(-ENOMEM); 704 705 port = netdev_priv(dev); 706 spin_lock_init(&port->lock); 707 netif_carrier_off(dev); 708 709 return dev; 710 } 711 712 void gphonet_set_gadget(struct net_device *net, struct usb_gadget *g) 713 { 714 SET_NETDEV_DEV(net, &g->dev); 715 } 716 717 int gphonet_register_netdev(struct net_device *net) 718 { 719 int status; 720 721 status = register_netdev(net); 722 if (status) 723 free_netdev(net); 724 725 return status; 726 } 727 728 void gphonet_cleanup(struct net_device *dev) 729 { 730 unregister_netdev(dev); 731 } 732 733 DECLARE_USB_FUNCTION_INIT(phonet, phonet_alloc_inst, phonet_alloc); 734 MODULE_AUTHOR("Rémi Denis-Courmont"); 735 MODULE_LICENSE("GPL"); 736