Fwd: Re: [cpia] USB anyone?
sbertin@mindspring.com
sbertin@mindspring.com
Sun, 16 Jan 2000 11:07:11 -0500 (EST)
--1037094400-846930886-948038866=:728
Content-Type: TEXT/plain; charset=us-ascii
On 16 Jan, Peter Pregler wrote:
> What is a problem is hot-plug. The API was desinged based on
> features available for PPC-cameras. If need be just try to extend the
> API.
cpia.c was designed to support hot-plug. That is what the
cpia_register_camera and cpia_unregister_camera functions are for. I
assume USB provides some way to determine when a device is
added/removed. There isn't a good way to do that with the parallel
port, so hot plugging there isn't implemented.
Since this is becoming such a hot topic, I've attached a patch to allow
cpia.c to compile on 2.3 kernels. This has not been well tested, so use
it at your own risk.
Scott J. Bertin
sbertin@mindspring.com
--1037094400-846930886-948038866=:728
Content-Type: TEXT/plain; CHARSET=US-ASCII
Content-Description: 2.3-cpia.patch
diff -r -c --exclude=linux cpia-0.5.0/module/cpia.c work/module/cpia.c
*** cpia-0.5.0/module/cpia.c Wed Jan 12 16:04:26 2000
--- work/module/cpia.c Sun Jan 16 00:36:52 2000
***************
*** 34,39 ****
--- 34,40 ----
#include <linux/proc_fs.h>
#include <linux/ctype.h>
#include <linux/videodev.h>
+ #include <linux/pagemap.h>
#include <asm/io.h>
#include <asm/semaphore.h>
#include <linux/wrapper.h>
***************
*** 344,349 ****
--- 345,351 ----
/* forward declaration of local function */
static void reset_camera_struct(struct cam_data *cam);
+ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
/**********************************************************************
*
* Memory management
***************
*** 374,426 ****
return 0;
}
! static inline unsigned long kvirt_to_phys(unsigned long adr)
{
return uvirt_to_phys(VMALLOC_VMADDR(adr));
}
! static void * rvmalloc(unsigned long size)
{
! void * mem;
unsigned long adr, page;
size += (PAGE_SIZE - 1);
size &= ~(PAGE_SIZE - 1);
! mem=vmalloc(size);
! if (mem) {
! /* Clear the ram out, no junk to the user */
! memset(mem, 0, size);
! adr=(unsigned long) mem;
! while (size > 0) {
! page = kvirt_to_phys(adr);
! mem_map_reserve(MAP_NR(phys_to_virt(page)));
! adr+=PAGE_SIZE;
! if (size > PAGE_SIZE) size-=PAGE_SIZE;
! else size=0;
! }
}
return mem;
}
! static void rvfree(void * mem, unsigned long size)
{
unsigned long adr, page;
!
size += (PAGE_SIZE - 1);
size &= ~(PAGE_SIZE - 1);
! if (mem) {
! adr=(unsigned long) mem;
! while (size > 0) {
! page = kvirt_to_phys(adr);
! mem_map_unreserve(MAP_NR(phys_to_virt(page)));
! adr+=PAGE_SIZE;
! if (size > PAGE_SIZE) size-=PAGE_SIZE;
! else size=0;
! }
! vfree(mem);
}
}
/**********************************************************************
--- 376,490 ----
return 0;
}
! static inline unsigned long kvirt_to_pa(unsigned long adr)
{
return uvirt_to_phys(VMALLOC_VMADDR(adr));
}
! #else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)) */
!
! /**********************************************************************
! *
! * Memory management
! *
! * This is a shameless copy from the USB-cpia driver (linux kernel
! * version 2.3.29 or so, I have no idea what this code actually does ;).
! * Actually it seems to be a copy of a shameless copy of the bttv-driver.
! * Or that is a copy of a shameless copy of ... (To the powers: is there
! * no generic kernel-function to do this sort of stuff?)
! *
! **********************************************************************/
!
! /* Given PGD from the address space's page table, return the kernel
! * virtual mapping of the physical memory mapped at ADR.
! */
! static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
{
! unsigned long ret = 0UL;
! pmd_t *pmd;
! pte_t *ptep, pte;
!
! if (!pgd_none(*pgd)) {
! pmd = pmd_offset(pgd, adr);
! if (!pmd_none(*pmd)) {
! ptep = pte_offset(pmd, adr);
! pte = *ptep;
! if (pte_present(pte))
! ret = page_address(pte_page(pte)) |
! (adr & (PAGE_SIZE-1));
! }
! }
! return ret;
! }
!
! /* Here we want the physical address of the memory.
! * This is used when initializing the contents of the
! * area and marking the pages as reserved.
! */
! static inline unsigned long kvirt_to_pa(unsigned long adr)
! {
! unsigned long va, kva, ret;
!
! va = VMALLOC_VMADDR(adr);
! kva = uvirt_to_kva(pgd_offset_k(va), va);
! ret = __pa(kva);
! return ret;
! }
! #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)) */
!
! static void *rvmalloc(unsigned long size)
! {
! void *mem;
unsigned long adr, page;
+ /* Round it off to PAGE_SIZE */
size += (PAGE_SIZE - 1);
size &= ~(PAGE_SIZE - 1);
! mem = vmalloc(size);
! if (!mem)
! return NULL;
!
! memset(mem, 0, size); /* Clear the ram out, no junk to the user */
! adr = (unsigned long) mem;
! while (size > 0) {
! page = kvirt_to_pa(adr);
! #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
! mem_map_reserve(MAP_NR(phys_to_virt(page)));
! #else
! mem_map_reserve(MAP_NR(__va(page)));
! #endif
! adr += PAGE_SIZE;
! if (size > PAGE_SIZE)
! size -= PAGE_SIZE;
! else
! size = 0;
}
+
return mem;
}
! static void rvfree(void *mem, unsigned long size)
{
unsigned long adr, page;
!
! if (!mem)
! return;
!
size += (PAGE_SIZE - 1);
size &= ~(PAGE_SIZE - 1);
! adr=(unsigned long) mem;
! while (size > 0) {
! page = kvirt_to_pa(adr);
! mem_map_unreserve(MAP_NR(__va(page)));
! adr += PAGE_SIZE;
! if (size > PAGE_SIZE)
! size -= PAGE_SIZE;
! else
! size = 0;
}
+ vfree(mem);
}
***************
*** 3108,3114 ****
}
pos = (unsigned long)(cam->frame_buf);
while (size > 0) {
! page = kvirt_to_phys(pos);
if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
up(&cam->busy_lock);
return -EAGAIN;
--- 3187,3193 ----
}
pos = (unsigned long)(cam->frame_buf);
while (size > 0) {
! page = kvirt_to_pa(pos);
if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
up(&cam->busy_lock);
return -EAGAIN;
--1037094400-846930886-948038866=:728--