[parisc-linux-cvs] Re: DIFF 2.4.20-pa10 sg_virt_addr() usage in ccio/pci-dma

Grant Grundler grundler@dsl2.external.hp.com
Tue, 3 Dec 2002 18:29:21 -0700


On Tue, Dec 03, 2002 at 06:05:24PM -0700, Grant Grundler wrote:
> Log message:
> 2.4.20-pa10 use sg_virt_addr() for B/C-XXX DMA support
> 
> o fix pci-dma.c, ccio drivers to not directly reference scatter_gather->address
> scsi midlayer highmem support will sometimes use page/offset instead.
> o changes in cpu_eiem are now visible immediately in the processing loop.

Ryan,
This is the basically the same diff I posted before for ccio driver.
Can you verify I didn't overlook/botch anything?
(my track record lately isn't so good...)

Verified this fixes the boot problems on 2.4.20 for B180.

My B180 still "freezes" for 15-30 seconds at a time during "normal"
use (ie editing a small text file with vi). heartbeat continues to
run - interrupts are still on but X11 output stops and mouse freezes.
Seems like process/user space gets CPU starved by the kernel.

And it looks like interrupt counts reported by vmstat are always zero.
Need to figure out which statistics aren't getting updated that should be.
/proc/interrupts output seems to be OK.

grant

Index: Makefile
===================================================================
RCS file: /var/cvs/linux/Makefile,v
retrieving revision 1.369
diff -u -p -r1.369 Makefile
--- Makefile	29 Nov 2002 02:20:58 -0000	1.369
+++ Makefile	4 Dec 2002 00:41:25 -0000
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 20
-EXTRAVERSION = -pa9
+EXTRAVERSION = -pa10
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
Index: arch/parisc/kernel/ccio-dma.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/ccio-dma.c,v
retrieving revision 1.56
diff -u -p -r1.56 ccio-dma.c
--- arch/parisc/kernel/ccio-dma.c	17 Nov 2002 20:44:11 -0000	1.56
+++ arch/parisc/kernel/ccio-dma.c	4 Dec 2002 00:41:27 -0000
@@ -805,7 +805,7 @@ ccio_fill_pdir(struct ioc *ioc, struct s
 
 		DBG_RUN_SG(" %d : %08lx/%05x %p/%05x\n", nents,
 			   (unsigned long)sg_dma_address(startsg), cnt,
-			   startsg->address, startsg->length
+			   sg_virt_addr(startsg), startsg->length
 		);
 
 		/*
@@ -825,7 +825,7 @@ ccio_fill_pdir(struct ioc *ioc, struct s
 		** Look for a VCONTIG chunk
 		*/
 		if (cnt) {
-			unsigned long vaddr = (unsigned long)startsg->address;
+			unsigned long vaddr = (unsigned long) sg_virt_addr(startsg);
 			ASSERT(pdirp);
 
 			/* Since multiple Vcontig blocks could make up
@@ -878,8 +878,8 @@ ccio_coalesce_chunks(struct ioc *ioc, st
 		*/
 		dma_sg = vcontig_sg = startsg;
 		dma_len = vcontig_len = vcontig_end = startsg->length;
-		vcontig_end += (unsigned long) startsg->address;
-		dma_offset = (unsigned long) startsg->address & ~IOVP_MASK;
+		vcontig_end += (unsigned long) sg_virt_addr(startsg);
+		dma_offset = (unsigned long) sg_virt_addr(startsg) & ~IOVP_MASK;
 
 		/* PARANOID: clear entries */
 		sg_dma_address(startsg) = 0;
@@ -893,7 +893,7 @@ ccio_coalesce_chunks(struct ioc *ioc, st
 			unsigned long startsg_end;
 
 			startsg++;
-			startsg_end = (unsigned long)startsg->address + 
+			startsg_end = (unsigned long) sg_virt_addr(startsg) + 
 				startsg->length;
 
 			/* PARANOID: clear entries */
@@ -912,7 +912,7 @@ ccio_coalesce_chunks(struct ioc *ioc, st
 			/*
 			** Append the next transaction?
 			*/
-			if(vcontig_end == (unsigned long) startsg->address) {
+			if(vcontig_end == (unsigned long) sg_virt_addr(startsg)) {
 				vcontig_len += startsg->length;
 				vcontig_end += startsg->length;
 				dma_len     += startsg->length;
@@ -981,7 +981,8 @@ ccio_map_sg(struct pci_dev *dev, struct 
 
 	/* Fast path single entry scatterlists. */
 	if(nents == 1) {
-		sg_dma_address(sglist)= ccio_map_single(dev, sglist->address,
+		sg_dma_address(sglist)= ccio_map_single(dev,
+							sg_virt_addr(sglist),
 							sglist->length, 
 							direction);
 		sg_dma_len(sglist)= sglist->length;
@@ -1043,7 +1044,7 @@ ccio_unmap_sg(struct pci_dev *dev, struc
 	ioc = GET_IOC(dev);
 
 	DBG_RUN_SG("%s() START %d entries,  %p,%x\n",
-		__FUNCTION__, nents, sglist->address, sglist->length);
+		__FUNCTION__, nents, sg_virt_address(sglist), sglist->length);
 
 #ifdef CONFIG_PROC_FS
 	ioc->usg_calls++;
Index: arch/parisc/kernel/ccio-rm-dma.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/ccio-rm-dma.c,v
retrieving revision 1.6
diff -u -p -r1.6 ccio-rm-dma.c
--- arch/parisc/kernel/ccio-rm-dma.c	17 Nov 2002 20:44:11 -0000	1.6
+++ arch/parisc/kernel/ccio-rm-dma.c	4 Dec 2002 00:41:27 -0000
@@ -118,7 +118,7 @@ static int ccio_map_sg(struct pci_dev *d
 
         /* KISS: map each buffer seperately. */
 	while (nents) {
-		sg_dma_address(sglist) = ccio_map_single(dev, sglist->address, sglist->length, direction);
+		sg_dma_address(sglist) = ccio_map_single(dev, sg_virt_addr(sglist), sglist->length, direction);
 		sg_dma_len(sglist) = sglist->length;
 		nents--;
 		sglist++;
Index: arch/parisc/kernel/irq.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/irq.c,v
retrieving revision 1.59
diff -u -p -r1.59 irq.c
--- arch/parisc/kernel/irq.c	23 Oct 2002 13:17:48 -0000	1.59
+++ arch/parisc/kernel/irq.c	4 Dec 2002 00:41:27 -0000
@@ -57,7 +57,7 @@ extern void ipi_interrupt(int, void *, s
 /* Bits in EIEM correlate with cpu_irq_action[].
 ** Numbered *Big Endian*! (ie bit 0 is MSB)
 */
-static unsigned long cpu_eiem = 0;
+static volatile unsigned long cpu_eiem = 0;
 
 static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;  /* protect IRQ regions */
 
@@ -462,7 +462,7 @@ void do_cpu_irq_mask(struct pt_regs *reg
 
 		for (irq = 0; eirr_val && bit; bit>>=1, irq++)
 		{
-			if (!(bit&eirr_val))
+			if (!(bit&eirr_val&cpu_eiem))
 				continue;
 
 			/* clear bit in mask - can exit loop sooner */
Index: arch/parisc/kernel/pci-dma.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/pci-dma.c,v
retrieving revision 1.23
diff -u -p -r1.23 pci-dma.c
--- arch/parisc/kernel/pci-dma.c	4 Feb 2002 19:29:43 -0000	1.23
+++ arch/parisc/kernel/pci-dma.c	4 Dec 2002 00:41:33 -0000
@@ -428,9 +428,9 @@ static int pa11_dma_map_sg(struct pci_de
 	    BUG();
 
 	for (i = 0; i < nents; i++, sglist++ ) {
-		sg_dma_address(sglist) = (dma_addr_t) virt_to_phys(sglist->address);
+		sg_dma_address(sglist) = (dma_addr_t) virt_to_phys(sg_virt_addr(sglist));
 		sg_dma_len(sglist) = sglist->length;
-		flush_kernel_dcache_range((unsigned long)sglist->address,
+		flush_kernel_dcache_range((unsigned long)sg_virt_addr(sglist),
 				sglist->length);
 	}
 	return nents;
@@ -449,7 +449,7 @@ static void pa11_dma_unmap_sg(struct pci
 	/* once we do combining we'll need to use phys_to_virt(sg_dma_address(sglist)) */
 
 	for (i = 0; i < nents; i++, sglist++ )
-		flush_kernel_dcache_range((unsigned long) sglist->address, sglist->length);
+		flush_kernel_dcache_range((unsigned long) sg_virt_addr(sglist), sglist->length);
 	return;
 }
 
@@ -468,7 +468,7 @@ static void pa11_dma_sync_sg(struct pci_
 	/* once we do combining we'll need to use phys_to_virt(sg_dma_address(sglist)) */
 
 	for (i = 0; i < nents; i++, sglist++ )
-		flush_kernel_dcache_range((unsigned long) sglist->address, sglist->length);
+		flush_kernel_dcache_range((unsigned long) sg_virt_addr(sglist), sglist->length);
 }
 
 struct pci_dma_ops pcxl_dma_ops = {