Messages in this thread Patch in this message | | | Date | Sun, 15 Jun 2003 18:31:38 +0200 | From | Stelian Pop <> | Subject | [PATCH 2.4.21] meye driver update |
| |
Hi,
Here is my latest meye driver version, ready to be integrated in the next -pre cycle.
The attached patch: * replaces the pci_alloc_consistent calls with dma_alloc_coherent because we want to do the allocations at GFP_KERNEL priority and not GFP_ATOMIC because we request quite a bit of memory and the allocation fails quite frequently.
It would be better to have a pci_alloc_consistent with an extra parameter (priority) but since we haven't, and the meye driver is supposed to work only on ix86 platforms we can safely do the change. Moreover, in 2.4 we don't even have a dma_alloc_coherent function, so the meye driver is carrying a local version, backported from 2.5.
* fixes the DMA engine stop request. The hard freezes encountered when using this driver and repeatedly opening/closing the device have been tracked down to this particular piece of code. The new version seems to work way better, I haven't had a single freeze since the change.
Marcelo, please apply.
Stelian.
===== drivers/media/video/meye.h 1.7 vs edited ===== --- 1.7/drivers/media/video/meye.h Fri Feb 21 11:24:07 2003 +++ edited/drivers/media/video/meye.h Tue Jun 10 11:18:50 2003 @@ -31,7 +31,7 @@ #define _MEYE_PRIV_H_ #define MEYE_DRIVER_MAJORVERSION 1 -#define MEYE_DRIVER_MINORVERSION 6 +#define MEYE_DRIVER_MINORVERSION 7 #include <linux/config.h> #include <linux/types.h> ===== drivers/media/video/meye.c 1.13 vs edited ===== --- 1.13/drivers/media/video/meye.c Tue Feb 18 12:31:10 2003 +++ edited/drivers/media/video/meye.c Thu Apr 17 10:23:00 2003 @@ -161,6 +161,34 @@ } } +/****************************************************************************/ +/* dma_alloc_coherent / dma_free_coherent ported from 2.5 */ +/****************************************************************************/ + +void *dma_alloc_coherent(struct pci_dev *dev, size_t size, + dma_addr_t *dma_handle, int gfp) +{ + void *ret; + /* ignore region specifiers */ + gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); + + if (dev == NULL || ((u32)dev->dma_mask < 0xffffffff)) + gfp |= GFP_DMA; + ret = (void *)__get_free_pages(gfp, get_order(size)); + + if (ret != NULL) { + memset(ret, 0, size); + *dma_handle = virt_to_phys(ret); + } + return ret; +} + +void dma_free_coherent(struct pci_dev *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + free_pages((unsigned long)vaddr, get_order(size)); +} + /* return a page table pointing to N pages of locked memory */ static int ptable_alloc(void) { u32 *pt; @@ -168,9 +196,10 @@ memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable)); - meye.mchip_ptable[MCHIP_NB_PAGES] = pci_alloc_consistent(meye.mchip_dev, - PAGE_SIZE, - &meye.mchip_dmahandle); + meye.mchip_ptable[MCHIP_NB_PAGES] = dma_alloc_coherent(meye.mchip_dev, + PAGE_SIZE, + &meye.mchip_dmahandle, + GFP_KERNEL); if (!meye.mchip_ptable[MCHIP_NB_PAGES]) { meye.mchip_dmahandle = 0; return -1; @@ -178,16 +207,17 @@ pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES]; for (i = 0; i < MCHIP_NB_PAGES; i++) { - meye.mchip_ptable[i] = pci_alloc_consistent(meye.mchip_dev, - PAGE_SIZE, - pt); + meye.mchip_ptable[i] = dma_alloc_coherent(meye.mchip_dev, + PAGE_SIZE, + pt, + GFP_KERNEL); if (!meye.mchip_ptable[i]) { int j; pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES]; for (j = 0; j < i; ++j) { - pci_free_consistent(meye.mchip_dev, - PAGE_SIZE, - meye.mchip_ptable[j], *pt); + dma_free_coherent(meye.mchip_dev, + PAGE_SIZE, + meye.mchip_ptable[j], *pt); pt++; } meye.mchip_dmahandle = 0; @@ -205,17 +235,17 @@ pt = (u32 *)meye.mchip_ptable[MCHIP_NB_PAGES]; for (i = 0; i < MCHIP_NB_PAGES; i++) { if (meye.mchip_ptable[i]) - pci_free_consistent(meye.mchip_dev, - PAGE_SIZE, - meye.mchip_ptable[i], *pt); + dma_free_coherent(meye.mchip_dev, + PAGE_SIZE, + meye.mchip_ptable[i], *pt); pt++; } if (meye.mchip_ptable[MCHIP_NB_PAGES]) - pci_free_consistent(meye.mchip_dev, - PAGE_SIZE, - meye.mchip_ptable[MCHIP_NB_PAGES], - meye.mchip_dmahandle); + dma_free_coherent(meye.mchip_dev, + PAGE_SIZE, + meye.mchip_ptable[MCHIP_NB_PAGES], + meye.mchip_dmahandle); memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable)); meye.mchip_dmahandle = 0; @@ -614,25 +644,25 @@ /* stop any existing HIC action and wait for any dma to complete then reset the dma engine */ static void mchip_hic_stop(void) { - int i = 0; + int i, j; meye.mchip_mode = MCHIP_HIC_MODE_NOOP; - if (!(mchip_read(MCHIP_HIC_STATUS) & MCHIP_HIC_STATUS_BUSY)) + if (!(mchip_read(MCHIP_HIC_STATUS) & MCHIP_HIC_STATUS_BUSY)) return; - mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP); - mchip_delay(MCHIP_HIC_CMD, 0); - while (!mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE)) { - /* resetting HIC */ + for (i = 0; i < 20; ++i) { mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP); mchip_delay(MCHIP_HIC_CMD, 0); + for (j = 0; j < 100; ++j) { + if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE)) + return; + wait_ms(1); + } + printk(KERN_ERR "meye: need to reset HIC!\n"); + mchip_set(MCHIP_HIC_CTL, MCHIP_HIC_CTL_SOFT_RESET); wait_ms(250); - if (i++ > 20) { - printk(KERN_ERR "meye: resetting HIC hanged!\n"); - break; - } } - wait_ms(100); + printk(KERN_ERR "meye: resetting HIC hanged!\n"); } /****************************************************************************/ @@ -1392,6 +1422,8 @@ mchip_hic_stop(); + mchip_dma_free(); + /* disable interrupts */ mchip_set(MCHIP_MM_INTA, 0x0); @@ -1403,8 +1435,6 @@ pci_resource_len(meye.mchip_dev, 0)); pci_disable_device(meye.mchip_dev); - - mchip_dma_free(); if (meye.grab_fbuffer) rvfree(meye.grab_fbuffer, gbuffers*gbufsize);
-- Stelian Pop <stelian@popies.net> - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |