diff options
author | Magnus Damm <damm@igel.co.jp> | 2009-08-19 14:19:08 +0000 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-08-20 10:30:44 +0900 |
commit | ef5ce3b69028ea32aa87e98c9a3802e7c9f824b6 (patch) | |
tree | dddda44be0639cb6c49b7d066394c9b41b33a391 /drivers/usb/gadget/r8a66597-udc.c | |
parent | d2e27bdf2870e507dd4abba1f56ca84ee6ae7232 (diff) |
usb: r8a66597-udc buffer management update
This patch updates the r8a66597-udc buffer management code.
Use fixed buffers for bulk and isochronous pipes, also make
sure to handle the isochronous-as-bulk case. With fixed buffers
there is no need to keep track of used buffers with bi_bufnum.
Also, this fixes a potential buffer offset problem where the
base offset incorrectly varies with the number of pipes used.
The m66592 driver recently got fixed in a similar way.
Signed-off-by: Magnus Damm <damm@igel.co.jp>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/usb/gadget/r8a66597-udc.c')
-rw-r--r-- | drivers/usb/gadget/r8a66597-udc.c | 32 |
1 files changed, 11 insertions, 21 deletions
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index c65753ffe0f..956618400a7 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c @@ -252,24 +252,27 @@ static int pipe_buffer_setting(struct r8a66597 *r8a66597, buf_bsize = 0; break; case R8A66597_BULK: - bufnum = r8a66597->bi_bufnum + - (info->pipe - R8A66597_BASE_PIPENUM_BULK) * 16; - r8a66597->bi_bufnum += 16; + /* isochronous pipes may be used as bulk pipes */ + if (info->pipe > R8A66597_BASE_PIPENUM_BULK) + bufnum = info->pipe - R8A66597_BASE_PIPENUM_BULK; + else + bufnum = info->pipe - R8A66597_BASE_PIPENUM_ISOC; + + bufnum = R8A66597_BASE_BUFNUM + (bufnum * 16); buf_bsize = 7; pipecfg |= R8A66597_DBLB; if (!info->dir_in) pipecfg |= R8A66597_SHTNAK; break; case R8A66597_ISO: - bufnum = r8a66597->bi_bufnum + + bufnum = R8A66597_BASE_BUFNUM + (info->pipe - R8A66597_BASE_PIPENUM_ISOC) * 16; - r8a66597->bi_bufnum += 16; buf_bsize = 7; break; } - if (r8a66597->bi_bufnum > R8A66597_MAX_BUFNUM) { - printk(KERN_ERR "r8a66597 pipe memory is insufficient(%d)\n", - r8a66597->bi_bufnum); + + if (buf_bsize && ((bufnum + 16) >= R8A66597_MAX_BUFNUM)) { + pr_err(KERN_ERR "r8a66597 pipe memory is insufficient\n"); return -ENOMEM; } @@ -289,17 +292,6 @@ static void pipe_buffer_release(struct r8a66597 *r8a66597, if (info->pipe == 0) return; - switch (info->type) { - case R8A66597_BULK: - if (is_bulk_pipe(info->pipe)) - r8a66597->bi_bufnum -= 16; - break; - case R8A66597_ISO: - if (is_isoc_pipe(info->pipe)) - r8a66597->bi_bufnum -= 16; - break; - } - if (is_bulk_pipe(info->pipe)) r8a66597->bulk--; else if (is_interrupt_pipe(info->pipe)) @@ -1553,8 +1545,6 @@ static int __init r8a66597_probe(struct platform_device *pdev) r8a66597->timer.data = (unsigned long)r8a66597; r8a66597->reg = (unsigned long)reg; - r8a66597->bi_bufnum = R8A66597_BASE_BUFNUM; - #ifdef CONFIG_HAVE_CLK if (r8a66597->pdata->on_chip) { snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id); |