Skip to content

Commit

Permalink
usb gadget stack: remove usb_ep_*_buffer(), part 2
Browse files Browse the repository at this point in the history
This patch removes controller driver infrastructure which supported
the now-removed usb_ep_{alloc,free}_buffer() calls.

As can be seen, many of the implementations of this were broken to
various degrees.  Many didn't properly return dma-coherent mappings;
those which did so were necessarily ugly because of bogosity in the
underlying dma_free_coherent() calls ... which on many platforms
can't be called from the same contexts (notably in_irq) from which
their dma_alloc_coherent() sibling can be called.

The main potential downside of removing this is that gadget drivers
wouldn't have specific knowledge that the controller drivers have:
endpoints that aren't dma-capable don't need any dma mappings at all.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
David Brownell authored and Greg Kroah-Hartman committed Jul 12, 2007
1 parent 9d8bab5 commit c67ab13
Show file tree
Hide file tree
Showing 10 changed files with 0 additions and 436 deletions.
21 changes: 0 additions & 21 deletions drivers/usb/gadget/at91_udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -601,25 +601,6 @@ static void at91_ep_free_request(struct usb_ep *_ep, struct usb_request *_req)
kfree(req);
}

static void *at91_ep_alloc_buffer(
struct usb_ep *_ep,
unsigned bytes,
dma_addr_t *dma,
gfp_t gfp_flags)
{
*dma = ~0;
return kmalloc(bytes, gfp_flags);
}

static void at91_ep_free_buffer(
struct usb_ep *ep,
void *buf,
dma_addr_t dma,
unsigned bytes)
{
kfree(buf);
}

