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 <[EMAIL PROTECTED]>  Sun, 31 Dec 2006 17:07:53 +0100
+ -- Christian T. Steigies <[EMAIL PROTECTED]>  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: [EMAIL PROTECTED]
+
+        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 <[EMAIL PROTECTED]>
+ 
+ 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 [EMAIL PROTECTED]
+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 <[EMAIL PROTECTED]>
+
+--- 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

_______________________________________________
Kernel-svn-changes mailing list
[email protected]
http://lists.alioth.debian.org/mailman/listinfo/kernel-svn-changes

Reply via email to