[kernel] r8062 - in dists/sid/linux-2.6/debian: . patches patches/series

Christian T. Steigies cts at alioth.debian.org
Sun Dec 31 16:31:00 UTC 2006


Author: cts
Date: Sun Dec 31 17:30:59 2006
New Revision: 8062

Added:
   dists/sid/linux-2.6/debian/patches/m68k-atari-scsi2.patch
   dists/sid/linux-2.6/debian/patches/m68k-mac-cuda.patch
   dists/sid/linux-2.6/debian/patches/m68k-mac-mace.patch
Modified:
   dists/sid/linux-2.6/debian/changelog
   dists/sid/linux-2.6/debian/patches/series/9-extra
Log:
atari scsi driver fixes by Michael and mac mace and cuda fixes by Finn


Modified: dists/sid/linux-2.6/debian/changelog
==============================================================================
--- dists/sid/linux-2.6/debian/changelog	(original)
+++ dists/sid/linux-2.6/debian/changelog	Sun Dec 31 17:30:59 2006
@@ -49,6 +49,8 @@
   [ Christian T. Steigies ]
   * m68k/atari: enable keyboard, mouse and fb drivers
   * m68k/atari: fixes for ethernec and video driver by Michael Schmitz
+  * m68k/atari: fixes for scsi driver by Michael Schmitz
+  * m68k/mac: fixes for mace and cuda driver by Finn Thain
 
   [ maximilian attems ]
   * Add stable release 2.6.18.6:
@@ -110,7 +112,7 @@
     - r8169: more magic during initialization of the hardware
     - r8169: perform a PHY reset before any other operation at boot time
     - r8169: Fix iteration variable sign
-    - r8169: remove extraneous Cmd{Tx/Rx}Enb write 
+    - r8169: remove extraneous Cmd{Tx/Rx}Enb write
 
   [ Jurij Smakov ]
   * Add bugfix/sparc/isa-dev-no-reg.patch to make sure that
@@ -122,7 +124,7 @@
     memory accesses in ehci-hub-control() by adding an alignment attribute
     to the tbuf array declaration. Thanks to David Miller for the patch.
 
- -- maximilian attems <maks at sternwelten.at>  Sun, 31 Dec 2006 17:07:53 +0100
+ -- Christian T. Steigies <cts at debian.org>  Sun, 31 Dec 2006 17:29:17 +0100
 
 linux-2.6 (2.6.18-8) unstable; urgency=low
 

