Subject: Re: BUS-DMA functions
To: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: port-arm32
Date: 02/21/1999 10:32:41
On Sun, 21 Feb 1999 14:30:48 +0900 (JST) 
 Izumi Tsutsui <tsutsui@ceres.dti.ne.jp> wrote:

 > scsibus0 at pcscp0: 8 targets, 8 luns per target
 > probe(pcscp0:1:0): max sync rate 10.00Mb/s
 > sd0 at scsibus0 targ 1 lun 0: <, , > SCSI0 0/direct fixed
 > sd0: 1919MB, 3900 cyl, 16 head, 63 sec, 512 bytes/sect x 3931200 sectors

This is due to a bug in the arm32 bus_dma routines.  The Alpha had the
same problem at one point when I did the original bus_dma work.  Basically,
if you have KVAs which don't appear in the kernel pmap (such that
pmap_extract() will return an error), this can happen.  In this case,
it's probably the kernel text/data segments aren't mapped in the kernel
pmap.  (The inquiry buffer used by the SCSI code is a static buffer,
not on the stack or malloc'd.)

Please try the following patch:


Index: bus_dma.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm32/arm32/bus_dma.c,v
retrieving revision 1.11
diff -c -r1.11 bus_dma.c
*** bus_dma.c	1998/09/21 22:53:35	1.11
--- bus_dma.c	1999/02/21 18:27:08
***************
*** 641,658 ****
  	bus_addr_t curaddr, lastaddr, baddr, bmask;
  	vm_offset_t vaddr = (vm_offset_t)buf;
  	int seg;
- 	pmap_t pmap;
  
  #ifdef DEBUG_DMA
  	printf("_bus_dmamem_load_buffer(buf=%p, len=%lx, flags=%d, 1st=%d)\n",
  	    buf, buflen, flags, first);
  #endif	/* DEBUG_DMA */
  
- 	if (p != NULL)
- 		pmap = p->p_vmspace->vm_map.pmap;
- 	else
- 		pmap = pmap_kernel();
- 
  	lastaddr = *lastaddrp;
  	bmask  = ~(map->_dm_boundary - 1);
  
--- 641,652 ----
***************
*** 660,666 ****
  		/*
  		 * Get the physical address for this segment.
  		 */
! 		curaddr = pmap_extract(pmap, (vm_offset_t)vaddr);
  
  		/*
  		 * Make sure we're in an allowed DMA range.
--- 654,664 ----
  		/*
  		 * Get the physical address for this segment.
  		 */
! 		if (p != NULL)
! 			curaddr = pmap_extract(p->p_vmspace->vm_map.pmap,
! 			    vaddr);
! 		else
! 			curaddr = vtophys(vaddr);
  
  		/*
  		 * Make sure we're in an allowed DMA range.