static int at91_ep_queue(struct usb_ep *_ep,
struct usb_request *_req, gfp_t gfp_flags)
{
Expand Down Expand Up @@ -788,8 +769,6 @@ static const struct usb_ep_ops at91_ep_ops = {
.disable = at91_ep_disable,
.alloc_request = at91_ep_alloc_request,
.free_request = at91_ep_free_request,
.alloc_buffer = at91_ep_alloc_buffer,
.free_buffer = at91_ep_free_buffer,
.queue = at91_ep_queue,
.dequeue = at91_ep_dequeue,
.set_halt = at91_ep_set_halt,
Expand Down
36 changes: 0 additions & 36 deletions drivers/usb/gadget/dummy_hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,38 +497,6 @@ dummy_free_request (struct usb_ep *_ep, struct usb_request *_req)
kfree (req);
}

static void *
dummy_alloc_buffer (
struct usb_ep *_ep,
unsigned bytes,
dma_addr_t *dma,
gfp_t mem_flags
) {
char *retval;
struct dummy_ep *ep;
struct dummy *dum;

ep = usb_ep_to_dummy_ep (_ep);
dum = ep_to_dummy (ep);

if (!dum->driver)
return NULL;
retval = kmalloc (bytes, mem_flags);
*dma = (dma_addr_t) retval;
return retval;
}

static void
dummy_free_buffer (
struct usb_ep *_ep,
void *buf,
dma_addr_t dma,
unsigned bytes
) {
if (bytes)
kfree (buf);
}

static void
fifo_complete (struct usb_ep *ep, struct usb_request *req)
{
Expand Down Expand Up @@ -659,10 +627,6 @@ static const struct usb_ep_ops dummy_ep_ops = {
.alloc_request = dummy_alloc_request,
.free_request = dummy_free_request,

.alloc_buffer = dummy_alloc_buffer,
.free_buffer = dummy_free_buffer,
/* map, unmap, ... eventually hook the "generic" dma calls */

.queue = dummy_queue,
.dequeue = dummy_dequeue,

Expand Down
36 changes: 0 additions & 36 deletions drivers/usb/gadget/fsl_usb2_udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -601,39 +601,6 @@ static void fsl_free_request(struct usb_ep *_ep, struct usb_request *_req)
kfree(req);
}

/*------------------------------------------------------------------
* Allocate an I/O buffer
*---------------------------------------------------------------------*/
static void *fsl_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
dma_addr_t *dma, gfp_t gfp_flags)
{
struct fsl_ep *ep;

if (!_ep)
return NULL;

ep = container_of(_ep, struct fsl_ep, ep);

return dma_alloc_coherent(ep->udc->gadget.dev.parent,
bytes, dma, gfp_flags);
}

/*------------------------------------------------------------------
* frees an i/o buffer
*---------------------------------------------------------------------*/
static void fsl_free_buffer(struct usb_ep *_ep, void *buf,
dma_addr_t dma, unsigned bytes)
{
struct fsl_ep *ep;

if (!_ep)
return;

ep = container_of(_ep, struct fsl_ep, ep);

dma_free_coherent(ep->udc->gadget.dev.parent, bytes, buf, dma);
}

/*-------------------------------------------------------------------------*/
static int fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
{
Expand Down Expand Up @@ -1047,9 +1014,6 @@ static struct usb_ep_ops fsl_ep_ops = {
.alloc_request = fsl_alloc_request,
.free_request = fsl_free_request,

.alloc_buffer = fsl_alloc_buffer,
.free_buffer = fsl_free_buffer,

.queue = fsl_ep_queue,
.dequeue = fsl_ep_dequeue,

Expand Down
48 changes: 0 additions & 48 deletions drivers/usb/gadget/goku_udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,51 +296,6 @@ goku_free_request(struct usb_ep *_ep, struct usb_request *_req)

/*-------------------------------------------------------------------------*/

/* allocating buffers this way eliminates dma mapping overhead, which
* on some platforms will mean eliminating a per-io buffer copy. with
* some kinds of system caches, further tweaks may still be needed.
*/
static void *
goku_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
dma_addr_t *dma, gfp_t gfp_flags)
{
void *retval;
struct goku_ep *ep;

ep = container_of(_ep, struct goku_ep, ep);
if (!_ep)
return NULL;
*dma = DMA_ADDR_INVALID;

if (ep->dma) {
/* the main problem with this call is that it wastes memory
* on typical 1/N page allocations: it allocates 1-N pages.
*/
#warning Using dma_alloc_coherent even with buffers smaller than a page.
retval = dma_alloc_coherent(&ep->dev->pdev->dev,
bytes, dma, gfp_flags);
} else
retval = kmalloc(bytes, gfp_flags);
return retval;
}

static void
goku_free_buffer(struct usb_ep *_ep, void *buf, dma_addr_t dma, unsigned bytes)
{
/* free memory into the right allocator */
if (dma != DMA_ADDR_INVALID) {
struct goku_ep *ep;

ep = container_of(_ep, struct goku_ep, ep);
if (!_ep)
return;
dma_free_coherent(&ep->dev->pdev->dev, bytes, buf, dma);
} else
kfree (buf);
}

/*-------------------------------------------------------------------------*/

static void
done(struct goku_ep *ep, struct goku_request *req, int status)
{
Expand Down Expand Up @@ -1026,9 +981,6 @@ static struct usb_ep_ops goku_ep_ops = {
.alloc_request = goku_alloc_request,
.free_request = goku_free_request,

.alloc_buffer = goku_alloc_buffer,
.free_buffer = goku_free_buffer,

.queue = goku_queue,
.dequeue = goku_dequeue,

Expand Down
27 changes: 0 additions & 27 deletions drivers/usb/gadget/lh7a40x_udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,6 @@ static int lh7a40x_ep_enable(struct usb_ep *ep,
static int lh7a40x_ep_disable(struct usb_ep *ep);
static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep, gfp_t);
static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *);
static void *lh7a40x_alloc_buffer(struct usb_ep *ep, unsigned, dma_addr_t *,
gfp_t);
static void lh7a40x_free_buffer(struct usb_ep *ep, void *, dma_addr_t,
unsigned);
static int lh7a40x_queue(struct usb_ep *ep, struct usb_request *, gfp_t);
static int lh7a40x_dequeue(struct usb_ep *ep, struct usb_request *);
static int lh7a40x_set_halt(struct usb_ep *ep, int);
Expand All @@ -104,9 +100,6 @@ static struct usb_ep_ops lh7a40x_ep_ops = {
.alloc_request = lh7a40x_alloc_request,
.free_request = lh7a40x_free_request,

.alloc_buffer = lh7a40x_alloc_buffer,
.free_buffer = lh7a40x_free_buffer,

.queue = lh7a40x_queue,
.dequeue = lh7a40x_dequeue,

Expand Down Expand Up @@ -1134,26 +1127,6 @@ static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *_req)
kfree(req);
}

static void *lh7a40x_alloc_buffer(struct usb_ep *ep, unsigned bytes,
dma_addr_t * dma, gfp_t gfp_flags)
{
char *retval;

DEBUG("%s (%p, %d, %d)\n", __FUNCTION__, ep, bytes, gfp_flags);

retval = kmalloc(bytes, gfp_flags & ~(__GFP_DMA | __GFP_HIGHMEM));
if (retval)
*dma = virt_to_bus(retval);
return retval;
}

static void lh7a40x_free_buffer(struct usb_ep *ep, void *buf, dma_addr_t dma,
unsigned bytes)
{
DEBUG("%s, %p\n", __FUNCTION__, ep);
kfree(buf);
}

/** Queue one request
* Kickstart transfer if needed
* NOTE: Sets INDEX register
Expand Down
97 changes: 0 additions & 97 deletions drivers/usb/gadget/net2280.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,100 +450,6 @@ net2280_free_request (struct usb_ep *_ep, struct usb_request *_req)

/*-------------------------------------------------------------------------*/

/*
* dma-coherent memory allocation (for dma-capable endpoints)
*
* NOTE: the dma_*_coherent() API calls suck. Most implementations are
* (a) page-oriented, so small buffers lose big; and (b) asymmetric with
* respect to calls with irqs disabled: alloc is safe, free is not.
* We currently work around (b), but not (a).
*/

static void *
net2280_alloc_buffer (
struct usb_ep *_ep,
unsigned bytes,
dma_addr_t *dma,
gfp_t gfp_flags
)
{
void *retval;
struct net2280_ep *ep;

ep = container_of (_ep, struct net2280_ep, ep);
if (!_ep)
return NULL;
*dma = DMA_ADDR_INVALID;

if (ep->dma)
retval = dma_alloc_coherent(&ep->dev->pdev->dev,
bytes, dma, gfp_flags);
else
retval = kmalloc(bytes, gfp_flags);
return retval;
}

static DEFINE_SPINLOCK(buflock);
static LIST_HEAD(buffers);

struct free_record {
struct list_head list;
struct device *dev;
unsigned bytes;
dma_addr_t dma;
};

static void do_free(unsigned long ignored)
{
spin_lock_irq(&buflock);
while (!list_empty(&buffers)) {
struct free_record *buf;

buf = list_entry(buffers.next, struct free_record, list);
list_del(&buf->list);
spin_unlock_irq(&buflock);

dma_free_coherent(buf->dev, buf->bytes, buf, buf->dma);

spin_lock_irq(&buflock);
}
spin_unlock_irq(&buflock);
}

static DECLARE_TASKLET(deferred_free, do_free, 0);

static void
net2280_free_buffer (
struct usb_ep *_ep,
void *address,
dma_addr_t dma,
unsigned bytes
) {
/* free memory into the right allocator */
if (dma != DMA_ADDR_INVALID) {
struct net2280_ep *ep;
struct free_record *buf = address;
unsigned long flags;

ep = container_of(_ep, struct net2280_ep, ep);
if (!_ep)
return;

ep = container_of (_ep, struct net2280_ep, ep);
buf->dev = &ep->dev->pdev->dev;
buf->bytes = bytes;
buf->dma = dma;

spin_lock_irqsave(&buflock, flags);
list_add_tail(&buf->list, &buffers);
tasklet_schedule(&deferred_free);
spin_unlock_irqrestore(&buflock, flags);
} else
kfree (address);
}

/*-------------------------------------------------------------------------*/

/* load a packet into the fifo we use for usb IN transfers.
* works for all endpoints.
*
Expand Down Expand Up @@ -1392,9 +1298,6 @@ static const struct usb_ep_ops net2280_ep_ops = {
.alloc_request = net2280_alloc_request,
.free_request = net2280_free_request,

.alloc_buffer = net2280_alloc_buffer,
.free_buffer = net2280_free_buffer,

.queue = net2280_queue,
.dequeue = net2280_dequeue,

Expand Down
Loading

0 comments on commit c67ab13

Please sign in to comment.