Merge branch 'drm-next-merged' of git://people.freedesktop.org/~airlied/linux into v4l_for_linus
* 'drm-next-merged' of git://people.freedesktop.org/~airlied/linux: (9717 commits) media-bus: Fixup RGB444_1X12, RGB565_1X16, and YUV8_1X24 media bus format hexdump: avoid warning in test function fs: take i_mutex during prepare_binprm for set[ug]id executables smp: Fix error case handling in smp_call_function_*() iommu-common: Fix PARISC compile-time warnings sparc: Make LDC use common iommu poll management functions sparc: Make sparc64 use scalable lib/iommu-common.c functions Break up monolithic iommu table/lock into finer graularity pools and lock sparc: Revert generic IOMMU allocator. tools/power turbostat: correct dumped pkg-cstate-limit value tools/power turbostat: calculate TSC frequency from CPUID(0x15) on SKL tools/power turbostat: correct DRAM RAPL units on recent Xeon processors tools/power turbostat: Initial Skylake support tools/power turbostat: Use $(CURDIR) instead of $(PWD) and add support for O= option in Makefile tools/power turbostat: modprobe msr, if needed tools/power turbostat: dump MSR_TURBO_RATIO_LIMIT2 tools/power turbostat: use new MSR_TURBO_RATIO_LIMIT names Bluetooth: hidp: Fix regression with older userspace and flags validation config: Enable NEED_DMA_MAP_STATE by default when SWIOTLB is selected perf/x86/intel/pt: Fix and clean up error handling in pt_event_add() ... That solves several merge conflicts: Documentation/DocBook/media/v4l/subdev-formats.xml Documentation/devicetree/bindings/vendor-prefixes.txt drivers/staging/media/mn88473/mn88473.c include/linux/kconfig.h include/uapi/linux/media-bus-format.h The ones at subdev-formats.xml and media-bus-format.h are not trivial. That's why we opted to merge from DRM.
This commit is contained in:
@@ -42,3 +42,5 @@ usb_f_midi-y := f_midi.o
|
||||
obj-$(CONFIG_USB_F_MIDI) += usb_f_midi.o
|
||||
usb_f_hid-y := f_hid.o
|
||||
obj-$(CONFIG_USB_F_HID) += usb_f_hid.o
|
||||
usb_f_printer-y := f_printer.o
|
||||
obj-$(CONFIG_USB_F_PRINTER) += usb_f_printer.o
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include <linux/export.h>
|
||||
#include <linux/hid.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/uio.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include <linux/usb/composite.h>
|
||||
@@ -144,10 +145,9 @@ struct ffs_io_data {
|
||||
bool read;
|
||||
|
||||
struct kiocb *kiocb;
|
||||
const struct iovec *iovec;
|
||||
unsigned long nr_segs;
|
||||
char __user *buf;
|
||||
size_t len;
|
||||
struct iov_iter data;
|
||||
const void *to_free;
|
||||
char *buf;
|
||||
|
||||
struct mm_struct *mm;
|
||||
struct work_struct work;
|
||||
@@ -649,42 +649,24 @@ static void ffs_user_copy_worker(struct work_struct *work)
|
||||
io_data->req->actual;
|
||||
|
||||
if (io_data->read && ret > 0) {
|
||||
int i;
|
||||
size_t pos = 0;
|
||||
|
||||
/*
|
||||
* Since req->length may be bigger than io_data->len (after
|
||||
* being rounded up to maxpacketsize), we may end up with more
|
||||
* data then user space has space for.
|
||||
*/
|
||||
ret = min_t(int, ret, io_data->len);
|
||||
|
||||
use_mm(io_data->mm);
|
||||
for (i = 0; i < io_data->nr_segs; i++) {
|
||||
size_t len = min_t(size_t, ret - pos,
|
||||
io_data->iovec[i].iov_len);
|
||||
if (!len)
|
||||
break;
|
||||
if (unlikely(copy_to_user(io_data->iovec[i].iov_base,
|
||||
&io_data->buf[pos], len))) {
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
pos += len;
|
||||
}
|
||||
ret = copy_to_iter(io_data->buf, ret, &io_data->data);
|
||||
if (iov_iter_count(&io_data->data))
|
||||
ret = -EFAULT;
|
||||
unuse_mm(io_data->mm);
|
||||
}
|
||||
|
||||
aio_complete(io_data->kiocb, ret, ret);
|
||||
io_data->kiocb->ki_complete(io_data->kiocb, ret, ret);
|
||||
|
||||
if (io_data->ffs->ffs_eventfd && !io_data->kiocb->ki_eventfd)
|
||||
if (io_data->ffs->ffs_eventfd &&
|
||||
!(io_data->kiocb->ki_flags & IOCB_EVENTFD))
|
||||
eventfd_signal(io_data->ffs->ffs_eventfd, 1);
|
||||
|
||||
usb_ep_free_request(io_data->ep, io_data->req);
|
||||
|
||||
io_data->kiocb->private = NULL;
|
||||
if (io_data->read)
|
||||
kfree(io_data->iovec);
|
||||
kfree(io_data->to_free);
|
||||
kfree(io_data->buf);
|
||||
kfree(io_data);
|
||||
}
|
||||
@@ -743,6 +725,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
|
||||
* before the waiting completes, so do not assign to 'gadget' earlier
|
||||
*/
|
||||
struct usb_gadget *gadget = epfile->ffs->gadget;
|
||||
size_t copied;
|
||||
|
||||
spin_lock_irq(&epfile->ffs->eps_lock);
|
||||
/* In the meantime, endpoint got disabled or changed. */
|
||||
@@ -750,34 +733,21 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
|
||||
spin_unlock_irq(&epfile->ffs->eps_lock);
|
||||
return -ESHUTDOWN;
|
||||
}
|
||||
data_len = iov_iter_count(&io_data->data);
|
||||
/*
|
||||
* Controller may require buffer size to be aligned to
|
||||
* maxpacketsize of an out endpoint.
|
||||
*/
|
||||
data_len = io_data->read ?
|
||||
usb_ep_align_maybe(gadget, ep->ep, io_data->len) :
|
||||
io_data->len;
|
||||
if (io_data->read)
|
||||
data_len = usb_ep_align_maybe(gadget, ep->ep, data_len);
|
||||
spin_unlock_irq(&epfile->ffs->eps_lock);
|
||||
|
||||
data = kmalloc(data_len, GFP_KERNEL);
|
||||
if (unlikely(!data))
|
||||
return -ENOMEM;
|
||||
if (io_data->aio && !io_data->read) {
|
||||
int i;
|
||||
size_t pos = 0;
|
||||
for (i = 0; i < io_data->nr_segs; i++) {
|
||||
if (unlikely(copy_from_user(&data[pos],
|
||||
io_data->iovec[i].iov_base,
|
||||
io_data->iovec[i].iov_len))) {
|
||||
ret = -EFAULT;
|
||||
goto error;
|
||||
}
|
||||
pos += io_data->iovec[i].iov_len;
|
||||
}
|
||||
} else {
|
||||
if (!io_data->read &&
|
||||
unlikely(__copy_from_user(data, io_data->buf,
|
||||
io_data->len))) {
|
||||
if (!io_data->read) {
|
||||
copied = copy_from_iter(data, data_len, &io_data->data);
|
||||
if (copied != data_len) {
|
||||
ret = -EFAULT;
|
||||
goto error;
|
||||
}
|
||||
@@ -876,10 +846,8 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
|
||||
*/
|
||||
ret = ep->status;
|
||||
if (io_data->read && ret > 0) {
|
||||
ret = min_t(size_t, ret, io_data->len);
|
||||
|
||||
if (unlikely(copy_to_user(io_data->buf,
|
||||
data, ret)))
|
||||
ret = copy_to_iter(data, ret, &io_data->data);
|
||||
if (unlikely(iov_iter_count(&io_data->data)))
|
||||
ret = -EFAULT;
|
||||
}
|
||||
}
|
||||
@@ -898,37 +866,6 @@ error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ffs_epfile_write(struct file *file, const char __user *buf, size_t len,
|
||||
loff_t *ptr)
|
||||
{
|
||||
struct ffs_io_data io_data;
|
||||
|
||||
ENTER();
|
||||
|
||||
io_data.aio = false;
|
||||
io_data.read = false;
|
||||
io_data.buf = (char * __user)buf;
|
||||
io_data.len = len;
|
||||
|
||||
return ffs_epfile_io(file, &io_data);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ffs_epfile_read(struct file *file, char __user *buf, size_t len, loff_t *ptr)
|
||||
{
|
||||
struct ffs_io_data io_data;
|
||||
|
||||
ENTER();
|
||||
|
||||
io_data.aio = false;
|
||||
io_data.read = true;
|
||||
io_data.buf = buf;
|
||||
io_data.len = len;
|
||||
|
||||
return ffs_epfile_io(file, &io_data);
|
||||
}
|
||||
|
||||
static int
|
||||
ffs_epfile_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
@@ -965,67 +902,86 @@ static int ffs_aio_cancel(struct kiocb *kiocb)
|
||||
return value;
|
||||
}
|
||||
|
||||
static ssize_t ffs_epfile_aio_write(struct kiocb *kiocb,
|
||||
const struct iovec *iovec,
|
||||
unsigned long nr_segs, loff_t loff)
|
||||
static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from)
|
||||
{
|
||||
struct ffs_io_data *io_data;
|
||||
struct ffs_io_data io_data, *p = &io_data;
|
||||
ssize_t res;
|
||||
|
||||
ENTER();
|
||||
|
||||
io_data = kmalloc(sizeof(*io_data), GFP_KERNEL);
|
||||
if (unlikely(!io_data))
|
||||
return -ENOMEM;
|
||||
|
||||
io_data->aio = true;
|
||||
io_data->read = false;
|
||||
io_data->kiocb = kiocb;
|
||||
io_data->iovec = iovec;
|
||||
io_data->nr_segs = nr_segs;
|
||||
io_data->len = kiocb->ki_nbytes;
|
||||
io_data->mm = current->mm;
|
||||
|
||||
kiocb->private = io_data;
|
||||
|
||||
kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
|
||||
|
||||
return ffs_epfile_io(kiocb->ki_filp, io_data);
|
||||
}
|
||||
|
||||
static ssize_t ffs_epfile_aio_read(struct kiocb *kiocb,
|
||||
const struct iovec *iovec,
|
||||
unsigned long nr_segs, loff_t loff)
|
||||
{
|
||||
struct ffs_io_data *io_data;
|
||||
struct iovec *iovec_copy;
|
||||
|
||||
ENTER();
|
||||
|
||||
iovec_copy = kmalloc_array(nr_segs, sizeof(*iovec_copy), GFP_KERNEL);
|
||||
if (unlikely(!iovec_copy))
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(iovec_copy, iovec, sizeof(struct iovec)*nr_segs);
|
||||
|
||||
io_data = kmalloc(sizeof(*io_data), GFP_KERNEL);
|
||||
if (unlikely(!io_data)) {
|
||||
kfree(iovec_copy);
|
||||
return -ENOMEM;
|
||||
if (!is_sync_kiocb(kiocb)) {
|
||||
p = kmalloc(sizeof(io_data), GFP_KERNEL);
|
||||
if (unlikely(!p))
|
||||
return -ENOMEM;
|
||||
p->aio = true;
|
||||
} else {
|
||||
p->aio = false;
|
||||
}
|
||||
|
||||
io_data->aio = true;
|
||||
io_data->read = true;
|
||||
io_data->kiocb = kiocb;
|
||||
io_data->iovec = iovec_copy;
|
||||
io_data->nr_segs = nr_segs;
|
||||
io_data->len = kiocb->ki_nbytes;
|
||||
io_data->mm = current->mm;
|
||||
p->read = false;
|
||||
p->kiocb = kiocb;
|
||||
p->data = *from;
|
||||
p->mm = current->mm;
|
||||
|
||||
kiocb->private = io_data;
|
||||
kiocb->private = p;
|
||||
|
||||
kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
|
||||
|
||||
return ffs_epfile_io(kiocb->ki_filp, io_data);
|
||||
res = ffs_epfile_io(kiocb->ki_filp, p);
|
||||
if (res == -EIOCBQUEUED)
|
||||
return res;
|
||||
if (p->aio)
|
||||
kfree(p);
|
||||
else
|
||||
*from = p->data;
|
||||
return res;
|
||||
}
|
||||
|
||||
static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to)
|
||||
{
|
||||
struct ffs_io_data io_data, *p = &io_data;
|
||||
ssize_t res;
|
||||
|
||||
ENTER();
|
||||
|
||||
if (!is_sync_kiocb(kiocb)) {
|
||||
p = kmalloc(sizeof(io_data), GFP_KERNEL);
|
||||
if (unlikely(!p))
|
||||
return -ENOMEM;
|
||||
p->aio = true;
|
||||
} else {
|
||||
p->aio = false;
|
||||
}
|
||||
|
||||
p->read = true;
|
||||
p->kiocb = kiocb;
|
||||
if (p->aio) {
|
||||
p->to_free = dup_iter(&p->data, to, GFP_KERNEL);
|
||||
if (!p->to_free) {
|
||||
kfree(p);
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else {
|
||||
p->data = *to;
|
||||
p->to_free = NULL;
|
||||
}
|
||||
p->mm = current->mm;
|
||||
|
||||
kiocb->private = p;
|
||||
|
||||
kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
|
||||
|
||||
res = ffs_epfile_io(kiocb->ki_filp, p);
|
||||
if (res == -EIOCBQUEUED)
|
||||
return res;
|
||||
|
||||
if (p->aio) {
|
||||
kfree(p->to_free);
|
||||
kfree(p);
|
||||
} else {
|
||||
*to = p->data;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1105,10 +1061,8 @@ static const struct file_operations ffs_epfile_operations = {
|
||||
.llseek = no_llseek,
|
||||
|
||||
.open = ffs_epfile_open,
|
||||
.write = ffs_epfile_write,
|
||||
.read = ffs_epfile_read,
|
||||
.aio_write = ffs_epfile_aio_write,
|
||||
.aio_read = ffs_epfile_aio_read,
|
||||
.write_iter = ffs_epfile_write_iter,
|
||||
.read_iter = ffs_epfile_read_iter,
|
||||
.release = ffs_epfile_release,
|
||||
.unlocked_ioctl = ffs_epfile_ioctl,
|
||||
};
|
||||
|
@@ -569,7 +569,7 @@ fail:
|
||||
return status;
|
||||
}
|
||||
|
||||
const struct file_operations f_hidg_fops = {
|
||||
static const struct file_operations f_hidg_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = f_hidg_open,
|
||||
.release = f_hidg_release,
|
||||
@@ -908,7 +908,6 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f)
|
||||
|
||||
/* disable/free request and end point */
|
||||
usb_ep_disable(hidg->in_ep);
|
||||
usb_ep_dequeue(hidg->in_ep, hidg->req);
|
||||
kfree(hidg->req->buf);
|
||||
usb_ep_free_request(hidg->in_ep, hidg->req);
|
||||
|
||||
|
@@ -289,8 +289,7 @@ static void disable_loopback(struct f_loopback *loop)
|
||||
struct usb_composite_dev *cdev;
|
||||
|
||||
cdev = loop->function.config->cdev;
|
||||
disable_endpoints(cdev, loop->in_ep, loop->out_ep, NULL, NULL, NULL,
|
||||
NULL);
|
||||
disable_endpoints(cdev, loop->in_ep, loop->out_ep, NULL, NULL);
|
||||
VDBG(cdev, "%s disabled\n", loop->function.name);
|
||||
}
|
||||
|
||||
|
@@ -1085,7 +1085,7 @@ static int do_inquiry(struct fsg_common *common, struct fsg_buffhd *bh)
|
||||
if (!curlun) { /* Unsupported LUNs are okay */
|
||||
common->bad_lun_okay = 1;
|
||||
memset(buf, 0, 36);
|
||||
buf[0] = 0x7f; /* Unsupported, no device-type */
|
||||
buf[0] = TYPE_NO_LUN; /* Unsupported, no device-type */
|
||||
buf[4] = 31; /* Additional length */
|
||||
return 36;
|
||||
}
|
||||
@@ -2624,13 +2624,10 @@ static ssize_t file_store(struct device *dev, struct device_attribute *attr,
|
||||
return fsg_store_file(curlun, filesem, buf, count);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(ro);
|
||||
static DEVICE_ATTR_RW(nofua);
|
||||
static DEVICE_ATTR_RW(file);
|
||||
|
||||
static struct device_attribute dev_attr_ro_cdrom = __ATTR_RO(ro);
|
||||
static struct device_attribute dev_attr_file_nonremovable = __ATTR_RO(file);
|
||||
|
||||
/* mode wil be set in fsg_lun_attr_is_visible() */
|
||||
static DEVICE_ATTR(ro, 0, ro_show, ro_store);
|
||||
static DEVICE_ATTR(file, 0, file_show, file_store);
|
||||
|
||||
/****************************** FSG COMMON ******************************/
|
||||
|
||||
@@ -2745,40 +2742,10 @@ error_release:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fsg_common_set_num_buffers);
|
||||
|
||||
static inline void fsg_common_remove_sysfs(struct fsg_lun *lun)
|
||||
{
|
||||
device_remove_file(&lun->dev, &dev_attr_nofua);
|
||||
/*
|
||||
* device_remove_file() =>
|
||||
*
|
||||
* here the attr (e.g. dev_attr_ro) is only used to be passed to:
|
||||
*
|
||||
* sysfs_remove_file() =>
|
||||
*
|
||||
* here e.g. both dev_attr_ro_cdrom and dev_attr_ro are in
|
||||
* the same namespace and
|
||||
* from here only attr->name is passed to:
|
||||
*
|
||||
* sysfs_hash_and_remove()
|
||||
*
|
||||
* attr->name is the same for dev_attr_ro_cdrom and
|
||||
* dev_attr_ro
|
||||
* attr->name is the same for dev_attr_file and
|
||||
* dev_attr_file_nonremovable
|
||||
*
|
||||
* so we don't differentiate between removing e.g. dev_attr_ro_cdrom
|
||||
* and dev_attr_ro
|
||||
*/
|
||||
device_remove_file(&lun->dev, &dev_attr_ro);
|
||||
device_remove_file(&lun->dev, &dev_attr_file);
|
||||
}
|
||||
|
||||
void fsg_common_remove_lun(struct fsg_lun *lun, bool sysfs)
|
||||
{
|
||||
if (sysfs) {
|
||||
fsg_common_remove_sysfs(lun);
|
||||
if (sysfs)
|
||||
device_unregister(&lun->dev);
|
||||
}
|
||||
fsg_lun_close(lun);
|
||||
kfree(lun);
|
||||
}
|
||||
@@ -2877,42 +2844,36 @@ int fsg_common_set_cdev(struct fsg_common *common,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fsg_common_set_cdev);
|
||||
|
||||
static inline int fsg_common_add_sysfs(struct fsg_common *common,
|
||||
struct fsg_lun *lun)
|
||||
static struct attribute *fsg_lun_dev_attrs[] = {
|
||||
&dev_attr_ro.attr,
|
||||
&dev_attr_file.attr,
|
||||
&dev_attr_nofua.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static umode_t fsg_lun_dev_is_visible(struct kobject *kobj,
|
||||
struct attribute *attr, int idx)
|
||||
{
|
||||
int rc;
|
||||
struct device *dev = kobj_to_dev(kobj);
|
||||
struct fsg_lun *lun = fsg_lun_from_dev(dev);
|
||||
|
||||
rc = device_register(&lun->dev);
|
||||
if (rc) {
|
||||
put_device(&lun->dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = device_create_file(&lun->dev,
|
||||
lun->cdrom
|
||||
? &dev_attr_ro_cdrom
|
||||
: &dev_attr_ro);
|
||||
if (rc)
|
||||
goto error;
|
||||
rc = device_create_file(&lun->dev,
|
||||
lun->removable
|
||||
? &dev_attr_file
|
||||
: &dev_attr_file_nonremovable);
|
||||
if (rc)
|
||||
goto error;
|
||||
rc = device_create_file(&lun->dev, &dev_attr_nofua);
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
/* removing nonexistent files is a no-op */
|
||||
fsg_common_remove_sysfs(lun);
|
||||
device_unregister(&lun->dev);
|
||||
return rc;
|
||||
if (attr == &dev_attr_ro.attr)
|
||||
return lun->cdrom ? S_IRUGO : (S_IWUSR | S_IRUGO);
|
||||
if (attr == &dev_attr_file.attr)
|
||||
return lun->removable ? (S_IWUSR | S_IRUGO) : S_IRUGO;
|
||||
return attr->mode;
|
||||
}
|
||||
|
||||
static const struct attribute_group fsg_lun_dev_group = {
|
||||
.attrs = fsg_lun_dev_attrs,
|
||||
.is_visible = fsg_lun_dev_is_visible,
|
||||
};
|
||||
|
||||
static const struct attribute_group *fsg_lun_dev_groups[] = {
|
||||
&fsg_lun_dev_group,
|
||||
NULL
|
||||
};
|
||||
|
||||
int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
|
||||
unsigned int id, const char *name,
|
||||
const char **name_pfx)
|
||||
@@ -2949,13 +2910,15 @@ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
|
||||
} else {
|
||||
lun->dev.release = fsg_lun_release;
|
||||
lun->dev.parent = &common->gadget->dev;
|
||||
lun->dev.groups = fsg_lun_dev_groups;
|
||||
dev_set_drvdata(&lun->dev, &common->filesem);
|
||||
dev_set_name(&lun->dev, "%s", name);
|
||||
lun->name = dev_name(&lun->dev);
|
||||
|
||||
rc = fsg_common_add_sysfs(common, lun);
|
||||
rc = device_register(&lun->dev);
|
||||
if (rc) {
|
||||
pr_info("failed to register LUN%d: %d\n", id, rc);
|
||||
put_device(&lun->dev);
|
||||
goto error_sysfs;
|
||||
}
|
||||
}
|
||||
@@ -2988,10 +2951,8 @@ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
|
||||
return 0;
|
||||
|
||||
error_lun:
|
||||
if (common->sysfs) {
|
||||
fsg_common_remove_sysfs(lun);
|
||||
if (common->sysfs)
|
||||
device_unregister(&lun->dev);
|
||||
}
|
||||
fsg_lun_close(lun);
|
||||
common->luns[id] = NULL;
|
||||
error_sysfs:
|
||||
@@ -3077,8 +3038,6 @@ static void fsg_common_release(struct kref *ref)
|
||||
struct fsg_lun *lun = *lun_it;
|
||||
if (!lun)
|
||||
continue;
|
||||
if (common->sysfs)
|
||||
fsg_common_remove_sysfs(lun);
|
||||
fsg_lun_close(lun);
|
||||
if (common->sysfs)
|
||||
device_unregister(&lun->dev);
|
||||
|
@@ -417,7 +417,10 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock(&port->lock);
|
||||
__pn_reset(f);
|
||||
|
||||
if (fp->in_ep->driver_data)
|
||||
__pn_reset(f);
|
||||
|
||||
if (alt == 1) {
|
||||
int i;
|
||||
|
||||
|
1471
drivers/usb/gadget/function/f_printer.c
Normal file
1471
drivers/usb/gadget/function/f_printer.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -23,15 +23,6 @@
|
||||
#include "gadget_chips.h"
|
||||
#include "u_f.h"
|
||||
|
||||
#define USB_MS_TO_SS_INTERVAL(x) USB_MS_TO_HS_INTERVAL(x)
|
||||
|
||||
enum eptype {
|
||||
EP_CONTROL = 0,
|
||||
EP_BULK,
|
||||
EP_ISOC,
|
||||
EP_INTERRUPT,
|
||||
};
|
||||
|
||||
/*
|
||||
* SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripheral
|
||||
* controller drivers.
|
||||
@@ -64,8 +55,6 @@ struct f_sourcesink {
|
||||
struct usb_ep *out_ep;
|
||||
struct usb_ep *iso_in_ep;
|
||||
struct usb_ep *iso_out_ep;
|
||||
struct usb_ep *int_in_ep;
|
||||
struct usb_ep *int_out_ep;
|
||||
int cur_alt;
|
||||
};
|
||||
|
||||
@@ -79,10 +68,6 @@ static unsigned isoc_interval;
|
||||
static unsigned isoc_maxpacket;
|
||||
static unsigned isoc_mult;
|
||||
static unsigned isoc_maxburst;
|
||||
static unsigned int_interval; /* In ms */
|
||||
static unsigned int_maxpacket;
|
||||
static unsigned int_mult;
|
||||
static unsigned int_maxburst;
|
||||
static unsigned buflen;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
@@ -107,16 +92,6 @@ static struct usb_interface_descriptor source_sink_intf_alt1 = {
|
||||
/* .iInterface = DYNAMIC */
|
||||
};
|
||||
|
||||
static struct usb_interface_descriptor source_sink_intf_alt2 = {
|
||||
.bLength = USB_DT_INTERFACE_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
|
||||
.bAlternateSetting = 2,
|
||||
.bNumEndpoints = 2,
|
||||
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
|
||||
/* .iInterface = DYNAMIC */
|
||||
};
|
||||
|
||||
/* full speed support: */
|
||||
|
||||
static struct usb_endpoint_descriptor fs_source_desc = {
|
||||
@@ -155,26 +130,6 @@ static struct usb_endpoint_descriptor fs_iso_sink_desc = {
|
||||
.bInterval = 4,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor fs_int_source_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = cpu_to_le16(64),
|
||||
.bInterval = GZERO_INT_INTERVAL,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor fs_int_sink_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = cpu_to_le16(64),
|
||||
.bInterval = GZERO_INT_INTERVAL,
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *fs_source_sink_descs[] = {
|
||||
(struct usb_descriptor_header *) &source_sink_intf_alt0,
|
||||
(struct usb_descriptor_header *) &fs_sink_desc,
|
||||
@@ -185,10 +140,6 @@ static struct usb_descriptor_header *fs_source_sink_descs[] = {
|
||||
(struct usb_descriptor_header *) &fs_source_desc,
|
||||
(struct usb_descriptor_header *) &fs_iso_sink_desc,
|
||||
(struct usb_descriptor_header *) &fs_iso_source_desc,
|
||||
(struct usb_descriptor_header *) &source_sink_intf_alt2,
|
||||
#define FS_ALT_IFC_2_OFFSET 8
|
||||
(struct usb_descriptor_header *) &fs_int_sink_desc,
|
||||
(struct usb_descriptor_header *) &fs_int_source_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -228,24 +179,6 @@ static struct usb_endpoint_descriptor hs_iso_sink_desc = {
|
||||
.bInterval = 4,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor hs_int_source_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = cpu_to_le16(1024),
|
||||
.bInterval = USB_MS_TO_HS_INTERVAL(GZERO_INT_INTERVAL),
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor hs_int_sink_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = cpu_to_le16(1024),
|
||||
.bInterval = USB_MS_TO_HS_INTERVAL(GZERO_INT_INTERVAL),
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *hs_source_sink_descs[] = {
|
||||
(struct usb_descriptor_header *) &source_sink_intf_alt0,
|
||||
(struct usb_descriptor_header *) &hs_source_desc,
|
||||
@@ -256,10 +189,6 @@ static struct usb_descriptor_header *hs_source_sink_descs[] = {
|
||||
(struct usb_descriptor_header *) &hs_sink_desc,
|
||||
(struct usb_descriptor_header *) &hs_iso_source_desc,
|
||||
(struct usb_descriptor_header *) &hs_iso_sink_desc,
|
||||
(struct usb_descriptor_header *) &source_sink_intf_alt2,
|
||||
#define HS_ALT_IFC_2_OFFSET 8
|
||||
(struct usb_descriptor_header *) &hs_int_source_desc,
|
||||
(struct usb_descriptor_header *) &hs_int_sink_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -335,42 +264,6 @@ static struct usb_ss_ep_comp_descriptor ss_iso_sink_comp_desc = {
|
||||
.wBytesPerInterval = cpu_to_le16(1024),
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor ss_int_source_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = cpu_to_le16(1024),
|
||||
.bInterval = USB_MS_TO_SS_INTERVAL(GZERO_INT_INTERVAL),
|
||||
};
|
||||
|
||||
struct usb_ss_ep_comp_descriptor ss_int_source_comp_desc = {
|
||||
.bLength = USB_DT_SS_EP_COMP_SIZE,
|
||||
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
||||
|
||||
.bMaxBurst = 0,
|
||||
.bmAttributes = 0,
|
||||
.wBytesPerInterval = cpu_to_le16(1024),
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor ss_int_sink_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_INT,
|
||||
.wMaxPacketSize = cpu_to_le16(1024),
|
||||
.bInterval = USB_MS_TO_SS_INTERVAL(GZERO_INT_INTERVAL),
|
||||
};
|
||||
|
||||
struct usb_ss_ep_comp_descriptor ss_int_sink_comp_desc = {
|
||||
.bLength = USB_DT_SS_EP_COMP_SIZE,
|
||||
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
||||
|
||||
.bMaxBurst = 0,
|
||||
.bmAttributes = 0,
|
||||
.wBytesPerInterval = cpu_to_le16(1024),
|
||||
};
|
||||
|
||||
static struct usb_descriptor_header *ss_source_sink_descs[] = {
|
||||
(struct usb_descriptor_header *) &source_sink_intf_alt0,
|
||||
(struct usb_descriptor_header *) &ss_source_desc,
|
||||
@@ -387,12 +280,6 @@ static struct usb_descriptor_header *ss_source_sink_descs[] = {
|
||||
(struct usb_descriptor_header *) &ss_iso_source_comp_desc,
|
||||
(struct usb_descriptor_header *) &ss_iso_sink_desc,
|
||||
(struct usb_descriptor_header *) &ss_iso_sink_comp_desc,
|
||||
(struct usb_descriptor_header *) &source_sink_intf_alt2,
|
||||
#define SS_ALT_IFC_2_OFFSET 14
|
||||
(struct usb_descriptor_header *) &ss_int_source_desc,
|
||||
(struct usb_descriptor_header *) &ss_int_source_comp_desc,
|
||||
(struct usb_descriptor_header *) &ss_int_sink_desc,
|
||||
(struct usb_descriptor_header *) &ss_int_sink_comp_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -414,21 +301,6 @@ static struct usb_gadget_strings *sourcesink_strings[] = {
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static const char *get_ep_string(enum eptype ep_type)
|
||||
{
|
||||
switch (ep_type) {
|
||||
case EP_ISOC:
|
||||
return "ISOC-";
|
||||
case EP_INTERRUPT:
|
||||
return "INTERRUPT-";
|
||||
case EP_CONTROL:
|
||||
return "CTRL-";
|
||||
case EP_BULK:
|
||||
return "BULK-";
|
||||
default:
|
||||
return "UNKNOWN-";
|
||||
}
|
||||
}
|
||||
|
||||
static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len)
|
||||
{
|
||||
@@ -456,8 +328,7 @@ static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
|
||||
|
||||
void disable_endpoints(struct usb_composite_dev *cdev,
|
||||
struct usb_ep *in, struct usb_ep *out,
|
||||
struct usb_ep *iso_in, struct usb_ep *iso_out,
|
||||
struct usb_ep *int_in, struct usb_ep *int_out)
|
||||
struct usb_ep *iso_in, struct usb_ep *iso_out)
|
||||
{
|
||||
disable_ep(cdev, in);
|
||||
disable_ep(cdev, out);
|
||||
@@ -465,10 +336,6 @@ void disable_endpoints(struct usb_composite_dev *cdev,
|
||||
disable_ep(cdev, iso_in);
|
||||
if (iso_out)
|
||||
disable_ep(cdev, iso_out);
|
||||
if (int_in)
|
||||
disable_ep(cdev, int_in);
|
||||
if (int_out)
|
||||
disable_ep(cdev, int_out);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -485,7 +352,6 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
return id;
|
||||
source_sink_intf_alt0.bInterfaceNumber = id;
|
||||
source_sink_intf_alt1.bInterfaceNumber = id;
|
||||
source_sink_intf_alt2.bInterfaceNumber = id;
|
||||
|
||||
/* allocate bulk endpoints */
|
||||
ss->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc);
|
||||
@@ -546,55 +412,14 @@ no_iso:
|
||||
if (isoc_maxpacket > 1024)
|
||||
isoc_maxpacket = 1024;
|
||||
|
||||
/* sanity check the interrupt module parameters */
|
||||
if (int_interval < 1)
|
||||
int_interval = 1;
|
||||
if (int_interval > 4096)
|
||||
int_interval = 4096;
|
||||
if (int_mult > 2)
|
||||
int_mult = 2;
|
||||
if (int_maxburst > 15)
|
||||
int_maxburst = 15;
|
||||
|
||||
/* fill in the FS interrupt descriptors from the module parameters */
|
||||
fs_int_source_desc.wMaxPacketSize = int_maxpacket > 64 ?
|
||||
64 : int_maxpacket;
|
||||
fs_int_source_desc.bInterval = int_interval > 255 ?
|
||||
255 : int_interval;
|
||||
fs_int_sink_desc.wMaxPacketSize = int_maxpacket > 64 ?
|
||||
64 : int_maxpacket;
|
||||
fs_int_sink_desc.bInterval = int_interval > 255 ?
|
||||
255 : int_interval;
|
||||
|
||||
/* allocate int endpoints */
|
||||
ss->int_in_ep = usb_ep_autoconfig(cdev->gadget, &fs_int_source_desc);
|
||||
if (!ss->int_in_ep)
|
||||
goto no_int;
|
||||
ss->int_in_ep->driver_data = cdev; /* claim */
|
||||
|
||||
ss->int_out_ep = usb_ep_autoconfig(cdev->gadget, &fs_int_sink_desc);
|
||||
if (ss->int_out_ep) {
|
||||
ss->int_out_ep->driver_data = cdev; /* claim */
|
||||
} else {
|
||||
ss->int_in_ep->driver_data = NULL;
|
||||
ss->int_in_ep = NULL;
|
||||
no_int:
|
||||
fs_source_sink_descs[FS_ALT_IFC_2_OFFSET] = NULL;
|
||||
hs_source_sink_descs[HS_ALT_IFC_2_OFFSET] = NULL;
|
||||
ss_source_sink_descs[SS_ALT_IFC_2_OFFSET] = NULL;
|
||||
}
|
||||
|
||||
if (int_maxpacket > 1024)
|
||||
int_maxpacket = 1024;
|
||||
|
||||
/* support high speed hardware */
|
||||
hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
|
||||
hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress;
|
||||
|
||||
/*
|
||||
* Fill in the HS isoc and interrupt descriptors from the module
|
||||
* parameters. We assume that the user knows what they are doing and
|
||||
* won't give parameters that their UDC doesn't support.
|
||||
* Fill in the HS isoc descriptors from the module parameters.
|
||||
* We assume that the user knows what they are doing and won't
|
||||
* give parameters that their UDC doesn't support.
|
||||
*/
|
||||
hs_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
|
||||
hs_iso_source_desc.wMaxPacketSize |= isoc_mult << 11;
|
||||
@@ -607,17 +432,6 @@ no_int:
|
||||
hs_iso_sink_desc.bInterval = isoc_interval;
|
||||
hs_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
|
||||
|
||||
hs_int_source_desc.wMaxPacketSize = int_maxpacket;
|
||||
hs_int_source_desc.wMaxPacketSize |= int_mult << 11;
|
||||
hs_int_source_desc.bInterval = USB_MS_TO_HS_INTERVAL(int_interval);
|
||||
hs_int_source_desc.bEndpointAddress =
|
||||
fs_int_source_desc.bEndpointAddress;
|
||||
|
||||
hs_int_sink_desc.wMaxPacketSize = int_maxpacket;
|
||||
hs_int_sink_desc.wMaxPacketSize |= int_mult << 11;
|
||||
hs_int_sink_desc.bInterval = USB_MS_TO_HS_INTERVAL(int_interval);
|
||||
hs_int_sink_desc.bEndpointAddress = fs_int_sink_desc.bEndpointAddress;
|
||||
|
||||
/* support super speed hardware */
|
||||
ss_source_desc.bEndpointAddress =
|
||||
fs_source_desc.bEndpointAddress;
|
||||
@@ -625,9 +439,9 @@ no_int:
|
||||
fs_sink_desc.bEndpointAddress;
|
||||
|
||||
/*
|
||||
* Fill in the SS isoc and interrupt descriptors from the module
|
||||
* parameters. We assume that the user knows what they are doing and
|
||||
* won't give parameters that their UDC doesn't support.
|
||||
* Fill in the SS isoc descriptors from the module parameters.
|
||||
* We assume that the user knows what they are doing and won't
|
||||
* give parameters that their UDC doesn't support.
|
||||
*/
|
||||
ss_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
|
||||
ss_iso_source_desc.bInterval = isoc_interval;
|
||||
@@ -646,37 +460,17 @@ no_int:
|
||||
isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
|
||||
ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
|
||||
|
||||
ss_int_source_desc.wMaxPacketSize = int_maxpacket;
|
||||
ss_int_source_desc.bInterval = USB_MS_TO_SS_INTERVAL(int_interval);
|
||||
ss_int_source_comp_desc.bmAttributes = int_mult;
|
||||
ss_int_source_comp_desc.bMaxBurst = int_maxburst;
|
||||
ss_int_source_comp_desc.wBytesPerInterval =
|
||||
int_maxpacket * (int_mult + 1) * (int_maxburst + 1);
|
||||
ss_int_source_desc.bEndpointAddress =
|
||||
fs_int_source_desc.bEndpointAddress;
|
||||
|
||||
ss_int_sink_desc.wMaxPacketSize = int_maxpacket;
|
||||
ss_int_sink_desc.bInterval = USB_MS_TO_SS_INTERVAL(int_interval);
|
||||
ss_int_sink_comp_desc.bmAttributes = int_mult;
|
||||
ss_int_sink_comp_desc.bMaxBurst = int_maxburst;
|
||||
ss_int_sink_comp_desc.wBytesPerInterval =
|
||||
int_maxpacket * (int_mult + 1) * (int_maxburst + 1);
|
||||
ss_int_sink_desc.bEndpointAddress = fs_int_sink_desc.bEndpointAddress;
|
||||
|
||||
ret = usb_assign_descriptors(f, fs_source_sink_descs,
|
||||
hs_source_sink_descs, ss_source_sink_descs);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
DBG(cdev, "%s speed %s: IN/%s, OUT/%s, ISO-IN/%s, ISO-OUT/%s, "
|
||||
"INT-IN/%s, INT-OUT/%s\n",
|
||||
DBG(cdev, "%s speed %s: IN/%s, OUT/%s, ISO-IN/%s, ISO-OUT/%s\n",
|
||||
(gadget_is_superspeed(c->cdev->gadget) ? "super" :
|
||||
(gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")),
|
||||
f->name, ss->in_ep->name, ss->out_ep->name,
|
||||
ss->iso_in_ep ? ss->iso_in_ep->name : "<none>",
|
||||
ss->iso_out_ep ? ss->iso_out_ep->name : "<none>",
|
||||
ss->int_in_ep ? ss->int_in_ep->name : "<none>",
|
||||
ss->int_out_ep ? ss->int_out_ep->name : "<none>");
|
||||
ss->iso_out_ep ? ss->iso_out_ep->name : "<none>");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -807,15 +601,14 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req)
|
||||
}
|
||||
|
||||
static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
|
||||
enum eptype ep_type, int speed)
|
||||
bool is_iso, int speed)
|
||||
{
|
||||
struct usb_ep *ep;
|
||||
struct usb_request *req;
|
||||
int i, size, status;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
switch (ep_type) {
|
||||
case EP_ISOC:
|
||||
if (is_iso) {
|
||||
switch (speed) {
|
||||
case USB_SPEED_SUPER:
|
||||
size = isoc_maxpacket * (isoc_mult + 1) *
|
||||
@@ -831,28 +624,9 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
|
||||
}
|
||||
ep = is_in ? ss->iso_in_ep : ss->iso_out_ep;
|
||||
req = ss_alloc_ep_req(ep, size);
|
||||
break;
|
||||
case EP_INTERRUPT:
|
||||
switch (speed) {
|
||||
case USB_SPEED_SUPER:
|
||||
size = int_maxpacket * (int_mult + 1) *
|
||||
(int_maxburst + 1);
|
||||
break;
|
||||
case USB_SPEED_HIGH:
|
||||
size = int_maxpacket * (int_mult + 1);
|
||||
break;
|
||||
default:
|
||||
size = int_maxpacket > 1023 ?
|
||||
1023 : int_maxpacket;
|
||||
break;
|
||||
}
|
||||
ep = is_in ? ss->int_in_ep : ss->int_out_ep;
|
||||
req = ss_alloc_ep_req(ep, size);
|
||||
break;
|
||||
default:
|
||||
} else {
|
||||
ep = is_in ? ss->in_ep : ss->out_ep;
|
||||
req = ss_alloc_ep_req(ep, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!req)
|
||||
@@ -870,12 +644,12 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
|
||||
|
||||
cdev = ss->function.config->cdev;
|
||||
ERROR(cdev, "start %s%s %s --> %d\n",
|
||||
get_ep_string(ep_type), is_in ? "IN" : "OUT",
|
||||
ep->name, status);
|
||||
is_iso ? "ISO-" : "", is_in ? "IN" : "OUT",
|
||||
ep->name, status);
|
||||
free_ep_req(ep, req);
|
||||
}
|
||||
|
||||
if (!(ep_type == EP_ISOC))
|
||||
if (!is_iso)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -888,7 +662,7 @@ static void disable_source_sink(struct f_sourcesink *ss)
|
||||
|
||||
cdev = ss->function.config->cdev;
|
||||
disable_endpoints(cdev, ss->in_ep, ss->out_ep, ss->iso_in_ep,
|
||||
ss->iso_out_ep, ss->int_in_ep, ss->int_out_ep);
|
||||
ss->iso_out_ep);
|
||||
VDBG(cdev, "%s disabled\n", ss->function.name);
|
||||
}
|
||||
|
||||
@@ -900,62 +674,6 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
|
||||
int speed = cdev->gadget->speed;
|
||||
struct usb_ep *ep;
|
||||
|
||||
if (alt == 2) {
|
||||
/* Configure for periodic interrupt endpoint */
|
||||
ep = ss->int_in_ep;
|
||||
if (ep) {
|
||||
result = config_ep_by_speed(cdev->gadget,
|
||||
&(ss->function), ep);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
result = usb_ep_enable(ep);
|
||||
if (result < 0)
|
||||
return result;
|
||||
|
||||
ep->driver_data = ss;
|
||||
result = source_sink_start_ep(ss, true, EP_INTERRUPT,
|
||||
speed);
|
||||
if (result < 0) {
|
||||
fail1:
|
||||
ep = ss->int_in_ep;
|
||||
if (ep) {
|
||||
usb_ep_disable(ep);
|
||||
ep->driver_data = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* one interrupt endpoint reads (sinks) anything OUT (from the
|
||||
* host)
|
||||
*/
|
||||
ep = ss->int_out_ep;
|
||||
if (ep) {
|
||||
result = config_ep_by_speed(cdev->gadget,
|
||||
&(ss->function), ep);
|
||||
if (result)
|
||||
goto fail1;
|
||||
|
||||
result = usb_ep_enable(ep);
|
||||
if (result < 0)
|
||||
goto fail1;
|
||||
|
||||
ep->driver_data = ss;
|
||||
result = source_sink_start_ep(ss, false, EP_INTERRUPT,
|
||||
speed);
|
||||
if (result < 0) {
|
||||
ep = ss->int_out_ep;
|
||||
usb_ep_disable(ep);
|
||||
ep->driver_data = NULL;
|
||||
goto fail1;
|
||||
}
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* one bulk endpoint writes (sources) zeroes IN (to the host) */
|
||||
ep = ss->in_ep;
|
||||
result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
|
||||
@@ -966,7 +684,7 @@ fail1:
|
||||
return result;
|
||||
ep->driver_data = ss;
|
||||
|
||||
result = source_sink_start_ep(ss, true, EP_BULK, speed);
|
||||
result = source_sink_start_ep(ss, true, false, speed);
|
||||
if (result < 0) {
|
||||
fail:
|
||||
ep = ss->in_ep;
|
||||
@@ -985,7 +703,7 @@ fail:
|
||||
goto fail;
|
||||
ep->driver_data = ss;
|
||||
|
||||
result = source_sink_start_ep(ss, false, EP_BULK, speed);
|
||||
result = source_sink_start_ep(ss, false, false, speed);
|
||||
if (result < 0) {
|
||||
fail2:
|
||||
ep = ss->out_ep;
|
||||
@@ -1008,7 +726,7 @@ fail2:
|
||||
goto fail2;
|
||||
ep->driver_data = ss;
|
||||
|
||||
result = source_sink_start_ep(ss, true, EP_ISOC, speed);
|
||||
result = source_sink_start_ep(ss, true, true, speed);
|
||||
if (result < 0) {
|
||||
fail3:
|
||||
ep = ss->iso_in_ep;
|
||||
@@ -1031,14 +749,13 @@ fail3:
|
||||
goto fail3;
|
||||
ep->driver_data = ss;
|
||||
|
||||
result = source_sink_start_ep(ss, false, EP_ISOC, speed);
|
||||
result = source_sink_start_ep(ss, false, true, speed);
|
||||
if (result < 0) {
|
||||
usb_ep_disable(ep);
|
||||
ep->driver_data = NULL;
|
||||
goto fail3;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
ss->cur_alt = alt;
|
||||
|
||||
@@ -1054,8 +771,6 @@ static int sourcesink_set_alt(struct usb_function *f,
|
||||
|
||||
if (ss->in_ep->driver_data)
|
||||
disable_source_sink(ss);
|
||||
else if (alt == 2 && ss->int_in_ep->driver_data)
|
||||
disable_source_sink(ss);
|
||||
return enable_source_sink(cdev, ss, alt);
|
||||
}
|
||||
|
||||
@@ -1168,10 +883,6 @@ static struct usb_function *source_sink_alloc_func(
|
||||
isoc_maxpacket = ss_opts->isoc_maxpacket;
|
||||
isoc_mult = ss_opts->isoc_mult;
|
||||
isoc_maxburst = ss_opts->isoc_maxburst;
|
||||
int_interval = ss_opts->int_interval;
|
||||
int_maxpacket = ss_opts->int_maxpacket;
|
||||
int_mult = ss_opts->int_mult;
|
||||
int_maxburst = ss_opts->int_maxburst;
|
||||
buflen = ss_opts->bulk_buflen;
|
||||
|
||||
ss->function.name = "source/sink";
|
||||
@@ -1468,182 +1179,6 @@ static struct f_ss_opts_attribute f_ss_opts_bulk_buflen =
|
||||
f_ss_opts_bulk_buflen_show,
|
||||
f_ss_opts_bulk_buflen_store);
|
||||
|
||||
static ssize_t f_ss_opts_int_interval_show(struct f_ss_opts *opts, char *page)
|
||||
{
|
||||
int result;
|
||||
|
||||
mutex_lock(&opts->lock);
|
||||
result = sprintf(page, "%u", opts->int_interval);
|
||||
mutex_unlock(&opts->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static ssize_t f_ss_opts_int_interval_store(struct f_ss_opts *opts,
|
||||
const char *page, size_t len)
|
||||
{
|
||||
int ret;
|
||||
u32 num;
|
||||
|
||||
mutex_lock(&opts->lock);
|
||||
if (opts->refcnt) {
|
||||
ret = -EBUSY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = kstrtou32(page, 0, &num);
|
||||
if (ret)
|
||||
goto end;
|
||||
|
||||
if (num > 4096) {
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
opts->int_interval = num;
|
||||
ret = len;
|
||||
end:
|
||||
mutex_unlock(&opts->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct f_ss_opts_attribute f_ss_opts_int_interval =
|
||||
__CONFIGFS_ATTR(int_interval, S_IRUGO | S_IWUSR,
|
||||
f_ss_opts_int_interval_show,
|
||||
f_ss_opts_int_interval_store);
|
||||
|
||||
static ssize_t f_ss_opts_int_maxpacket_show(struct f_ss_opts *opts, char *page)
|
||||
{
|
||||
int result;
|
||||
|
||||
mutex_lock(&opts->lock);
|
||||
result = sprintf(page, "%u", opts->int_maxpacket);
|
||||
mutex_unlock(&opts->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static ssize_t f_ss_opts_int_maxpacket_store(struct f_ss_opts *opts,
|
||||
const char *page, size_t len)
|
||||
{
|
||||
int ret;
|
||||
u16 num;
|
||||
|
||||
mutex_lock(&opts->lock);
|
||||
if (opts->refcnt) {
|
||||
ret = -EBUSY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = kstrtou16(page, 0, &num);
|
||||
if (ret)
|
||||
goto end;
|
||||
|
||||
if (num > 1024) {
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
opts->int_maxpacket = num;
|
||||
ret = len;
|
||||
end:
|
||||
mutex_unlock(&opts->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct f_ss_opts_attribute f_ss_opts_int_maxpacket =
|
||||
__CONFIGFS_ATTR(int_maxpacket, S_IRUGO | S_IWUSR,
|
||||
f_ss_opts_int_maxpacket_show,
|
||||
f_ss_opts_int_maxpacket_store);
|
||||
|
||||
static ssize_t f_ss_opts_int_mult_show(struct f_ss_opts *opts, char *page)
|
||||
{
|
||||
int result;
|
||||
|
||||
mutex_lock(&opts->lock);
|
||||
result = sprintf(page, "%u", opts->int_mult);
|
||||
mutex_unlock(&opts->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static ssize_t f_ss_opts_int_mult_store(struct f_ss_opts *opts,
|
||||
const char *page, size_t len)
|
||||
{
|
||||
int ret;
|
||||
u8 num;
|
||||
|
||||
mutex_lock(&opts->lock);
|
||||
if (opts->refcnt) {
|
||||
ret = -EBUSY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = kstrtou8(page, 0, &num);
|
||||
if (ret)
|
||||
goto end;
|
||||
|
||||
if (num > 2) {
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
opts->int_mult = num;
|
||||
ret = len;
|
||||
end:
|
||||
mutex_unlock(&opts->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct f_ss_opts_attribute f_ss_opts_int_mult =
|
||||
__CONFIGFS_ATTR(int_mult, S_IRUGO | S_IWUSR,
|
||||
f_ss_opts_int_mult_show,
|
||||
f_ss_opts_int_mult_store);
|
||||
|
||||
static ssize_t f_ss_opts_int_maxburst_show(struct f_ss_opts *opts, char *page)
|
||||
{
|
||||
int result;
|
||||
|
||||
mutex_lock(&opts->lock);
|
||||
result = sprintf(page, "%u", opts->int_maxburst);
|
||||
mutex_unlock(&opts->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static ssize_t f_ss_opts_int_maxburst_store(struct f_ss_opts *opts,
|
||||
const char *page, size_t len)
|
||||
{
|
||||
int ret;
|
||||
u8 num;
|
||||
|
||||
mutex_lock(&opts->lock);
|
||||
if (opts->refcnt) {
|
||||
ret = -EBUSY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = kstrtou8(page, 0, &num);
|
||||
if (ret)
|
||||
goto end;
|
||||
|
||||
if (num > 15) {
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
opts->int_maxburst = num;
|
||||
ret = len;
|
||||
end:
|
||||
mutex_unlock(&opts->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct f_ss_opts_attribute f_ss_opts_int_maxburst =
|
||||
__CONFIGFS_ATTR(int_maxburst, S_IRUGO | S_IWUSR,
|
||||
f_ss_opts_int_maxburst_show,
|
||||
f_ss_opts_int_maxburst_store);
|
||||
|
||||
static struct configfs_attribute *ss_attrs[] = {
|
||||
&f_ss_opts_pattern.attr,
|
||||
&f_ss_opts_isoc_interval.attr,
|
||||
@@ -1651,10 +1186,6 @@ static struct configfs_attribute *ss_attrs[] = {
|
||||
&f_ss_opts_isoc_mult.attr,
|
||||
&f_ss_opts_isoc_maxburst.attr,
|
||||
&f_ss_opts_bulk_buflen.attr,
|
||||
&f_ss_opts_int_interval.attr,
|
||||
&f_ss_opts_int_maxpacket.attr,
|
||||
&f_ss_opts_int_mult.attr,
|
||||
&f_ss_opts_int_maxburst.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -1684,8 +1215,6 @@ static struct usb_function_instance *source_sink_alloc_inst(void)
|
||||
ss_opts->isoc_interval = GZERO_ISOC_INTERVAL;
|
||||
ss_opts->isoc_maxpacket = GZERO_ISOC_MAXPACKET;
|
||||
ss_opts->bulk_buflen = GZERO_BULK_BUFLEN;
|
||||
ss_opts->int_interval = GZERO_INT_INTERVAL;
|
||||
ss_opts->int_maxpacket = GZERO_INT_MAXPACKET;
|
||||
|
||||
config_group_init_type_name(&ss_opts->func_inst.group, "",
|
||||
&ss_func_type);
|
||||
|
@@ -54,7 +54,7 @@
|
||||
#define UNFLW_CTRL 8
|
||||
#define OVFLW_CTRL 10
|
||||
|
||||
const char *uac2_name = "snd_uac2";
|
||||
static const char *uac2_name = "snd_uac2";
|
||||
|
||||
struct uac2_req {
|
||||
struct uac2_rtd_params *pp; /* parent param */
|
||||
@@ -634,7 +634,7 @@ static struct usb_interface_descriptor std_ac_if_desc = {
|
||||
};
|
||||
|
||||
/* Clock source for IN traffic */
|
||||
struct uac_clock_source_descriptor in_clk_src_desc = {
|
||||
static struct uac_clock_source_descriptor in_clk_src_desc = {
|
||||
.bLength = sizeof in_clk_src_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -646,7 +646,7 @@ struct uac_clock_source_descriptor in_clk_src_desc = {
|
||||
};
|
||||
|
||||
/* Clock source for OUT traffic */
|
||||
struct uac_clock_source_descriptor out_clk_src_desc = {
|
||||
static struct uac_clock_source_descriptor out_clk_src_desc = {
|
||||
.bLength = sizeof out_clk_src_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -658,7 +658,7 @@ struct uac_clock_source_descriptor out_clk_src_desc = {
|
||||
};
|
||||
|
||||
/* Input Terminal for USB_OUT */
|
||||
struct uac2_input_terminal_descriptor usb_out_it_desc = {
|
||||
static struct uac2_input_terminal_descriptor usb_out_it_desc = {
|
||||
.bLength = sizeof usb_out_it_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -672,7 +672,7 @@ struct uac2_input_terminal_descriptor usb_out_it_desc = {
|
||||
};
|
||||
|
||||
/* Input Terminal for I/O-In */
|
||||
struct uac2_input_terminal_descriptor io_in_it_desc = {
|
||||
static struct uac2_input_terminal_descriptor io_in_it_desc = {
|
||||
.bLength = sizeof io_in_it_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -686,7 +686,7 @@ struct uac2_input_terminal_descriptor io_in_it_desc = {
|
||||
};
|
||||
|
||||
/* Ouput Terminal for USB_IN */
|
||||
struct uac2_output_terminal_descriptor usb_in_ot_desc = {
|
||||
static struct uac2_output_terminal_descriptor usb_in_ot_desc = {
|
||||
.bLength = sizeof usb_in_ot_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -700,7 +700,7 @@ struct uac2_output_terminal_descriptor usb_in_ot_desc = {
|
||||
};
|
||||
|
||||
/* Ouput Terminal for I/O-Out */
|
||||
struct uac2_output_terminal_descriptor io_out_ot_desc = {
|
||||
static struct uac2_output_terminal_descriptor io_out_ot_desc = {
|
||||
.bLength = sizeof io_out_ot_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -713,7 +713,7 @@ struct uac2_output_terminal_descriptor io_out_ot_desc = {
|
||||
.bmControls = (CONTROL_RDWR << COPY_CTRL),
|
||||
};
|
||||
|
||||
struct uac2_ac_header_descriptor ac_hdr_desc = {
|
||||
static struct uac2_ac_header_descriptor ac_hdr_desc = {
|
||||
.bLength = sizeof ac_hdr_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -751,7 +751,7 @@ static struct usb_interface_descriptor std_as_out_if1_desc = {
|
||||
};
|
||||
|
||||
/* Audio Stream OUT Intface Desc */
|
||||
struct uac2_as_header_descriptor as_out_hdr_desc = {
|
||||
static struct uac2_as_header_descriptor as_out_hdr_desc = {
|
||||
.bLength = sizeof as_out_hdr_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -764,7 +764,7 @@ struct uac2_as_header_descriptor as_out_hdr_desc = {
|
||||
};
|
||||
|
||||
/* Audio USB_OUT Format */
|
||||
struct uac2_format_type_i_descriptor as_out_fmt1_desc = {
|
||||
static struct uac2_format_type_i_descriptor as_out_fmt1_desc = {
|
||||
.bLength = sizeof as_out_fmt1_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubtype = UAC_FORMAT_TYPE,
|
||||
@@ -772,7 +772,7 @@ struct uac2_format_type_i_descriptor as_out_fmt1_desc = {
|
||||
};
|
||||
|
||||
/* STD AS ISO OUT Endpoint */
|
||||
struct usb_endpoint_descriptor fs_epout_desc = {
|
||||
static struct usb_endpoint_descriptor fs_epout_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
@@ -782,7 +782,7 @@ struct usb_endpoint_descriptor fs_epout_desc = {
|
||||
.bInterval = 1,
|
||||
};
|
||||
|
||||
struct usb_endpoint_descriptor hs_epout_desc = {
|
||||
static struct usb_endpoint_descriptor hs_epout_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
@@ -828,7 +828,7 @@ static struct usb_interface_descriptor std_as_in_if1_desc = {
|
||||
};
|
||||
|
||||
/* Audio Stream IN Intface Desc */
|
||||
struct uac2_as_header_descriptor as_in_hdr_desc = {
|
||||
static struct uac2_as_header_descriptor as_in_hdr_desc = {
|
||||
.bLength = sizeof as_in_hdr_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
|
||||
@@ -841,7 +841,7 @@ struct uac2_as_header_descriptor as_in_hdr_desc = {
|
||||
};
|
||||
|
||||
/* Audio USB_IN Format */
|
||||
struct uac2_format_type_i_descriptor as_in_fmt1_desc = {
|
||||
static struct uac2_format_type_i_descriptor as_in_fmt1_desc = {
|
||||
.bLength = sizeof as_in_fmt1_desc,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubtype = UAC_FORMAT_TYPE,
|
||||
@@ -849,7 +849,7 @@ struct uac2_format_type_i_descriptor as_in_fmt1_desc = {
|
||||
};
|
||||
|
||||
/* STD AS ISO IN Endpoint */
|
||||
struct usb_endpoint_descriptor fs_epin_desc = {
|
||||
static struct usb_endpoint_descriptor fs_epin_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
@@ -859,7 +859,7 @@ struct usb_endpoint_descriptor fs_epin_desc = {
|
||||
.bInterval = 1,
|
||||
};
|
||||
|
||||
struct usb_endpoint_descriptor hs_epin_desc = {
|
||||
static struct usb_endpoint_descriptor hs_epin_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
@@ -1563,7 +1563,7 @@ static void afunc_unbind(struct usb_configuration *c, struct usb_function *f)
|
||||
agdev->out_ep->driver_data = NULL;
|
||||
}
|
||||
|
||||
struct usb_function *afunc_alloc(struct usb_function_instance *fi)
|
||||
static struct usb_function *afunc_alloc(struct usb_function_instance *fi)
|
||||
{
|
||||
struct audio_dev *agdev;
|
||||
struct f_uac2_opts *opts;
|
||||
|
@@ -10,8 +10,6 @@
|
||||
#define GZERO_QLEN 32
|
||||
#define GZERO_ISOC_INTERVAL 4
|
||||
#define GZERO_ISOC_MAXPACKET 1024
|
||||
#define GZERO_INT_INTERVAL 1 /* Default interrupt interval = 1 ms */
|
||||
#define GZERO_INT_MAXPACKET 1024
|
||||
|
||||
struct usb_zero_options {
|
||||
unsigned pattern;
|
||||
@@ -19,10 +17,6 @@ struct usb_zero_options {
|
||||
unsigned isoc_maxpacket;
|
||||
unsigned isoc_mult;
|
||||
unsigned isoc_maxburst;
|
||||
unsigned int_interval; /* In ms */
|
||||
unsigned int_maxpacket;
|
||||
unsigned int_mult;
|
||||
unsigned int_maxburst;
|
||||
unsigned bulk_buflen;
|
||||
unsigned qlen;
|
||||
};
|
||||
@@ -34,10 +28,6 @@ struct f_ss_opts {
|
||||
unsigned isoc_maxpacket;
|
||||
unsigned isoc_mult;
|
||||
unsigned isoc_maxburst;
|
||||
unsigned int_interval; /* In ms */
|
||||
unsigned int_maxpacket;
|
||||
unsigned int_mult;
|
||||
unsigned int_maxburst;
|
||||
unsigned bulk_buflen;
|
||||
|
||||
/*
|
||||
@@ -72,7 +62,6 @@ int lb_modinit(void);
|
||||
void free_ep_req(struct usb_ep *ep, struct usb_request *req);
|
||||
void disable_endpoints(struct usb_composite_dev *cdev,
|
||||
struct usb_ep *in, struct usb_ep *out,
|
||||
struct usb_ep *iso_in, struct usb_ep *iso_out,
|
||||
struct usb_ep *int_in, struct usb_ep *int_out);
|
||||
struct usb_ep *iso_in, struct usb_ep *iso_out);
|
||||
|
||||
#endif /* __G_ZERO_H */
|
||||
|
37
drivers/usb/gadget/function/u_printer.h
Normal file
37
drivers/usb/gadget/function/u_printer.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* u_printer.h
|
||||
*
|
||||
* Utility definitions for the printer function
|
||||
*
|
||||
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com
|
||||
*
|
||||
* Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef U_PRINTER_H
|
||||
#define U_PRINTER_H
|
||||
|
||||
#include <linux/usb/composite.h>
|
||||
|
||||
#define PNP_STRING_LEN 1024
|
||||
|
||||
struct f_printer_opts {
|
||||
struct usb_function_instance func_inst;
|
||||
int minor;
|
||||
char pnp_string[PNP_STRING_LEN];
|
||||
unsigned q_len;
|
||||
|
||||
/*
|
||||
* Protect the data from concurrent access by read/write
|
||||
* and create symlink/remove symlink
|
||||
*/
|
||||
struct mutex lock;
|
||||
int refcnt;
|
||||
};
|
||||
|
||||
#endif /* U_PRINTER_H */
|
@@ -912,7 +912,7 @@ static int gs_put_char(struct tty_struct *tty, unsigned char ch)
|
||||
unsigned long flags;
|
||||
int status;
|
||||
|
||||
pr_vdebug("gs_put_char: (%d,%p) char=0x%x, called from %pf\n",
|
||||
pr_vdebug("gs_put_char: (%d,%p) char=0x%x, called from %ps\n",
|
||||
port->port_num, tty, ch, __builtin_return_address(0));
|
||||
|
||||
spin_lock_irqsave(&port->port_lock, flags);
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include "uvc.h"
|
||||
#include "uvc_queue.h"
|
||||
#include "uvc_video.h"
|
||||
#include "uvc_v4l2.h"
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* Requests handling
|
||||
|
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "uvc.h"
|
||||
#include "uvc_queue.h"
|
||||
#include "uvc_video.h"
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* Video codecs
|
||||
|
Reference in New Issue
Block a user