Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- static usbd_status
- usb_block_allocmem(bus_dma_tag_t tag, size_t size, size_t align,
- usb_dma_block_t **dmap)
- {
- usb_dma_block_t *p;
- DPRINTFN(5, ("usb_block_allocmem: size=%lu align=%lu\n",
- (u_long)size, (u_long)align));
- crit_enter();
- /* First check the free list. */
- for (p = LIST_FIRST(&usb_blk_freelist); p; p = LIST_NEXT(p, next)) {
- if (p->tag == tag && p->size >= size && p->align >= align) {
- LIST_REMOVE(p, next);
- usb_blk_nfree--;
- crit_exit();
- *dmap = p;
- DPRINTFN(6,("usb_block_allocmem: free list size=%lu\n",
- (u_long)p->size));
- logmemory(blkalloc2, p, NULL, size, align);
- return (USBD_NORMAL_COMPLETION);
- }
- }
- crit_exit();
- DPRINTFN(6, ("usb_block_allocmem: no free\n"));
- p = kmalloc(sizeof *p, M_USB, M_INTWAIT);
- logmemory(blkalloc, p, NULL, size, align);
- if (bus_dma_tag_create(tag, align, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- size, NELEM(p->segs), size, BUS_DMA_ALLOCNOW, &p->tag) == ENOMEM) {
- goto free;
- }
- p->size = size;
- p->align = align;
- if (bus_dmamem_alloc(p->tag, &p->kaddr,
- BUS_DMA_NOWAIT|BUS_DMA_COHERENT, &p->map))
- goto tagfree;
- if (bus_dmamap_load(p->tag, p->map, p->kaddr, p->size,
- usbmem_callback, p, 0))
- goto memfree;
- /* XXX - override the tag, ok since we never free it */
- p->tag = tag;
- *dmap = p;
- return (USBD_NORMAL_COMPLETION);
- /*
- * XXX - do we need to _unload? is the order of _free and _destroy
- * correct?
- */
- memfree:
- bus_dmamem_free(p->tag, p->kaddr, p->map);
- tagfree:
- bus_dma_tag_destroy(p->tag);
- free:
- kfree(p, M_USB);
- return (USBD_NOMEM);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement