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