Loading drivers/usb/gadget/f_fs.c +133 −41 Original line number Diff line number Diff line Loading @@ -197,13 +197,17 @@ struct ffs_data { * Real descriptors are 16 bytes after raw_descs (so you need * to skip 16 bytes (ie. ffs->raw_descs + 16) to get to the * first full speed descriptor). raw_descs_length and * raw_fs_descs_length do not have those 16 bytes added. * raw_fs_hs_descs_length do not have those 16 bytes added. * ss_desc are 8 bytes (ss_magic + count) pass the hs_descs */ const void *raw_descs; unsigned raw_descs_length; unsigned raw_fs_descs_length; unsigned raw_fs_hs_descs_length; unsigned raw_ss_descs_offset; unsigned raw_ss_descs_length; unsigned fs_descs_count; unsigned hs_descs_count; unsigned ss_descs_count; unsigned short strings_count; unsigned short interfaces_count; Loading Loading @@ -301,8 +305,8 @@ struct ffs_ep { struct usb_ep *ep; /* P: ffs->eps_lock */ struct usb_request *req; /* P: epfile->mutex */ /* [0]: full speed, [1]: high speed */ struct usb_endpoint_descriptor *descs[2]; /* [0]: full speed, [1]: high speed, [2]: super speed */ struct usb_endpoint_descriptor *descs[3]; u8 num; Loading Loading @@ -757,7 +761,7 @@ static ssize_t ffs_epfile_io(struct file *file, char *data = NULL; ssize_t ret; int halt; int buffer_len = !read ? len : round_up(len, 512); int buffer_len = !read ? len : round_up(len, 1024); pr_debug("%s: len %d, buffer_len %d, read %d\n", __func__, len, buffer_len, read); Loading Loading @@ -1365,9 +1369,12 @@ static void ffs_data_reset(struct ffs_data *ffs) ffs->stringtabs = NULL; ffs->raw_descs_length = 0; ffs->raw_fs_descs_length = 0; ffs->raw_fs_hs_descs_length = 0; ffs->raw_ss_descs_offset = 0; ffs->raw_ss_descs_length = 0; ffs->fs_descs_count = 0; ffs->hs_descs_count = 0; ffs->ss_descs_count = 0; ffs->strings_count = 0; ffs->interfaces_count = 0; Loading Loading @@ -1575,7 +1582,15 @@ static int ffs_func_eps_enable(struct ffs_function *func) spin_lock_irqsave(&func->ffs->eps_lock, flags); do { struct usb_endpoint_descriptor *ds; int desc_idx = ffs->gadget->speed == USB_SPEED_HIGH ? 1 : 0; int desc_idx; if (ffs->gadget->speed == USB_SPEED_SUPER) desc_idx = 2; else if (ffs->gadget->speed == USB_SPEED_HIGH) desc_idx = 1; else desc_idx = 0; ds = ep->descs[desc_idx]; if (!ds) { ret = -EINVAL; Loading Loading @@ -1715,6 +1730,12 @@ static int __must_check ffs_do_desc(char *data, unsigned len, } break; case USB_DT_SS_ENDPOINT_COMP: pr_vdebug("EP SS companion descriptor\n"); if (length != sizeof(struct usb_ss_ep_comp_descriptor)) goto inv_length; break; case USB_DT_OTHER_SPEED_CONFIG: case USB_DT_INTERFACE_POWER: case USB_DT_DEBUG: Loading Loading @@ -1825,8 +1846,8 @@ static int __ffs_data_do_entity(enum ffs_entity_type type, static int __ffs_data_got_descs(struct ffs_data *ffs, char *const _data, size_t len) { unsigned fs_count, hs_count; int fs_len, ret = -EINVAL; unsigned fs_count, hs_count, ss_count = 0; int fs_len, hs_len, ss_len, ss_magic, ret = -EINVAL; char *data = _data; ENTER(); Loading @@ -1837,9 +1858,6 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, fs_count = get_unaligned_le32(data + 8); hs_count = get_unaligned_le32(data + 12); if (!fs_count && !hs_count) goto einval; data += 16; len -= 16; Loading @@ -1858,22 +1876,58 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, } if (likely(hs_count)) { ret = ffs_do_descs(hs_count, data, len, hs_len = ffs_do_descs(hs_count, data, len, __ffs_data_do_entity, ffs); if (unlikely(ret < 0)) if (unlikely(hs_len < 0)) { ret = hs_len; goto error; } } else { hs_len = 0; } if ((len >= hs_len + 8)) { /* Check SS_MAGIC for presence of ss_descs and get SS_COUNT */ ss_magic = get_unaligned_le32(data + hs_len); if (ss_magic != FUNCTIONFS_SS_DESC_MAGIC) goto einval; ss_count = get_unaligned_le32(data + hs_len + 4); data += hs_len + 8; len -= hs_len + 8; } else { data += hs_len; len -= hs_len; } if (!fs_count && !hs_count && !ss_count) goto einval; if (ss_count) { ss_len = ffs_do_descs(ss_count, data, len, __ffs_data_do_entity, ffs); if (unlikely(ss_len < 0)) { ret = ss_len; goto error; } ret = ss_len; } else { ss_len = 0; ret = 0; } if (unlikely(len != ret)) goto einval; ffs->raw_fs_descs_length = fs_len; ffs->raw_descs_length = fs_len + ret; ffs->raw_fs_hs_descs_length = fs_len + hs_len; ffs->raw_ss_descs_length = ss_len; ffs->raw_descs_length = ffs->raw_fs_hs_descs_length + ss_len; ffs->raw_descs = _data; ffs->fs_descs_count = fs_count; ffs->hs_descs_count = hs_count; ffs->ss_descs_count = ss_count; if (ffs->ss_descs_count) ffs->raw_ss_descs_offset = 16 + ffs->raw_fs_hs_descs_length + 8; return 0; Loading Loading @@ -2097,16 +2151,23 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep, * If hs_descriptors is not NULL then we are reading hs * descriptors now */ const int isHS = func->function.hs_descriptors != NULL; unsigned idx; const int is_hs = func->function.hs_descriptors != NULL; const int is_ss = func->function.ss_descriptors != NULL; unsigned ep_desc_id, idx; if (type != FFS_DESCRIPTOR) return 0; if (isHS) if (is_ss) { func->function.ss_descriptors[(long)valuep] = desc; ep_desc_id = 2; } else if (is_hs) { func->function.hs_descriptors[(long)valuep] = desc; else ep_desc_id = 1; } else { func->function.fs_descriptors[(long)valuep] = desc; ep_desc_id = 0; } if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT) return 0; Loading @@ -2114,13 +2175,13 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep, idx = (ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) - 1; ffs_ep = func->eps + idx; if (unlikely(ffs_ep->descs[isHS])) { if (unlikely(ffs_ep->descs[ep_desc_id])) { pr_vdebug("two %sspeed descriptors for EP %d\n", isHS ? "high" : "full", is_ss ? "super" : "high/full", ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); return -EINVAL; } ffs_ep->descs[isHS] = ds; ffs_ep->descs[ep_desc_id] = ds; ffs_dump_mem(": Original ep desc", ds, ds->bLength); if (ffs_ep->ep) { Loading Loading @@ -2215,8 +2276,10 @@ static int ffs_func_bind(struct usb_configuration *c, const int full = !!func->ffs->fs_descs_count; const int high = gadget_is_dualspeed(func->gadget) && func->ffs->hs_descs_count; const int super = gadget_is_superspeed(func->gadget) && func->ffs->ss_descs_count; int ret; int fs_len, hs_len, ret; /* Make it a single chunk, less management later on */ struct { Loading @@ -2225,15 +2288,16 @@ static int ffs_func_bind(struct usb_configuration *c, *fs_descs[full ? ffs->fs_descs_count + 1 : 0]; struct usb_descriptor_header *hs_descs[high ? ffs->hs_descs_count + 1 : 0]; struct usb_descriptor_header *ss_descs[super ? ffs->ss_descs_count + 1 : 0]; short inums[ffs->interfaces_count]; char raw_descs[high ? ffs->raw_descs_length : ffs->raw_fs_descs_length]; char raw_descs[ffs->raw_descs_length]; } *data; ENTER(); /* Only high speed but not supported by gadget? */ if (unlikely(!(full | high))) /* Only high/super speed but not supported by gadget? */ if (unlikely(!(full | high | super))) return -ENOTSUPP; /* Allocate */ Loading @@ -2243,7 +2307,15 @@ static int ffs_func_bind(struct usb_configuration *c, /* Zero */ memset(data->eps, 0, sizeof data->eps); memcpy(data->raw_descs, ffs->raw_descs + 16, sizeof data->raw_descs); /* Copy only raw (hs,fs) descriptors (until ss_magic and ss_count) */ memcpy(data->raw_descs, ffs->raw_descs + 16, ffs->raw_fs_hs_descs_length); /* Copy SS descriptors */ if (func->ffs->ss_descs_count) memcpy(data->raw_descs + ffs->raw_fs_hs_descs_length, ffs->raw_descs + ffs->raw_ss_descs_offset, ffs->raw_ss_descs_length); memset(data->inums, 0xff, sizeof data->inums); for (ret = ffs->eps_count; ret; --ret) data->eps[ret].num = -1; Loading @@ -2259,23 +2331,42 @@ static int ffs_func_bind(struct usb_configuration *c, */ if (likely(full)) { func->function.fs_descriptors = data->fs_descs; ret = ffs_do_descs(ffs->fs_descs_count, fs_len = ffs_do_descs(ffs->fs_descs_count, data->raw_descs, sizeof data->raw_descs, sizeof(data->raw_descs), __ffs_func_bind_do_descs, func); if (unlikely(ret < 0)) if (unlikely(fs_len < 0)) { ret = fs_len; goto error; } } else { ret = 0; fs_len = 0; } if (likely(high)) { func->function.hs_descriptors = data->hs_descs; ret = ffs_do_descs(ffs->hs_descs_count, data->raw_descs + ret, (sizeof data->raw_descs) - ret, hs_len = ffs_do_descs(ffs->hs_descs_count, data->raw_descs + fs_len, (sizeof(data->raw_descs)) - fs_len, __ffs_func_bind_do_descs, func); if (unlikely(hs_len < 0)) { ret = hs_len; goto error; } } else { hs_len = 0; } if (likely(super)) { func->function.ss_descriptors = data->ss_descs; ret = ffs_do_descs(ffs->ss_descs_count, data->raw_descs + fs_len + hs_len, (sizeof(data->raw_descs)) - fs_len - hs_len, __ffs_func_bind_do_descs, func); if (unlikely(ret < 0)) goto error; } /* * Now handle interface numbers allocation and interface and Loading @@ -2283,8 +2374,9 @@ static int ffs_func_bind(struct usb_configuration *c, * now. */ ret = ffs_do_descs(ffs->fs_descs_count + (high ? ffs->hs_descs_count : 0), data->raw_descs, sizeof data->raw_descs, (high ? ffs->hs_descs_count : 0) + (super ? ffs->ss_descs_count : 0), data->raw_descs, sizeof(data->raw_descs), __ffs_func_bind_do_nums, func); if (unlikely(ret < 0)) goto error; Loading include/uapi/linux/usb/functionfs.h +5 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ enum { FUNCTIONFS_STRINGS_MAGIC = 2 }; #define FUNCTIONFS_SS_DESC_MAGIC 0x0055DE5C #ifndef __KERNEL__ Loading Loading @@ -50,7 +51,11 @@ struct usb_functionfs_descs_head { * | 12 | hs_count | LE32 | number of high-speed descriptors | * | 16 | fs_descrs | Descriptor[] | list of full-speed descriptors | * | | hs_descrs | Descriptor[] | list of high-speed descriptors | * | | ss_magic | LE32 | FUNCTIONFS_SS_DESC_MAGIC | * | | ss_count | LE32 | number of super-speed descriptors | * | | ss_descrs | Descriptor[] | list of super-speed descriptors | * * ss_magic: if present then it implies that SS_DESCs are also present * descs are just valid USB descriptors and have the following format: * * | off | name | type | description | Loading Loading
drivers/usb/gadget/f_fs.c +133 −41 Original line number Diff line number Diff line Loading @@ -197,13 +197,17 @@ struct ffs_data { * Real descriptors are 16 bytes after raw_descs (so you need * to skip 16 bytes (ie. ffs->raw_descs + 16) to get to the * first full speed descriptor). raw_descs_length and * raw_fs_descs_length do not have those 16 bytes added. * raw_fs_hs_descs_length do not have those 16 bytes added. * ss_desc are 8 bytes (ss_magic + count) pass the hs_descs */ const void *raw_descs; unsigned raw_descs_length; unsigned raw_fs_descs_length; unsigned raw_fs_hs_descs_length; unsigned raw_ss_descs_offset; unsigned raw_ss_descs_length; unsigned fs_descs_count; unsigned hs_descs_count; unsigned ss_descs_count; unsigned short strings_count; unsigned short interfaces_count; Loading Loading @@ -301,8 +305,8 @@ struct ffs_ep { struct usb_ep *ep; /* P: ffs->eps_lock */ struct usb_request *req; /* P: epfile->mutex */ /* [0]: full speed, [1]: high speed */ struct usb_endpoint_descriptor *descs[2]; /* [0]: full speed, [1]: high speed, [2]: super speed */ struct usb_endpoint_descriptor *descs[3]; u8 num; Loading Loading @@ -757,7 +761,7 @@ static ssize_t ffs_epfile_io(struct file *file, char *data = NULL; ssize_t ret; int halt; int buffer_len = !read ? len : round_up(len, 512); int buffer_len = !read ? len : round_up(len, 1024); pr_debug("%s: len %d, buffer_len %d, read %d\n", __func__, len, buffer_len, read); Loading Loading @@ -1365,9 +1369,12 @@ static void ffs_data_reset(struct ffs_data *ffs) ffs->stringtabs = NULL; ffs->raw_descs_length = 0; ffs->raw_fs_descs_length = 0; ffs->raw_fs_hs_descs_length = 0; ffs->raw_ss_descs_offset = 0; ffs->raw_ss_descs_length = 0; ffs->fs_descs_count = 0; ffs->hs_descs_count = 0; ffs->ss_descs_count = 0; ffs->strings_count = 0; ffs->interfaces_count = 0; Loading Loading @@ -1575,7 +1582,15 @@ static int ffs_func_eps_enable(struct ffs_function *func) spin_lock_irqsave(&func->ffs->eps_lock, flags); do { struct usb_endpoint_descriptor *ds; int desc_idx = ffs->gadget->speed == USB_SPEED_HIGH ? 1 : 0; int desc_idx; if (ffs->gadget->speed == USB_SPEED_SUPER) desc_idx = 2; else if (ffs->gadget->speed == USB_SPEED_HIGH) desc_idx = 1; else desc_idx = 0; ds = ep->descs[desc_idx]; if (!ds) { ret = -EINVAL; Loading Loading @@ -1715,6 +1730,12 @@ static int __must_check ffs_do_desc(char *data, unsigned len, } break; case USB_DT_SS_ENDPOINT_COMP: pr_vdebug("EP SS companion descriptor\n"); if (length != sizeof(struct usb_ss_ep_comp_descriptor)) goto inv_length; break; case USB_DT_OTHER_SPEED_CONFIG: case USB_DT_INTERFACE_POWER: case USB_DT_DEBUG: Loading Loading @@ -1825,8 +1846,8 @@ static int __ffs_data_do_entity(enum ffs_entity_type type, static int __ffs_data_got_descs(struct ffs_data *ffs, char *const _data, size_t len) { unsigned fs_count, hs_count; int fs_len, ret = -EINVAL; unsigned fs_count, hs_count, ss_count = 0; int fs_len, hs_len, ss_len, ss_magic, ret = -EINVAL; char *data = _data; ENTER(); Loading @@ -1837,9 +1858,6 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, fs_count = get_unaligned_le32(data + 8); hs_count = get_unaligned_le32(data + 12); if (!fs_count && !hs_count) goto einval; data += 16; len -= 16; Loading @@ -1858,22 +1876,58 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, } if (likely(hs_count)) { ret = ffs_do_descs(hs_count, data, len, hs_len = ffs_do_descs(hs_count, data, len, __ffs_data_do_entity, ffs); if (unlikely(ret < 0)) if (unlikely(hs_len < 0)) { ret = hs_len; goto error; } } else { hs_len = 0; } if ((len >= hs_len + 8)) { /* Check SS_MAGIC for presence of ss_descs and get SS_COUNT */ ss_magic = get_unaligned_le32(data + hs_len); if (ss_magic != FUNCTIONFS_SS_DESC_MAGIC) goto einval; ss_count = get_unaligned_le32(data + hs_len + 4); data += hs_len + 8; len -= hs_len + 8; } else { data += hs_len; len -= hs_len; } if (!fs_count && !hs_count && !ss_count) goto einval; if (ss_count) { ss_len = ffs_do_descs(ss_count, data, len, __ffs_data_do_entity, ffs); if (unlikely(ss_len < 0)) { ret = ss_len; goto error; } ret = ss_len; } else { ss_len = 0; ret = 0; } if (unlikely(len != ret)) goto einval; ffs->raw_fs_descs_length = fs_len; ffs->raw_descs_length = fs_len + ret; ffs->raw_fs_hs_descs_length = fs_len + hs_len; ffs->raw_ss_descs_length = ss_len; ffs->raw_descs_length = ffs->raw_fs_hs_descs_length + ss_len; ffs->raw_descs = _data; ffs->fs_descs_count = fs_count; ffs->hs_descs_count = hs_count; ffs->ss_descs_count = ss_count; if (ffs->ss_descs_count) ffs->raw_ss_descs_offset = 16 + ffs->raw_fs_hs_descs_length + 8; return 0; Loading Loading @@ -2097,16 +2151,23 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep, * If hs_descriptors is not NULL then we are reading hs * descriptors now */ const int isHS = func->function.hs_descriptors != NULL; unsigned idx; const int is_hs = func->function.hs_descriptors != NULL; const int is_ss = func->function.ss_descriptors != NULL; unsigned ep_desc_id, idx; if (type != FFS_DESCRIPTOR) return 0; if (isHS) if (is_ss) { func->function.ss_descriptors[(long)valuep] = desc; ep_desc_id = 2; } else if (is_hs) { func->function.hs_descriptors[(long)valuep] = desc; else ep_desc_id = 1; } else { func->function.fs_descriptors[(long)valuep] = desc; ep_desc_id = 0; } if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT) return 0; Loading @@ -2114,13 +2175,13 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep, idx = (ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) - 1; ffs_ep = func->eps + idx; if (unlikely(ffs_ep->descs[isHS])) { if (unlikely(ffs_ep->descs[ep_desc_id])) { pr_vdebug("two %sspeed descriptors for EP %d\n", isHS ? "high" : "full", is_ss ? "super" : "high/full", ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); return -EINVAL; } ffs_ep->descs[isHS] = ds; ffs_ep->descs[ep_desc_id] = ds; ffs_dump_mem(": Original ep desc", ds, ds->bLength); if (ffs_ep->ep) { Loading Loading @@ -2215,8 +2276,10 @@ static int ffs_func_bind(struct usb_configuration *c, const int full = !!func->ffs->fs_descs_count; const int high = gadget_is_dualspeed(func->gadget) && func->ffs->hs_descs_count; const int super = gadget_is_superspeed(func->gadget) && func->ffs->ss_descs_count; int ret; int fs_len, hs_len, ret; /* Make it a single chunk, less management later on */ struct { Loading @@ -2225,15 +2288,16 @@ static int ffs_func_bind(struct usb_configuration *c, *fs_descs[full ? ffs->fs_descs_count + 1 : 0]; struct usb_descriptor_header *hs_descs[high ? ffs->hs_descs_count + 1 : 0]; struct usb_descriptor_header *ss_descs[super ? ffs->ss_descs_count + 1 : 0]; short inums[ffs->interfaces_count]; char raw_descs[high ? ffs->raw_descs_length : ffs->raw_fs_descs_length]; char raw_descs[ffs->raw_descs_length]; } *data; ENTER(); /* Only high speed but not supported by gadget? */ if (unlikely(!(full | high))) /* Only high/super speed but not supported by gadget? */ if (unlikely(!(full | high | super))) return -ENOTSUPP; /* Allocate */ Loading @@ -2243,7 +2307,15 @@ static int ffs_func_bind(struct usb_configuration *c, /* Zero */ memset(data->eps, 0, sizeof data->eps); memcpy(data->raw_descs, ffs->raw_descs + 16, sizeof data->raw_descs); /* Copy only raw (hs,fs) descriptors (until ss_magic and ss_count) */ memcpy(data->raw_descs, ffs->raw_descs + 16, ffs->raw_fs_hs_descs_length); /* Copy SS descriptors */ if (func->ffs->ss_descs_count) memcpy(data->raw_descs + ffs->raw_fs_hs_descs_length, ffs->raw_descs + ffs->raw_ss_descs_offset, ffs->raw_ss_descs_length); memset(data->inums, 0xff, sizeof data->inums); for (ret = ffs->eps_count; ret; --ret) data->eps[ret].num = -1; Loading @@ -2259,23 +2331,42 @@ static int ffs_func_bind(struct usb_configuration *c, */ if (likely(full)) { func->function.fs_descriptors = data->fs_descs; ret = ffs_do_descs(ffs->fs_descs_count, fs_len = ffs_do_descs(ffs->fs_descs_count, data->raw_descs, sizeof data->raw_descs, sizeof(data->raw_descs), __ffs_func_bind_do_descs, func); if (unlikely(ret < 0)) if (unlikely(fs_len < 0)) { ret = fs_len; goto error; } } else { ret = 0; fs_len = 0; } if (likely(high)) { func->function.hs_descriptors = data->hs_descs; ret = ffs_do_descs(ffs->hs_descs_count, data->raw_descs + ret, (sizeof data->raw_descs) - ret, hs_len = ffs_do_descs(ffs->hs_descs_count, data->raw_descs + fs_len, (sizeof(data->raw_descs)) - fs_len, __ffs_func_bind_do_descs, func); if (unlikely(hs_len < 0)) { ret = hs_len; goto error; } } else { hs_len = 0; } if (likely(super)) { func->function.ss_descriptors = data->ss_descs; ret = ffs_do_descs(ffs->ss_descs_count, data->raw_descs + fs_len + hs_len, (sizeof(data->raw_descs)) - fs_len - hs_len, __ffs_func_bind_do_descs, func); if (unlikely(ret < 0)) goto error; } /* * Now handle interface numbers allocation and interface and Loading @@ -2283,8 +2374,9 @@ static int ffs_func_bind(struct usb_configuration *c, * now. */ ret = ffs_do_descs(ffs->fs_descs_count + (high ? ffs->hs_descs_count : 0), data->raw_descs, sizeof data->raw_descs, (high ? ffs->hs_descs_count : 0) + (super ? ffs->ss_descs_count : 0), data->raw_descs, sizeof(data->raw_descs), __ffs_func_bind_do_nums, func); if (unlikely(ret < 0)) goto error; Loading
include/uapi/linux/usb/functionfs.h +5 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ enum { FUNCTIONFS_STRINGS_MAGIC = 2 }; #define FUNCTIONFS_SS_DESC_MAGIC 0x0055DE5C #ifndef __KERNEL__ Loading Loading @@ -50,7 +51,11 @@ struct usb_functionfs_descs_head { * | 12 | hs_count | LE32 | number of high-speed descriptors | * | 16 | fs_descrs | Descriptor[] | list of full-speed descriptors | * | | hs_descrs | Descriptor[] | list of high-speed descriptors | * | | ss_magic | LE32 | FUNCTIONFS_SS_DESC_MAGIC | * | | ss_count | LE32 | number of super-speed descriptors | * | | ss_descrs | Descriptor[] | list of super-speed descriptors | * * ss_magic: if present then it implies that SS_DESCs are also present * descs are just valid USB descriptors and have the following format: * * | off | name | type | description | Loading