This is the first shot at this - I've tested it on ARM, covering both
ISA ALSA devices on a PCI machine, and driver model devices on a non-
PCI, non-ISA machine.  However, it needs more testing.  Can people
on alsa-devel please test these patches.

Convert PCI-based memory allocators to use the new driver model-based
allocators.

diff -urpN orig/sound/core/memalloc.c linux/sound/core/memalloc.c
--- orig/sound/core/memalloc.c  Sun Feb 29 18:32:23 2004
+++ linux/sound/core/memalloc.c Sun Feb 29 18:32:07 2004
@@ -78,9 +78,9 @@ struct snd_mem_list {
 #define HACK_PCI_ALLOC_CONSISTENT
 
 /*
- * A hack to allocate large buffers via pci_alloc_consistent()
+ * A hack to allocate large buffers via dma_alloc_coherent()
  *
- * since pci_alloc_consistent always tries GFP_DMA when the requested
+ * since dma_alloc_coherent always tries GFP_DMA when the requested
  * pci memory region is below 32bit, it happens quite often that even
  * 2 order of pages cannot be allocated.
  *
@@ -88,43 +88,41 @@ struct snd_mem_list {
  * allocation will be done without GFP_DMA.  if the area doesn't match
  * with the requested region, then realloate with the original dma_mask
  * again.
+ *
+ * Really, we want to move this type of thing into dma_alloc_coherent()
+ * so dma_mask doesn't have to be messed with.
  */
 
-static void *snd_pci_hack_alloc_consistent(struct pci_dev *hwdev, size_t size,
-                                   dma_addr_t *dma_handle)
+static void *snd_dma_hack_alloc_coherent(struct device *dev, size_t size,
+                                        dma_addr_t *dma_handle)
 {
        void *ret;
-       u64 dma_mask, cdma_mask;
-       unsigned long mask;
+       u64 dma_mask;
 
-       if (hwdev == NULL)
-               return pci_alloc_consistent(hwdev, size, dma_handle);
-       dma_mask = hwdev->dma_mask;
-       cdma_mask = hwdev->consistent_dma_mask;
-       mask = (unsigned long)dma_mask && (unsigned long)cdma_mask;
-       hwdev->dma_mask = 0xffffffff; /* do without masking */
-       hwdev->consistent_dma_mask = 0xffffffff; /* do without masking */
-       ret = pci_alloc_consistent(hwdev, size, dma_handle);
-       hwdev->dma_mask = dma_mask; /* restore */
-       hwdev->consistent_dma_mask = cdma_mask; /* restore */
+       if (dev == NULL)
+               return dev_alloc_coherent(dev, size, dma_handle);
+       dma_mask = dev->dma_mask;
+       dev->dma_mask = 0xffffffff; /* do without masking */
+       ret = dev_alloc_coherent(dev, size, dma_handle, GFP_KERNEL);
+       dev->dma_mask = dma_mask; /* restore */
        if (ret) {
                /* obtained address is out of range? */
-               if (((unsigned long)*dma_handle + size - 1) & ~mask) {
+               if (((unsigned long)*dma_handle + size - 1) & ~dma_mask) {
                        /* reallocate with the proper mask */
-                       pci_free_consistent(hwdev, size, ret, *dma_handle);
-                       ret = pci_alloc_consistent(hwdev, size, dma_handle);
+                       dma_free_coherent(dev, size, ret, *dma_handle);
+                       ret = dma_alloc_coherent(dev, size, dma_handle, GFP_KERNEL);
                }
        } else {
                /* wish to success now with the proper mask... */
-               if (mask != 0xffffffffUL)
-                       ret = pci_alloc_consistent(hwdev, size, dma_handle);
+               if (dma_mask != 0xffffffffUL)
+                       ret = dma_alloc_coherent(dev, size, dma_handle, GFP_KERNEL);
        }
        return ret;
 }
 
-/* redefine pci_alloc_consistent for some architectures */
-#undef pci_alloc_consistent
-#define pci_alloc_consistent snd_pci_hack_alloc_consistent
+/* redefine dma_alloc_coherent for some architectures */
+#undef dma_alloc_coherent
+#define dma_alloc_coherent snd_dma_hack_alloc_coherent
 
 #endif /* arch */
 #endif /* CONFIG_PCI */
@@ -667,17 +665,7 @@ void *snd_malloc_pci_pages(struct pci_de
                           size_t size,
                           dma_addr_t *dma_addr)
 {
-       int pg;
-       void *res;
-
-       snd_assert(size > 0, return NULL);
-       snd_assert(dma_addr != NULL, return NULL);
-       for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
-       res = pci_alloc_consistent(pci, PAGE_SIZE * (1 << pg), dma_addr);
-       if (res != NULL) {
-               mark_pages(res, pg);
-       }
-       return res;
+       return snd_malloc_dev_pages(pci ? &pci->dev : NULL, size, dma_addr);
 }
 
 /**
@@ -699,17 +687,8 @@ void *snd_malloc_pci_pages_fallback(stru
                                    dma_addr_t *dma_addr,
                                    size_t *res_size)
 {
-       void *res;
-
-       snd_assert(res_size != NULL, return NULL);
-       do {
-               if ((res = snd_malloc_pci_pages(pci, size, dma_addr)) != NULL) {
-                       *res_size = size;
-                       return res;
-               }
-               size >>= 1;
-       } while (size >= PAGE_SIZE);
-       return NULL;
+       return snd_malloc_dev_pages_fallback(pci ? &pci->dev : NULL, size,
+                                            dma_addr, res_size);
 }
 
 /**
@@ -726,24 +705,10 @@ void snd_free_pci_pages(struct pci_dev *
                        void *ptr,
                        dma_addr_t dma_addr)
 {
-       int pg;
-
-       if (ptr == NULL)
-               return;
-       for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
-       unmark_pages(ptr, pg);
-       pci_free_consistent(pci, PAGE_SIZE * (1 << pg), ptr, dma_addr);
+       snd_free_dev_pages(pci ? &pci->dev : NULL, size, ptr, dma_addr);
 }
 
 
-#if defined(__i386__)
-/*
- * on ix86, we allocate a page with GFP_KERNEL to assure the
- * allocation.  the code is almost same with kernel/i386/pci-dma.c but
- * it allocates only a single page and checks the validity of the
- * page address with the given pci dma mask.
- */
-
 /**
  * snd_malloc_pci_page - allocate a page in the valid pci dma mask
  * @pci: pci device pointer
@@ -757,45 +722,9 @@ void snd_free_pci_pages(struct pci_dev *
  */
 void *snd_malloc_pci_page(struct pci_dev *pci, dma_addr_t *addrp)
 {
-       void *ptr;
-       dma_addr_t addr;
-       unsigned long mask;
-
-       mask = pci ? (unsigned long)pci->consistent_dma_mask : 0x00ffffffUL;
-       ptr = (void *)__get_free_page(GFP_KERNEL);
-       if (ptr) {
-               addr = virt_to_phys(ptr);
-               if (((unsigned long)addr + PAGE_SIZE - 1) & ~mask) {
-                       /* try to reallocate with the GFP_DMA */
-                       free_page((unsigned long)ptr);
-                       /* use GFP_ATOMIC for the DMA zone to avoid stall */
-                       ptr = (void *)__get_free_page(GFP_ATOMIC | GFP_DMA);
-                       if (ptr) /* ok, the address must be within lower 16MB... */
-                               addr = virt_to_phys(ptr);
-                       else
-                               addr = 0;
-               }
-       } else
-               addr = 0;
-       if (ptr) {
-               memset(ptr, 0, PAGE_SIZE);
-               mark_pages(ptr, 0);
-       }
-       *addrp = addr;
-       return ptr;
-}
-#else
-
-/* on other architectures, call snd_malloc_pci_pages() helper function
- * which uses pci_alloc_consistent().
- */
-void *snd_malloc_pci_page(struct pci_dev *pci, dma_addr_t *addrp)
-{
        return snd_malloc_pci_pages(pci, PAGE_SIZE, addrp);
 }
 
-#endif
-
 #if 0 /* for kernel-doc */
 /**
  * snd_free_pci_page - release a page


-- 
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 PCMCIA      - http://pcmcia.arm.linux.org.uk/
                 2.6 Serial core


-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
_______________________________________________
Alsa-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-devel

Reply via email to