Added: dists/sid/linux-2.6/debian/patches/m68k-atari-scsi2.patch
==============================================================================
--- (empty file)
+++ dists/sid/linux-2.6/debian/patches/m68k-atari-scsi2.patch	Sun Dec 31 17:30:59 2006
@@ -0,0 +1,349 @@
+I've looked at the SCSI situation in more detail, and updated the Atari
+SCSI code to cope with the changes in 2.6 (scsi_error expect different
+return codes; queuecmnd called from softirq and cannot sleep). I get no
+more lockups, but writing to a ZIP drive corrupts data on the drive. May
+just be a broken ZIP drive, who knows. I need to try with a real SCSI
+disk...
+
+Christian, please apply this on top of my other 2.6.18 patch.
+
+
+diff -u source-m68k-none/drivers/scsi/atari_scsi.c source-m68k-msch/drivers/scsi/atari_scsi.c
+--- source-m68k-none/drivers/scsi/atari_scsi.c	2006-12-31 14:06:09.000000000 +0100
++++ source-m68k-msch/drivers/scsi/atari_scsi.c	2006-12-31 16:29:46.000000000 +0100
+@@ -67,12 +67,40 @@
+ 
+ #include <linux/module.h>
+ 
+-#define NDEBUG (0)
++#define NDEBUG_ARBITRATION     0x1
++#define NDEBUG_AUTOSENSE       0x2
++#define NDEBUG_DMA             0x4
++#define NDEBUG_HANDSHAKE       0x8
++#define NDEBUG_INFORMATION     0x10
++#define NDEBUG_INIT            0x20
++#define NDEBUG_INTR            0x40
++#define NDEBUG_LINKED          0x80
++#define NDEBUG_MAIN            0x100
++#define NDEBUG_NO_DATAOUT      0x200
++#define NDEBUG_NO_WRITE                0x400
++#define NDEBUG_PIO             0x800
++#define NDEBUG_PSEUDO_DMA      0x1000
++#define NDEBUG_QUEUES          0x2000
++#define NDEBUG_RESELECTION     0x4000
++#define NDEBUG_SELECTION       0x8000
++#define NDEBUG_USLEEP          0x10000
++#define NDEBUG_LAST_BYTE_SENT  0x20000
++#define NDEBUG_RESTART_SELECT  0x40000
++#define NDEBUG_EXTENDED                0x80000
++#define NDEBUG_C400_PREAD      0x100000
++#define NDEBUG_C400_PWRITE     0x200000
++#define NDEBUG_LISTS           0x400000
+ 
+ #define NDEBUG_ABORT	0x800000
+ #define NDEBUG_TAGS	0x1000000
+ #define NDEBUG_MERGING	0x2000000
+ 
++#define NDEBUG_ANY             0xFFFFFFFFUL
++
++#define NDEBUG (0)
++//#define NDEBUG (NDEBUG_MAIN)
++
++
+ #define AUTOSENSE
+ /* For the Atari version, use only polled IO or REAL_DMA */
+ #define	REAL_DMA
+@@ -506,6 +534,15 @@
+  * again (but others waiting longer more probably will win).
+  */
+ 
++/* MSch 20061228: in 2.6, the fairness wait appears to open a race with
++* the IDE driver's use of the lock, resulting in scheduling_in_interrupt
++* level BUG() messages.
++* The low level queuecmd function now appears to be called from soft
++* interrupt context (block queue task??) and cannot sleep on the lock
++* anymore once IDE has stolen the lock.
++* Can we return 'please retry later' to the block queue task or mid level??
++* MSch 20061229: the race persists regardless ... leave it off for now.
++*/
+ static void
+ falcon_release_lock_if_possible( struct NCR5380_hostdata * hostdata )
+ {
+@@ -529,7 +566,9 @@
+ 		}
+ 		falcon_got_lock = 0;
+ 		stdma_release();
++#if defined(FALCON_FAIRNESS_WAIT)
+ 		wake_up( &falcon_fairness_wait );
++#endif
+ 	}
+ 
+ 	local_irq_restore(flags);
+@@ -550,20 +589,38 @@
+  * Complicated, complicated.... Sigh...
+  */
+ 
+-static void falcon_get_lock( void )
++/* MSch 20061229: atari_queue_command gets called from softirq context quite
++ * heavily in the 2.6 kernel series. Since atari_queue_command might need to
++ * sleep in order to grab the ST-DMA lock, I have modified falcon_get_lock to
++ * immediately return with error status if called in softirq context with the
++ * lock not currently held by the SCSI driver, and the ST-DMA locked by some
++ * other driver. atari_queue_command then returns SCSI_MLQUEUE_HOST_BUSY and
++ * prevents further commands from issueing.
++ */
++
++static int falcon_get_lock( void )
+ {
+ 	unsigned long flags;
+ 
+-	if (IS_A_TT()) return;
++	if (IS_A_TT()) return 0;
+ 
+ 	local_irq_save(flags);
+ 
++#if defined (FALCON_FAIRNESS_WAIT)
+ 	while( !in_interrupt() && falcon_got_lock && stdma_others_waiting() )
+ 		sleep_on( &falcon_fairness_wait );
++#endif
+ 
+ 	while (!falcon_got_lock) {
+-		if (in_interrupt())
++		if (in_irq())
+ 			panic( "Falcon SCSI hasn't ST-DMA lock in interrupt" );
++               /* we may not sleep in soft interrupts neither, so bail out */
++               if (in_softirq() && stdma_islocked()) {
++                       printk(KERN_INFO "Falcon SCSI does not hold ST-DMA lock in softirq!\n" );
++                       local_irq_restore(flags);
++                       return 1;
++               }
++
+ 		if (!falcon_trying_lock) {
+ 			falcon_trying_lock = 1;
+ 			stdma_lock(scsi_falcon_intr, NULL);
+@@ -579,6 +636,8 @@
+ 	local_irq_restore(flags);
+ 	if (!falcon_got_lock)
+ 		panic("Falcon SCSI: someone stole the lock :-(\n");
++
++	return 0;
+ }
+ 
+ 
+@@ -826,6 +885,8 @@
+ 	struct NCR5380_hostdata *hostdata =
+ 		(struct NCR5380_hostdata *)cmd->device->host->hostdata;
+ 
++	printk( "scsi%d: resetting the SCSI bus!\n", (cmd)->device->host->host_no);
++	
+ 	/* For doing the reset, SCSI interrupts must be disabled first,
+ 	 * since the 5380 raises its IRQ line while _RST is active and we
+ 	 * can't disable interrupts completely, since we need the timer.
+@@ -855,8 +916,10 @@
+ 	else {
+ 		atari_turnon_irq( IRQ_MFP_FSCSI );
+ 	}
+-	if ((rv & SCSI_RESET_ACTION) == SCSI_RESET_SUCCESS)
++	if (rv == SUCCESS) {
+ 		falcon_release_lock_if_possible(hostdata);
++	}
++	printk( "scsi%d: bus reset done!\n", (cmd)->device->host->host_no);
+ 
+ 	return( rv );
+ }
+
+diff -u source-m68k-none/drivers/scsi/atari_NCR5380.c source-m68k-msch/drivers/scsi/atari_NCR5380.c
+--- source-m68k-none/drivers/scsi/atari_NCR5380.c	2006-12-31 14:06:09.000000000 +0100
++++ source-m68k-msch/drivers/scsi/atari_NCR5380.c	2006-12-31 16:39:34.000000000 +0100
+@@ -474,7 +474,8 @@
+ 	 virt_to_phys(page_address(cmd->SCp.buffer[1].page)+
+ 		      cmd->SCp.buffer[1].offset) == endaddr; ) {
+ 	MER_PRINTK("VTOP(%p) == %08lx -> merging\n",
+-		   cmd->SCp.buffer[1].address, endaddr);
++		   page_address(cmd->SCp.buffer[1].page)+cmd->SCp.buffer[1].offset,
++		   endaddr);
+ #if (NDEBUG & NDEBUG_MERGING)
+ 	++cnt;
+ #endif
+@@ -947,17 +948,6 @@
+ #endif
+ 
+     /* 
+-     * We use the host_scribble field as a pointer to the next command  
+-     * in a queue 
+-     */
+-
+-    NEXT(cmd) = NULL;
+-    cmd->scsi_done = done;
+-
+-    cmd->result = 0;
+-
+-
+-    /* 
+      * Insert the cmd into the issue queue. Note that REQUEST SENSE 
+      * commands are added to the head of the queue since any command will
+      * clear the contingent allegiance condition that exists and the 
+@@ -978,10 +968,32 @@
+      * alter queues and touch the lock.
+      */
+     if (!IS_A_TT()) {
++      int rv;
++      /* MSch: since we get called from softirq context here, and cannot
++       * sleep safely, the return status of falcon_get_lock is now used to
++       * figure out if we could successfully lock, or need to bail out.
++       * Signal the midlevel we're unable to queue the command in this case.
++       */
++
+ 	oldto = update_timeout(cmd, 0);
+-	falcon_get_lock();
+-	update_timeout(cmd, oldto);
++	rv = falcon_get_lock();
++	atari_scsi_update_timeout(cmd, oldto);
++	if (rv) {
++	  local_irq_restore(flags);
++	  return SCSI_MLQUEUE_HOST_BUSY;
++	}
+     }
++
++    /*
++     * We use the host_scribble field as a pointer to the next command
++     * in a queue
++     */
++
++    NEXT(cmd) = NULL;
++    cmd->scsi_done = done;
++
++    cmd->result = 0;
++
+     if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
+ 	LIST(cmd, hostdata->issue_queue);
+ 	NEXT(cmd) = hostdata->issue_queue;
+@@ -1005,10 +1017,13 @@
+      * If we're not in an interrupt, we can call NCR5380_main()
+      * unconditionally, because it cannot be already running.
+      */
+-    if (in_interrupt() || ((flags >> 8) & 7) >= 6)
++
++    /* MSch: in 2.6.19, we need to unconditionally use the task queue
++     * instead of directly starting main. Yet another side effect of
++     * the softirq business, I bet. */
++
+ 	queue_main();
+-    else
+-	NCR5380_main(NULL);
++
+     return 0;
+ }
+ 
+@@ -2630,7 +2645,7 @@
+  * 	host byte of the result field to, if zero DID_ABORTED is 
+  *	used.
+  *
+- * Returns : 0 - success, -1 on failure.
++ * Returns : SUCCESS - success, FAILED on failure.
+  *
+  * XXX - there is no way to abort the command that is currently 
+  * 	 connected, you have to wait for it to complete.  If this is 
+@@ -2700,11 +2715,12 @@
+ 	  local_irq_restore(flags);
+ 	  cmd->scsi_done(cmd);
+ 	  falcon_release_lock_if_possible( hostdata );
+-	  return SCSI_ABORT_SUCCESS;
++	  return SUCCESS;
+ 	} else {
++	  /* Why is this not restoring IRQs?? */
+ /*	  local_irq_restore(flags); */
+ 	  printk("scsi%d: abort of connected command failed!\n", HOSTNO);
+-	  return SCSI_ABORT_ERROR;
++	  return FAILED;
+ 	} 
+    }
+ #endif
+@@ -2728,7 +2744,7 @@
+ 	     * yet... */
+ 	    tmp->scsi_done(tmp);
+ 	    falcon_release_lock_if_possible( hostdata );
+-	    return SCSI_ABORT_SUCCESS;
++	    return SUCCESS;
+ 	}
+ 
+ /* 
+@@ -2745,7 +2761,7 @@
+     if (hostdata->connected) {
+ 	local_irq_restore(flags);
+ 	ABRT_PRINTK("scsi%d: abort failed, command connected.\n", HOSTNO);
+-        return SCSI_ABORT_SNOOZE;
++        return FAILED;
+     }
+ 
+ /*
+@@ -2807,7 +2823,7 @@
+ 		    local_irq_restore(flags);
+ 		    tmp->scsi_done(tmp);
+ 		    falcon_release_lock_if_possible( hostdata );
+-		    return SCSI_ABORT_SUCCESS;
++		    return SUCCESS;
+ 		}
+ 	}
+ 
+@@ -2831,7 +2847,7 @@
+  */
+     falcon_release_lock_if_possible( hostdata );
+ 
+-    return SCSI_ABORT_NOT_RUNNING;
++    return SUCCESS;
+ }
+ 
+ 
+@@ -2840,7 +2856,7 @@
+  * 
+  * Purpose : reset the SCSI bus.
+  *
+- * Returns : SCSI_RESET_WAKEUP
++ * Returns : SUCCESS
+  *
+  */ 
+ 
+@@ -2905,15 +2921,15 @@
+      */
+ 
+     if ((cmd = connected)) {
+-	ABRT_PRINTK("scsi%d: reset aborted a connected command\n", H_NO(cmd));
+-	cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16);
+-	cmd->scsi_done( cmd );
++        ABRT_PRINTK("scsi%d: reset aborted a connected command, calling scsi_done() ...\n", H_NO(cmd));
++        cmd->result = (DID_RESET << 16);
++        cmd->scsi_done( cmd );
+     }
+ 
+     for (i = 0; (cmd = disconnected_queue); ++i) {
+ 	disconnected_queue = NEXT(cmd);
+ 	NEXT(cmd) = NULL;
+-	cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16);
++	cmd->result = (DID_RESET << 16);
+ 	cmd->scsi_done( cmd );
+     }
+     if (i > 0)
+@@ -2930,7 +2946,7 @@
+      * the midlevel code that the reset was SUCCESSFUL, and there is no 
+      * need to 'wake up' the commands by a request_sense
+      */
+-    return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
++    return SUCCESS;
+ #else /* 1 */
+ 
+     /* MSch: new-style reset handling: let the mid-level do what it can */
+@@ -2978,7 +2994,9 @@
+     local_irq_restore(flags);
+ 
+     /* we did no complete reset of all commands, so a wakeup is required */
+-    return SCSI_RESET_WAKEUP | SCSI_RESET_BUS_RESET;
++    /* The new error handler code implicitly does this for us anyway */
++    return SUCCESS;
++
+ #endif /* 1 */
+ }
+ 
+Signed-Off-By: schmitz at debian.org
+
+        Michael

