0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/errno.h>
0009 #include <linux/slab.h>
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/list.h>
0013 #include <linux/string.h>
0014 #include <linux/device.h>
0015
0016 #include <linux/usb/ch9.h>
0017 #include <linux/usb/gadget.h>
0018 #include <linux/usb/composite.h>
0019 #include <linux/usb/otg.h>
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 int
0034 usb_descriptor_fillbuf(void *buf, unsigned buflen,
0035 const struct usb_descriptor_header **src)
0036 {
0037 u8 *dest = buf;
0038
0039 if (!src)
0040 return -EINVAL;
0041
0042
0043 for (; NULL != *src; src++) {
0044 unsigned len = (*src)->bLength;
0045
0046 if (len > buflen)
0047 return -EINVAL;
0048 memcpy(dest, *src, len);
0049 buflen -= len;
0050 dest += len;
0051 }
0052 return dest - (u8 *)buf;
0053 }
0054 EXPORT_SYMBOL_GPL(usb_descriptor_fillbuf);
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 int usb_gadget_config_buf(
0077 const struct usb_config_descriptor *config,
0078 void *buf,
0079 unsigned length,
0080 const struct usb_descriptor_header **desc
0081 )
0082 {
0083 struct usb_config_descriptor *cp = buf;
0084 int len;
0085
0086
0087 if (length < USB_DT_CONFIG_SIZE || !desc)
0088 return -EINVAL;
0089 *cp = *config;
0090
0091
0092 len = usb_descriptor_fillbuf(USB_DT_CONFIG_SIZE + (u8 *)buf,
0093 length - USB_DT_CONFIG_SIZE, desc);
0094 if (len < 0)
0095 return len;
0096 len += USB_DT_CONFIG_SIZE;
0097 if (len > 0xffff)
0098 return -EINVAL;
0099
0100
0101 cp->bLength = USB_DT_CONFIG_SIZE;
0102 cp->bDescriptorType = USB_DT_CONFIG;
0103 cp->wTotalLength = cpu_to_le16(len);
0104 cp->bmAttributes |= USB_CONFIG_ATT_ONE;
0105 return len;
0106 }
0107 EXPORT_SYMBOL_GPL(usb_gadget_config_buf);
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 struct usb_descriptor_header **
0122 usb_copy_descriptors(struct usb_descriptor_header **src)
0123 {
0124 struct usb_descriptor_header **tmp;
0125 unsigned bytes;
0126 unsigned n_desc;
0127 void *mem;
0128 struct usb_descriptor_header **ret;
0129
0130
0131 for (bytes = 0, n_desc = 0, tmp = src; *tmp; tmp++, n_desc++)
0132 bytes += (*tmp)->bLength;
0133 bytes += (n_desc + 1) * sizeof(*tmp);
0134
0135 mem = kmalloc(bytes, GFP_KERNEL);
0136 if (!mem)
0137 return NULL;
0138
0139
0140
0141
0142
0143 tmp = mem;
0144 ret = mem;
0145 mem += (n_desc + 1) * sizeof(*tmp);
0146 while (*src) {
0147 memcpy(mem, *src, (*src)->bLength);
0148 *tmp = mem;
0149 tmp++;
0150 mem += (*src)->bLength;
0151 src++;
0152 }
0153 *tmp = NULL;
0154
0155 return ret;
0156 }
0157 EXPORT_SYMBOL_GPL(usb_copy_descriptors);
0158
0159 int usb_assign_descriptors(struct usb_function *f,
0160 struct usb_descriptor_header **fs,
0161 struct usb_descriptor_header **hs,
0162 struct usb_descriptor_header **ss,
0163 struct usb_descriptor_header **ssp)
0164 {
0165 struct usb_gadget *g = f->config->cdev->gadget;
0166
0167
0168
0169
0170
0171
0172 if (!ssp)
0173 ssp = ss;
0174
0175 if (fs) {
0176 f->fs_descriptors = usb_copy_descriptors(fs);
0177 if (!f->fs_descriptors)
0178 goto err;
0179 }
0180 if (hs && gadget_is_dualspeed(g)) {
0181 f->hs_descriptors = usb_copy_descriptors(hs);
0182 if (!f->hs_descriptors)
0183 goto err;
0184 }
0185 if (ss && gadget_is_superspeed(g)) {
0186 f->ss_descriptors = usb_copy_descriptors(ss);
0187 if (!f->ss_descriptors)
0188 goto err;
0189 }
0190 if (ssp && gadget_is_superspeed_plus(g)) {
0191 f->ssp_descriptors = usb_copy_descriptors(ssp);
0192 if (!f->ssp_descriptors)
0193 goto err;
0194 }
0195 return 0;
0196 err:
0197 usb_free_all_descriptors(f);
0198 return -ENOMEM;
0199 }
0200 EXPORT_SYMBOL_GPL(usb_assign_descriptors);
0201
0202 void usb_free_all_descriptors(struct usb_function *f)
0203 {
0204 usb_free_descriptors(f->fs_descriptors);
0205 f->fs_descriptors = NULL;
0206 usb_free_descriptors(f->hs_descriptors);
0207 f->hs_descriptors = NULL;
0208 usb_free_descriptors(f->ss_descriptors);
0209 f->ss_descriptors = NULL;
0210 usb_free_descriptors(f->ssp_descriptors);
0211 f->ssp_descriptors = NULL;
0212 }
0213 EXPORT_SYMBOL_GPL(usb_free_all_descriptors);
0214
0215 struct usb_descriptor_header *usb_otg_descriptor_alloc(
0216 struct usb_gadget *gadget)
0217 {
0218 struct usb_descriptor_header *otg_desc;
0219 unsigned length = 0;
0220
0221 if (gadget->otg_caps && (gadget->otg_caps->otg_rev >= 0x0200))
0222 length = sizeof(struct usb_otg20_descriptor);
0223 else
0224 length = sizeof(struct usb_otg_descriptor);
0225
0226 otg_desc = kzalloc(length, GFP_KERNEL);
0227 return otg_desc;
0228 }
0229 EXPORT_SYMBOL_GPL(usb_otg_descriptor_alloc);
0230
0231 int usb_otg_descriptor_init(struct usb_gadget *gadget,
0232 struct usb_descriptor_header *otg_desc)
0233 {
0234 struct usb_otg_descriptor *otg1x_desc;
0235 struct usb_otg20_descriptor *otg20_desc;
0236 struct usb_otg_caps *otg_caps = gadget->otg_caps;
0237 u8 otg_attributes = 0;
0238
0239 if (!otg_desc)
0240 return -EINVAL;
0241
0242 if (otg_caps && otg_caps->otg_rev) {
0243 if (otg_caps->hnp_support)
0244 otg_attributes |= USB_OTG_HNP;
0245 if (otg_caps->srp_support)
0246 otg_attributes |= USB_OTG_SRP;
0247 if (otg_caps->adp_support && (otg_caps->otg_rev >= 0x0200))
0248 otg_attributes |= USB_OTG_ADP;
0249 } else {
0250 otg_attributes = USB_OTG_SRP | USB_OTG_HNP;
0251 }
0252
0253 if (otg_caps && (otg_caps->otg_rev >= 0x0200)) {
0254 otg20_desc = (struct usb_otg20_descriptor *)otg_desc;
0255 otg20_desc->bLength = sizeof(struct usb_otg20_descriptor);
0256 otg20_desc->bDescriptorType = USB_DT_OTG;
0257 otg20_desc->bmAttributes = otg_attributes;
0258 otg20_desc->bcdOTG = cpu_to_le16(otg_caps->otg_rev);
0259 } else {
0260 otg1x_desc = (struct usb_otg_descriptor *)otg_desc;
0261 otg1x_desc->bLength = sizeof(struct usb_otg_descriptor);
0262 otg1x_desc->bDescriptorType = USB_DT_OTG;
0263 otg1x_desc->bmAttributes = otg_attributes;
0264 }
0265
0266 return 0;
0267 }
0268 EXPORT_SYMBOL_GPL(usb_otg_descriptor_init);