Commit 15928d8f authored by Deepak Saxena's avatar Deepak Saxena Committed by Greg Kroah-Hartman

[PATCH] PCI: Replace pci_pool with generic dma_pool

- Move drivers/pci/pool.c to drivers/base/pool.c
- Initialize struct device.dma_pools in device_initialize()
- Remove initialization of struct pci_dev.pools from pci_setup_device()
parent 08ccf518
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
obj-y := core.o sys.o interface.o bus.o \ obj-y := core.o sys.o interface.o bus.o \
driver.o class.o class_simple.o platform.o \ driver.o class.o class_simple.o platform.o \
cpu.o firmware.o init.o map.o cpu.o firmware.o init.o map.o dmapool.o
obj-y += power/ obj-y += power/
obj-$(CONFIG_FW_LOADER) += firmware_class.o obj-$(CONFIG_FW_LOADER) += firmware_class.o
obj-$(CONFIG_NUMA) += node.o memblk.o obj-$(CONFIG_NUMA) += node.o memblk.o
...@@ -197,6 +197,7 @@ void device_initialize(struct device *dev) ...@@ -197,6 +197,7 @@ void device_initialize(struct device *dev)
INIT_LIST_HEAD(&dev->children); INIT_LIST_HEAD(&dev->children);
INIT_LIST_HEAD(&dev->driver_list); INIT_LIST_HEAD(&dev->driver_list);
INIT_LIST_HEAD(&dev->bus_list); INIT_LIST_HEAD(&dev->bus_list);
INIT_LIST_HEAD(&dev->dma_pools);
} }
/** /**
......
#include <linux/pci.h>
#include <linux/device.h>
#include <linux/mm.h>
#include <asm/io.h> /* Needed for i386 to build */
#include <asm/scatterlist.h> /* Needed for i386 to build */
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
/* /*
* Pool allocator ... wraps the pci_alloc_consistent page allocator, so * Pool allocator ... wraps the dma_alloc_coherent page allocator, so
* small blocks are easily used by drivers for bus mastering controllers. * small blocks are easily used by drivers for bus mastering controllers.
* This should probably be sharing the guts of the slab allocator. * This should probably be sharing the guts of the slab allocator.
*/ */
struct pci_pool { /* the pool */ struct dma_pool { /* the pool */
struct list_head page_list; struct list_head page_list;
spinlock_t lock; spinlock_t lock;
size_t blocks_per_page; size_t blocks_per_page;
size_t size; size_t size;
struct pci_dev *dev; struct device *dev;
size_t allocation; size_t allocation;
char name [32]; char name [32];
wait_queue_head_t waitq; wait_queue_head_t waitq;
struct list_head pools; struct list_head pools;
}; };
struct pci_page { /* cacheable header for 'allocation' bytes */ struct dma_page { /* cacheable header for 'allocation' bytes */
struct list_head page_list; struct list_head page_list;
void *vaddr; void *vaddr;
dma_addr_t dma; dma_addr_t dma;
...@@ -37,12 +43,10 @@ static DECLARE_MUTEX (pools_lock); ...@@ -37,12 +43,10 @@ static DECLARE_MUTEX (pools_lock);
static ssize_t static ssize_t
show_pools (struct device *dev, char *buf) show_pools (struct device *dev, char *buf)
{ {
struct pci_dev *pdev;
unsigned temp, size; unsigned temp, size;
char *next; char *next;
struct list_head *i, *j; struct list_head *i, *j;
pdev = container_of (dev, struct pci_dev, dev);
next = buf; next = buf;
size = PAGE_SIZE; size = PAGE_SIZE;
...@@ -51,16 +55,16 @@ show_pools (struct device *dev, char *buf) ...@@ -51,16 +55,16 @@ show_pools (struct device *dev, char *buf)
next += temp; next += temp;
down (&pools_lock); down (&pools_lock);
list_for_each (i, &pdev->pools) { list_for_each (i, &dev->dma_pools) {
struct pci_pool *pool; struct dma_pool *pool;
unsigned pages = 0, blocks = 0; unsigned pages = 0, blocks = 0;
pool = list_entry (i, struct pci_pool, pools); pool = list_entry (i, struct dma_pool, pools);
list_for_each (j, &pool->page_list) { list_for_each (j, &pool->page_list) {
struct pci_page *page; struct dma_page *page;
page = list_entry (j, struct pci_page, page_list); page = list_entry (j, struct dma_page, page_list);
pages++; pages++;
blocks += page->in_use; blocks += page->in_use;
} }
...@@ -80,31 +84,31 @@ show_pools (struct device *dev, char *buf) ...@@ -80,31 +84,31 @@ show_pools (struct device *dev, char *buf)
static DEVICE_ATTR (pools, S_IRUGO, show_pools, NULL); static DEVICE_ATTR (pools, S_IRUGO, show_pools, NULL);
/** /**
* pci_pool_create - Creates a pool of pci consistent memory blocks, for dma. * dma_pool_create - Creates a pool of consistent memory blocks, for dma.
* @name: name of pool, for diagnostics * @name: name of pool, for diagnostics
* @pdev: pci device that will be doing the DMA * @dev: device that will be doing the DMA
* @size: size of the blocks in this pool. * @size: size of the blocks in this pool.
* @align: alignment requirement for blocks; must be a power of two * @align: alignment requirement for blocks; must be a power of two
* @allocation: returned blocks won't cross this boundary (or zero) * @allocation: returned blocks won't cross this boundary (or zero)
* Context: !in_interrupt() * Context: !in_interrupt()
* *
* Returns a pci allocation pool with the requested characteristics, or * Returns a dma allocation pool with the requested characteristics, or
* null if one can't be created. Given one of these pools, pci_pool_alloc() * null if one can't be created. Given one of these pools, dma_pool_alloc()
* may be used to allocate memory. Such memory will all have "consistent" * may be used to allocate memory. Such memory will all have "consistent"
* DMA mappings, accessible by the device and its driver without using * DMA mappings, accessible by the device and its driver without using
* cache flushing primitives. The actual size of blocks allocated may be * cache flushing primitives. The actual size of blocks allocated may be
* larger than requested because of alignment. * larger than requested because of alignment.
* *
* If allocation is nonzero, objects returned from pci_pool_alloc() won't * If allocation is nonzero, objects returned from dma_pool_alloc() won't
* cross that size boundary. This is useful for devices which have * cross that size boundary. This is useful for devices which have
* addressing restrictions on individual DMA transfers, such as not crossing * addressing restrictions on individual DMA transfers, such as not crossing
* boundaries of 4KBytes. * boundaries of 4KBytes.
*/ */
struct pci_pool * struct dma_pool *
pci_pool_create (const char *name, struct pci_dev *pdev, dma_pool_create (const char *name, struct device *dev,
size_t size, size_t align, size_t allocation) size_t size, size_t align, size_t allocation)
{ {
struct pci_pool *retval; struct dma_pool *retval;
if (align == 0) if (align == 0)
align = 1; align = 1;
...@@ -131,7 +135,7 @@ pci_pool_create (const char *name, struct pci_dev *pdev, ...@@ -131,7 +135,7 @@ pci_pool_create (const char *name, struct pci_dev *pdev,
strlcpy (retval->name, name, sizeof retval->name); strlcpy (retval->name, name, sizeof retval->name);
retval->dev = pdev; retval->dev = dev;
INIT_LIST_HEAD (&retval->page_list); INIT_LIST_HEAD (&retval->page_list);
spin_lock_init (&retval->lock); spin_lock_init (&retval->lock);
...@@ -140,12 +144,12 @@ pci_pool_create (const char *name, struct pci_dev *pdev, ...@@ -140,12 +144,12 @@ pci_pool_create (const char *name, struct pci_dev *pdev,
retval->blocks_per_page = allocation / size; retval->blocks_per_page = allocation / size;
init_waitqueue_head (&retval->waitq); init_waitqueue_head (&retval->waitq);
if (pdev) { if (dev) {
down (&pools_lock); down (&pools_lock);
if (list_empty (&pdev->pools)) if (list_empty (&dev->dma_pools))
device_create_file (&pdev->dev, &dev_attr_pools); device_create_file (dev, &dev_attr_pools);
/* note: not currently insisting "name" be unique */ /* note: not currently insisting "name" be unique */
list_add (&retval->pools, &pdev->pools); list_add (&retval->pools, &dev->dma_pools);
up (&pools_lock); up (&pools_lock);
} else } else
INIT_LIST_HEAD (&retval->pools); INIT_LIST_HEAD (&retval->pools);
...@@ -154,22 +158,23 @@ pci_pool_create (const char *name, struct pci_dev *pdev, ...@@ -154,22 +158,23 @@ pci_pool_create (const char *name, struct pci_dev *pdev,
} }
static struct pci_page * static struct dma_page *
pool_alloc_page (struct pci_pool *pool, int mem_flags) pool_alloc_page (struct dma_pool *pool, int mem_flags)
{ {
struct pci_page *page; struct dma_page *page;
int mapsize; int mapsize;
mapsize = pool->blocks_per_page; mapsize = pool->blocks_per_page;
mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG; mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG;
mapsize *= sizeof (long); mapsize *= sizeof (long);
page = (struct pci_page *) kmalloc (mapsize + sizeof *page, mem_flags); page = (struct dma_page *) kmalloc (mapsize + sizeof *page, mem_flags);
if (!page) if (!page)
return 0; return 0;
page->vaddr = pci_alloc_consistent (pool->dev, page->vaddr = dma_alloc_coherent (pool->dev,
pool->allocation, pool->allocation,
&page->dma); &page->dma,
mem_flags);
if (page->vaddr) { if (page->vaddr) {
memset (page->bitmap, 0xff, mapsize); // bit set == free memset (page->bitmap, 0xff, mapsize); // bit set == free
#ifdef CONFIG_DEBUG_SLAB #ifdef CONFIG_DEBUG_SLAB
...@@ -197,43 +202,43 @@ is_page_busy (int blocks, unsigned long *bitmap) ...@@ -197,43 +202,43 @@ is_page_busy (int blocks, unsigned long *bitmap)
} }
static void static void
pool_free_page (struct pci_pool *pool, struct pci_page *page) pool_free_page (struct dma_pool *pool, struct dma_page *page)
{ {
dma_addr_t dma = page->dma; dma_addr_t dma = page->dma;
#ifdef CONFIG_DEBUG_SLAB #ifdef CONFIG_DEBUG_SLAB
memset (page->vaddr, POOL_POISON_FREED, pool->allocation); memset (page->vaddr, POOL_POISON_FREED, pool->allocation);
#endif #endif
pci_free_consistent (pool->dev, pool->allocation, page->vaddr, dma); dma_free_coherent (pool->dev, pool->allocation, page->vaddr, dma);
list_del (&page->page_list); list_del (&page->page_list);
kfree (page); kfree (page);
} }
/** /**
* pci_pool_destroy - destroys a pool of pci memory blocks. * dma_pool_destroy - destroys a pool of dma memory blocks.
* @pool: pci pool that will be destroyed * @pool: dma pool that will be destroyed
* Context: !in_interrupt() * Context: !in_interrupt()
* *
* Caller guarantees that no more memory from the pool is in use, * Caller guarantees that no more memory from the pool is in use,
* and that nothing will try to use the pool after this call. * and that nothing will try to use the pool after this call.
*/ */
void void
pci_pool_destroy (struct pci_pool *pool) dma_pool_destroy (struct dma_pool *pool)
{ {
down (&pools_lock); down (&pools_lock);
list_del (&pool->pools); list_del (&pool->pools);
if (pool->dev && list_empty (&pool->dev->pools)) if (pool->dev && list_empty (&pool->dev->dma_pools))
device_remove_file (&pool->dev->dev, &dev_attr_pools); device_remove_file (pool->dev, &dev_attr_pools);
up (&pools_lock); up (&pools_lock);
while (!list_empty (&pool->page_list)) { while (!list_empty (&pool->page_list)) {
struct pci_page *page; struct dma_page *page;
page = list_entry (pool->page_list.next, page = list_entry (pool->page_list.next,
struct pci_page, page_list); struct dma_page, page_list);
if (is_page_busy (pool->blocks_per_page, page->bitmap)) { if (is_page_busy (pool->blocks_per_page, page->bitmap)) {
printk (KERN_ERR "pci_pool_destroy %s/%s, %p busy\n", printk (KERN_ERR "dma_pool_destroy %s/%s, %p busy\n",
pool->dev ? pci_name(pool->dev) : NULL, pool->dev ? pool->dev->bus_id : NULL,
pool->name, page->vaddr); pool->name, page->vaddr);
/* leak the still-in-use consistent memory */ /* leak the still-in-use consistent memory */
list_del (&page->page_list); list_del (&page->page_list);
...@@ -247,8 +252,8 @@ pci_pool_destroy (struct pci_pool *pool) ...@@ -247,8 +252,8 @@ pci_pool_destroy (struct pci_pool *pool)
/** /**
* pci_pool_alloc - get a block of consistent memory * dma_pool_alloc - get a block of consistent memory
* @pool: pci pool that will produce the block * @pool: dma pool that will produce the block
* @mem_flags: SLAB_KERNEL or SLAB_ATOMIC * @mem_flags: SLAB_KERNEL or SLAB_ATOMIC
* @handle: pointer to dma address of block * @handle: pointer to dma address of block
* *
...@@ -257,11 +262,11 @@ pci_pool_destroy (struct pci_pool *pool) ...@@ -257,11 +262,11 @@ pci_pool_destroy (struct pci_pool *pool)
* If such a memory block can't be allocated, null is returned. * If such a memory block can't be allocated, null is returned.
*/ */
void * void *
pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle) dma_pool_alloc (struct dma_pool *pool, int mem_flags, dma_addr_t *handle)
{ {
unsigned long flags; unsigned long flags;
struct list_head *entry; struct list_head *entry;
struct pci_page *page; struct dma_page *page;
int map, block; int map, block;
size_t offset; size_t offset;
void *retval; void *retval;
...@@ -270,7 +275,7 @@ pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle) ...@@ -270,7 +275,7 @@ pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle)
spin_lock_irqsave (&pool->lock, flags); spin_lock_irqsave (&pool->lock, flags);
list_for_each (entry, &pool->page_list) { list_for_each (entry, &pool->page_list) {
int i; int i;
page = list_entry (entry, struct pci_page, page_list); page = list_entry (entry, struct dma_page, page_list);
/* only cachable accesses here ... */ /* only cachable accesses here ... */
for (map = 0, i = 0; for (map = 0, i = 0;
i < pool->blocks_per_page; i < pool->blocks_per_page;
...@@ -318,16 +323,16 @@ pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle) ...@@ -318,16 +323,16 @@ pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle)
} }
static struct pci_page * static struct dma_page *
pool_find_page (struct pci_pool *pool, dma_addr_t dma) pool_find_page (struct dma_pool *pool, dma_addr_t dma)
{ {
unsigned long flags; unsigned long flags;
struct list_head *entry; struct list_head *entry;
struct pci_page *page; struct dma_page *page;
spin_lock_irqsave (&pool->lock, flags); spin_lock_irqsave (&pool->lock, flags);
list_for_each (entry, &pool->page_list) { list_for_each (entry, &pool->page_list) {
page = list_entry (entry, struct pci_page, page_list); page = list_entry (entry, struct dma_page, page_list);
if (dma < page->dma) if (dma < page->dma)
continue; continue;
if (dma < (page->dma + pool->allocation)) if (dma < (page->dma + pool->allocation))
...@@ -341,8 +346,8 @@ pool_find_page (struct pci_pool *pool, dma_addr_t dma) ...@@ -341,8 +346,8 @@ pool_find_page (struct pci_pool *pool, dma_addr_t dma)
/** /**
* pci_pool_free - put block back into pci pool * dma_pool_free - put block back into dma pool
* @pool: the pci pool holding the block * @pool: the dma pool holding the block
* @vaddr: virtual address of block * @vaddr: virtual address of block
* @dma: dma address of block * @dma: dma address of block
* *
...@@ -350,15 +355,15 @@ pool_find_page (struct pci_pool *pool, dma_addr_t dma) ...@@ -350,15 +355,15 @@ pool_find_page (struct pci_pool *pool, dma_addr_t dma)
* unless it is first re-allocated. * unless it is first re-allocated.
*/ */
void void
pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma) dma_pool_free (struct dma_pool *pool, void *vaddr, dma_addr_t dma)
{ {
struct pci_page *page; struct dma_page *page;
unsigned long flags; unsigned long flags;
int map, block; int map, block;
if ((page = pool_find_page (pool, dma)) == 0) { if ((page = pool_find_page (pool, dma)) == 0) {
printk (KERN_ERR "pci_pool_free %s/%s, %p/%lx (bad dma)\n", printk (KERN_ERR "dma_pool_free %s/%s, %p/%lx (bad dma)\n",
pool->dev ? pci_name(pool->dev) : NULL, pool->dev ? pool->dev->bus_id : NULL,
pool->name, vaddr, (unsigned long) dma); pool->name, vaddr, (unsigned long) dma);
return; return;
} }
...@@ -370,14 +375,14 @@ pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma) ...@@ -370,14 +375,14 @@ pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma)
#ifdef CONFIG_DEBUG_SLAB #ifdef CONFIG_DEBUG_SLAB
if (((dma - page->dma) + (void *)page->vaddr) != vaddr) { if (((dma - page->dma) + (void *)page->vaddr) != vaddr) {
printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%Lx\n", printk (KERN_ERR "dma_pool_free %s/%s, %p (bad vaddr)/%Lx\n",
pool->dev ? pci_name(pool->dev) : NULL, pool->dev ? pool->dev->bus_id : NULL,
pool->name, vaddr, (unsigned long long) dma); pool->name, vaddr, (unsigned long long) dma);
return; return;
} }
if (page->bitmap [map] & (1UL << block)) { if (page->bitmap [map] & (1UL << block)) {
printk (KERN_ERR "pci_pool_free %s/%s, dma %Lx already free\n", printk (KERN_ERR "dma_pool_free %s/%s, dma %Lx already free\n",
pool->dev ? pci_name(pool->dev) : NULL, pool->dev ? pool->dev->bus_id : NULL,
pool->name, (unsigned long long)dma); pool->name, (unsigned long long)dma);
return; return;
} }
...@@ -398,7 +403,7 @@ pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma) ...@@ -398,7 +403,7 @@ pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma)
} }
EXPORT_SYMBOL (pci_pool_create); EXPORT_SYMBOL (dma_pool_create);
EXPORT_SYMBOL (pci_pool_destroy); EXPORT_SYMBOL (dma_pool_destroy);
EXPORT_SYMBOL (pci_pool_alloc); EXPORT_SYMBOL (dma_pool_alloc);
EXPORT_SYMBOL (pci_pool_free); EXPORT_SYMBOL (dma_pool_free);
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Makefile for the PCI bus specific drivers. # Makefile for the PCI bus specific drivers.
# #
obj-y += access.o bus.o probe.o remove.o pci.o pool.o quirks.o \ obj-y += access.o bus.o probe.o remove.o pci.o quirks.o \
names.o pci-driver.o search.o pci-sysfs.o names.o pci-driver.o search.o pci-sysfs.o
obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_PROC_FS) += proc.o
......
...@@ -452,8 +452,6 @@ static int pci_setup_device(struct pci_dev * dev) ...@@ -452,8 +452,6 @@ static int pci_setup_device(struct pci_dev * dev)
sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus), sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus),
dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
INIT_LIST_HEAD(&dev->pools);
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
class >>= 8; /* upper 3 bytes */ class >>= 8; /* upper 3 bytes */
dev->class = class; dev->class = class;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment