diff options
author | David Brownell <david-b@pacbell.net> | 2007-07-01 15:21:00 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-07-12 19:34:42 -0400 |
commit | c67ab134ba9f83f9de86e58adfeaa14a9efa6e00 (patch) | |
tree | df9022b4a38e955abbf254d71e00ac1fecce6420 /drivers/usb/gadget/omap_udc.c | |
parent | 9d8bab58b758cd5a96d368a8cc64111c9ab50407 (diff) |
usb gadget stack: remove usb_ep_*_buffer(), part 2
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>
Diffstat (limited to 'drivers/usb/gadget/omap_udc.c')
-rw-r--r-- | drivers/usb/gadget/omap_udc.c | 108 |
1 files changed, 0 insertions, 108 deletions
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index c4975a6cf777..9b0f0925dddf 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -296,111 +296,6 @@ omap_free_request(struct usb_ep *ep, struct usb_request *_req) | |||
296 | 296 | ||
297 | /*-------------------------------------------------------------------------*/ | 297 | /*-------------------------------------------------------------------------*/ |
298 | 298 | ||
299 | /* | ||
300 | * dma-coherent memory allocation (for dma-capable endpoints) | ||
301 | * | ||
302 | * NOTE: the dma_*_coherent() API calls suck. Most implementations are | ||
303 | * (a) page-oriented, so small buffers lose big; and (b) asymmetric with | ||
304 | * respect to calls with irqs disabled: alloc is safe, free is not. | ||
305 | * We currently work around (b), but not (a). | ||
306 | */ | ||
307 | |||
308 | static void * | ||
309 | omap_alloc_buffer( | ||
310 | struct usb_ep *_ep, | ||
311 | unsigned bytes, | ||
312 | dma_addr_t *dma, | ||
313 | gfp_t gfp_flags | ||
314 | ) | ||
315 | { | ||
316 | void *retval; | ||
317 | struct omap_ep *ep; | ||
318 | |||
319 | if (!_ep) | ||
320 | return NULL; | ||
321 | |||
322 | ep = container_of(_ep, struct omap_ep, ep); | ||
323 | if (use_dma && ep->has_dma) { | ||
324 | static int warned; | ||
325 | if (!warned && bytes < PAGE_SIZE) { | ||
326 | dev_warn(ep->udc->gadget.dev.parent, | ||
327 | "using dma_alloc_coherent for " | ||
328 | "small allocations wastes memory\n"); | ||
329 | warned++; | ||
330 | } | ||
331 | return dma_alloc_coherent(ep->udc->gadget.dev.parent, | ||
332 | bytes, dma, gfp_flags); | ||
333 | } | ||
334 | |||
335 | retval = kmalloc(bytes, gfp_flags); | ||
336 | if (retval) | ||
337 | *dma = virt_to_phys(retval); | ||
338 | return retval; | ||
339 | } | ||
340 | |||
341 | static DEFINE_SPINLOCK(buflock); | ||
342 | static LIST_HEAD(buffers); | ||
343 | |||
344 | struct free_record { | ||
345 | struct list_head list; | ||
346 | struct device *dev; | ||
347 | unsigned bytes; | ||
348 | dma_addr_t dma; | ||
349 | }; | ||
350 | |||
351 | static void do_free(unsigned long ignored) | ||
352 | { | ||
353 | spin_lock_irq(&buflock); | ||
354 | while (!list_empty(&buffers)) { | ||
355 | struct free_record *buf; | ||
356 | |||
357 | buf = list_entry(buffers.next, struct free_record, list); | ||
358 | list_del(&buf->list); | ||
359 | spin_unlock_irq(&buflock); | ||
360 | |||
361 | dma_free_coherent(buf->dev, buf->bytes, buf, buf->dma); | ||
362 | |||
363 | spin_lock_irq(&buflock); | ||
364 | } | ||
365 | spin_unlock_irq(&buflock); | ||
366 | } | ||
367 | |||
368 | static DECLARE_TASKLET(deferred_free, do_free, 0); | ||
369 | |||
370 | static void omap_free_buffer( | ||
371 | struct usb_ep *_ep, | ||
372 | void *buf, | ||
373 | dma_addr_t dma, | ||
374 | unsigned bytes | ||
375 | ) | ||
376 | { | ||
377 | if (!_ep) { | ||
378 | WARN_ON(1); | ||
379 | return; | ||
380 | } | ||
381 | |||
382 | /* free memory into the right allocator */ | ||
383 | if (dma != DMA_ADDR_INVALID) { | ||
384 | struct omap_ep *ep; | ||
385 | struct free_record *rec = buf; | ||
386 | unsigned long flags; | ||
387 | |||
388 | ep = container_of(_ep, struct omap_ep, ep); | ||
389 | |||
390 | rec->dev = ep->udc->gadget.dev.parent; | ||
391 | rec->bytes = bytes; | ||
392 | rec->dma = dma; | ||
393 | |||
394 | spin_lock_irqsave(&buflock, flags); | ||
395 | list_add_tail(&rec->list, &buffers); | ||
396 | tasklet_schedule(&deferred_free); | ||
397 | spin_unlock_irqrestore(&buflock, flags); | ||
398 | } else | ||
399 | kfree(buf); | ||
400 | } | ||
401 | |||
402 | /*-------------------------------------------------------------------------*/ | ||
403 | |||
404 | static void | 299 | static void |
405 | done(struct omap_ep *ep, struct omap_req *req, int status) | 300 | done(struct omap_ep *ep, struct omap_req *req, int status) |
406 | { | 301 | { |
@@ -1271,9 +1166,6 @@ static struct usb_ep_ops omap_ep_ops = { | |||
1271 | .alloc_request = omap_alloc_request, | 1166 | .alloc_request = omap_alloc_request, |
1272 | .free_request = omap_free_request, | 1167 | .free_request = omap_free_request, |
1273 | 1168 | ||
1274 | .alloc_buffer = omap_alloc_buffer, | ||
1275 | .free_buffer = omap_free_buffer, | ||
1276 | |||
1277 | .queue = omap_ep_queue, | 1169 | .queue = omap_ep_queue, |
1278 | .dequeue = omap_ep_dequeue, | 1170 | .dequeue = omap_ep_dequeue, |
1279 | 1171 | ||