Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 592 → Rev 1047

/shark/trunk/drivers/pci/pool.c
186,7 → 186,34
return page;
}
 
static struct pci_page *
pool_alloc_page_usb (struct pci_pool *pool, int mem_flags)
{
struct pci_page *page;
int mapsize;
 
mapsize = pool->blocks_per_page;
mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG;
mapsize *= sizeof (long);
 
page = (struct pci_page *) kmalloc (mapsize + sizeof *page, mem_flags);
if (!page)
return 0;
page->vaddr = pci_alloc_consistent_usb (pool->dev, pool->allocation, &page->dma);
if (page->vaddr) {
memset (page->bitmap, 0xff, mapsize); // bit set == free
#ifdef CONFIG_DEBUG_SLAB
memset (page->vaddr, POOL_POISON_FREED, pool->allocation);
#endif
list_add (&page->page_list, &pool->page_list);
page->in_use = 0;
} else {
kfree (page);
page = 0;
}
return page;
}
 
static inline int
is_page_busy (int blocks, unsigned long *bitmap)
{
211,7 → 238,6
kfree (page);
}
 
 
/**
* pci_pool_destroy - destroys a pool of pci memory blocks.
* @pool: pci pool that will be destroyed
247,7 → 273,6
kfree (pool);
}
 
 
/**
* pci_pool_alloc - get a block of consistent memory
* @pool: pci pool that will produce the block
319,7 → 344,77
return retval;
}
 
/**
* pci_pool_alloc_usb - get a block of consistent memory
* @pool: pci pool that will produce the block
* @mem_flags: SLAB_KERNEL or SLAB_ATOMIC
* @handle: pointer to dma address of block
*
* This returns the kernel virtual address of a currently unused block,
* and reports its dma address through the handle.
* If such a memory block can't be allocated, null is returned.
*/
void *
pci_pool_alloc_usb (struct pci_pool *pool, int mem_flags, dma_addr_t *handle)
{
unsigned long flags;
struct list_head *entry;
struct pci_page *page;
int map, block;
size_t offset;
void *retval;
 
restart:
spin_lock_irqsave (&pool->lock, flags);
list_for_each (entry, &pool->page_list) {
int i;
page = list_entry (entry, struct pci_page, page_list);
/* only cachable accesses here ... */
for (map = 0, i = 0;
i < pool->blocks_per_page;
i += BITS_PER_LONG, map++) {
if (page->bitmap [map] == 0)
continue;
block = ffz (~ page->bitmap [map]);
if ((i + block) < pool->blocks_per_page) {
clear_bit (block, &page->bitmap [map]);
offset = (BITS_PER_LONG * map) + block;
offset *= pool->size;
goto ready;
}
}
}
if (!(page = pool_alloc_page_usb (pool, SLAB_ATOMIC))) {
if (mem_flags == SLAB_KERNEL) {
DECLARE_WAITQUEUE (wait, current);
 
//current->state = TASK_INTERRUPTIBLE;
add_wait_queue (&pool->waitq, &wait);
spin_unlock_irqrestore (&pool->lock, flags);
 
schedule_timeout (POOL_TIMEOUT_JIFFIES);
 
remove_wait_queue (&pool->waitq, &wait);
goto restart;
}
retval = 0;
goto done;
}
 
clear_bit (0, &page->bitmap [0]);
offset = 0;
ready:
page->in_use++;
retval = offset + page->vaddr;
*handle = offset + page->dma;
#ifdef CONFIG_DEBUG_SLAB
memset (retval, POOL_POISON_ALLOCATED, pool->size);
#endif
done:
spin_unlock_irqrestore (&pool->lock, flags);
return retval;
}
 
static struct pci_page *
pool_find_page (struct pci_pool *pool, dma_addr_t dma)
{
341,7 → 436,6
return page;
}
 
 
/**
* pci_pool_free - put block back into pci pool
* @pool: the pci pool holding the block
399,7 → 493,6
spin_unlock_irqrestore (&pool->lock, flags);
}
 
 
EXPORT_SYMBOL (pci_pool_create);
EXPORT_SYMBOL (pci_pool_destroy);
EXPORT_SYMBOL (pci_pool_alloc);