root/drivers/usb/gadget/legacy/nokia.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nokia_bind_config
  2. nokia_bind
  3. nokia_unbind

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * nokia.c -- Nokia Composite Gadget Driver
   4  *
   5  * Copyright (C) 2008-2010 Nokia Corporation
   6  * Contact: Felipe Balbi <felipe.balbi@nokia.com>
   7  *
   8  * This gadget driver borrows from serial.c which is:
   9  *
  10  * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
  11  * Copyright (C) 2008 by David Brownell
  12  * Copyright (C) 2008 by Nokia Corporation
  13  */
  14 
  15 #include <linux/kernel.h>
  16 #include <linux/module.h>
  17 #include <linux/device.h>
  18 
  19 #include "u_serial.h"
  20 #include "u_ether.h"
  21 #include "u_phonet.h"
  22 #include "u_ecm.h"
  23 #include "f_mass_storage.h"
  24 
  25 /* Defines */
  26 
  27 #define NOKIA_VERSION_NUM               0x0211
  28 #define NOKIA_LONG_NAME                 "N900 (PC-Suite Mode)"
  29 
  30 USB_GADGET_COMPOSITE_OPTIONS();
  31 
  32 USB_ETHERNET_MODULE_PARAMETERS();
  33 
  34 static struct fsg_module_parameters fsg_mod_data = {
  35         .stall = 0,
  36         .luns = 2,
  37         .removable_count = 2,
  38         .removable = { 1, 1, },
  39 };
  40 
  41 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
  42 
  43 static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
  44 
  45 #else
  46 
  47 /*
  48  * Number of buffers we will use.
  49  * 2 is usually enough for good buffering pipeline
  50  */
  51 #define fsg_num_buffers CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
  52 
  53 #endif /* CONFIG_USB_DEBUG */
  54 
  55 FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
  56 
  57 #define NOKIA_VENDOR_ID                 0x0421  /* Nokia */
  58 #define NOKIA_PRODUCT_ID                0x01c8  /* Nokia Gadget */
  59 
  60 /* string IDs are assigned dynamically */
  61 
  62 #define STRING_DESCRIPTION_IDX          USB_GADGET_FIRST_AVAIL_IDX
  63 
  64 static char manufacturer_nokia[] = "Nokia";
  65 static const char product_nokia[] = NOKIA_LONG_NAME;
  66 static const char description_nokia[] = "PC-Suite Configuration";
  67 
  68 static struct usb_string strings_dev[] = {
  69         [USB_GADGET_MANUFACTURER_IDX].s = manufacturer_nokia,
  70         [USB_GADGET_PRODUCT_IDX].s = NOKIA_LONG_NAME,
  71         [USB_GADGET_SERIAL_IDX].s = "",
  72         [STRING_DESCRIPTION_IDX].s = description_nokia,
  73         {  } /* end of list */
  74 };
  75 
  76 static struct usb_gadget_strings stringtab_dev = {
  77         .language       = 0x0409,       /* en-us */
  78         .strings        = strings_dev,
  79 };
  80 
  81 static struct usb_gadget_strings *dev_strings[] = {
  82         &stringtab_dev,
  83         NULL,
  84 };
  85 
  86 static struct usb_device_descriptor device_desc = {
  87         .bLength                = USB_DT_DEVICE_SIZE,
  88         .bDescriptorType        = USB_DT_DEVICE,
  89         /* .bcdUSB = DYNAMIC */
  90         .bDeviceClass           = USB_CLASS_COMM,
  91         .idVendor               = cpu_to_le16(NOKIA_VENDOR_ID),
  92         .idProduct              = cpu_to_le16(NOKIA_PRODUCT_ID),
  93         .bcdDevice              = cpu_to_le16(NOKIA_VERSION_NUM),
  94         /* .iManufacturer = DYNAMIC */
  95         /* .iProduct = DYNAMIC */
  96         .bNumConfigurations =   1,
  97 };
  98 
  99 /*-------------------------------------------------------------------------*/
 100 
 101 /* Module */
 102 MODULE_DESCRIPTION("Nokia composite gadget driver for N900");
 103 MODULE_AUTHOR("Felipe Balbi");
 104 MODULE_LICENSE("GPL");
 105 
 106 /*-------------------------------------------------------------------------*/
 107 static struct usb_function *f_acm_cfg1;
 108 static struct usb_function *f_acm_cfg2;
 109 static struct usb_function *f_ecm_cfg1;
 110 static struct usb_function *f_ecm_cfg2;
 111 static struct usb_function *f_obex1_cfg1;
 112 static struct usb_function *f_obex2_cfg1;
 113 static struct usb_function *f_obex1_cfg2;
 114 static struct usb_function *f_obex2_cfg2;
 115 static struct usb_function *f_phonet_cfg1;
 116 static struct usb_function *f_phonet_cfg2;
 117 static struct usb_function *f_msg_cfg1;
 118 static struct usb_function *f_msg_cfg2;
 119 
 120 
 121 static struct usb_configuration nokia_config_500ma_driver = {
 122         .label          = "Bus Powered",
 123         .bConfigurationValue = 1,
 124         /* .iConfiguration = DYNAMIC */
 125         .bmAttributes   = USB_CONFIG_ATT_ONE,
 126         .MaxPower       = 500,
 127 };
 128 
 129 static struct usb_configuration nokia_config_100ma_driver = {
 130         .label          = "Self Powered",
 131         .bConfigurationValue = 2,
 132         /* .iConfiguration = DYNAMIC */
 133         .bmAttributes   = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
 134         .MaxPower       = 100,
 135 };
 136 
 137 static struct usb_function_instance *fi_acm;
 138 static struct usb_function_instance *fi_ecm;
 139 static struct usb_function_instance *fi_obex1;
 140 static struct usb_function_instance *fi_obex2;
 141 static struct usb_function_instance *fi_phonet;
 142 static struct usb_function_instance *fi_msg;
 143 
 144 static int nokia_bind_config(struct usb_configuration *c)
 145 {
 146         struct usb_function *f_acm;
 147         struct usb_function *f_phonet = NULL;
 148         struct usb_function *f_obex1 = NULL;
 149         struct usb_function *f_ecm;
 150         struct usb_function *f_obex2 = NULL;
 151         struct usb_function *f_msg;
 152         int status = 0;
 153         int obex1_stat = -1;
 154         int obex2_stat = -1;
 155         int phonet_stat = -1;
 156 
 157         if (!IS_ERR(fi_phonet)) {
 158                 f_phonet = usb_get_function(fi_phonet);
 159                 if (IS_ERR(f_phonet))
 160                         pr_debug("could not get phonet function\n");
 161         }
 162 
 163         if (!IS_ERR(fi_obex1)) {
 164                 f_obex1 = usb_get_function(fi_obex1);
 165                 if (IS_ERR(f_obex1))
 166                         pr_debug("could not get obex function 0\n");
 167         }
 168 
 169         if (!IS_ERR(fi_obex2)) {
 170                 f_obex2 = usb_get_function(fi_obex2);
 171                 if (IS_ERR(f_obex2))
 172                         pr_debug("could not get obex function 1\n");
 173         }
 174 
 175         f_acm = usb_get_function(fi_acm);
 176         if (IS_ERR(f_acm)) {
 177                 status = PTR_ERR(f_acm);
 178                 goto err_get_acm;
 179         }
 180 
 181         f_ecm = usb_get_function(fi_ecm);
 182         if (IS_ERR(f_ecm)) {
 183                 status = PTR_ERR(f_ecm);
 184                 goto err_get_ecm;
 185         }
 186 
 187         f_msg = usb_get_function(fi_msg);
 188         if (IS_ERR(f_msg)) {
 189                 status = PTR_ERR(f_msg);
 190                 goto err_get_msg;
 191         }
 192 
 193         if (!IS_ERR_OR_NULL(f_phonet)) {
 194                 phonet_stat = usb_add_function(c, f_phonet);
 195                 if (phonet_stat)
 196                         pr_debug("could not add phonet function\n");
 197         }
 198 
 199         if (!IS_ERR_OR_NULL(f_obex1)) {
 200                 obex1_stat = usb_add_function(c, f_obex1);
 201                 if (obex1_stat)
 202                         pr_debug("could not add obex function 0\n");
 203         }
 204 
 205         if (!IS_ERR_OR_NULL(f_obex2)) {
 206                 obex2_stat = usb_add_function(c, f_obex2);
 207                 if (obex2_stat)
 208                         pr_debug("could not add obex function 1\n");
 209         }
 210 
 211         status = usb_add_function(c, f_acm);
 212         if (status)
 213                 goto err_conf;
 214 
 215         status = usb_add_function(c, f_ecm);
 216         if (status) {
 217                 pr_debug("could not bind ecm config %d\n", status);
 218                 goto err_ecm;
 219         }
 220 
 221         status = usb_add_function(c, f_msg);
 222         if (status)
 223                 goto err_msg;
 224 
 225         if (c == &nokia_config_500ma_driver) {
 226                 f_acm_cfg1 = f_acm;
 227                 f_ecm_cfg1 = f_ecm;
 228                 f_phonet_cfg1 = f_phonet;
 229                 f_obex1_cfg1 = f_obex1;
 230                 f_obex2_cfg1 = f_obex2;
 231                 f_msg_cfg1 = f_msg;
 232         } else {
 233                 f_acm_cfg2 = f_acm;
 234                 f_ecm_cfg2 = f_ecm;
 235                 f_phonet_cfg2 = f_phonet;
 236                 f_obex1_cfg2 = f_obex1;
 237                 f_obex2_cfg2 = f_obex2;
 238                 f_msg_cfg2 = f_msg;
 239         }
 240 
 241         return status;
 242 err_msg:
 243         usb_remove_function(c, f_ecm);
 244 err_ecm:
 245         usb_remove_function(c, f_acm);
 246 err_conf:
 247         if (!obex2_stat)
 248                 usb_remove_function(c, f_obex2);
 249         if (!obex1_stat)
 250                 usb_remove_function(c, f_obex1);
 251         if (!phonet_stat)
 252                 usb_remove_function(c, f_phonet);
 253         usb_put_function(f_msg);
 254 err_get_msg:
 255         usb_put_function(f_ecm);
 256 err_get_ecm:
 257         usb_put_function(f_acm);
 258 err_get_acm:
 259         if (!IS_ERR_OR_NULL(f_obex2))
 260                 usb_put_function(f_obex2);
 261         if (!IS_ERR_OR_NULL(f_obex1))
 262                 usb_put_function(f_obex1);
 263         if (!IS_ERR_OR_NULL(f_phonet))
 264                 usb_put_function(f_phonet);
 265         return status;
 266 }
 267 
 268 static int nokia_bind(struct usb_composite_dev *cdev)
 269 {
 270         struct usb_gadget       *gadget = cdev->gadget;
 271         struct fsg_opts         *fsg_opts;
 272         struct fsg_config       fsg_config;
 273         int                     status;
 274 
 275         status = usb_string_ids_tab(cdev, strings_dev);
 276         if (status < 0)
 277                 goto err_usb;
 278         device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id;
 279         device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
 280         status = strings_dev[STRING_DESCRIPTION_IDX].id;
 281         nokia_config_500ma_driver.iConfiguration = status;
 282         nokia_config_100ma_driver.iConfiguration = status;
 283 
 284         if (!gadget_is_altset_supported(gadget)) {
 285                 status = -ENODEV;
 286                 goto err_usb;
 287         }
 288 
 289         fi_phonet = usb_get_function_instance("phonet");
 290         if (IS_ERR(fi_phonet))
 291                 pr_debug("could not find phonet function\n");
 292 
 293         fi_obex1 = usb_get_function_instance("obex");
 294         if (IS_ERR(fi_obex1))
 295                 pr_debug("could not find obex function 1\n");
 296 
 297         fi_obex2 = usb_get_function_instance("obex");
 298         if (IS_ERR(fi_obex2))
 299                 pr_debug("could not find obex function 2\n");
 300 
 301         fi_acm = usb_get_function_instance("acm");
 302         if (IS_ERR(fi_acm)) {
 303                 status = PTR_ERR(fi_acm);
 304                 goto err_obex2_inst;
 305         }
 306 
 307         fi_ecm = usb_get_function_instance("ecm");
 308         if (IS_ERR(fi_ecm)) {
 309                 status = PTR_ERR(fi_ecm);
 310                 goto err_acm_inst;
 311         }
 312 
 313         fi_msg = usb_get_function_instance("mass_storage");
 314         if (IS_ERR(fi_msg)) {
 315                 status = PTR_ERR(fi_msg);
 316                 goto err_ecm_inst;
 317         }
 318 
 319         /* set up mass storage function */
 320         fsg_config_from_params(&fsg_config, &fsg_mod_data, fsg_num_buffers);
 321         fsg_config.vendor_name = "Nokia";
 322         fsg_config.product_name = "N900";
 323 
 324         fsg_opts = fsg_opts_from_func_inst(fi_msg);
 325         fsg_opts->no_configfs = true;
 326 
 327         status = fsg_common_set_num_buffers(fsg_opts->common, fsg_num_buffers);
 328         if (status)
 329                 goto err_msg_inst;
 330 
 331         status = fsg_common_set_cdev(fsg_opts->common, cdev, fsg_config.can_stall);
 332         if (status)
 333                 goto err_msg_buf;
 334 
 335         fsg_common_set_sysfs(fsg_opts->common, true);
 336 
 337         status = fsg_common_create_luns(fsg_opts->common, &fsg_config);
 338         if (status)
 339                 goto err_msg_buf;
 340 
 341         fsg_common_set_inquiry_string(fsg_opts->common, fsg_config.vendor_name,
 342                                       fsg_config.product_name);
 343 
 344         /* finally register the configuration */
 345         status = usb_add_config(cdev, &nokia_config_500ma_driver,
 346                         nokia_bind_config);
 347         if (status < 0)
 348                 goto err_msg_luns;
 349 
 350         status = usb_add_config(cdev, &nokia_config_100ma_driver,
 351                         nokia_bind_config);
 352         if (status < 0)
 353                 goto err_put_cfg1;
 354 
 355         usb_composite_overwrite_options(cdev, &coverwrite);
 356         dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME);
 357 
 358         return 0;
 359 
 360 err_put_cfg1:
 361         usb_put_function(f_acm_cfg1);
 362         if (!IS_ERR_OR_NULL(f_obex1_cfg1))
 363                 usb_put_function(f_obex1_cfg1);
 364         if (!IS_ERR_OR_NULL(f_obex2_cfg1))
 365                 usb_put_function(f_obex2_cfg1);
 366         if (!IS_ERR_OR_NULL(f_phonet_cfg1))
 367                 usb_put_function(f_phonet_cfg1);
 368         usb_put_function(f_ecm_cfg1);
 369 err_msg_luns:
 370         fsg_common_remove_luns(fsg_opts->common);
 371 err_msg_buf:
 372         fsg_common_free_buffers(fsg_opts->common);
 373 err_msg_inst:
 374         usb_put_function_instance(fi_msg);
 375 err_ecm_inst:
 376         usb_put_function_instance(fi_ecm);
 377 err_acm_inst:
 378         usb_put_function_instance(fi_acm);
 379 err_obex2_inst:
 380         if (!IS_ERR(fi_obex2))
 381                 usb_put_function_instance(fi_obex2);
 382         if (!IS_ERR(fi_obex1))
 383                 usb_put_function_instance(fi_obex1);
 384         if (!IS_ERR(fi_phonet))
 385                 usb_put_function_instance(fi_phonet);
 386 err_usb:
 387         return status;
 388 }
 389 
 390 static int nokia_unbind(struct usb_composite_dev *cdev)
 391 {
 392         if (!IS_ERR_OR_NULL(f_obex1_cfg2))
 393                 usb_put_function(f_obex1_cfg2);
 394         if (!IS_ERR_OR_NULL(f_obex2_cfg2))
 395                 usb_put_function(f_obex2_cfg2);
 396         if (!IS_ERR_OR_NULL(f_obex1_cfg1))
 397                 usb_put_function(f_obex1_cfg1);
 398         if (!IS_ERR_OR_NULL(f_obex2_cfg1))
 399                 usb_put_function(f_obex2_cfg1);
 400         if (!IS_ERR_OR_NULL(f_phonet_cfg1))
 401                 usb_put_function(f_phonet_cfg1);
 402         if (!IS_ERR_OR_NULL(f_phonet_cfg2))
 403                 usb_put_function(f_phonet_cfg2);
 404         usb_put_function(f_acm_cfg1);
 405         usb_put_function(f_acm_cfg2);
 406         usb_put_function(f_ecm_cfg1);
 407         usb_put_function(f_ecm_cfg2);
 408         usb_put_function(f_msg_cfg1);
 409         usb_put_function(f_msg_cfg2);
 410 
 411         usb_put_function_instance(fi_msg);
 412         usb_put_function_instance(fi_ecm);
 413         if (!IS_ERR(fi_obex2))
 414                 usb_put_function_instance(fi_obex2);
 415         if (!IS_ERR(fi_obex1))
 416                 usb_put_function_instance(fi_obex1);
 417         if (!IS_ERR(fi_phonet))
 418                 usb_put_function_instance(fi_phonet);
 419         usb_put_function_instance(fi_acm);
 420 
 421         return 0;
 422 }
 423 
 424 static struct usb_composite_driver nokia_driver = {
 425         .name           = "g_nokia",
 426         .dev            = &device_desc,
 427         .strings        = dev_strings,
 428         .max_speed      = USB_SPEED_HIGH,
 429         .bind           = nokia_bind,
 430         .unbind         = nokia_unbind,
 431 };
 432 
 433 module_usb_composite_driver(nokia_driver);

/* [<][>][^][v][top][bottom][index][help] */