linux/drivers/usb/gadget/legacy/g_ffs.c
<<
>>
Prefs
   1/*
   2 * g_ffs.c -- user mode file system API for USB composite function controllers
   3 *
   4 * Copyright (C) 2010 Samsung Electronics
   5 * Author: Michal Nazarewicz <mina86@mina86.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 */
  12
  13#define pr_fmt(fmt) "g_ffs: " fmt
  14
  15#include <linux/module.h>
  16
  17#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
  18#include <linux/netdevice.h>
  19
  20#  if defined USB_ETH_RNDIS
  21#    undef USB_ETH_RNDIS
  22#  endif
  23#  ifdef CONFIG_USB_FUNCTIONFS_RNDIS
  24#    define USB_ETH_RNDIS y
  25#  endif
  26
  27#  include "u_ecm.h"
  28#  include "u_gether.h"
  29#  ifdef USB_ETH_RNDIS
  30#    include "u_rndis.h"
  31#    include "rndis.h"
  32#  endif
  33#  include "u_ether.h"
  34
  35USB_ETHERNET_MODULE_PARAMETERS();
  36
  37#  ifdef CONFIG_USB_FUNCTIONFS_ETH
  38static int eth_bind_config(struct usb_configuration *c);
  39static struct usb_function_instance *fi_ecm;
  40static struct usb_function *f_ecm;
  41static struct usb_function_instance *fi_geth;
  42static struct usb_function *f_geth;
  43#  endif
  44#  ifdef CONFIG_USB_FUNCTIONFS_RNDIS
  45static int bind_rndis_config(struct usb_configuration *c);
  46static struct usb_function_instance *fi_rndis;
  47static struct usb_function *f_rndis;
  48#  endif
  49#endif
  50
  51#include "u_fs.h"
  52
  53#define DRIVER_NAME     "g_ffs"
  54#define DRIVER_DESC     "USB Function Filesystem"
  55#define DRIVER_VERSION  "24 Aug 2004"
  56
  57MODULE_DESCRIPTION(DRIVER_DESC);
  58MODULE_AUTHOR("Michal Nazarewicz");
  59MODULE_LICENSE("GPL");
  60
  61#define GFS_VENDOR_ID   0x1d6b  /* Linux Foundation */
  62#define GFS_PRODUCT_ID  0x0105  /* FunctionFS Gadget */
  63
  64#define GFS_MAX_DEVS    10
  65
  66USB_GADGET_COMPOSITE_OPTIONS();
  67
  68static struct usb_device_descriptor gfs_dev_desc = {
  69        .bLength                = sizeof gfs_dev_desc,
  70        .bDescriptorType        = USB_DT_DEVICE,
  71
  72        .bcdUSB                 = cpu_to_le16(0x0200),
  73        .bDeviceClass           = USB_CLASS_PER_INTERFACE,
  74
  75        .idVendor               = cpu_to_le16(GFS_VENDOR_ID),
  76        .idProduct              = cpu_to_le16(GFS_PRODUCT_ID),
  77};
  78
  79static char *func_names[GFS_MAX_DEVS];
  80static unsigned int func_num;
  81
  82module_param_named(bDeviceClass,    gfs_dev_desc.bDeviceClass,    byte,   0644);
  83MODULE_PARM_DESC(bDeviceClass, "USB Device class");
  84module_param_named(bDeviceSubClass, gfs_dev_desc.bDeviceSubClass, byte,   0644);
  85MODULE_PARM_DESC(bDeviceSubClass, "USB Device subclass");
  86module_param_named(bDeviceProtocol, gfs_dev_desc.bDeviceProtocol, byte,   0644);
  87MODULE_PARM_DESC(bDeviceProtocol, "USB Device protocol");
  88module_param_array_named(functions, func_names, charp, &func_num, 0);
  89MODULE_PARM_DESC(functions, "USB Functions list");
  90
  91static const struct usb_descriptor_header *gfs_otg_desc[] = {
  92        (const struct usb_descriptor_header *)
  93        &(const struct usb_otg_descriptor) {
  94                .bLength                = sizeof(struct usb_otg_descriptor),
  95                .bDescriptorType        = USB_DT_OTG,
  96
  97                /*
  98                 * REVISIT SRP-only hardware is possible, although
  99                 * it would not be called "OTG" ...
 100                 */
 101                .bmAttributes           = USB_OTG_SRP | USB_OTG_HNP,
 102        },
 103
 104        NULL
 105};
 106
 107/* String IDs are assigned dynamically */
 108static struct usb_string gfs_strings[] = {
 109        [USB_GADGET_MANUFACTURER_IDX].s = "",
 110        [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC,
 111        [USB_GADGET_SERIAL_IDX].s = "",
 112#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
 113        { .s = "FunctionFS + RNDIS" },
 114#endif
 115#ifdef CONFIG_USB_FUNCTIONFS_ETH
 116        { .s = "FunctionFS + ECM" },
 117#endif
 118#ifdef CONFIG_USB_FUNCTIONFS_GENERIC
 119        { .s = "FunctionFS" },
 120#endif
 121        {  } /* end of list */
 122};
 123
 124static struct usb_gadget_strings *gfs_dev_strings[] = {
 125        &(struct usb_gadget_strings) {
 126                .language       = 0x0409,       /* en-us */
 127                .strings        = gfs_strings,
 128        },
 129        NULL,
 130};
 131
 132struct gfs_configuration {
 133        struct usb_configuration c;
 134        int (*eth)(struct usb_configuration *c);
 135        int num;
 136};
 137
 138static struct gfs_configuration gfs_configurations[] = {
 139#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
 140        {
 141                .eth            = bind_rndis_config,
 142        },
 143#endif
 144
 145#ifdef CONFIG_USB_FUNCTIONFS_ETH
 146        {
 147                .eth            = eth_bind_config,
 148        },
 149#endif
 150
 151#ifdef CONFIG_USB_FUNCTIONFS_GENERIC
 152        {
 153        },
 154#endif
 155};
 156
 157static void *functionfs_acquire_dev(struct ffs_dev *dev);
 158static void functionfs_release_dev(struct ffs_dev *dev);
 159static int functionfs_ready_callback(struct ffs_data *ffs);
 160static void functionfs_closed_callback(struct ffs_data *ffs);
 161static int gfs_bind(struct usb_composite_dev *cdev);
 162static int gfs_unbind(struct usb_composite_dev *cdev);
 163static int gfs_do_config(struct usb_configuration *c);
 164
 165
 166static __refdata struct usb_composite_driver gfs_driver = {
 167        .name           = DRIVER_NAME,
 168        .dev            = &gfs_dev_desc,
 169        .strings        = gfs_dev_strings,
 170        .max_speed      = USB_SPEED_HIGH,
 171        .bind           = gfs_bind,
 172        .unbind         = gfs_unbind,
 173};
 174
 175static unsigned int missing_funcs;
 176static bool gfs_registered;
 177static bool gfs_single_func;
 178static struct usb_function_instance **fi_ffs;
 179static struct usb_function **f_ffs[] = {
 180#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
 181        NULL,
 182#endif
 183
 184#ifdef CONFIG_USB_FUNCTIONFS_ETH
 185        NULL,
 186#endif
 187
 188#ifdef CONFIG_USB_FUNCTIONFS_GENERIC
 189        NULL,
 190#endif
 191};
 192
 193#define N_CONF ARRAY_SIZE(f_ffs)
 194
 195static int __init gfs_init(void)
 196{
 197        struct f_fs_opts *opts;
 198        int i;
 199        int ret = 0;
 200
 201        ENTER();
 202
 203        if (func_num < 2) {
 204                gfs_single_func = true;
 205                func_num = 1;
 206        }
 207
 208        /*
 209         * Allocate in one chunk for easier maintenance
 210         */
 211        f_ffs[0] = kcalloc(func_num * N_CONF, sizeof(*f_ffs), GFP_KERNEL);
 212        if (!f_ffs[0]) {
 213                ret = -ENOMEM;
 214                goto no_func;
 215        }
 216        for (i = 1; i < N_CONF; ++i)
 217                f_ffs[i] = f_ffs[0] + i * func_num;
 218
 219        fi_ffs = kcalloc(func_num, sizeof(*fi_ffs), GFP_KERNEL);
 220        if (!fi_ffs) {
 221                ret = -ENOMEM;
 222                goto no_func;
 223        }
 224
 225        for (i = 0; i < func_num; i++) {
 226                fi_ffs[i] = usb_get_function_instance("ffs");
 227                if (IS_ERR(fi_ffs[i])) {
 228                        ret = PTR_ERR(fi_ffs[i]);
 229                        --i;
 230                        goto no_dev;
 231                }
 232                opts = to_f_fs_opts(fi_ffs[i]);
 233                if (gfs_single_func)
 234                        ret = ffs_single_dev(opts->dev);
 235                else
 236                        ret = ffs_name_dev(opts->dev, func_names[i]);
 237                if (ret)
 238                        goto no_dev;
 239                opts->dev->ffs_ready_callback = functionfs_ready_callback;
 240                opts->dev->ffs_closed_callback = functionfs_closed_callback;
 241                opts->dev->ffs_acquire_dev_callback = functionfs_acquire_dev;
 242                opts->dev->ffs_release_dev_callback = functionfs_release_dev;
 243                opts->no_configfs = true;
 244        }
 245
 246        missing_funcs = func_num;
 247
 248        return 0;
 249no_dev:
 250        while (i >= 0)
 251                usb_put_function_instance(fi_ffs[i--]);
 252        kfree(fi_ffs);
 253no_func:
 254        kfree(f_ffs[0]);
 255        return ret;
 256}
 257module_init(gfs_init);
 258
 259static void __exit gfs_exit(void)
 260{
 261        int i;
 262
 263        ENTER();
 264
 265        if (gfs_registered)
 266                usb_composite_unregister(&gfs_driver);
 267        gfs_registered = false;
 268
 269        kfree(f_ffs[0]);
 270
 271        for (i = 0; i < func_num; i++)
 272                usb_put_function_instance(fi_ffs[i]);
 273
 274        kfree(fi_ffs);
 275}
 276module_exit(gfs_exit);
 277
 278static void *functionfs_acquire_dev(struct ffs_dev *dev)
 279{
 280        if (!try_module_get(THIS_MODULE))
 281                return ERR_PTR(-ENOENT);
 282        
 283        return NULL;
 284}
 285
 286static void functionfs_release_dev(struct ffs_dev *dev)
 287{
 288        module_put(THIS_MODULE);
 289}
 290
 291/*
 292 * The caller of this function takes ffs_lock 
 293 */
 294static int functionfs_ready_callback(struct ffs_data *ffs)
 295{
 296        int ret = 0;
 297
 298        if (--missing_funcs)
 299                return 0;
 300
 301        if (gfs_registered)
 302                return -EBUSY;
 303
 304        gfs_registered = true;
 305
 306        ret = usb_composite_probe(&gfs_driver);
 307        if (unlikely(ret < 0))
 308                gfs_registered = false;
 309        
 310        return ret;
 311}
 312
 313/*
 314 * The caller of this function takes ffs_lock 
 315 */
 316static void functionfs_closed_callback(struct ffs_data *ffs)
 317{
 318        missing_funcs++;
 319
 320        if (gfs_registered)
 321                usb_composite_unregister(&gfs_driver);
 322        gfs_registered = false;
 323}
 324
 325/*
 326 * It is assumed that gfs_bind is called from a context where ffs_lock is held
 327 */
 328static int gfs_bind(struct usb_composite_dev *cdev)
 329{
 330#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
 331        struct net_device *net;
 332#endif
 333        int ret, i;
 334
 335        ENTER();
 336
 337        if (missing_funcs)
 338                return -ENODEV;
 339#if defined CONFIG_USB_FUNCTIONFS_ETH
 340        if (can_support_ecm(cdev->gadget)) {
 341                struct f_ecm_opts *ecm_opts;
 342
 343                fi_ecm = usb_get_function_instance("ecm");
 344                if (IS_ERR(fi_ecm))
 345                        return PTR_ERR(fi_ecm);
 346                ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
 347                net = ecm_opts->net;
 348        } else {
 349                struct f_gether_opts *geth_opts;
 350
 351                fi_geth = usb_get_function_instance("geth");
 352                if (IS_ERR(fi_geth))
 353                        return PTR_ERR(fi_geth);
 354                geth_opts = container_of(fi_geth, struct f_gether_opts,
 355                                         func_inst);
 356                net = geth_opts->net;
 357        }
 358#endif
 359
 360#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
 361        {
 362                struct f_rndis_opts *rndis_opts;
 363
 364                fi_rndis = usb_get_function_instance("rndis");
 365                if (IS_ERR(fi_rndis)) {
 366                        ret = PTR_ERR(fi_rndis);
 367                        goto error;
 368                }
 369                rndis_opts = container_of(fi_rndis, struct f_rndis_opts,
 370                                          func_inst);
 371#ifndef CONFIG_USB_FUNCTIONFS_ETH
 372                net = rndis_opts->net;
 373#endif
 374        }
 375#endif
 376
 377#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
 378        gether_set_qmult(net, qmult);
 379        if (!gether_set_host_addr(net, host_addr))
 380                pr_info("using host ethernet address: %s", host_addr);
 381        if (!gether_set_dev_addr(net, dev_addr))
 382                pr_info("using self ethernet address: %s", dev_addr);
 383#endif
 384
 385#if defined CONFIG_USB_FUNCTIONFS_RNDIS && defined CONFIG_USB_FUNCTIONFS_ETH
 386        gether_set_gadget(net, cdev->gadget);
 387        ret = gether_register_netdev(net);
 388        if (ret)
 389                goto error_rndis;
 390
 391        if (can_support_ecm(cdev->gadget)) {
 392                struct f_ecm_opts *ecm_opts;
 393
 394                ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
 395                ecm_opts->bound = true;
 396        } else {
 397                struct f_gether_opts *geth_opts;
 398
 399                geth_opts = container_of(fi_geth, struct f_gether_opts,
 400                                         func_inst);
 401                geth_opts->bound = true;
 402        }
 403
 404        rndis_borrow_net(fi_rndis, net);
 405#endif
 406
 407        /* TODO: gstrings_attach? */
 408        ret = usb_string_ids_tab(cdev, gfs_strings);
 409        if (unlikely(ret < 0))
 410                goto error_rndis;
 411        gfs_dev_desc.iProduct = gfs_strings[USB_GADGET_PRODUCT_IDX].id;
 412
 413        for (i = 0; i < ARRAY_SIZE(gfs_configurations); ++i) {
 414                struct gfs_configuration *c = gfs_configurations + i;
 415                int sid = USB_GADGET_FIRST_AVAIL_IDX + i;
 416
 417                c->c.label                      = gfs_strings[sid].s;
 418                c->c.iConfiguration             = gfs_strings[sid].id;
 419                c->c.bConfigurationValue        = 1 + i;
 420                c->c.bmAttributes               = USB_CONFIG_ATT_SELFPOWER;
 421
 422                c->num = i;
 423
 424                ret = usb_add_config(cdev, &c->c, gfs_do_config);
 425                if (unlikely(ret < 0))
 426                        goto error_unbind;
 427        }
 428        usb_composite_overwrite_options(cdev, &coverwrite);
 429        return 0;
 430
 431/* TODO */
 432error_unbind:
 433error_rndis:
 434#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
 435        usb_put_function_instance(fi_rndis);
 436error:
 437#endif
 438#if defined CONFIG_USB_FUNCTIONFS_ETH
 439        if (can_support_ecm(cdev->gadget))
 440                usb_put_function_instance(fi_ecm);
 441        else
 442                usb_put_function_instance(fi_geth);
 443#endif
 444        return ret;
 445}
 446
 447/*
 448 * It is assumed that gfs_unbind is called from a context where ffs_lock is held
 449 */
 450static int gfs_unbind(struct usb_composite_dev *cdev)
 451{
 452        int i;
 453
 454        ENTER();
 455
 456
 457#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
 458        usb_put_function(f_rndis);
 459        usb_put_function_instance(fi_rndis);
 460#endif
 461
 462#if defined CONFIG_USB_FUNCTIONFS_ETH
 463        if (can_support_ecm(cdev->gadget)) {
 464                usb_put_function(f_ecm);
 465                usb_put_function_instance(fi_ecm);
 466        } else {
 467                usb_put_function(f_geth);
 468                usb_put_function_instance(fi_geth);
 469        }
 470#endif
 471        for (i = 0; i < N_CONF * func_num; ++i)
 472                usb_put_function(*(f_ffs[0] + i));
 473
 474        return 0;
 475}
 476
 477/*
 478 * It is assumed that gfs_do_config is called from a context where
 479 * ffs_lock is held
 480 */
 481static int gfs_do_config(struct usb_configuration *c)
 482{
 483        struct gfs_configuration *gc =
 484                container_of(c, struct gfs_configuration, c);
 485        int i;
 486        int ret;
 487
 488        if (missing_funcs)
 489                return -ENODEV;
 490
 491        if (gadget_is_otg(c->cdev->gadget)) {
 492                c->descriptors = gfs_otg_desc;
 493                c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
 494        }
 495
 496        if (gc->eth) {
 497                ret = gc->eth(c);
 498                if (unlikely(ret < 0))
 499                        return ret;
 500        }
 501
 502        for (i = 0; i < func_num; i++) {
 503                f_ffs[gc->num][i] = usb_get_function(fi_ffs[i]);
 504                if (IS_ERR(f_ffs[gc->num][i])) {
 505                        ret = PTR_ERR(f_ffs[gc->num][i]);
 506                        goto error;
 507                }
 508                ret = usb_add_function(c, f_ffs[gc->num][i]);
 509                if (ret < 0) {
 510                        usb_put_function(f_ffs[gc->num][i]);
 511                        goto error;
 512                }
 513        }
 514
 515        /*
 516         * After previous do_configs there may be some invalid
 517         * pointers in c->interface array.  This happens every time
 518         * a user space function with fewer interfaces than a user
 519         * space function that was run before the new one is run.  The
 520         * compasit's set_config() assumes that if there is no more
 521         * then MAX_CONFIG_INTERFACES interfaces in a configuration
 522         * then there is a NULL pointer after the last interface in
 523         * c->interface array.  We need to make sure this is true.
 524         */
 525        if (c->next_interface_id < ARRAY_SIZE(c->interface))
 526                c->interface[c->next_interface_id] = NULL;
 527
 528        return 0;
 529error:
 530        while (--i >= 0) {
 531                if (!IS_ERR(f_ffs[gc->num][i]))
 532                        usb_remove_function(c, f_ffs[gc->num][i]);
 533                usb_put_function(f_ffs[gc->num][i]);
 534        }
 535        return ret;
 536}
 537
 538#ifdef CONFIG_USB_FUNCTIONFS_ETH
 539
 540static int eth_bind_config(struct usb_configuration *c)
 541{
 542        int status = 0;
 543
 544        if (can_support_ecm(c->cdev->gadget)) {
 545                f_ecm = usb_get_function(fi_ecm);
 546                if (IS_ERR(f_ecm))
 547                        return PTR_ERR(f_ecm);
 548
 549                status = usb_add_function(c, f_ecm);
 550                if (status < 0)
 551                        usb_put_function(f_ecm);
 552
 553        } else {
 554                f_geth = usb_get_function(fi_geth);
 555                if (IS_ERR(f_geth))
 556                        return PTR_ERR(f_geth);
 557
 558                status = usb_add_function(c, f_geth);
 559                if (status < 0)
 560                        usb_put_function(f_geth);
 561        }
 562        return status;
 563}
 564
 565#endif
 566
 567#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
 568
 569static int bind_rndis_config(struct usb_configuration *c)
 570{
 571        int status = 0;
 572
 573        f_rndis = usb_get_function(fi_rndis);
 574        if (IS_ERR(f_rndis))
 575                return PTR_ERR(f_rndis);
 576
 577        status = usb_add_function(c, f_rndis);
 578        if (status < 0)
 579                usb_put_function(f_rndis);
 580
 581        return status;
 582}
 583
 584#endif
 585