epfile->ffs = ffs;
mutex_init(&epfile->mutex);
init_waitqueue_head(&epfile->wait);
- sprintf(epfiles->name, "ep%u", i);
+ if (ffs->user_flags & FUNCTIONFS_VIRTUAL_ADDR)
+ sprintf(epfiles->name, "ep%02x", ffs->eps_addrmap[i]);
+ else
+ sprintf(epfiles->name, "ep%u", i);
if (!unlikely(ffs_sb_create_file(ffs->sb, epfiles->name, epfile,
&ffs_epfile_operations,
&epfile->dentry))) {
break;
case FUNCTIONFS_DESCRIPTORS_MAGIC_V2:
flags = get_unaligned_le32(data + 8);
+ ffs->user_flags = flags;
if (flags & ~(FUNCTIONFS_HAS_FS_DESC |
FUNCTIONFS_HAS_HS_DESC |
FUNCTIONFS_HAS_SS_DESC |
- FUNCTIONFS_HAS_MS_OS_DESC)) {
+ FUNCTIONFS_HAS_MS_OS_DESC |
+ FUNCTIONFS_VIRTUAL_ADDR)) {
ret = -ENOSYS;
goto error;
}
} else {
struct usb_request *req;
struct usb_ep *ep;
+ u8 bEndpointAddress;
+ /*
+ * We back up bEndpointAddress because autoconfig overwrites
+ * it with physical endpoint address.
+ */
+ bEndpointAddress = ds->bEndpointAddress;
pr_vdebug("autoconfig\n");
ep = usb_ep_autoconfig(func->gadget, ds);
if (unlikely(!ep))
ffs_ep->req = req;
func->eps_revmap[ds->bEndpointAddress &
USB_ENDPOINT_NUMBER_MASK] = idx + 1;
+ /*
+ * If we use virtual address mapping, we restore
+ * original bEndpointAddress value.
+ */
+ if (func->ffs->user_flags & FUNCTIONFS_VIRTUAL_ADDR)
+ ds->bEndpointAddress = bEndpointAddress;
}
ffs_dump_mem(": Rewritten ep desc", ds, ds->bLength);
ret = ffs_func_revmap_ep(func, le16_to_cpu(creq->wIndex));
if (unlikely(ret < 0))
return ret;
+ if (func->ffs->user_flags & FUNCTIONFS_VIRTUAL_ADDR)
+ ret = func->ffs->eps_addrmap[ret];
break;
default: