Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9224d6ad authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "USB: composite: Increase the IN endpoint buffer allocation"

parents a495cc04 570c1b01
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -2288,7 +2288,8 @@ int composite_dev_prepare(struct usb_composite_driver *composite,
	if (!cdev->req)
		return -ENOMEM;

	cdev->req->buf = kmalloc(USB_COMP_EP0_BUFSIZ, GFP_KERNEL);
	cdev->req->buf = kmalloc(USB_COMP_EP0_BUFSIZ +
				(gadget->extra_buf_alloc), GFP_KERNEL);
	if (!cdev->req->buf)
		goto fail;

+1 −1
Original line number Diff line number Diff line
@@ -664,7 +664,7 @@ acm_bind(struct usb_configuration *c, struct usb_function *f)
	/* allocate notification */
	acm->notify_req = gs_alloc_req(ep,
			sizeof(struct usb_cdc_notification) + 2,
			GFP_KERNEL);
			cdev->gadget->extra_buf_alloc, GFP_KERNEL);
	if (!acm->notify_req)
		goto fail;

+11 −6
Original line number Diff line number Diff line
@@ -752,7 +752,8 @@ static void usb_cser_free_requests(struct usb_ep *ep, struct list_head *head)
}

static struct usb_request *
usb_cser_alloc_req(struct usb_ep *ep, unsigned int len, gfp_t flags)
usb_cser_alloc_req(struct usb_ep *ep, unsigned int len, size_t extra_sz,
			gfp_t flags)
{
	struct usb_request *req;

@@ -763,7 +764,7 @@ usb_cser_alloc_req(struct usb_ep *ep, unsigned int len, gfp_t flags)
	}

	req->length = len;
	req->buf = kmalloc(len, flags);
	req->buf = kmalloc(len + extra_sz, flags);
	if (!req->buf) {
		pr_err("request buf allocation failed\n");
		usb_ep_free_request(ep, req);
@@ -816,7 +817,8 @@ static int usb_cser_bind(struct usb_configuration *c, struct usb_function *f)
	ep->driver_data = cdev;
	/* allocate notification */
	port->port_usb.notify_req = usb_cser_alloc_req(ep,
			sizeof(struct usb_cdc_notification) + 2, GFP_KERNEL);
			sizeof(struct usb_cdc_notification) + 2,
			cdev->gadget->extra_buf_alloc, GFP_KERNEL);
	if (!port->port_usb.notify_req)
		goto fail;

@@ -895,7 +897,7 @@ static void usb_cser_unbind(struct usb_configuration *c, struct usb_function *f)
}

