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--