linux/drivers/usb/gadget/legacy/multi.c
<<
>>
Prefs
   1/*
   2 * multi.c -- Multifunction Composite driver
   3 *
   4 * Copyright (C) 2008 David Brownell
   5 * Copyright (C) 2008 Nokia Corporation
   6 * Copyright (C) 2009 Samsung Electronics
   7 * Author: Michal Nazarewicz (mina86@mina86.com)
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License as published by
  11 * the Free Software Foundation; either version 2 of the License, or
  12 * (at your option) any later version.
  13 */
  14
  15
  16#include <linux/kernel.h>
  17#include <linux/module.h>
  18#include <linux/netdevice.h>
  19
  20#include "u_serial.h"
  21#if defined USB_ETH_RNDIS
  22#  undef USB_ETH_RNDIS
  23#endif
  24#ifdef CONFIG_USB_G_MULTI_RNDIS
  25#  define USB_ETH_RNDIS y
  26#endif
  27
  28
  29#define DRIVER_DESC             "Multifunction Composite Gadget"
  30
  31MODULE_DESCRIPTION(DRIVER_DESC);
  32MODULE_AUTHOR("Michal Nazarewicz");
  33MODULE_LICENSE("GPL");
  34
  35
  36#include "f_mass_storage.h"
  37
  38#include "u_ecm.h"
  39#ifdef USB_ETH_RNDIS
  40#  include "u_rndis.h"
  41#  include "rndis.h"
  42#endif
  43#include "u_ether.h"
  44
  45USB_GADGET_COMPOSITE_OPTIONS();
  46
  47USB_ETHERNET_MODULE_PARAMETERS();
  48
  49/***************************** Device Descriptor ****************************/
  50
  51#define MULTI_VENDOR_NUM        0x1d6b  /* Linux Foundation */
  52#define MULTI_PRODUCT_NUM       0x0104  /* Multifunction Composite Gadget */
  53
  54
  55enum {
  56        __MULTI_NO_CONFIG,
  57#ifdef CONFIG_USB_G_MULTI_RNDIS
  58        MULTI_RNDIS_CONFIG_NUM,
  59#endif
  60#ifdef CONFIG_USB_G_MULTI_CDC
  61        MULTI_CDC_CONFIG_NUM,
  62#endif
  63};
  64
  65
  66static struct usb_device_descriptor device_desc = {
  67        .bLength =              sizeof device_desc,
  68        .bDescriptorType =      USB_DT_DEVICE,
  69
  70        /* .bcdUSB = DYNAMIC */
  71
  72        .bDeviceClass =         USB_CLASS_MISC /* 0xEF */,
  73        .bDeviceSubClass =      2,
  74        .bDeviceProtocol =      1,
  75
  76        /* Vendor and product id can be overridden by module parameters.  */
  77        .idVendor =             cpu_to_le16(MULTI_VENDOR_NUM),
  78        .idProduct =            cpu_to_le16(MULTI_PRODUCT_NUM),
  79};
  80
  81static const struct usb_descriptor_header *otg_desc[2];
  82
  83enum {
  84        MULTI_STRING_RNDIS_CONFIG_IDX = USB_GADGET_FIRST_AVAIL_IDX,
  85        MULTI_STRING_CDC_CONFIG_IDX,
  86};
  87
  88static struct usb_string strings_dev[] = {
  89        [USB_GADGET_MANUFACTURER_IDX].s = "",
  90        [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC,
  91        [USB_GADGET_SERIAL_IDX].s = "",
  92        [MULTI_STRING_RNDIS_CONFIG_IDX].s = "Multifunction with RNDIS",
  93        [MULTI_STRING_CDC_CONFIG_IDX].s   = "Multifunction with CDC ECM",
  94        {  } /* end of list */
  95};
  96
  97static struct usb_gadget_strings *dev_strings[] = {
  98        &(struct usb_gadget_strings){
  99                .language       = 0x0409,       /* en-us */
 100                .strings        = strings_dev,
 101        },
 102        NULL,
 103};
 104
 105
 106
 107
 108/****************************** Configurations ******************************/
 109
 110static struct fsg_module_parameters fsg_mod_data = { .stall = 1 };
 111#ifdef CONFIG_USB_GADGET_DEBUG_FILES
 112
 113static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
 114
 115#else
 116
 117/*
 118 * Number of buffers we will use.
 119 * 2 is usually enough for good buffering pipeline
 120 */
 121#define fsg_num_buffers CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
 122
 123#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
 124
 125FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
 126
 127static struct usb_function_instance *fi_acm;
 128static struct usb_function_instance *fi_msg;
 129
 130/********** RNDIS **********/
 131
 132#ifdef USB_ETH_RNDIS
 133static struct usb_function_instance *fi_rndis;
 134static struct usb_function *f_acm_rndis;
 135static struct usb_function *f_rndis;
 136static struct usb_function *f_msg_rndis;
 137
 138static int rndis_do_config(struct usb_configuration *c)
 139{
 140        struct fsg_opts *fsg_opts;
 141        int ret;
 142
 143        if (gadget_is_otg(c->cdev->gadget)) {
 144                c->descriptors = otg_desc;
 145                c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
 146        }
 147
 148        f_rndis = usb_get_function(fi_rndis);
 149        if (IS_ERR(f_rndis))
 150                return PTR_ERR(f_rndis);
 151
 152        ret = usb_add_function(c, f_rndis);
 153        if (ret < 0)
 154                goto err_func_rndis;
 155
 156        f_acm_rndis = usb_get_function(fi_acm);
 157        if (IS_ERR(f_acm_rndis)) {
 158                ret = PTR_ERR(f_acm_rndis);
 159                goto err_func_acm;
 160        }
 161
 162        ret = usb_add_function(c, f_acm_rndis);
 163        if (ret)
 164                goto err_conf;
 165
 166        f_msg_rndis = usb_get_function(fi_msg);
 167        if (IS_ERR(f_msg_rndis)) {
 168                ret = PTR_ERR(f_msg_rndis);
 169                goto err_fsg;
 170        }
 171
 172        fsg_opts = fsg_opts_from_func_inst(fi_msg);
 173        ret = fsg_common_run_thread(fsg_opts->common);
 174        if (ret)
 175                goto err_run;
 176
 177        ret = usb_add_function(c, f_msg_rndis);
 178        if (ret)
 179                goto err_run;
 180
 181        return 0;
 182err_run:
 183        usb_put_function(f_msg_rndis);
 184err_fsg:
 185        usb_remove_function(c, f_acm_rndis);
 186err_conf:
 187        usb_put_function(f_acm_rndis);
 188err_func_acm:
 189        usb_remove_function(c, f_rndis);
 190err_func_rndis:
 191        usb_put_function(f_rndis);
 192        return ret;
 193}
 194
 195static __ref int rndis_config_register(struct usb_composite_dev *cdev)
 196{
 197        static struct usb_configuration config = {
 198                .bConfigurationValue    = MULTI_RNDIS_CONFIG_NUM,
 199                .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
 200        };
 201
 202        config.label          = strings_dev[MULTI_STRING_RNDIS_CONFIG_IDX].s;
 203        config.iConfiguration = strings_dev[MULTI_STRING_RNDIS_CONFIG_IDX].id;
 204
 205        return usb_add_config(cdev, &config, rndis_do_config);
 206}
 207
 208#else
 209
 210static __ref int rndis_config_register(struct usb_composite_dev *cdev)
 211{
 212        return 0;
 213}
 214
 215#endif
 216
 217
 218/********** CDC ECM **********/
 219
 220#ifdef CONFIG_USB_G_MULTI_CDC
 221static struct usb_function_instance *fi_ecm;
 222static struct usb_function *f_acm_multi;
 223static struct usb_function *f_ecm;
 224static struct usb_function *f_msg_multi;
 225
 226static int cdc_do_config(struct usb_configuration *c)
 227{
 228        struct fsg_opts *fsg_opts;
 229        int ret;
 230
 231        if (gadget_is_otg(c->cdev->gadget)) {
 232                c->descriptors = otg_desc;
 233                c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
 234        }
 235
 236        f_ecm = usb_get_function(fi_ecm);
 237        if (IS_ERR(f_ecm))
 238                return PTR_ERR(f_ecm);
 239
 240        ret = usb_add_function(c, f_ecm);
 241        if (ret < 0)
 242                goto err_func_ecm;
 243
 244        /* implicit port_num is zero */
 245        f_acm_multi = usb_get_function(fi_acm);
 246        if (IS_ERR(f_acm_multi)) {
 247                ret = PTR_ERR(f_acm_multi);
 248                goto err_func_acm;
 249        }
 250
 251        ret = usb_add_function(c, f_acm_multi);
 252        if (ret)
 253                goto err_conf;
 254
 255        f_msg_multi = usb_get_function(fi_msg);
 256        if (IS_ERR(f_msg_multi)) {
 257                ret = PTR_ERR(f_msg_multi);
 258                goto err_fsg;
 259        }
 260
 261        fsg_opts = fsg_opts_from_func_inst(fi_msg);
 262        ret = fsg_common_run_thread(fsg_opts->common);
 263        if (ret)
 264                goto err_run;
 265
 266        ret = usb_add_function(c, f_msg_multi);
 267        if (ret)
 268                goto err_run;
 269
 270        return 0;
 271err_run:
 272        usb_put_function(f_msg_multi);
 273err_fsg:
 274        usb_remove_function(c, f_acm_multi);
 275err_conf:
 276        usb_put_function(f_acm_multi);
 277err_func_acm:
 278        usb_remove_function(c, f_ecm);
 279err_func_ecm:
 280        usb_put_function(f_ecm);
 281        return ret;
 282}
 283
 284static __ref int cdc_config_register(struct usb_composite_dev *cdev)
 285{
 286        static struct usb_configuration config = {
 287                .bConfigurationValue    = MULTI_CDC_CONFIG_NUM,
 288                .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
 289        };
 290
 291        config.label          = strings_dev[MULTI_STRING_CDC_CONFIG_IDX].s;
 292        config.iConfiguration = strings_dev[MULTI_STRING_CDC_CONFIG_IDX].id;
 293
 294        return usb_add_config(cdev, &config, cdc_do_config);
 295}
 296
 297#else
 298
 299static __ref int cdc_config_register(struct usb_composite_dev *cdev)
 300{
 301        return 0;
 302}
 303
 304#endif
 305
 306
 307
 308/****************************** Gadget Bind ******************************/
 309
 310static int __ref multi_bind(struct usb_composite_dev *cdev)
 311{
 312        struct usb_gadget *gadget = cdev->gadget;
 313#ifdef CONFIG_USB_G_MULTI_CDC
 314        struct f_ecm_opts *ecm_opts;
 315#endif
 316#ifdef USB_ETH_RNDIS
 317        struct f_rndis_opts *rndis_opts;
 318#endif
 319        struct fsg_opts *fsg_opts;
 320        struct fsg_config config;
 321        int status;
 322
 323        if (!can_support_ecm(cdev->gadget)) {
 324                dev_err(&gadget->dev, "controller '%s' not usable\n",
 325                        gadget->name);
 326                return -EINVAL;
 327        }
 328
 329#ifdef CONFIG_USB_G_MULTI_CDC
 330        fi_ecm = usb_get_function_instance("ecm");
 331        if (IS_ERR(fi_ecm))
 332                return PTR_ERR(fi_ecm);
 333
 334        ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
 335
 336        gether_set_qmult(ecm_opts->net, qmult);
 337        if (!gether_set_host_addr(ecm_opts->net, host_addr))
 338                pr_info("using host ethernet address: %s", host_addr);
 339        if (!gether_set_dev_addr(ecm_opts->net, dev_addr))
 340                pr_info("using self ethernet address: %s", dev_addr);
 341#endif
 342
 343#ifdef USB_ETH_RNDIS
 344        fi_rndis = usb_get_function_instance("rndis");
 345        if (IS_ERR(fi_rndis)) {
 346                status = PTR_ERR(fi_rndis);
 347                goto fail;
 348        }
 349
 350        rndis_opts = container_of(fi_rndis, struct f_rndis_opts, func_inst);
 351
 352        gether_set_qmult(rndis_opts->net, qmult);
 353        if (!gether_set_host_addr(rndis_opts->net, host_addr))
 354                pr_info("using host ethernet address: %s", host_addr);
 355        if (!gether_set_dev_addr(rndis_opts->net, dev_addr))
 356                pr_info("using self ethernet address: %s", dev_addr);
 357#endif
 358
 359#if (defined CONFIG_USB_G_MULTI_CDC && defined USB_ETH_RNDIS)
 360        /*
 361         * If both ecm and rndis are selected then:
 362         *      1) rndis borrows the net interface from ecm
 363         *      2) since the interface is shared it must not be bound
 364         *      twice - in ecm's _and_ rndis' binds, so do it here.
 365         */
 366        gether_set_gadget(ecm_opts->net, cdev->gadget);
 367        status = gether_register_netdev(ecm_opts->net);
 368        if (status)
 369                goto fail0;
 370
 371        rndis_borrow_net(fi_rndis, ecm_opts->net);
 372        ecm_opts->bound = true;
 373#endif
 374
 375        /* set up serial link layer */
 376        fi_acm = usb_get_function_instance("acm");
 377        if (IS_ERR(fi_acm)) {
 378                status = PTR_ERR(fi_acm);
 379                goto fail0;
 380        }
 381
 382        /* set up mass storage function */
 383        fi_msg = usb_get_function_instance("mass_storage");
 384        if (IS_ERR(fi_msg)) {
 385                status = PTR_ERR(fi_msg);
 386                goto fail1;
 387        }
 388        fsg_config_from_params(&config, &fsg_mod_data, fsg_num_buffers);
 389        fsg_opts = fsg_opts_from_func_inst(fi_msg);
 390
 391        fsg_opts->no_configfs = true;
 392        status = fsg_common_set_num_buffers(fsg_opts->common, fsg_num_buffers);
 393        if (status)
 394                goto fail2;
 395
 396        status = fsg_common_set_cdev(fsg_opts->common, cdev, config.can_stall);
 397        if (status)
 398                goto fail_set_cdev;
 399
 400        fsg_common_set_sysfs(fsg_opts->common, true);
 401        status = fsg_common_create_luns(fsg_opts->common, &config);
 402        if (status)
 403                goto fail_set_cdev;
 404
 405        fsg_common_set_inquiry_string(fsg_opts->common, config.vendor_name,
 406                                      config.product_name);
 407
 408        /* allocate string IDs */
 409        status = usb_string_ids_tab(cdev, strings_dev);
 410        if (unlikely(status < 0))
 411                goto fail_string_ids;
 412        device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
 413
 414        if (gadget_is_otg(gadget) && !otg_desc[0]) {
 415                struct usb_descriptor_header *usb_desc;
 416
 417                usb_desc = usb_otg_descriptor_alloc(gadget);
 418                if (!usb_desc)
 419                        goto fail_string_ids;
 420                usb_otg_descriptor_init(gadget, usb_desc);
 421                otg_desc[0] = usb_desc;
 422                otg_desc[1] = NULL;
 423        }
 424
 425        /* register configurations */
 426        status = rndis_config_register(cdev);
 427        if (unlikely(status < 0))
 428                goto fail_otg_desc;
 429
 430        status = cdc_config_register(cdev);
 431        if (unlikely(status < 0))
 432                goto fail_otg_desc;
 433        usb_composite_overwrite_options(cdev, &coverwrite);
 434
 435        /* we're done */
 436        dev_info(&gadget->dev, DRIVER_DESC "\n");
 437        return 0;
 438
 439
 440        /* error recovery */
 441fail_otg_desc:
 442        kfree(otg_desc[0]);
 443        otg_desc[0] = NULL;
 444fail_string_ids:
 445        fsg_common_remove_luns(fsg_opts->common);
 446fail_set_cdev:
 447        fsg_common_free_buffers(fsg_opts->common);
 448fail2:
 449        usb_put_function_instance(fi_msg);
 450fail1:
 451        usb_put_function_instance(fi_acm);
 452fail0:
 453#ifdef USB_ETH_RNDIS
 454        usb_put_function_instance(fi_rndis);
 455fail:
 456#endif
 457#ifdef CONFIG_USB_G_MULTI_CDC
 458        usb_put_function_instance(fi_ecm);
 459#endif
 460        return status;
 461}
 462
 463static int multi_unbind(struct usb_composite_dev *cdev)
 464{
 465#ifdef CONFIG_USB_G_MULTI_CDC
 466        usb_put_function(f_msg_multi);
 467#endif
 468#ifdef USB_ETH_RNDIS
 469        usb_put_function(f_msg_rndis);
 470#endif
 471        usb_put_function_instance(fi_msg);
 472#ifdef CONFIG_USB_G_MULTI_CDC
 473        usb_put_function(f_acm_multi);
 474#endif
 475#ifdef USB_ETH_RNDIS
 476        usb_put_function(f_acm_rndis);
 477#endif
 478        usb_put_function_instance(fi_acm);
 479#ifdef USB_ETH_RNDIS
 480        usb_put_function(f_rndis);
 481        usb_put_function_instance(fi_rndis);
 482#endif
 483#ifdef CONFIG_USB_G_MULTI_CDC
 484        usb_put_function(f_ecm);
 485        usb_put_function_instance(fi_ecm);
 486#endif
 487        kfree(otg_desc[0]);
 488        otg_desc[0] = NULL;
 489
 490        return 0;
 491}
 492
 493
 494/****************************** Some noise ******************************/
 495
 496
 497static struct usb_composite_driver multi_driver = {
 498        .name           = "g_multi",
 499        .dev            = &device_desc,
 500        .strings        = dev_strings,
 501        .max_speed      = USB_SPEED_HIGH,
 502        .bind           = multi_bind,
 503        .unbind         = multi_unbind,
 504        .needs_serial   = 1,
 505};
 506
 507module_usb_composite_driver(multi_driver);
 508