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