static int usb_cser_alloc_requests(struct usb_ep *ep, struct list_head *head,
		int num, int size,
		int num, int size, size_t extra_sz,
		void (*cb)(struct usb_ep *ep, struct usb_request *))
{
	int i;
@@ -905,7 +907,7 @@ static int usb_cser_alloc_requests(struct usb_ep *ep, struct list_head *head,
				ep, head, num, size, cb);

	for (i = 0; i < num; i++) {
		req = usb_cser_alloc_req(ep, size, GFP_ATOMIC);
		req = usb_cser_alloc_req(ep, size, extra_sz, GFP_ATOMIC);
		if (!req) {
			pr_debug("req allocated:%d\n", i);
			return list_empty(head) ? -ENOMEM : 0;
@@ -1025,6 +1027,8 @@ static void usb_cser_write_complete(struct usb_ep *ep, struct usb_request *req)

static void usb_cser_start_io(struct f_cdev *port)
{
	struct usb_function *f = &port->port_usb.func;
	struct usb_composite_dev *cdev = f->config->cdev;
	int ret = -ENODEV;
	unsigned long	flags;

@@ -1040,7 +1044,7 @@ static void usb_cser_start_io(struct f_cdev *port)

	ret = usb_cser_alloc_requests(port->port_usb.out,
				&port->read_pool,
				BRIDGE_RX_QUEUE_SIZE, BRIDGE_RX_BUF_SIZE,
				BRIDGE_RX_QUEUE_SIZE, BRIDGE_RX_BUF_SIZE, 0,
				usb_cser_read_complete);
	if (ret) {
		pr_err("unable to allocate out requests\n");
@@ -1050,6 +1054,7 @@ static void usb_cser_start_io(struct f_cdev *port)
	ret = usb_cser_alloc_requests(port->port_usb.in,
				&port->write_pool,
				BRIDGE_TX_QUEUE_SIZE, BRIDGE_TX_BUF_SIZE,
				cdev->gadget->extra_buf_alloc,
				usb_cser_write_complete);
	if (ret) {
		usb_cser_free_requests(port->port_usb.out, &port->read_pool);
+23 −6
Original line number Diff line number Diff line
@@ -265,7 +265,8 @@ static void ffs_closed(struct ffs_data *ffs);

static int ffs_mutex_lock(struct mutex *mutex, unsigned nonblock)
	__attribute__((warn_unused_result, nonnull));
static char *ffs_prepare_buffer(const char __user *buf, size_t len)
static char *ffs_prepare_buffer(const char __user *buf, size_t len,
	size_t extra_buf_alloc)
	__attribute__((warn_unused_result, nonnull));


@@ -342,6 +343,7 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf,
			     size_t len, loff_t *ptr)
{
	struct ffs_data *ffs = file->private_data;
	struct usb_gadget *gadget = ffs->gadget;
	ssize_t ret;
	char *data;

@@ -369,7 +371,7 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf,
			break;
		}

		data = ffs_prepare_buffer(buf, len);
		data = ffs_prepare_buffer(buf, len, 0);
		if (IS_ERR(data)) {
			ret = PTR_ERR(data);
			break;
@@ -441,7 +443,7 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf,

		spin_unlock_irq(&ffs->ev.waitq.lock);

		data = ffs_prepare_buffer(buf, len);
		data = ffs_prepare_buffer(buf, len, gadget->extra_buf_alloc);
		if (IS_ERR(data)) {
			ret = PTR_ERR(data);
			break;
@@ -944,6 +946,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
	char *data = NULL;
	ssize_t ret, data_len = -EINVAL;
	int halt;
	size_t extra_buf_alloc = 0;

	ffs_log("enter: %s", epfile->name);

@@ -1022,6 +1025,11 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
			data_len = usb_ep_align_maybe(gadget, ep->ep, data_len);
		spin_unlock_irq(&epfile->ffs->eps_lock);

		extra_buf_alloc = gadget->extra_buf_alloc;
		if (!io_data->read)
			data = kmalloc(data_len + extra_buf_alloc,
					GFP_KERNEL);
		else
			data = kmalloc(data_len, GFP_KERNEL);
		if (unlikely(!data)) {
			ret = -ENOMEM;
@@ -4041,14 +4049,23 @@ static int ffs_mutex_lock(struct mutex *mutex, unsigned nonblock)
		: mutex_lock_interruptible(mutex);
}

static char *ffs_prepare_buffer(const char __user *buf, size_t len)
/**
 * ffs_prepare_buffer() - copy userspace buffer into kernel.
 * @buf: userspace buffer
 * @len: length of the buffer
 * @extra_alloc_buf: Extra buffer allocation if required by UDC.
 *
 * This function returns pointer to the copied buffer
 */
static char *ffs_prepare_buffer(const char __user *buf, size_t len,
		size_t extra_buf_alloc)
{
	char *data;

	if (unlikely(!len))
		return NULL;

	data = kmalloc(len, GFP_KERNEL);
	data = kmalloc(len + extra_buf_alloc, GFP_KERNEL);
	if (unlikely(!data))
		return ERR_PTR(-ENOMEM);

+9 −4
Original line number Diff line number Diff line
@@ -156,7 +156,8 @@ static struct portmaster {
 * usb_request or NULL if there is an error.
 */
struct usb_request *
gs_alloc_req(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags)
gs_alloc_req(struct usb_ep *ep, unsigned int len, size_t extra_sz,
		gfp_t kmalloc_flags)
{
	struct usb_request *req;

@@ -164,7 +165,7 @@ gs_alloc_req(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags)

	if (req != NULL) {
		req->length = len;
		req->buf = kmalloc(len, kmalloc_flags);
		req->buf = kmalloc(len + extra_sz, kmalloc_flags);
		if (req->buf == NULL) {
			usb_ep_free_request(ep, req);
			return NULL;
@@ -506,6 +507,7 @@ static void gs_free_requests(struct usb_ep *ep, struct list_head *head,
}

static int gs_alloc_requests(struct usb_ep *ep, struct list_head *head,
		size_t extra_sz,
		void (*fn)(struct usb_ep *, struct usb_request *),
		int *allocated)
{
@@ -518,7 +520,7 @@ static int gs_alloc_requests(struct usb_ep *ep, struct list_head *head,
	 * be as speedy as we might otherwise be.
	 */
	for (i = 0; i < n; i++) {
		req = gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC);
		req = gs_alloc_req(ep, ep->maxpacket, extra_sz, GFP_ATOMIC);
		if (!req)
			return list_empty(head) ? -ENOMEM : 0;
		req->complete = fn;
@@ -540,6 +542,8 @@ static int gs_alloc_requests(struct usb_ep *ep, struct list_head *head,
 */
static int gs_start_io(struct gs_port *port)
{
	struct usb_function	*f = &port->port_usb->func;
	struct usb_composite_dev *cdev = f->config->cdev;
	struct list_head	*head = &port->read_pool;
	struct usb_ep		*ep = port->port_usb->out;
	int			status;
@@ -551,12 +555,13 @@ static int gs_start_io(struct gs_port *port)
	 * configurations may use different endpoints with a given port;
	 * and high speed vs full speed changes packet sizes too.
	 */
	status = gs_alloc_requests(ep, head, gs_read_complete,
	status = gs_alloc_requests(ep, head, 0, gs_read_complete,
		&port->read_allocated);
	if (status)
		return status;

	status = gs_alloc_requests(port->port_usb->in, &port->write_pool,
			cdev->gadget->extra_buf_alloc,
			gs_write_complete, &port->write_allocated);
	if (status) {
		gs_free_requests(ep, head, &port->read_allocated);
Loading