Merge tag 'usb-for-v4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
Felipe writes: usb: changes for v4.12 With 51 non-merge commits, this is one of the smallest USB Gadget pull requests. Apart from your expected set of non-critical fixes, and other miscellaneous items, we have most of the changes in dwc3 (52.5%) with all other UDCs following with 34.8%. As for the actual changes, the most important of them are all the recent changes to reduce memory footprint of dwc3, bare minimum dual-role support on dwc3 and reworked endpoint count and initialization routines.
This commit is contained in:
@@ -246,7 +246,6 @@ EXPORT_SYMBOL_GPL(ffs_lock);
|
||||
|
||||
static struct ffs_dev *_ffs_find_dev(const char *name);
|
||||
static struct ffs_dev *_ffs_alloc_dev(void);
|
||||
static int _ffs_name_dev(struct ffs_dev *dev, const char *name);
|
||||
static void _ffs_free_dev(struct ffs_dev *dev);
|
||||
static void *ffs_acquire_dev(const char *dev_name);
|
||||
static void ffs_release_dev(struct ffs_data *ffs_data);
|
||||
@@ -3302,9 +3301,10 @@ static struct ffs_dev *_ffs_do_find_dev(const char *name)
|
||||
{
|
||||
struct ffs_dev *dev;
|
||||
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
list_for_each_entry(dev, &ffs_devices, entry) {
|
||||
if (!dev->name || !name)
|
||||
continue;
|
||||
if (strcmp(dev->name, name) == 0)
|
||||
return dev;
|
||||
}
|
||||
@@ -3380,42 +3380,11 @@ static void ffs_free_inst(struct usb_function_instance *f)
|
||||
kfree(opts);
|
||||
}
|
||||
|
||||
#define MAX_INST_NAME_LEN 40
|
||||
|
||||
static int ffs_set_inst_name(struct usb_function_instance *fi, const char *name)
|
||||
{
|
||||
struct f_fs_opts *opts;
|
||||
char *ptr;
|
||||
const char *tmp;
|
||||
int name_len, ret;
|
||||
|
||||
name_len = strlen(name) + 1;
|
||||
if (name_len > MAX_INST_NAME_LEN)
|
||||
if (strlen(name) >= FIELD_SIZEOF(struct ffs_dev, name))
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
ptr = kstrndup(name, name_len, GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return -ENOMEM;
|
||||
|
||||
opts = to_f_fs_opts(fi);
|
||||
tmp = NULL;
|
||||
|
||||
ffs_dev_lock();
|
||||
|
||||
tmp = opts->dev->name_allocated ? opts->dev->name : NULL;
|
||||
ret = _ffs_name_dev(opts->dev, ptr);
|
||||
if (ret) {
|
||||
kfree(ptr);
|
||||
ffs_dev_unlock();
|
||||
return ret;
|
||||
}
|
||||
opts->dev->name_allocated = true;
|
||||
|
||||
ffs_dev_unlock();
|
||||
|
||||
kfree(tmp);
|
||||
|
||||
return 0;
|
||||
return ffs_name_dev(to_f_fs_opts(fi)->dev, name);
|
||||
}
|
||||
|
||||
static struct usb_function_instance *ffs_alloc_inst(void)
|
||||
@@ -3545,32 +3514,19 @@ static struct ffs_dev *_ffs_alloc_dev(void)
|
||||
return dev;
|
||||
}
|
||||
|
||||
/*
|
||||
* ffs_lock must be taken by the caller of this function
|
||||
* The caller is responsible for "name" being available whenever f_fs needs it
|
||||
*/
|
||||
static int _ffs_name_dev(struct ffs_dev *dev, const char *name)
|
||||
{
|
||||
struct ffs_dev *existing;
|
||||
|
||||
existing = _ffs_do_find_dev(name);
|
||||
if (existing)
|
||||
return -EBUSY;
|
||||
|
||||
dev->name = name;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The caller is responsible for "name" being available whenever f_fs needs it
|
||||
*/
|
||||
int ffs_name_dev(struct ffs_dev *dev, const char *name)
|
||||
{
|
||||
int ret;
|
||||
struct ffs_dev *existing;
|
||||
int ret = 0;
|
||||
|
||||
ffs_dev_lock();
|
||||
ret = _ffs_name_dev(dev, name);
|
||||
|
||||
existing = _ffs_do_find_dev(name);
|
||||
if (!existing)
|
||||
strlcpy(dev->name, name, ARRAY_SIZE(dev->name));
|
||||
else if (existing != dev)
|
||||
ret = -EBUSY;
|
||||
|
||||
ffs_dev_unlock();
|
||||
|
||||
return ret;
|
||||
@@ -3600,8 +3556,6 @@ EXPORT_SYMBOL_GPL(ffs_single_dev);
|
||||
static void _ffs_free_dev(struct ffs_dev *dev)
|
||||
{
|
||||
list_del(&dev->entry);
|
||||
if (dev->name_allocated)
|
||||
kfree(dev->name);
|
||||
|
||||
/* Clear the private_data pointer to stop incorrect dev access */
|
||||
if (dev->ffs_data)
|
||||
|
@@ -178,6 +178,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req);
|
||||
static int
|
||||
rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
|
||||
{
|
||||
struct usb_gadget *g = dev->gadget;
|
||||
struct sk_buff *skb;
|
||||
int retval = -ENOMEM;
|
||||
size_t size = 0;
|
||||
@@ -209,8 +210,11 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
|
||||
*/
|
||||
size += sizeof(struct ethhdr) + dev->net->mtu + RX_EXTRA;
|
||||
size += dev->port_usb->header_len;
|
||||
size += out->maxpacket - 1;
|
||||
size -= size % out->maxpacket;
|
||||
|
||||
if (g->quirk_ep_out_aligned_size) {
|
||||
size += out->maxpacket - 1;
|
||||
size -= size % out->maxpacket;
|
||||
}
|
||||
|
||||
if (dev->port_usb->is_fixed)
|
||||
size = max_t(size_t, size, dev->port_usb->fixed_out_len);
|
||||
@@ -401,13 +405,12 @@ done:
|
||||
static void rx_fill(struct eth_dev *dev, gfp_t gfp_flags)
|
||||
{
|
||||
struct usb_request *req;
|
||||
struct usb_request *tmp;
|
||||
unsigned long flags;
|
||||
|
||||
/* fill unused rxq slots with some skb */
|
||||
spin_lock_irqsave(&dev->req_lock, flags);
|
||||
while (!list_empty(&dev->rx_reqs)) {
|
||||
req = container_of(dev->rx_reqs.next,
|
||||
struct usb_request, list);
|
||||
list_for_each_entry_safe(req, tmp, &dev->rx_reqs, list) {
|
||||
list_del_init(&req->list);
|
||||
spin_unlock_irqrestore(&dev->req_lock, flags);
|
||||
|
||||
@@ -527,7 +530,7 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
req = container_of(dev->tx_reqs.next, struct usb_request, list);
|
||||
req = list_first_entry(&dev->tx_reqs, struct usb_request, list);
|
||||
list_del(&req->list);
|
||||
|
||||
/* temporarily stop TX queue when the freelist empties */
|
||||
@@ -1122,6 +1125,7 @@ void gether_disconnect(struct gether *link)
|
||||
{
|
||||
struct eth_dev *dev = link->ioport;
|
||||
struct usb_request *req;
|
||||
struct usb_request *tmp;
|
||||
|
||||
WARN_ON(!dev);
|
||||
if (!dev)
|
||||
@@ -1138,9 +1142,7 @@ void gether_disconnect(struct gether *link)
|
||||
*/
|
||||
usb_ep_disable(link->in_ep);
|
||||
spin_lock(&dev->req_lock);
|
||||
while (!list_empty(&dev->tx_reqs)) {
|
||||
req = container_of(dev->tx_reqs.next,
|
||||
struct usb_request, list);
|
||||
list_for_each_entry_safe(req, tmp, &dev->tx_reqs, list) {
|
||||
list_del(&req->list);
|
||||
|
||||
spin_unlock(&dev->req_lock);
|
||||
@@ -1152,9 +1154,7 @@ void gether_disconnect(struct gether *link)
|
||||
|
||||
usb_ep_disable(link->out_ep);
|
||||
spin_lock(&dev->req_lock);
|
||||
while (!list_empty(&dev->rx_reqs)) {
|
||||
req = container_of(dev->rx_reqs.next,
|
||||
struct usb_request, list);
|
||||
list_for_each_entry_safe(req, tmp, &dev->rx_reqs, list) {
|
||||
list_del(&req->list);
|
||||
|
||||
spin_unlock(&dev->req_lock);
|
||||
|
@@ -40,15 +40,16 @@
|
||||
struct f_fs_opts;
|
||||
|
||||
struct ffs_dev {
|
||||
const char *name;
|
||||
bool name_allocated;
|
||||
bool mounted;
|
||||
bool desc_ready;
|
||||
bool single;
|
||||
struct ffs_data *ffs_data;
|
||||
struct f_fs_opts *opts;
|
||||
struct list_head entry;
|
||||
|
||||
char name[41];
|
||||
|
||||
bool mounted;
|
||||
bool desc_ready;
|
||||
bool single;
|
||||
|
||||
int (*ffs_ready_callback)(struct ffs_data *ffs);
|
||||
void (*ffs_closed_callback)(struct ffs_data *ffs);
|
||||
void *(*ffs_acquire_dev_callback)(struct ffs_dev *dev);
|
||||
|
@@ -2125,7 +2125,7 @@ static struct configfs_item_operations uvc_item_ops = {
|
||||
.release = uvc_attr_release,
|
||||
};
|
||||
|
||||
#define UVCG_OPTS_ATTR(cname, conv, str2u, uxx, vnoc, limit) \
|
||||
#define UVCG_OPTS_ATTR(cname, aname, conv, str2u, uxx, vnoc, limit) \
|
||||
static ssize_t f_uvc_opts_##cname##_show( \
|
||||
struct config_item *item, char *page) \
|
||||
{ \
|
||||
@@ -2168,16 +2168,16 @@ end: \
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
UVC_ATTR(f_uvc_opts_, cname, aname)
|
||||
UVC_ATTR(f_uvc_opts_, cname, cname)
|
||||
|
||||
#define identity_conv(x) (x)
|
||||
|
||||
UVCG_OPTS_ATTR(streaming_interval, identity_conv, kstrtou8, u8, identity_conv,
|
||||
16);
|
||||
UVCG_OPTS_ATTR(streaming_maxpacket, le16_to_cpu, kstrtou16, u16, le16_to_cpu,
|
||||
3072);
|
||||
UVCG_OPTS_ATTR(streaming_maxburst, identity_conv, kstrtou8, u8, identity_conv,
|
||||
15);
|
||||
UVCG_OPTS_ATTR(streaming_interval, streaming_interval, identity_conv,
|
||||
kstrtou8, u8, identity_conv, 16);
|
||||
UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, le16_to_cpu,
|
||||
kstrtou16, u16, le16_to_cpu, 3072);
|
||||
UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, identity_conv,
|
||||
kstrtou8, u8, identity_conv, 15);
|
||||
|
||||
#undef identity_conv
|
||||
|
||||
|
Reference in New Issue
Block a user