Added: dists/sid/linux-2.6/debian/patches/m68k-mac-cuda.patch
==============================================================================
--- (empty file)
+++ dists/sid/linux-2.6/debian/patches/m68k-mac-cuda.patch	Sun Dec 31 17:30:59 2006
@@ -0,0 +1,87 @@
+
+Fix the flakiness in the CUDA ADB driver (keypresses getting wedged down 
+or ADB just going AWOL altogether). Stops lost VIA1 interrupts.
+
+Tested on Quadra 840av & 660av, LC630 and LC475. (This does not address 
+the problems with the other m68k Mac ADB drivers.)
+
+Signed-off-by: Finn Thain <fthain at telegraphics.com.au>
+ 
+ arch/m68k/mac/via.c          |    2 +-
+ drivers/macintosh/via-cuda.c |   26 +++++++++++++++++++++-----
+ 2 files changed, 22 insertions(+), 6 deletions(-)
+
+Index: linux-2.6.18/drivers/macintosh/via-cuda.c
+===================================================================
+--- linux-2.6.18.orig/drivers/macintosh/via-cuda.c	2006-12-26 13:48:02.000000000 +1100
++++ linux-2.6.18/drivers/macintosh/via-cuda.c	2006-12-26 14:11:43.000000000 +1100
+@@ -429,16 +429,19 @@ cuda_start(void)
+ void
+ cuda_poll(void)
+ {
+-    unsigned long flags;
+-
+     /* cuda_interrupt only takes a normal lock, we disable
+      * interrupts here to avoid re-entering and thus deadlocking.
+-     * An option would be to disable only the IRQ source with
+-     * disable_irq(), would that work on m68k ? --BenH
+      */
++#ifdef CONFIG_MAC
++    disable_irq(IRQ_MAC_ADB);
++    cuda_interrupt(0, NULL, NULL);
++    enable_irq(IRQ_MAC_ADB);
++#else
++    unsigned long flags;
+     local_irq_save(flags);
+     cuda_interrupt(0, NULL, NULL);
+     local_irq_restore(flags);
++#endif
+ }
+ 
+ static irqreturn_t
+@@ -453,13 +456,26 @@ cuda_interrupt(int irq, void *arg, struc
+     
+     spin_lock(&cuda_lock);
+ 
++#ifdef CONFIG_MAC
++    /* only do this when polling */
++    if (!arg) {
++        virq = in_8(&via[IFR]) & 0x7f;
++        if ((virq & SR_INT) == 0) {
++            spin_unlock(&cuda_lock);
++            return IRQ_NONE;
++        }
++        out_8(&via[IFR], SR_INT);
++    }
++#else
++    /* it would appear that powermacs don't use the other VIA interrupts */
+     virq = in_8(&via[IFR]) & 0x7f;
+     out_8(&via[IFR], virq);   
+     if ((virq & SR_INT) == 0) {
+         spin_unlock(&cuda_lock);
+ 	return IRQ_NONE;
+     }
+-    
++#endif
++
+     status = (~in_8(&via[B]) & (TIP|TREQ)) | (in_8(&via[ACR]) & SR_OUT);
+     /* printk("cuda_interrupt: state=%d status=%x\n", cuda_state, status); */
+     switch (cuda_state) {
+Index: linux-2.6.18/arch/m68k/mac/via.c
+===================================================================
+--- linux-2.6.18.orig/arch/m68k/mac/via.c	2006-12-26 13:48:02.000000000 +1100
++++ linux-2.6.18/arch/m68k/mac/via.c	2006-12-26 14:11:43.000000000 +1100
+@@ -431,8 +431,8 @@ irqreturn_t via1_irq(int irq, void *dev_
+ 	for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1)
+ 		if (events & irq_bit) {
+ 			via1[vIER] = irq_bit;
+-			m68k_handle_int(VIA1_SOURCE_BASE + i, regs);
+ 			via1[vIFR] = irq_bit;
++			m68k_handle_int(VIA1_SOURCE_BASE + i, regs);
+ 			via1[vIER] = irq_bit | 0x80;
+ 		}
+ 
+-
+To unsubscribe from this list: send the line "unsubscribe linux-m68k" in
+the body of a message to majordomo at vger.kernel.org
+More majordomo info at  http://vger.kernel.org/majordomo-info.html

Added: dists/sid/linux-2.6/debian/patches/m68k-mac-mace.patch
==============================================================================
--- (empty file)
+++ dists/sid/linux-2.6/debian/patches/m68k-mac-mace.patch	Sun Dec 31 17:30:59 2006
@@ -0,0 +1,649 @@
+Fix a race condition in the transmit code, where the dma interrupt could
+update the free tx buffer count concurrently and wedge the tx queue.
+
+Fix the misuse of the rx frame status and rx frame length registers: no
+more "fifo overrun" errors caused by the OFLOW bit being tested in the
+frame length register, and no more missed packets due to incorrect length
+taken from status register.
+
+Fix a panic (skb_over_panic BUG) caused by allocating and then copying an
+incoming packet while the packet length register was changing.
+
+Cut-and-paste reset code from the powermac mace driver (mace.c), so the
+NIC functions when MacOS does not initialise it (important for anyone
+wanting to use the Emile boot loader).
+
+Cut-and-paste error counting and timeout recovery code from the powermac
+mace driver (mace.c).
+
+Fix a race condition in the PSC interrupt dispatch code where the
+interrupt flag was cleared after the handler ran (same bug that was fixed
+recently in the VIA2 interrupt dispatcher).
+
+Since I've run out of ways to make it fail, and since it performs well
+now, promote the driver from EXPERIMENTAL status. Tested on both quadra
+840av and 660av.
+
+Signed-off-by: Finn Thain <fthain at telegraphics.com.au>
+
+--- source-m68k-none/arch/m68k/mac/psc.c	2006-09-20 05:42:06.000000000 +0200
++++ source-m68k-finn/arch/m68k/mac/psc.c	2006-12-31 16:48:50.000000000 +0100
+@@ -149,8 +149,8 @@
+ 	for (i = 0, irq_bit = 1 ; i < 4 ; i++, irq_bit <<= 1) {
+ 	        if (events & irq_bit) {
+ 			psc_write_byte(pIER, irq_bit);
+-			m68k_handle_int(base_irq + i, regs);
+ 			psc_write_byte(pIFR, irq_bit);
++			m68k_handle_int(base_irq + i, regs);
+ 			psc_write_byte(pIER, irq_bit | 0x80);
+ 		}
+ 	}
+--- source-m68k-none/drivers/net/Kconfig	2006-12-31 16:45:54.000000000 +0100
++++ source-m68k-finn/drivers/net/Kconfig	2006-12-31 16:49:28.000000000 +0100
+@@ -335,8 +335,8 @@
+ 	  be called macsonic.
+ 
+ config MACMACE
+-	bool "Macintosh (AV) onboard MACE ethernet (EXPERIMENTAL)"
+-	depends on NET_ETHERNET && MAC && EXPERIMENTAL
++	bool "Macintosh (AV) onboard MACE ethernet"
++       	depends on NET_ETHERNET && MAC
+ 	select CRC32
+ 	help
+ 	  Support for the onboard AMD 79C940 MACE Ethernet controller used in
+--- source-m68k-none/drivers/net/macmace.c	2006-12-31 16:45:54.000000000 +0100
++++ source-m68k-finn/drivers/net/macmace.c	2006-12-31 17:12:38.000000000 +0100
+@@ -36,6 +36,9 @@
+ #define N_RX_PAGES	((N_RX_RING * 0x0800 + PAGE_SIZE - 1) / PAGE_SIZE)
+ #define TX_TIMEOUT	HZ
+ 
++/* Chip rev needs workaround on HW & multicast addr change */
++#define BROKEN_ADDRCHG_REV     0x0941
++
+ /* Bits in transmit DMA status */
+ #define TX_DMA_ERR	0x80
+ 
+@@ -54,15 +57,20 @@
+ 	struct net_device_stats stats;
+ 	int rx_slot, rx_tail;
+ 	int tx_slot, tx_sloti, tx_count;
++        int chipid;
+ };
+ 
+ struct mace_frame {
+-	u16	len;
+-	u16	status;
+-	u16	rntpc;
+-	u16	rcvcc;
+-	u32	pad1;
+-	u32	pad2;
++        u8      rcvcnt;
++        u8      pad1;
++        u8      rcvsts;
++        u8      pad2;
++        u8      rntpc;
++        u8      pad3;
++        u8      rcvcc;
++        u8      pad4;
++        u32     pad5;
++        u32     pad6;
+ 	u8	data[1];	
+ 	/* And frame continues.. */
+ };
+@@ -77,9 +85,11 @@
+ static struct net_device_stats *mace_stats(struct net_device *dev);
+ static void mace_set_multicast(struct net_device *dev);
+ static int mace_set_address(struct net_device *dev, void *addr);
++static void mace_reset(struct net_device *dev);
+ static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+ static irqreturn_t mace_dma_intr(int irq, void *dev_id, struct pt_regs *regs);
+ static void mace_tx_timeout(struct net_device *dev);
++static void __mace_set_address(struct net_device *dev, void *addr);
+ 
+ /* Bit-reverse one byte of an ethernet hardware address. */
+ 
+@@ -209,6 +219,8 @@
+ 	dev->irq = IRQ_MAC_MACE;
+ 	mp->dma_intr = IRQ_MAC_MACE_DMA;
+ 
++	mp->chipid = mp->mace->chipid_hi << 8 | mp->mace->chipid_lo;
++	
+ 	/*
+ 	 * The PROM contains 8 bytes which total 0xFF when XOR'd
+ 	 * together. Due to the usual peculiar apple brain damage
+@@ -256,15 +268,92 @@
+ }
+ 
+ /*
++ * Reset the chip.
++ */
++
++static void mace_reset(struct net_device *dev)
++{
++  struct mace_data *mp = (struct mace_data *) dev->priv;
++  volatile struct mace *mb = mp->mace;
++  int i;
++  
++  /* soft-reset the chip */
++  i = 200;
++       while (--i) {
++	 mb->biucc = SWRST;
++	 if (mb->biucc & SWRST) {
++	   udelay(10);
++	   continue;
++	 }
++	 break;
++       }
++       if (!i) {
++	 printk(KERN_ERR "macmace: cannot reset chip!\n");
++	 return;
++       }
++       
++       mb->maccc = 0;  /* turn off tx, rx */
++       mb->imr = 0xFF; /* disable all intrs for now */
++       i = mb->ir;
++       
++       mb->biucc = XMTSP_64;
++       mb->utr = RTRD;
++       mb->fifocc = XMTFW_16 | RCVFW_64 | XMTFWU | RCVFWU | XMTBRST | RCVBRST;
++       mb->xmtfc = AUTO_PAD_XMIT; /* auto-pad short frames */
++       mb->rcvfc = 0;
++       
++       /* load up the hardware address */
++       __mace_set_address(dev, dev->dev_addr);
++       
++       /* clear the multicast filter */
++       if (mp->chipid == BROKEN_ADDRCHG_REV)
++	 mb->iac = LOGADDR;
++       else {
++	 mb->iac = ADDRCHG | LOGADDR;
++	 while ((mb->iac & ADDRCHG) != 0)
++                       ;
++       }
++       for (i = 0; i < 8; ++i)
++	 mb->ladrf = 0;
++       
++       /* done changing address */
++       if (mp->chipid != BROKEN_ADDRCHG_REV)
++	 mb->iac = 0;
++       
++       mb->plscc = PORTSEL_AUI;
++}
++
++
++/*
+  * Load the address on a mace controller.
+  */
+ 
+-static int mace_set_address(struct net_device *dev, void *addr)
++static void __mace_set_address(struct net_device *dev, void *addr)
+ {
+-	unsigned char *p = addr;
+ 	struct mace_data *mp = (struct mace_data *) dev->priv;
+ 	volatile struct mace *mb = mp->mace;
++	unsigned char *p = addr;
+ 	int i;
++
++	/* load up the hardware address */
++	if (mp->chipid == BROKEN_ADDRCHG_REV)
++	  mb->iac = PHYADDR;
++        else {
++	  mb->iac = ADDRCHG | PHYADDR;
++	  while ((mb->iac & ADDRCHG) != 0)
++	    ;
++        }
++        for (i = 0; i < 6; ++i)
++	  mb->padr = dev->dev_addr[i] = p[i];
++        if (mp->chipid != BROKEN_ADDRCHG_REV)
++	  mb->iac = 0;
++}
++
++static int mace_set_address(struct net_device *dev, void *addr)
++{
++        struct mace_data *mp = (struct mace_data *) dev->priv;
++        volatile struct mace *mb = mp->mace;
++
+ 	unsigned long flags;
+ 	u8 maccc;
+ 
+@@ -272,15 +361,10 @@
+ 
+ 	maccc = mb->maccc;
+ 
+-	/* load up the hardware address */
+-	mb->iac = ADDRCHG | PHYADDR;
+-	while ((mb->iac & ADDRCHG) != 0);
+-	
+-	for (i = 0; i < 6; ++i) {
+-		mb->padr = dev->dev_addr[i] = p[i];
+-	}
++	__mace_set_address(dev, addr);
+ 
+ 	mb->maccc = maccc;
++
+ 	local_irq_restore(flags);
+ 
+ 	return 0;
+@@ -295,29 +379,9 @@
+ {
+ 	struct mace_data *mp = (struct mace_data *) dev->priv;
+ 	volatile struct mace *mb = mp->mace;
+-#if 0
+-	int i;
+ 
+-	i = 200;
+-	while (--i) {
+-		mb->biucc = SWRST;
+-		if (mb->biucc & SWRST) {
+-			udelay(10);
+-			continue;
+-		}
+-		break;
+-	}
+-	if (!i) {
+-		printk(KERN_ERR "%s: software reset failed!!\n", dev->name);
+-		return -EAGAIN;
+-	}
+-#endif
+-
+-	mb->biucc = XMTSP_64;
+-	mb->fifocc = XMTFW_16 | RCVFW_64 | XMTFWU | RCVFWU | XMTBRST | RCVBRST;
+-	mb->xmtfc = AUTO_PAD_XMIT;
+-	mb->plscc = PORTSEL_AUI;
+-	/* mb->utr = RTRD; */
++	/* reset the chip */
++	mace_reset(dev);
+ 
+ 	if (request_irq(dev->irq, mace_interrupt, 0, dev->name, dev)) {
+ 		printk(KERN_ERR "%s: can't get irq %d\n", dev->name, dev->irq);
+@@ -360,33 +424,14 @@
+ 	psc_write_word(PSC_ENETWR_CTL, 0x0400);
+ 	psc_write_word(PSC_ENETRD_CTL, 0x0400);
+ 
+-#if 0
+-	/* load up the hardware address */
+-	
+-	mb->iac = ADDRCHG | PHYADDR;
+-	
+-	while ((mb->iac & ADDRCHG) != 0);
+-	
+-	for (i = 0; i < 6; ++i)
+-		mb->padr = dev->dev_addr[i];
+-
+-	/* clear the multicast filter */
+-	mb->iac = ADDRCHG | LOGADDR;
+-
+-	while ((mb->iac & ADDRCHG) != 0);
+-	
+-	for (i = 0; i < 8; ++i)
+-		mb->ladrf = 0;
+-
+-	mb->plscc = PORTSEL_GPSI + ENPLSIO;
++	mace_rxdma_reset(dev);
++	mace_txdma_reset(dev);
+ 
++	/* turn it on! */
+ 	mb->maccc = ENXMT | ENRCV;
++	/* enable all interrupts except receive interrupts */
+ 	mb->imr = RCVINT;
+-#endif
+ 
+-	mace_rxdma_reset(dev);
+-	mace_txdma_reset(dev);
+-	
+ 	return 0;
+ }
+ 
+@@ -419,15 +464,20 @@
+ static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
+ {
+ 	struct mace_data *mp = (struct mace_data *) dev->priv;
++	unsigned long flags;
+ 
+ 	/* Stop the queue if the buffer is full */
+ 
++	local_irq_save(flags);
+ 	if (!mp->tx_count) {
+ 		netif_stop_queue(dev);
+-		return 1;
++		local_irq_restore(flags);
++		return NETDEV_TX_BUSY;
++
+ 	}
+ 	mp->tx_count--;
+-	
++	local_irq_restore(flags);
++
+ 	mp->stats.tx_packets++;
+ 	mp->stats.tx_bytes += skb->len;
+ 
+@@ -461,7 +511,9 @@
+ 	int i, j;
+ 	u32 crc;
+ 	u8 maccc;
++	unsigned long flags;
+ 
++	local_irq_save(flags);
+ 	maccc = mb->maccc;
+ 	mb->maccc &= ~PROM;
+ 
+@@ -486,109 +538,96 @@
+ 			}
+ 		}
+ 
+-		mb->iac = ADDRCHG | LOGADDR;
+-		while (mb->iac & ADDRCHG);
+-		
+-		for (i = 0; i < 8; ++i) {
+-			mb->ladrf = multicast_filter[i];
++		if (mp->chipid == BROKEN_ADDRCHG_REV)
++                        mb->iac = LOGADDR;
++                else {
++                        mb->iac = ADDRCHG | LOGADDR;
++                        while ((mb->iac & ADDRCHG) != 0)
++                                ;
++                }
++                for (i = 0; i < 8; ++i)
++                        mb->ladrf = multicast_filter[i];
++                if (mp->chipid != BROKEN_ADDRCHG_REV)
++                        mb->iac = 0;
+ 		}
+ 	}
+ 
+ 	mb->maccc = maccc;
++        local_irq_restore(flags);
+ }
+ 
+-/*
+- * Miscellaneous interrupts are handled here. We may end up 
+- * having to bash the chip on the head for bad errors
+- */
+- 
+ static void mace_handle_misc_intrs(struct mace_data *mp, int intr)
+ {
+ 	volatile struct mace *mb = mp->mace;
+ 	static int mace_babbles, mace_jabbers;
+ 
+-	if (intr & MPCO) {
++	if (intr & MPCO) 
+ 		mp->stats.rx_missed_errors += 256;
+-	}
+-	mp->stats.rx_missed_errors += mb->mpc;	/* reading clears it */
+-
+-	if (intr & RNTPCO) {
++	mp->stats.rx_missed_errors += mb->mpc;   /* reading clears it */
++        if (intr & RNTPCO)
+ 		mp->stats.rx_length_errors += 256;
+-	}
+ 	mp->stats.rx_length_errors += mb->rntpc;	/* reading clears it */
+-
+-	if (intr & CERR) {
++	if (intr & CERR) 
+ 		++mp->stats.tx_heartbeat_errors;
+-	}
+-	if (intr & BABBLE) {
+-		if (mace_babbles++ < 4) {
+-			printk(KERN_DEBUG "mace: babbling transmitter\n");
+-		}
+-	}
+-	if (intr & JABBER) {
+-		if (mace_jabbers++ < 4) {
+-			printk(KERN_DEBUG "mace: jabbering transceiver\n");
+-		}
+-	}
++
++	if (intr & BABBLE)
++                if (mace_babbles++ < 4)
++                        printk(KERN_DEBUG "macmace: babbling transmitter\n");
++        if (intr & JABBER)
++                if (mace_jabbers++ < 4)
++                        printk(KERN_DEBUG "macmace: jabbering transceiver\n");
++
+ }
+ 
+-/*
+- *	A transmit error has occurred. (We kick the transmit side from
+- *	the DMA completion)
+- */
+- 
+-static void mace_xmit_error(struct net_device *dev)
++static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
++        struct net_device *dev = (struct net_device *) dev_id;
+ 	struct mace_data *mp = (struct mace_data *) dev->priv;
+ 	volatile struct mace *mb = mp->mace;
+-	u8 xmtfs, xmtrc;
+-	
+-	xmtfs = mb->xmtfs;
+-	xmtrc = mb->xmtrc;
+-	
+-	if (xmtfs & XMTSV) {
+-		if (xmtfs & UFLO) {
+-			printk("%s: DMA underrun.\n", dev->name);
+-			mp->stats.tx_errors++;
+-			mp->stats.tx_fifo_errors++;
+-			mace_txdma_reset(dev);
++	int intr, fs;
++	unsigned int flags;
++
++       /* don't want the dma interrupt handler to fire */
++       local_irq_save(flags);
++
++       intr = mb->ir; /* read interrupt register */
++       mace_handle_misc_intrs(mp, intr);
++
++       if (mb->pr & XMTSV) {
++	 fs = mb->xmtfs;
++	 if ((fs & XMTSV) == 0) {
++	   printk(KERN_ERR "macmace: xmtfs not valid! (fs=%x)\n", fs);
++	   mace_reset(dev);
++	   /*
++	    * XXX mace likes to hang the machine after a xmtfs error.
++	    * This is hard to reproduce, reseting *may* help
++	    */
+ 		}
+-		if (xmtfs & RTRY) {
+-			mp->stats.collisions++;
++	        /* dma should have finished */
++                if (!mp->tx_count) {
++                        printk(KERN_DEBUG "macmace: tx ring ran out? (fs=%x)\n", fs);
+ 		}
+-	}			
+-}
++		/* Update stats */
++                if (fs & (UFLO|LCOL|LCAR|RTRY)) {
++                        ++mp->stats.tx_errors;
++                        if (fs & LCAR)
++                                ++mp->stats.tx_carrier_errors;
++                        else if (fs & (UFLO|LCOL|RTRY)) {
++                                ++mp->stats.tx_aborted_errors;
++                                if (mb->xmtfs & UFLO) {
++                                        printk(KERN_ERR "%s: DMA underrun.\n", dev->name);
++                                        mp->stats.tx_fifo_errors++;
++                                        mace_txdma_reset(dev);
++                                }
++                        }
++                }
++        }
+ 
+-/*
+- *	A receive interrupt occurred.
+- */
++       if (mp->tx_count)
++                netif_wake_queue(dev);
+  
+-static void mace_recv_interrupt(struct net_device *dev)
+-{
+-/*	struct mace_data *mp = (struct mace_data *) dev->priv; */
+-//	volatile struct mace *mb = mp->mace;
+-}
++        local_irq_restore(flags);
+ 
+-/*
+- * Process the chip interrupt
+- */
+- 
+-static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+-{
+-	struct net_device *dev = (struct net_device *) dev_id;
+-	struct mace_data *mp = (struct mace_data *) dev->priv;
+-	volatile struct mace *mb = mp->mace;
+-	u8 ir;
+-	
+-	ir = mb->ir;
+-	mace_handle_misc_intrs(mp, ir);
+-	
+-	if (ir & XMTINT) {
+-		mace_xmit_error(dev);
+-	}
+-	if (ir & RCVINT) {
+-		mace_recv_interrupt(dev);
+-	}
+ 	return IRQ_HANDLED;
+ }
+ 
+@@ -598,51 +637,30 @@
+ 
+ static void mace_tx_timeout(struct net_device *dev)
+ {
+-	struct mace_data *mp = (struct mace_data *) dev->priv;
+-	volatile struct mace *mb = mp->mace;
+-	unsigned long flags;
+-	u8 maccc, imr;
+-
+-	local_irq_save(flags);
+-
+-	// save state
+-	maccc = mb->maccc;
+-	imr   = mb->imr;
+-
+-	// stop card
+-	mb->maccc = 0;		/* disable rx and tx	 */
+-	mb->imr = 0xFF;		/* disable all irqs	 */
+-	mace_dma_off(dev);
+-
+-	// reset card
+-	mb->biucc = XMTSP_64;
+-	mb->fifocc = XMTFW_16 | RCVFW_64 | XMTFWU | RCVFWU | XMTBRST | RCVBRST;
+-	mb->xmtfc = AUTO_PAD_XMIT;
+-	mb->plscc = PORTSEL_AUI;
+-
+-	/* Not sure what these do - perhaps reset the PSC ??? */
+-
+-	psc_write_word(PSC_ENETWR_CTL, 0x9000);
+-	psc_write_word(PSC_ENETRD_CTL, 0x9000);
+-	psc_write_word(PSC_ENETWR_CTL, 0x0400);
+-	psc_write_word(PSC_ENETRD_CTL, 0x0400);
+-
+-	// reset both DMAs
+-	mace_rxdma_reset(dev);
+-	mace_txdma_reset(dev);
+-	
+-	// free skb's - not necessary, already done in mace_xmit_start
+-	// ring buffer pointers reset in txdma_reset, so just log error
+-	mp->stats.tx_errors++;
+-
+-	// re-kick upper level
+-	netif_wake_queue(dev);
+-
+-	// re-enable card, using saved imr/maccc (where is this ever set?)
+-	mb->maccc = maccc;
+-	mb->imr   = imr;
+-
+-	local_irq_restore(flags);
++        struct mace_data *mp = (struct mace_data *) dev->priv;
++        volatile struct mace *mb = mp->mace;
++        unsigned long flags;
++
++        local_irq_save(flags);
++ 
++        /* turn off both tx and rx and reset the chip */
++        mb->maccc = 0;
++        printk(KERN_ERR "macmace: transmit timeout - resetting\n");
++        mace_txdma_reset(dev);
++        mace_reset(dev);
++ 
++        /* restart rx dma */
++        mace_rxdma_reset(dev);
++ 
++        mp->tx_count = N_TX_RING;
++        netif_wake_queue(dev);
++ 
++        /* turn it on! */
++        mb->maccc = ENXMT | ENRCV;
++        /* enable all interrupts except receive interrupts */
++        mb->imr = RCVINT;
++ 
++        local_irq_restore(flags);
+ }
+ 
+ /*
+@@ -653,39 +671,39 @@
+ {
+ 	struct mace_data *mp = (struct mace_data *) dev->priv;
+ 	struct sk_buff *skb;
++	unsigned int frame_status = mf->rcvsts;
+ 
+-	if (mf->status & RS_OFLO) {
+-		printk("%s: fifo overflow.\n", dev->name);
+-		mp->stats.rx_errors++;
+-		mp->stats.rx_fifo_errors++;
+-	}
+-	if (mf->status&(RS_CLSN|RS_FRAMERR|RS_FCSERR))
++        if (frame_status & (RS_OFLO | RS_CLSN | RS_FRAMERR | RS_FCSERR)) {
+ 		mp->stats.rx_errors++;
+ 		
+-	if (mf->status&RS_CLSN) {
+-		mp->stats.collisions++;
+-	}
+-	if (mf->status&RS_FRAMERR) {
+-		mp->stats.rx_frame_errors++;
+-	}
+-	if (mf->status&RS_FCSERR) {
+-		mp->stats.rx_crc_errors++;
++                if (frame_status & RS_OFLO) {
++                        printk(KERN_DEBUG "%s: fifo overflow.\n", dev->name);
++                        mp->stats.rx_fifo_errors++;
++                }
++                if (frame_status & RS_CLSN)
++                        mp->stats.collisions++;
++                if (frame_status & RS_FRAMERR)
++                        mp->stats.rx_frame_errors++;
++                if (frame_status & RS_FCSERR)
++                        mp->stats.rx_crc_errors++;
++        } else {
++                unsigned int frame_length = mf->rcvcnt + ((frame_status & 0x0F) << 8 );
++
++                skb = dev_alloc_skb(frame_length + 2);
++                 if (!skb) {
++                        mp->stats.rx_dropped++;
++                        return;
++                }
++                skb_reserve(skb, 2);
++                memcpy(skb_put(skb, frame_length), mf->data, frame_length);
++ 
++                skb->dev = dev;
++                skb->protocol = eth_type_trans(skb, dev);
++                netif_rx(skb);
++                dev->last_rx = jiffies;
++                mp->stats.rx_packets++;
++                mp->stats.rx_bytes += frame_length;
+ 	}
+-		
+-	skb = dev_alloc_skb(mf->len+2);
+-	if (!skb) {
+-		mp->stats.rx_dropped++;
+-		return;
+-	}
+-	skb_reserve(skb,2);
+-	memcpy(skb_put(skb, mf->len), mf->data, mf->len);
+-	
+-	skb->dev = dev;
+-	skb->protocol = eth_type_trans(skb, dev);
+-	netif_rx(skb);
+-	dev->last_rx = jiffies;
+-	mp->stats.rx_packets++;
+-	mp->stats.rx_bytes += mf->len;
+ }
+ 
+ /*

Modified: dists/sid/linux-2.6/debian/patches/series/9-extra
==============================================================================
--- dists/sid/linux-2.6/debian/patches/series/9-extra	(original)
+++ dists/sid/linux-2.6/debian/patches/series/9-extra	Sun Dec 31 17:30:59 2006
@@ -5,3 +5,7 @@
 + features/all/xen/vserver-update.patch *_xen-vserver
 + m68k-atari-net.patch m68k
 + m68k-atari-video2.patch m68k
+- m68k-atari-scsi.patch m68k
++ m68k-atari-scsi2.patch m68k
++ m68k-mac-mace.patch m68k
++ m68k-mac-cuda.patch m68k



More information about the Kernel-svn-changes mailing list