Merge tag 'usb-for-v4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
Felipe writes: usb: patches for v4.3 merge window New support for Allwinne SoC on the MUSB driver has been added to the list of glue layers. MUSB also got support for building all DMA engines in one binary; this will be great for distros. DWC3 now has no trace of dev_dbg()/dev_vdbg() usage. We will rely solely on tracing to debug DWC3. There was also a fix for memory corruption with EP0 when maxpacket size transfers are > 512 bytes. Robert's EP capabilities flags is making EP selection a lot simpler. UDCs are now required to set these flags up when adding endpoints to the framework. Other than these, we have the usual set of miscelaneous cleanups and minor fixes. Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
@@ -21,7 +21,6 @@
|
||||
#include <linux/err.h>
|
||||
|
||||
#include "u_serial.h"
|
||||
#include "gadget_chips.h"
|
||||
|
||||
|
||||
/*
|
||||
|
@@ -585,8 +585,8 @@ static int ecm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
|
||||
/* Enable zlps by default for ECM conformance;
|
||||
* override for musb_hdrc (avoids txdma ovhead).
|
||||
*/
|
||||
ecm->port.is_zlp_ok = !(gadget_is_musbhdrc(cdev->gadget)
|
||||
);
|
||||
ecm->port.is_zlp_ok =
|
||||
gadget_is_zlp_supported(cdev->gadget);
|
||||
ecm->port.cdc_filter = DEFAULT_FILTER;
|
||||
DBG(cdev, "activate ecm\n");
|
||||
net = gether_connect(&ecm->port);
|
||||
|
@@ -2897,11 +2897,17 @@ static int ffs_func_bind(struct usb_configuration *c,
|
||||
struct usb_function *f)
|
||||
{
|
||||
struct f_fs_opts *ffs_opts = ffs_do_functionfs_bind(f, c);
|
||||
struct ffs_function *func = ffs_func_from_usb(f);
|
||||
int ret;
|
||||
|
||||
if (IS_ERR(ffs_opts))
|
||||
return PTR_ERR(ffs_opts);
|
||||
|
||||
return _ffs_func_bind(c, f);
|
||||
ret = _ffs_func_bind(c, f);
|
||||
if (ret && !--ffs_opts->refcnt)
|
||||
functionfs_unbind(func->ffs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -28,11 +28,6 @@
|
||||
* This takes messages of various sizes written OUT to a device, and loops
|
||||
* them back so they can be read IN from it. It has been used by certain
|
||||
* test applications. It supports limited testing of data queueing logic.
|
||||
*
|
||||
*
|
||||
* This is currently packaged as a configuration driver, which can't be
|
||||
* combined with other functions to make composite devices. However, it
|
||||
* can be combined with other independent configurations.
|
||||
*/
|
||||
struct f_loopback {
|
||||
struct usb_function function;
|
||||
|
@@ -54,7 +54,7 @@
|
||||
* following fields:
|
||||
*
|
||||
* nluns Number of LUNs function have (anywhere from 1
|
||||
* to FSG_MAX_LUNS which is 8).
|
||||
* to FSG_MAX_LUNS).
|
||||
* luns An array of LUN configuration values. This
|
||||
* should be filled for each LUN that
|
||||
* function will include (ie. for "nluns"
|
||||
@@ -214,12 +214,12 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/gadget.h>
|
||||
#include <linux/usb/composite.h>
|
||||
|
||||
#include "gadget_chips.h"
|
||||
#include "configfs.h"
|
||||
|
||||
|
||||
@@ -279,9 +279,8 @@ struct fsg_common {
|
||||
int cmnd_size;
|
||||
u8 cmnd[MAX_COMMAND_SIZE];
|
||||
|
||||
unsigned int nluns;
|
||||
unsigned int lun;
|
||||
struct fsg_lun **luns;
|
||||
struct fsg_lun *luns[FSG_MAX_LUNS];
|
||||
struct fsg_lun *curlun;
|
||||
|
||||
unsigned int bulk_out_maxpacket;
|
||||
@@ -490,6 +489,16 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
|
||||
spin_unlock(&common->lock);
|
||||
}
|
||||
|
||||
static int _fsg_common_get_max_lun(struct fsg_common *common)
|
||||
{
|
||||
int i = ARRAY_SIZE(common->luns) - 1;
|
||||
|
||||
while (i >= 0 && !common->luns[i])
|
||||
--i;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static int fsg_setup(struct usb_function *f,
|
||||
const struct usb_ctrlrequest *ctrl)
|
||||
{
|
||||
@@ -533,7 +542,7 @@ static int fsg_setup(struct usb_function *f,
|
||||
w_length != 1)
|
||||
return -EDOM;
|
||||
VDBG(fsg, "get max LUN\n");
|
||||
*(u8 *)req->buf = fsg->common->nluns - 1;
|
||||
*(u8 *)req->buf = _fsg_common_get_max_lun(fsg->common);
|
||||
|
||||
/* Respond with data/status */
|
||||
req->length = min((u16)1, w_length);
|
||||
@@ -2131,8 +2140,9 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
|
||||
}
|
||||
|
||||
/* Is the CBW meaningful? */
|
||||
if (cbw->Lun >= FSG_MAX_LUNS || cbw->Flags & ~US_BULK_FLAG_IN ||
|
||||
cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) {
|
||||
if (cbw->Lun >= ARRAY_SIZE(common->luns) ||
|
||||
cbw->Flags & ~US_BULK_FLAG_IN || cbw->Length <= 0 ||
|
||||
cbw->Length > MAX_COMMAND_SIZE) {
|
||||
DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, "
|
||||
"cmdlen %u\n",
|
||||
cbw->Lun, cbw->Flags, cbw->Length);
|
||||
@@ -2159,7 +2169,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
|
||||
if (common->data_size == 0)
|
||||
common->data_dir = DATA_DIR_NONE;
|
||||
common->lun = cbw->Lun;
|
||||
if (common->lun < common->nluns)
|
||||
if (common->lun < ARRAY_SIZE(common->luns))
|
||||
common->curlun = common->luns[common->lun];
|
||||
else
|
||||
common->curlun = NULL;
|
||||
@@ -2307,7 +2317,7 @@ reset:
|
||||
}
|
||||
|
||||
common->running = 1;
|
||||
for (i = 0; i < common->nluns; ++i)
|
||||
for (i = 0; i < ARRAY_SIZE(common->luns); ++i)
|
||||
if (common->luns[i])
|
||||
common->luns[i]->unit_attention_data =
|
||||
SS_RESET_OCCURRED;
|
||||
@@ -2409,7 +2419,7 @@ static void handle_exception(struct fsg_common *common)
|
||||
if (old_state == FSG_STATE_ABORT_BULK_OUT)
|
||||
common->state = FSG_STATE_STATUS_PHASE;
|
||||
else {
|
||||
for (i = 0; i < common->nluns; ++i) {
|
||||
for (i = 0; i < ARRAY_SIZE(common->luns); ++i) {
|
||||
curlun = common->luns[i];
|
||||
if (!curlun)
|
||||
continue;
|
||||
@@ -2453,7 +2463,7 @@ static void handle_exception(struct fsg_common *common)
|
||||
* a waste of time. Ditto for the INTERFACE_CHANGE and
|
||||
* CONFIG_CHANGE cases.
|
||||
*/
|
||||
/* for (i = 0; i < common->nluns; ++i) */
|
||||
/* for (i = 0; i < common->ARRAY_SIZE(common->luns); ++i) */
|
||||
/* if (common->luns[i]) */
|
||||
/* common->luns[i]->unit_attention_data = */
|
||||
/* SS_RESET_OCCURRED; */
|
||||
@@ -2552,12 +2562,11 @@ static int fsg_main_thread(void *common_)
|
||||
|
||||
if (!common->ops || !common->ops->thread_exits
|
||||
|| common->ops->thread_exits(common) < 0) {
|
||||
struct fsg_lun **curlun_it = common->luns;
|
||||
unsigned i = common->nluns;
|
||||
int i;
|
||||
|
||||
down_write(&common->filesem);
|
||||
for (; i--; ++curlun_it) {
|
||||
struct fsg_lun *curlun = *curlun_it;
|
||||
for (i = 0; i < ARRAY_SIZE(common->luns); --i) {
|
||||
struct fsg_lun *curlun = common->luns[i];
|
||||
if (!curlun || !fsg_lun_is_open(curlun))
|
||||
continue;
|
||||
|
||||
@@ -2676,6 +2685,7 @@ static struct fsg_common *fsg_common_setup(struct fsg_common *common)
|
||||
init_completion(&common->thread_notifier);
|
||||
init_waitqueue_head(&common->fsg_wait);
|
||||
common->state = FSG_STATE_TERMINATED;
|
||||
memset(common->luns, 0, sizeof(common->luns));
|
||||
|
||||
return common;
|
||||
}
|
||||
@@ -2742,9 +2752,9 @@ error_release:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fsg_common_set_num_buffers);
|
||||
|
||||
void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs)
|
||||
void fsg_common_remove_lun(struct fsg_lun *lun)
|
||||
{
|
||||
if (sysfs)
|
||||
if (device_is_registered(&lun->dev))
|
||||
device_unregister(&lun->dev);
|
||||
fsg_lun_close(lun);
|
||||
kfree(lun);
|
||||
@@ -2757,48 +2767,16 @@ static void _fsg_common_remove_luns(struct fsg_common *common, int n)
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
if (common->luns[i]) {
|
||||
fsg_common_remove_lun(common->luns[i], common->sysfs);
|
||||
fsg_common_remove_lun(common->luns[i]);
|
||||
common->luns[i] = NULL;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fsg_common_remove_luns);
|
||||
|
||||
void fsg_common_remove_luns(struct fsg_common *common)
|
||||
{
|
||||
_fsg_common_remove_luns(common, common->nluns);
|
||||
_fsg_common_remove_luns(common, ARRAY_SIZE(common->luns));
|
||||
}
|
||||
|
||||
void fsg_common_free_luns(struct fsg_common *common)
|
||||
{
|
||||
fsg_common_remove_luns(common);
|
||||
kfree(common->luns);
|
||||
common->luns = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fsg_common_free_luns);
|
||||
|
||||
int fsg_common_set_nluns(struct fsg_common *common, int nluns)
|
||||
{
|
||||
struct fsg_lun **curlun;
|
||||
|
||||
/* Find out how many LUNs there should be */
|
||||
if (nluns < 1 || nluns > FSG_MAX_LUNS) {
|
||||
pr_err("invalid number of LUNs: %u\n", nluns);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
curlun = kcalloc(FSG_MAX_LUNS, sizeof(*curlun), GFP_KERNEL);
|
||||
if (unlikely(!curlun))
|
||||
return -ENOMEM;
|
||||
|
||||
if (common->luns)
|
||||
fsg_common_free_luns(common);
|
||||
|
||||
common->luns = curlun;
|
||||
common->nluns = nluns;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fsg_common_set_nluns);
|
||||
EXPORT_SYMBOL_GPL(fsg_common_remove_luns);
|
||||
|
||||
void fsg_common_set_ops(struct fsg_common *common,
|
||||
const struct fsg_operations *ops)
|
||||
@@ -2836,7 +2814,8 @@ int fsg_common_set_cdev(struct fsg_common *common,
|
||||
* halt bulk endpoints correctly. If one of them is present,
|
||||
* disable stalls.
|
||||
*/
|
||||
common->can_stall = can_stall && !(gadget_is_at91(common->gadget));
|
||||
common->can_stall = can_stall &&
|
||||
gadget_is_stall_supported(common->gadget);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2880,7 +2859,7 @@ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
|
||||
char *pathbuf, *p;
|
||||
int rc = -ENOMEM;
|
||||
|
||||
if (!common->nluns || !common->luns)
|
||||
if (id >= ARRAY_SIZE(common->luns))
|
||||
return -ENODEV;
|
||||
|
||||
if (common->luns[id])
|
||||
@@ -2949,7 +2928,7 @@ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
|
||||
return 0;
|
||||
|
||||
error_lun:
|
||||
if (common->sysfs)
|
||||
if (device_is_registered(&lun->dev))
|
||||
device_unregister(&lun->dev);
|
||||
fsg_lun_close(lun);
|
||||
common->luns[id] = NULL;
|
||||
@@ -2964,14 +2943,16 @@ int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg)
|
||||
char buf[8]; /* enough for 100000000 different numbers, decimal */
|
||||
int i, rc;
|
||||
|
||||
for (i = 0; i < common->nluns; ++i) {
|
||||
fsg_common_remove_luns(common);
|
||||
|
||||
for (i = 0; i < cfg->nluns; ++i) {
|
||||
snprintf(buf, sizeof(buf), "lun%d", i);
|
||||
rc = fsg_common_create_lun(common, &cfg->luns[i], i, buf, NULL);
|
||||
if (rc)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pr_info("Number of LUNs=%d\n", common->nluns);
|
||||
pr_info("Number of LUNs=%d\n", cfg->nluns);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -3020,6 +3001,7 @@ EXPORT_SYMBOL_GPL(fsg_common_run_thread);
|
||||
static void fsg_common_release(struct kref *ref)
|
||||
{
|
||||
struct fsg_common *common = container_of(ref, struct fsg_common, ref);
|
||||
int i;
|
||||
|
||||
/* If the thread isn't already dead, tell it to exit now */
|
||||
if (common->state != FSG_STATE_TERMINATED) {
|
||||
@@ -3027,22 +3009,14 @@ static void fsg_common_release(struct kref *ref)
|
||||
wait_for_completion(&common->thread_notifier);
|
||||
}
|
||||
|
||||
if (likely(common->luns)) {
|
||||
struct fsg_lun **lun_it = common->luns;
|
||||
unsigned i = common->nluns;
|
||||
|
||||
/* In error recovery common->nluns may be zero. */
|
||||
for (; i; --i, ++lun_it) {
|
||||
struct fsg_lun *lun = *lun_it;
|
||||
if (!lun)
|
||||
continue;
|
||||
fsg_lun_close(lun);
|
||||
if (common->sysfs)
|
||||
device_unregister(&lun->dev);
|
||||
kfree(lun);
|
||||
}
|
||||
|
||||
kfree(common->luns);
|
||||
for (i = 0; i < ARRAY_SIZE(common->luns); ++i) {
|
||||
struct fsg_lun *lun = common->luns[i];
|
||||
if (!lun)
|
||||
continue;
|
||||
fsg_lun_close(lun);
|
||||
if (device_is_registered(&lun->dev))
|
||||
device_unregister(&lun->dev);
|
||||
kfree(lun);
|
||||
}
|
||||
|
||||
_fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
|
||||
@@ -3056,6 +3030,7 @@ static void fsg_common_release(struct kref *ref)
|
||||
static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
{
|
||||
struct fsg_dev *fsg = fsg_from_func(f);
|
||||
struct fsg_common *common = fsg->common;
|
||||
struct usb_gadget *gadget = c->cdev->gadget;
|
||||
int i;
|
||||
struct usb_ep *ep;
|
||||
@@ -3063,6 +3038,13 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
int ret;
|
||||
struct fsg_opts *opts;
|
||||
|
||||
/* Don't allow to bind if we don't have at least one LUN */
|
||||
ret = _fsg_common_get_max_lun(common);
|
||||
if (ret < 0) {
|
||||
pr_err("There should be at least one LUN.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
opts = fsg_opts_from_func_inst(f->fi);
|
||||
if (!opts->no_configfs) {
|
||||
ret = fsg_common_set_cdev(fsg->common, c->cdev,
|
||||
@@ -3080,7 +3062,7 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
/* New interface */
|
||||
i = usb_interface_id(c, f);
|
||||
if (i < 0)
|
||||
return i;
|
||||
goto fail;
|
||||
fsg_intf_desc.bInterfaceNumber = i;
|
||||
fsg->interface_number = i;
|
||||
|
||||
@@ -3123,7 +3105,14 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
|
||||
autoconf_fail:
|
||||
ERROR(fsg, "unable to autoconfigure all endpoints\n");
|
||||
return -ENOTSUPP;
|
||||
i = -ENOTSUPP;
|
||||
fail:
|
||||
/* terminate the thread */
|
||||
if (fsg->common->state != FSG_STATE_TERMINATED) {
|
||||
raise_exception(fsg->common, FSG_STATE_EXIT);
|
||||
wait_for_completion(&fsg->common->thread_notifier);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/****************************** ALLOCATE FUNCTION *************************/
|
||||
@@ -3355,7 +3344,7 @@ static void fsg_lun_drop(struct config_group *group, struct config_item *item)
|
||||
unregister_gadget_item(gadget);
|
||||
}
|
||||
|
||||
fsg_common_remove_lun(lun_opts->lun, fsg_opts->common->sysfs);
|
||||
fsg_common_remove_lun(lun_opts->lun);
|
||||
fsg_opts->common->luns[lun_opts->lun_id] = NULL;
|
||||
lun_opts->lun_id = 0;
|
||||
mutex_unlock(&fsg_opts->lock);
|
||||
@@ -3509,14 +3498,11 @@ static struct usb_function_instance *fsg_alloc_inst(void)
|
||||
rc = PTR_ERR(opts->common);
|
||||
goto release_opts;
|
||||
}
|
||||
rc = fsg_common_set_nluns(opts->common, FSG_MAX_LUNS);
|
||||
if (rc)
|
||||
goto release_opts;
|
||||
|
||||
rc = fsg_common_set_num_buffers(opts->common,
|
||||
CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS);
|
||||
if (rc)
|
||||
goto release_luns;
|
||||
goto release_opts;
|
||||
|
||||
pr_info(FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
|
||||
|
||||
@@ -3524,6 +3510,9 @@ static struct usb_function_instance *fsg_alloc_inst(void)
|
||||
config.removable = true;
|
||||
rc = fsg_common_create_lun(opts->common, &config, 0, "lun.0",
|
||||
(const char **)&opts->func_inst.group.cg_item.ci_name);
|
||||
if (rc)
|
||||
goto release_buffers;
|
||||
|
||||
opts->lun0.lun = opts->common->luns[0];
|
||||
opts->lun0.lun_id = 0;
|
||||
config_group_init_type_name(&opts->lun0.group, "lun.0", &fsg_lun_type);
|
||||
@@ -3534,8 +3523,8 @@ static struct usb_function_instance *fsg_alloc_inst(void)
|
||||
|
||||
return &opts->func_inst;
|
||||
|
||||
release_luns:
|
||||
kfree(opts->common->luns);
|
||||
release_buffers:
|
||||
fsg_common_free_buffers(opts->common);
|
||||
release_opts:
|
||||
kfree(opts);
|
||||
return ERR_PTR(rc);
|
||||
@@ -3561,23 +3550,12 @@ static struct usb_function *fsg_alloc(struct usb_function_instance *fi)
|
||||
struct fsg_opts *opts = fsg_opts_from_func_inst(fi);
|
||||
struct fsg_common *common = opts->common;
|
||||
struct fsg_dev *fsg;
|
||||
unsigned nluns, i;
|
||||
|
||||
fsg = kzalloc(sizeof(*fsg), GFP_KERNEL);
|
||||
if (unlikely(!fsg))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
mutex_lock(&opts->lock);
|
||||
if (!opts->refcnt) {
|
||||
for (nluns = i = 0; i < FSG_MAX_LUNS; ++i)
|
||||
if (common->luns[i])
|
||||
nluns = i + 1;
|
||||
if (!nluns)
|
||||
pr_warn("No LUNS defined, continuing anyway\n");
|
||||
else
|
||||
common->nluns = nluns;
|
||||
pr_info("Number of LUNs=%u\n", common->nluns);
|
||||
}
|
||||
opts->refcnt++;
|
||||
mutex_unlock(&opts->lock);
|
||||
|
||||
|
@@ -137,14 +137,10 @@ void fsg_common_free_buffers(struct fsg_common *common);
|
||||
int fsg_common_set_cdev(struct fsg_common *common,
|
||||
struct usb_composite_dev *cdev, bool can_stall);
|
||||
|
||||
void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs);
|
||||
void fsg_common_remove_lun(struct fsg_lun *lun);
|
||||
|
||||
void fsg_common_remove_luns(struct fsg_common *common);
|
||||
|
||||
void fsg_common_free_luns(struct fsg_common *common);
|
||||
|
||||
int fsg_common_set_nluns(struct fsg_common *common, int nluns);
|
||||
|
||||
void fsg_common_set_ops(struct fsg_common *common,
|
||||
const struct fsg_operations *ops);
|
||||
|
||||
|
@@ -329,6 +329,10 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
|
||||
unsigned i;
|
||||
int err;
|
||||
|
||||
/* For Control Device interface we do nothing */
|
||||
if (intf == 0)
|
||||
return 0;
|
||||
|
||||
err = f_midi_start_ep(midi, f, midi->in_ep);
|
||||
if (err)
|
||||
return err;
|
||||
|
@@ -853,9 +853,8 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
|
||||
/* Enable zlps by default for NCM conformance;
|
||||
* override for musb_hdrc (avoids txdma ovhead)
|
||||
*/
|
||||
ncm->port.is_zlp_ok = !(
|
||||
gadget_is_musbhdrc(cdev->gadget)
|
||||
);
|
||||
ncm->port.is_zlp_ok =
|
||||
gadget_is_zlp_supported(cdev->gadget);
|
||||
ncm->port.cdc_filter = DEFAULT_FILTER;
|
||||
DBG(cdev, "activate ncm\n");
|
||||
net = gether_connect(&ncm->port);
|
||||
|
@@ -20,7 +20,6 @@
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "u_serial.h"
|
||||
#include "gadget_chips.h"
|
||||
|
||||
|
||||
/*
|
||||
@@ -37,7 +36,6 @@ struct f_obex {
|
||||
u8 data_id;
|
||||
u8 cur_alt;
|
||||
u8 port_num;
|
||||
u8 can_activate;
|
||||
};
|
||||
|
||||
static inline struct f_obex *func_to_obex(struct usb_function *f)
|
||||
@@ -268,9 +266,6 @@ static void obex_connect(struct gserial *g)
|
||||
struct usb_composite_dev *cdev = g->func.config->cdev;
|
||||
int status;
|
||||
|
||||
if (!obex->can_activate)
|
||||
return;
|
||||
|
||||
status = usb_function_activate(&g->func);
|
||||
if (status)
|
||||
dev_dbg(&cdev->gadget->dev,
|
||||
@@ -284,9 +279,6 @@ static void obex_disconnect(struct gserial *g)
|
||||
struct usb_composite_dev *cdev = g->func.config->cdev;
|
||||
int status;
|
||||
|
||||
if (!obex->can_activate)
|
||||
return;
|
||||
|
||||
status = usb_function_deactivate(&g->func);
|
||||
if (status)
|
||||
dev_dbg(&cdev->gadget->dev,
|
||||
@@ -304,7 +296,7 @@ static inline bool can_support_obex(struct usb_configuration *c)
|
||||
*
|
||||
* Altsettings are mandatory, however...
|
||||
*/
|
||||
if (!gadget_supports_altsettings(c->cdev->gadget))
|
||||
if (!gadget_is_altset_supported(c->cdev->gadget))
|
||||
return false;
|
||||
|
||||
/* everything else is *probably* fine ... */
|
||||
@@ -378,17 +370,6 @@ static int obex_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
if (status)
|
||||
goto fail;
|
||||
|
||||
/* Avoid letting this gadget enumerate until the userspace
|
||||
* OBEX server is active.
|
||||
*/
|
||||
status = usb_function_deactivate(f);
|
||||
if (status < 0)
|
||||
WARNING(cdev, "obex ttyGS%d: can't prevent enumeration, %d\n",
|
||||
obex->port_num, status);
|
||||
else
|
||||
obex->can_activate = true;
|
||||
|
||||
|
||||
dev_dbg(&cdev->gadget->dev, "obex ttyGS%d: %s speed IN/%s OUT/%s\n",
|
||||
obex->port_num,
|
||||
gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
|
||||
@@ -529,6 +510,7 @@ static struct usb_function *obex_alloc(struct usb_function_instance *fi)
|
||||
obex->port.func.get_alt = obex_get_alt;
|
||||
obex->port.func.disable = obex_disable;
|
||||
obex->port.func.free_func = obex_free;
|
||||
obex->port.func.bind_deactivated = true;
|
||||
|
||||
return &obex->port.func;
|
||||
}
|
||||
|
@@ -804,6 +804,8 @@ done:
|
||||
|
||||
static void printer_reset_interface(struct printer_dev *dev)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (dev->interface < 0)
|
||||
return;
|
||||
|
||||
@@ -815,9 +817,11 @@ static void printer_reset_interface(struct printer_dev *dev)
|
||||
if (dev->out_ep->desc)
|
||||
usb_ep_disable(dev->out_ep);
|
||||
|
||||
spin_lock_irqsave(&dev->lock, flags);
|
||||
dev->in_ep->desc = NULL;
|
||||
dev->out_ep->desc = NULL;
|
||||
dev->interface = -1;
|
||||
spin_unlock_irqrestore(&dev->lock, flags);
|
||||
}
|
||||
|
||||
/* Change our operational Interface. */
|
||||
@@ -1131,13 +1135,10 @@ static int printer_func_set_alt(struct usb_function *f,
|
||||
static void printer_func_disable(struct usb_function *f)
|
||||
{
|
||||
struct printer_dev *dev = func_to_printer(f);
|
||||
unsigned long flags;
|
||||
|
||||
DBG(dev, "%s\n", __func__);
|
||||
|
||||
spin_lock_irqsave(&dev->lock, flags);
|
||||
printer_reset_interface(dev);
|
||||
spin_unlock_irqrestore(&dev->lock, flags);
|
||||
}
|
||||
|
||||
static inline struct f_printer_opts
|
||||
|
@@ -16,7 +16,6 @@
|
||||
#include <linux/device.h>
|
||||
|
||||
#include "u_serial.h"
|
||||
#include "gadget_chips.h"
|
||||
|
||||
|
||||
/*
|
||||
|
@@ -20,7 +20,6 @@
|
||||
#include <linux/err.h>
|
||||
|
||||
#include "g_zero.h"
|
||||
#include "gadget_chips.h"
|
||||
#include "u_f.h"
|
||||
|
||||
/*
|
||||
@@ -42,11 +41,6 @@
|
||||
* queues are relatively independent, will receive a range of packet sizes,
|
||||
* and can often be made to run out completely. Those issues are important
|
||||
* when stress testing peripheral controller drivers.
|
||||
*
|
||||
*
|
||||
* This is currently packaged as a configuration driver, which can't be
|
||||
* combined with other functions to make composite devices. However, it
|
||||
* can be combined with other independent configurations.
|
||||
*/
|
||||
struct f_sourcesink {
|
||||
struct usb_function function;
|
||||
|
@@ -975,6 +975,29 @@ free_ep(struct uac2_rtd_params *prm, struct usb_ep *ep)
|
||||
"%s:%d Error!\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
|
||||
struct usb_endpoint_descriptor *ep_desc,
|
||||
unsigned int factor, bool is_playback)
|
||||
{
|
||||
int chmask, srate, ssize;
|
||||
u16 max_packet_size;
|
||||
|
||||
if (is_playback) {
|
||||
chmask = uac2_opts->p_chmask;
|
||||
srate = uac2_opts->p_srate;
|
||||
ssize = uac2_opts->p_ssize;
|
||||
} else {
|
||||
chmask = uac2_opts->c_chmask;
|
||||
srate = uac2_opts->c_srate;
|
||||
ssize = uac2_opts->c_ssize;
|
||||
}
|
||||
|
||||
max_packet_size = num_channels(chmask) * ssize *
|
||||
DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1)));
|
||||
ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_packet_size,
|
||||
le16_to_cpu(ep_desc->wMaxPacketSize)));
|
||||
}
|
||||
|
||||
static int
|
||||
afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
|
||||
{
|
||||
@@ -1070,10 +1093,14 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
|
||||
uac2->p_prm.uac2 = uac2;
|
||||
uac2->c_prm.uac2 = uac2;
|
||||
|
||||
/* Calculate wMaxPacketSize according to audio bandwidth */
|
||||
set_ep_max_packet_size(uac2_opts, &fs_epin_desc, 1000, true);
|
||||
set_ep_max_packet_size(uac2_opts, &fs_epout_desc, 1000, false);
|
||||
set_ep_max_packet_size(uac2_opts, &hs_epin_desc, 8000, true);
|
||||
set_ep_max_packet_size(uac2_opts, &hs_epout_desc, 8000, false);
|
||||
|
||||
hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress;
|
||||
hs_epout_desc.wMaxPacketSize = fs_epout_desc.wMaxPacketSize;
|
||||
hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress;
|
||||
hs_epin_desc.wMaxPacketSize = fs_epin_desc.wMaxPacketSize;
|
||||
|
||||
ret = usb_assign_descriptors(fn, fs_audio_desc, hs_audio_desc, NULL);
|
||||
if (ret)
|
||||
|
@@ -733,12 +733,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
uvc->control_req->complete = uvc_function_ep0_complete;
|
||||
uvc->control_req->context = uvc;
|
||||
|
||||
/* Avoid letting this gadget enumerate until the userspace server is
|
||||
* active.
|
||||
*/
|
||||
if ((ret = usb_function_deactivate(f)) < 0)
|
||||
goto error;
|
||||
|
||||
if (v4l2_device_register(&cdev->gadget->dev, &uvc->v4l2_dev)) {
|
||||
printk(KERN_INFO "v4l2_device_register failed\n");
|
||||
goto error;
|
||||
@@ -949,6 +943,7 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi)
|
||||
uvc->func.disable = uvc_function_disable;
|
||||
uvc->func.setup = uvc_function_setup;
|
||||
uvc->func.free_func = uvc_free;
|
||||
uvc->func.bind_deactivated = true;
|
||||
|
||||
return &uvc->func;
|
||||
}
|
||||
|
@@ -123,7 +123,7 @@ static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
|
||||
#define FSG_BUFLEN ((u32)16384)
|
||||
|
||||
/* Maximal number of LUNs supported in mass storage function */
|
||||
#define FSG_MAX_LUNS 8
|
||||
#define FSG_MAX_LUNS 16
|
||||
|
||||
enum fsg_buffer_state {
|
||||
BUF_STATE_EMPTY = 0,
|
||||
|
@@ -20,8 +20,6 @@
|
||||
#include <linux/usb/cdc.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
#include "gadget_chips.h"
|
||||
|
||||
#define QMULT_DEFAULT 5
|
||||
|
||||
/*
|
||||
@@ -259,7 +257,7 @@ void gether_disconnect(struct gether *);
|
||||
/* Some controllers can't support CDC Ethernet (ECM) ... */
|
||||
static inline bool can_support_ecm(struct usb_gadget *gadget)
|
||||
{
|
||||
if (!gadget_supports_altsettings(gadget))
|
||||
if (!gadget_is_altset_supported(gadget))
|
||||
return false;
|
||||
|
||||
/* Everything else is *presumably* fine ... but this is a bit
|
||||
|
@@ -21,8 +21,6 @@
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
|
||||
#include "gadget_chips.h"
|
||||
|
||||
#define FILE_PCM_PLAYBACK "/dev/snd/pcmC0D0p"
|
||||
#define FILE_PCM_CAPTURE "/dev/snd/pcmC0D0c"
|
||||
#define FILE_CONTROL "/dev/snd/controlC0"
|
||||
|
Reference in New Issue
Block a user