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

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

DEFINITIONS

This source file includes following definitions.
  1. guas_unbind
  2. tcm_do_config
  3. usb_target_bind
  4. usbg_attach
  5. usbg_detach
  6. usb_target_gadget_init
  7. usb_target_gadget_exit

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* Target based USB-Gadget
   3  *
   4  * UAS protocol handling, target callbacks, configfs handling,
   5  * BBB (USB Mass Storage Class Bulk-Only (BBB) and Transport protocol handling.
   6  *
   7  * Author: Sebastian Andrzej Siewior <bigeasy at linutronix dot de>
   8  */
   9 #include <linux/kernel.h>
  10 #include <linux/module.h>
  11 #include <linux/types.h>
  12 #include <linux/string.h>
  13 #include <linux/configfs.h>
  14 #include <linux/ctype.h>
  15 #include <linux/usb/ch9.h>
  16 #include <linux/usb/composite.h>
  17 #include <linux/usb/gadget.h>
  18 #include <linux/usb/storage.h>
  19 #include <scsi/scsi_tcq.h>
  20 #include <target/target_core_base.h>
  21 #include <target/target_core_fabric.h>
  22 #include <asm/unaligned.h>
  23 
  24 #include "u_tcm.h"
  25 
  26 USB_GADGET_COMPOSITE_OPTIONS();
  27 
  28 #define UAS_VENDOR_ID   0x0525  /* NetChip */
  29 #define UAS_PRODUCT_ID  0xa4a5  /* Linux-USB File-backed Storage Gadget */
  30 
  31 static struct usb_device_descriptor usbg_device_desc = {
  32         .bLength =              sizeof(usbg_device_desc),
  33         .bDescriptorType =      USB_DT_DEVICE,
  34         /* .bcdUSB = DYNAMIC */
  35         .bDeviceClass =         USB_CLASS_PER_INTERFACE,
  36         .idVendor =             cpu_to_le16(UAS_VENDOR_ID),
  37         .idProduct =            cpu_to_le16(UAS_PRODUCT_ID),
  38         .bNumConfigurations =   1,
  39 };
  40 
  41 #define USB_G_STR_CONFIG USB_GADGET_FIRST_AVAIL_IDX
  42 
  43 static struct usb_string        usbg_us_strings[] = {
  44         [USB_GADGET_MANUFACTURER_IDX].s = "Target Manufacturer",
  45         [USB_GADGET_PRODUCT_IDX].s      = "Target Product",
  46         [USB_GADGET_SERIAL_IDX].s       = "000000000001",
  47         [USB_G_STR_CONFIG].s            = "default config",
  48         { },
  49 };
  50 
  51 static struct usb_gadget_strings usbg_stringtab = {
  52         .language = 0x0409,
  53         .strings = usbg_us_strings,
  54 };
  55 
  56 static struct usb_gadget_strings *usbg_strings[] = {
  57         &usbg_stringtab,
  58         NULL,
  59 };
  60 
  61 static struct usb_function_instance *fi_tcm;
  62 static struct usb_function *f_tcm;
  63 
  64 static int guas_unbind(struct usb_composite_dev *cdev)
  65 {
  66         if (!IS_ERR_OR_NULL(f_tcm))
  67                 usb_put_function(f_tcm);
  68 
  69         return 0;
  70 }
  71 
  72 static int tcm_do_config(struct usb_configuration *c)
  73 {
  74         int status;
  75 
  76         f_tcm = usb_get_function(fi_tcm);
  77         if (IS_ERR(f_tcm))
  78                 return PTR_ERR(f_tcm);
  79 
  80         status = usb_add_function(c, f_tcm);
  81         if (status < 0) {
  82                 usb_put_function(f_tcm);
  83                 return status;
  84         }
  85 
  86         return 0;
  87 }
  88 
  89 static struct usb_configuration usbg_config_driver = {
  90         .label                  = "Linux Target",
  91         .bConfigurationValue    = 1,
  92         .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
  93 };
  94 
  95 static int usbg_attach(struct usb_function_instance *f);
  96 static void usbg_detach(struct usb_function_instance *f);
  97 
  98 static int usb_target_bind(struct usb_composite_dev *cdev)
  99 {
 100         int ret;
 101 
 102         ret = usb_string_ids_tab(cdev, usbg_us_strings);
 103         if (ret)
 104                 return ret;
 105 
 106         usbg_device_desc.iManufacturer =
 107                 usbg_us_strings[USB_GADGET_MANUFACTURER_IDX].id;
 108         usbg_device_desc.iProduct = usbg_us_strings[USB_GADGET_PRODUCT_IDX].id;
 109         usbg_device_desc.iSerialNumber =
 110                 usbg_us_strings[USB_GADGET_SERIAL_IDX].id;
 111         usbg_config_driver.iConfiguration =
 112                 usbg_us_strings[USB_G_STR_CONFIG].id;
 113 
 114         ret = usb_add_config(cdev, &usbg_config_driver, tcm_do_config);
 115         if (ret)
 116                 return ret;
 117         usb_composite_overwrite_options(cdev, &coverwrite);
 118         return 0;
 119 }
 120 
 121 static struct usb_composite_driver usbg_driver = {
 122         .name           = "g_target",
 123         .dev            = &usbg_device_desc,
 124         .strings        = usbg_strings,
 125         .max_speed      = USB_SPEED_SUPER,
 126         .bind           = usb_target_bind,
 127         .unbind         = guas_unbind,
 128 };
 129 
 130 static int usbg_attach(struct usb_function_instance *f)
 131 {
 132         return usb_composite_probe(&usbg_driver);
 133 }
 134 
 135 static void usbg_detach(struct usb_function_instance *f)
 136 {
 137         usb_composite_unregister(&usbg_driver);
 138 }
 139 
 140 static int __init usb_target_gadget_init(void)
 141 {
 142         struct f_tcm_opts *tcm_opts;
 143 
 144         fi_tcm = usb_get_function_instance("tcm");
 145         if (IS_ERR(fi_tcm))
 146                 return PTR_ERR(fi_tcm);
 147 
 148         tcm_opts = container_of(fi_tcm, struct f_tcm_opts, func_inst);
 149         mutex_lock(&tcm_opts->dep_lock);
 150         tcm_opts->tcm_register_callback = usbg_attach;
 151         tcm_opts->tcm_unregister_callback = usbg_detach;
 152         tcm_opts->dependent = THIS_MODULE;
 153         tcm_opts->can_attach = true;
 154         tcm_opts->has_dep = true;
 155         mutex_unlock(&tcm_opts->dep_lock);
 156 
 157         fi_tcm->set_inst_name(fi_tcm, "tcm-legacy");
 158 
 159         return 0;
 160 }
 161 module_init(usb_target_gadget_init);
 162 
 163 static void __exit usb_target_gadget_exit(void)
 164 {
 165         if (!IS_ERR_OR_NULL(fi_tcm))
 166                 usb_put_function_instance(fi_tcm);
 167 
 168 }
 169 module_exit(usb_target_gadget_exit);
 170 
 171 MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>");
 172 MODULE_DESCRIPTION("usb-gadget fabric");
 173 MODULE_LICENSE("GPL v2");

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