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 = DYNAMIC */
  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[2];
  92
  93/* String IDs are assigned dynamically */
  94static struct usb_string gfs_strings[] = {
  95        [USB_GADGET_MANUFACTURER_IDX].s = "",
  96        [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC,
  97        [USB_GADGET_SERIAL_IDX].s = "",
  98#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
  99        { .s = "FunctionFS + RNDIS" },
 100#endif
 101#ifdef CONFIG_USB_FUNCTIONFS_ETH
 102        { .s = "FunctionFS + ECM" },
 103#endif
 104#ifdef CONFIG_USB_FUNCTIONFS_GENERIC
 105        { .s = "FunctionFS" },
 106#endif
 107        {  } /* end of list */
 108};
 109
 110static struct usb_gadget_strings *gfs_dev_strings[] = {
 111        &(struct usb_gadget_strings) {
 112                .language       = 0x0409,       /* en-us */
 113                .strings        = gfs_strings,
 114        },
 115        NULL,
 116};
 117
 118struct gfs_configuration {
 119        struct usb_configuration c;
 120        int (*eth)(struct usb_configuration *c);
 121        int num;
 122};
 123
 124static struct gfs_configuration gfs_configurations[] = {
 125#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
 126        {
 127                .eth            = bind_rndis_config,
 128        },
 129#endif
 130
 131#ifdef CONFIG_USB_FUNCTIONFS_ETH
 132        {
 133                .eth            = eth_bind_config,
 134        },
 135#endif
 136
 137#ifdef CONFIG_USB_FUNCTIONFS_GENERIC
 138        {
 139        },
 140#endif
 141};
 142
 143static void *functionfs_acquire_dev(struct ffs_dev *dev);
 144static void functionfs_release_dev(struct ffs_dev *dev);
 145static int functionfs_ready_callback(struct ffs_data *ffs);
 146static void functionfs_closed_callback(struct ffs_data *ffs);
 147static int gfs_bind(struct usb_composite_dev *cdev);
 148static int gfs_unbind(struct usb_composite_dev *cdev);
 149static int gfs_do_config(struct usb_configuration *c);
 150
 151
 152static struct usb_composite_driver gfs_driver = {
 153        .name           = DRIVER_NAME,
 154        .dev            = &gfs_dev_desc,
 155        .strings        = gfs_dev_strings,
 156        .max_speed      = USB_SPEED_HIGH,
 157        .bind           = gfs_bind,
 158        .unbind         = gfs_unbind,
 159};
 160
 161static unsigned int missing_funcs;
 162static bool gfs_registered;
 163static bool gfs_single_func;
 164static struct usb_function_instance **fi_ffs;
 165static struct usb_function **f_ffs[] = {
 166#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
 167        NULL,
 168#endif
 169
 170#ifdef CONFIG_USB_FUNCTIONFS_ETH
 171        NULL,
 172#endif
 173
 174#ifdef CONFIG_USB_FUNCTIONFS_GENERIC
 175        NULL,
 176#endif
 177};
 178
 179#define N_CONF ARRAY_SIZE(f_ffs)
 180
 181static int __init gfs_init(void)
 182{
 183        struct f_fs_opts *opts;
 184        int i;
 185        int ret = 0;
 186
 187        ENTER();
 188
 189        if (func_num < 2) {
 190                gfs_single_func = true;
 191                func_num = 1;
 192        }
 193
 194        /*
 195         * Allocate in one chunk for easier maintenance
 196         */
 197        f_ffs[0] = kcalloc(func_num * N_CONF, sizeof(*f_ffs), GFP_KERNEL);
 198        if (!f_ffs[0]) {
 199                ret = -ENOMEM;
 200                goto no_func;
 201        }
 202        for (i = 1; i < N_CONF; ++i)
 203                f_ffs[i] = f_ffs[0] + i * func_num;
 204
 205        fi_ffs = kcalloc(func_num, sizeof(*fi_ffs), GFP_KERNEL);
 206        if (!fi_ffs) {
 207                ret = -ENOMEM;
 208                goto no_func;
 209        }
 210
 211        for (i = 0; i < func_num; i++) {
 212                fi_ffs[i] = usb_get_function_instance("ffs");
 213                if (IS_ERR(fi_ffs[i])) {
 214                        ret = PTR_ERR(fi_ffs[i]);
 215                        --i;
 216                        goto no_dev;
 217                }
 218                opts = to_f_fs_opts(fi_ffs[i]);
 219                if (gfs_single_func)
 220                        ret = ffs_single_dev(opts->dev);
 221                else
 222                        ret = ffs_name_dev(opts->dev, func_names[i]);
 223                if (ret)
 224                        goto no_dev;
 225                opts->dev->ffs_ready_callback = functionfs_ready_callback;
 226                opts->dev->ffs_closed_callback = functionfs_closed_callback;
 227                opts->dev->ffs_acquire_dev_callback = functionfs_acquire_dev;
 228                opts->dev->ffs_release_dev_callback = functionfs_release_dev;
 229                opts->no_configfs = true;
 230        }
 231
 232        missing_funcs = func_num;
 233
 234        return 0;
 235no_dev:
 236        while (i >= 0)
 237                usb_put_function_instance(fi_ffs[i--]);
 238        kfree(fi_ffs);
 239no_func:
 240        kfree(f_ffs[0]);
 241        return ret;
 242}
 243module_init(gfs_init);
 244
 245static void __exit gfs_exit(void)
 246{
 247        int i;
 248
 249        ENTER();
 250
 251        if (gfs_registered)
 252                usb_composite_unregister(&gfs_driver);
 253        gfs_registered = false;
 254
 255        kfree(f_ffs[0]);
 256
 257        for (i = 0; i < func_num; i++)
 258                usb_put_function_instance(fi_ffs[i]);
 259
 260        kfree(fi_ffs);
 261}
 262module_exit(gfs_exit);
 263
 264static void *functionfs_acquire_dev(struct ffs_dev *dev)
 265{
 266        if (!try_module_get(THIS_MODULE))
 267                return ERR_PTR(-ENOENT);
 268        
 269        return NULL;
 270}
 271
 272static void functionfs_release_dev(struct ffs_dev *dev)
 273{
 274        module_put(THIS_MODULE);
 275}
 276
 277/*
 278 * The caller of this function takes ffs_lock 
 279 */
 280static int functionfs_ready_callback(struct ffs_data *ffs)
 281{
 282        int ret = 0;
 283
 284        if (--missing_funcs)
 285                return 0;
 286
 287        if (gfs_registered)
 288                return -EBUSY;
 289
 290        gfs_registered = true;
 291
 292        ret = usb_composite_probe(&gfs_driver);
 293        if (unlikely(ret < 0)) {
 294                ++missing_funcs;
 295                gfs_registered = false;
 296        }
 297        
 298        return ret;
 299}
 300
 301/*
 302 * The caller of this function takes ffs_lock 
 303 */
 304static void functionfs_closed_callback(struct ffs_data *ffs)
 305{
 306        missing_funcs++;
 307
 308        if (gfs_registered)
 309                usb_composite_unregister(&gfs_driver);
 310        gfs_registered = false;
 311}
 312
 313/*
 314 * It is assumed that gfs_bind is called from a context where ffs_lock is held
 315 */
 316static int gfs_bind(struct usb_composite_dev *cdev)
 317{
 318#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
 319        struct net_device *net;
 320#endif
 321        int ret, i;
 322
 323        ENTER();
 324
 325        if (missing_funcs)
 326                return -ENODEV;
 327#if defined CONFIG_USB_FUNCTIONFS_ETH
 328        if (can_support_ecm(cdev->gadget)) {
 329                struct f_ecm_opts *ecm_opts;
 330
 331                fi_ecm = usb_get_function_instance("ecm");
 332                if (IS_ERR(fi_ecm))
 333                        return PTR_ERR(fi_ecm);
 334                ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
 335                net = ecm_opts->net;
 336        } else {
 337                struct f_gether_opts *geth_opts;
 338
 339                fi_geth = usb_get_function_instance("geth");
 340                if (IS_ERR(fi_geth))
 341                        return PTR_ERR(fi_geth);
 342                geth_opts = container_of(fi_geth, struct f_gether_opts,
 343                                         func_inst);
 344                net = geth_opts->net;
 345        }
 346#endif
 347
 348#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
 349        {
 350                struct f_rndis_opts *rndis_opts;
 351
 352                fi_rndis = usb_get_function_instance("rndis");
 353                if (IS_ERR(fi_rndis)) {
 354                        ret = PTR_ERR(fi_rndis);
 355                        goto error;
 356                }
 357                rndis_opts = container_of(fi_rndis, struct f_rndis_opts,
 358                                          func_inst);
 359#ifndef CONFIG_USB_FUNCTIONFS_ETH
 360                net = rndis_opts->net;
 361#endif
 362        }
 363#endif
 364
 365#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
 366        gether_set_qmult(net, qmult);
 367        if (!gether_set_host_addr(net, host_addr))
 368                pr_info("using host ethernet address: %s", host_addr);
 369        if (!gether_set_dev_addr(net, dev_addr))
 370                pr_info("using self ethernet address: %s", dev_addr);
 371#endif
 372
 373#if defined CONFIG_USB_FUNCTIONFS_RNDIS && defined CONFIG_USB_FUNCTIONFS_ETH
 374        gether_set_gadget(net, cdev->gadget);
 375        ret = gether_register_netdev(net);
 376        if (ret)
 377                goto error_rndis;
 378
 379        if (can_support_ecm(cdev->gadget)) {
 380                struct f_ecm_opts *ecm_opts;
 381
 382                ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
 383                ecm_opts->bound = true;
 384        } else {
 385                struct f_gether_opts *geth_opts;
 386
 387                geth_opts = container_of(fi_geth, struct f_gether_opts,
 388                                         func_inst);
 389                geth_opts->bound = true;
 390        }
 391
 392        rndis_borrow_net(fi_rndis, net);
 393#endif
 394
 395        /* TODO: gstrings_attach? */
 396        ret = usb_string_ids_tab(cdev, gfs_strings);
 397        if (unlikely(ret < 0))
 398                goto error_rndis;
 399        gfs_dev_desc.iProduct = gfs_strings[USB_GADGET_PRODUCT_IDX].id;
 400
 401        if (gadget_is_otg(cdev->gadget) && !gfs_otg_desc[0]) {
 402                struct usb_descriptor_header *usb_desc;
 403
 404                usb_desc = usb_otg_descriptor_alloc(cdev->gadget);
 405                if (!usb_desc)
 406                        goto error_rndis;
 407                usb_otg_descriptor_init(cdev->gadget, usb_desc);
 408                gfs_otg_desc[0] = usb_desc;
 409                gfs_otg_desc[1] = NULL;
 410        }
 411
 412        for (i = 0; i < ARRAY_SIZE(gfs_configurations); ++i) {
 413                struct gfs_configuration *c = gfs_configurations + i;
 414                int sid = USB_GADGET_FIRST_AVAIL_IDX + i;
 415
 416                c->c.label                      = gfs_strings[sid].s;
 417                c->c.iConfiguration             = gfs_strings[sid].id;
 418                c->c.bConfigurationValue        = 1 + i;
 419                c->c.bmAttributes               = USB_CONFIG_ATT_SELFPOWER;
 420
 421                c->num = i;
 422
 423                ret = usb_add_config(cdev, &c->c, gfs_do_config);
 424                if (unlikely(ret < 0))
 425                        goto error_unbind;
 426        }
 427        usb_composite_overwrite_options(cdev, &coverwrite);
 428        return 0;
 429
 430/* TODO */
 431error_unbind:
 432        kfree(gfs_otg_desc[0]);
 433        gfs_otg_desc[0] = NULL;
 434error_rndis:
 435#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
 436        usb_put_function_instance(fi_rndis);
 437error:
 438#endif
 439#if defined CONFIG_USB_FUNCTIONFS_ETH
 440        if (can_support_ecm(cdev->gadget))
 441                usb_put_function_instance(fi_ecm);
 442        else
 443                usb_put_function_instance(fi_geth);
 444#endif
 445        return ret;
 446}
 447
 448/*
 449 * It is assumed that gfs_unbind is called from a context where ffs_lock is held
 450 */
 451static int gfs_unbind(struct usb_composite_dev *cdev)
 452{
 453        int i;
 454
 455        ENTER();
 456
 457
 458#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
 459        usb_put_function(f_rndis);
 460        usb_put_function_instance(fi_rndis);
 461#endif
 462
 463#if defined CONFIG_USB_FUNCTIONFS_ETH
 464        if (can_support_ecm(cdev->gadget)) {
 465                usb_put_function(f_ecm);
 466                usb_put_function_instance(fi_ecm);
 467        } else {
 468                usb_put_function(f_geth);
 469                usb_put_function_instance(fi_geth);
 470        }
 471#endif
 472        for (i = 0; i < N_CONF * func_num; ++i)
 473                usb_put_function(*(f_ffs[0] + i));
 474
 475        kfree(gfs_otg_desc[0]);
 476        gfs_otg_desc[0] = NULL;
 477
 478        return 0;
 479}
 480
 481/*
 482 * It is assumed that gfs_do_config is called from a context where
 483 * ffs_lock is held
 484 */
 485static int gfs_do_config(struct usb_configuration *c)
 486{
 487        struct gfs_configuration *gc =
 488                container_of(c, struct gfs_configuration, c);
 489        int i;
 490        int ret;
 491
 492        if (missing_funcs)
 493                return -ENODEV;
 494
 495        if (gadget_is_otg(c->cdev->gadget)) {
 496                c->descriptors = gfs_otg_desc;
 497                c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
 498        }
 499
 500        if (gc->eth) {
 501                ret = gc->eth(c);
 502                if (unlikely(ret < 0))
 503                        return ret;
 504        }
 505
 506        for (i = 0; i < func_num; i++) {
 507                f_ffs[gc->num][i] = usb_get_function(fi_ffs[i]);
 508                if (IS_ERR(f_ffs[gc->num][i])) {
 509                        ret = PTR_ERR(f_ffs[gc->num][i]);
 510                        goto error;
 511                }
 512                ret = usb_add_function(c, f_ffs[gc->num][i]);
 513                if (ret < 0) {
 514                        usb_put_function(f_ffs[gc->num][i]);
 515                        goto error;
 516                }
 517        }
 518
 519        /*
 520         * After previous do_configs there may be some invalid
 521         * pointers in c->interface array.  This happens every time
 522         * a user space function with fewer interfaces than a user
 523         * space function that was run before the new one is run.  The
 524         * compasit's set_config() assumes that if there is no more
 525         * then MAX_CONFIG_INTERFACES interfaces in a configuration
 526         * then there is a NULL pointer after the last interface in
 527         * c->interface array.  We need to make sure this is true.
 528         */
 529        if (c->next_interface_id < ARRAY_SIZE(c->interface))
 530                c->interface[c->next_interface_id] = NULL;
 531
 532        return 0;
 533error:
 534        while (--i >= 0) {
 535                if (!IS_ERR(f_ffs[gc->num][i]))
 536                        usb_remove_function(c, f_ffs[gc->num][i]);
 537                usb_put_function(f_ffs[gc->num][i]);
 538        }
 539        return ret;
 540}
 541
 542#ifdef CONFIG_USB_FUNCTIONFS_ETH
 543
 544static int eth_bind_config(struct usb_configuration *c)
 545{
 546        int status = 0;
 547
 548        if (can_support_ecm(c->cdev->gadget)) {
 549                f_ecm = usb_get_function(fi_ecm);
 550                if (IS_ERR(f_ecm))
 551                        return PTR_ERR(f_ecm);
 552
 553                status = usb_add_function(c, f_ecm);
 554                if (status < 0)
 555                        usb_put_function(f_ecm);
 556
 557        } else {
 558                f_geth = usb_get_function(fi_geth);
 559                if (IS_ERR(f_geth))
 560                        return PTR_ERR(f_geth);
 561
 562                status = usb_add_function(c, f_geth);
 563                if (status < 0)
 564                        usb_put_function(f_geth);
 565        }
 566        return status;
 567}
 568
 569#endif
 570
 571#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
 572
 573static int bind_rndis_config(struct usb_configuration *c)
 574{
 575        int status = 0;
 576
 577        f_rndis = usb_get_function(fi_rndis);
 578        if (IS_ERR(f_rndis))
 579                return PTR_ERR(f_rndis);
 580
 581        status = usb_add_function(c, f_rndis);
 582        if (status < 0)
 583                usb_put_function(f_rndis);
 584
 585        return status;
 586}
 587
 588#endif
 589