From mboxrd@z Thu Jan 1 00:00:00 1970 From: Adrian Bunk Subject: [2.6 patch] more ACSI removal Date: Fri, 13 Jul 2007 01:45:53 +0200 Message-ID: <20070712234553.GR3492@stusta.de> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: QUOTED-PRINTABLE Cc: linux-kernel@vger.kernel.org, jgarzik@pobox.com, netdev@vger.kernel.org, geert@linux-m68k.org, zippel@linux-m68k.org, linux-m68k@lists.linux-m68k.org To: Jens Axboe , Boaz Harrosh Return-path: Received: from emailhub.stusta.mhn.de ([141.84.69.5]:59649 "EHLO mailhub.stusta.mhn.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1757898AbXGLXpU (ORCPT ); Thu, 12 Jul 2007 19:45:20 -0400 Content-Disposition: inline Sender: netdev-owner@vger.kernel.org List-Id: netdev.vger.kernel.org This patch removes some code that became dead code after the ATARI_ACSI= =20 removal. It also indirectly fixes the following bug introduced by commit c2bcf3b8978c291e1b7f6499475c8403a259d4d6: config ATARI_SLM tristate "Atari SLM laser printer support" - depends on ATARI && ATARI_ACSI!=3Dn + depends on ATARI Signed-off-by: Adrian Bunk --- Documentation/m68k/kernel-options.txt | 7=20 Documentation/networking/net-modules.txt | 6=20 drivers/block/Kconfig | 11=20 drivers/block/Makefile | 1=20 drivers/block/acsi_slm.c | 1032 ----------------------= - drivers/net/Kconfig | 16=20 drivers/net/Makefile | 2=20 drivers/net/Space.c | 8=20 drivers/net/atari_bionet.c | 675 --------------- drivers/net/atari_pamsnet.c | 878 ------------------- include/asm-m68k/atari_SLM.h | 28=20 include/asm-m68k/atari_acsi.h | 37=20 12 files changed, 2701 deletions(-) --- linux-2.6.22-rc6-mm1/Documentation/networking/net-modules.txt.old 2= 007-07-12 20:43:25.000000000 +0200 +++ linux-2.6.22-rc6-mm1/Documentation/networking/net-modules.txt 2007-= 07-12 20:43:37.000000000 +0200 @@ -146,12 +146,6 @@ irq =3D 0 (Probes ports: 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300= ) =20 -atari_bionet.c: - Supports full autoprobing. (m68k/Atari) - -atari_pamsnet.c: - Supports full autoprobing. (m68k/Atari) - atarilance.c: Supports full autoprobing. (m68k/Atari) =20 --- linux-2.6.22-rc6-mm1/Documentation/m68k/kernel-options.txt.old 2007= -07-12 20:31:06.000000000 +0200 +++ linux-2.6.22-rc6-mm1/Documentation/m68k/kernel-options.txt 2007-07-= 12 20:31:15.000000000 +0200 @@ -82,13 +82,6 @@ /dev/fd : -> 0x0200 (floppy disk) /dev/xda: -> 0x0c00 (first XT disk, unused in Linux/m68k) /dev/xdb: -> 0x0c40 (second XT disk, unused in Linux/m68k) - /dev/ada: -> 0x1c00 (first ACSI device) - /dev/adb: -> 0x1c10 (second ACSI device) - /dev/adc: -> 0x1c20 (third ACSI device) - /dev/add: -> 0x1c30 (forth ACSI device) - -The last four names are available only if the kernel has been compiled -with Atari and ACSI support. =20 The name must be followed by a decimal number, that stands for the partition number. Internally, the value of the number is just --- linux-2.6.22-rc6-mm1/drivers/block/Kconfig.old 2007-07-12 20:31:24.= 000000000 +0200 +++ linux-2.6.22-rc6-mm1/drivers/block/Kconfig 2007-07-12 20:31:43.0000= 00000 +0200 @@ -97,17 +97,6 @@ devices have only one LUN, and so most people can say N here and should in fact do so, because it is safer. =20 -config ATARI_SLM - tristate "Atari SLM laser printer support" - depends on ATARI - help - If you have an Atari SLM laser printer, say Y to include support fo= r - it in the kernel. Otherwise, say N. This driver is also available a= s - a module ( =3D code which can be inserted in and removed from the - running kernel whenever you want). The module will be called - acsi_slm. Be warned: the driver needs much ST-RAM and can cause - problems due to that fact! - config BLK_DEV_XD tristate "XT hard disk support" depends on ISA && ISA_DMA_API --- linux-2.6.22-rc6-mm1/drivers/block/Makefile.old 2007-07-12 20:31:51= =2E000000000 +0200 +++ linux-2.6.22-rc6-mm1/drivers/block/Makefile 2007-07-12 20:31:58.000= 000000 +0200 @@ -10,6 +10,5 @@ obj-$(CONFIG_AMIGA_FLOPPY) +=3D amiflop.o obj-$(CONFIG_ATARI_FLOPPY) +=3D ataflop.o -obj-$(CONFIG_ATARI_SLM) +=3D acsi_slm.o obj-$(CONFIG_AMIGA_Z2RAM) +=3D z2ram.o obj-$(CONFIG_BLK_DEV_RAM) +=3D rd.o obj-$(CONFIG_BLK_DEV_LOOP) +=3D loop.o --- linux-2.6.22-rc6-mm1/drivers/net/Kconfig.old 2007-07-12 20:33:44.00= 0000000 +0200 +++ linux-2.6.22-rc6-mm1/drivers/net/Kconfig 2007-07-12 20:34:03.000000= 000 +0200 @@ -378,22 +378,6 @@ on the AMD Lance chipset: RieblCard (with or without battery), or PAMCard VME (also the version by Rhotron, with different addresses)= =2E =20 -config ATARI_BIONET - tristate "BioNet-100 support" - depends on ATARI && ATARI_ACSI && BROKEN - help - Say Y to include support for BioData's BioNet-100 Ethernet adapter - for the ACSI port. The driver works (has to work...) with a polled - I/O scheme, so it's rather slow :-( - -config ATARI_PAMSNET - tristate "PAMsNet support" - depends on ATARI && ATARI_ACSI && BROKEN - help - Say Y to include support for the PAMsNet Ethernet adapter for the - ACSI port ("ACSI node"). The driver works (has to work...) with a - polled I/O scheme, so it's rather slow :-( - config SUN3LANCE tristate "Sun3/Sun3x on-board LANCE support" depends on SUN3 || SUN3X --- linux-2.6.22-rc6-mm1/drivers/net/Makefile.old 2007-07-12 20:34:15.0= 00000000 +0200 +++ linux-2.6.22-rc6-mm1/drivers/net/Makefile 2007-07-12 20:34:26.00000= 0000 +0200 @@ -175,8 +175,6 @@ obj-$(CONFIG_SGI_IOC3_ETH) +=3D ioc3-eth.o obj-$(CONFIG_DECLANCE) +=3D declance.o obj-$(CONFIG_ATARILANCE) +=3D atarilance.o -obj-$(CONFIG_ATARI_BIONET) +=3D atari_bionet.o -obj-$(CONFIG_ATARI_PAMSNET) +=3D atari_pamsnet.o obj-$(CONFIG_A2065) +=3D a2065.o obj-$(CONFIG_HYDRA) +=3D hydra.o obj-$(CONFIG_ARIADNE) +=3D ariadne.o --- linux-2.6.22-rc6-mm1/drivers/net/Space.c.old 2007-07-12 20:35:09.00= 0000000 +0200 +++ linux-2.6.22-rc6-mm1/drivers/net/Space.c 2007-07-12 20:35:23.000000= 000 +0200 @@ -75,8 +75,6 @@ extern struct net_device *sun3lance_probe(int unit); extern struct net_device *sun3_82586_probe(int unit); extern struct net_device *apne_probe(int unit); -extern struct net_device *bionet_probe(int unit); -extern struct net_device *pamsnet_probe(int unit); extern struct net_device *cs89x0_probe(int unit); extern struct net_device *hplance_probe(int unit); extern struct net_device *bagetlance_probe(int unit); @@ -264,12 +262,6 @@ #ifdef CONFIG_APNE /* A1200 PCMCIA NE2000 */ {apne_probe, 0}, #endif -#ifdef CONFIG_ATARI_BIONET /* Atari Bionet Ethernet board */ - {bionet_probe, 0}, -#endif -#ifdef CONFIG_ATARI_PAMSNET /* Atari PAMsNet Ethernet board */ - {pamsnet_probe, 0}, -#endif #ifdef CONFIG_MVME147_NET /* MVME147 internal Ethernet */ {mvme147lance_probe, 0}, #endif --- linux-2.6.22-rc6-mm1/include/asm-m68k/atari_acsi.h 2007-04-26 05:08= :32.000000000 +0200 +++ /dev/null 2006-09-19 00:45:31.000000000 +0200 @@ -1,37 +0,0 @@ -#ifndef _ASM_ATARI_ACSI_H -#define _ASM_ATARI_ACSI_H - -/* Functions exported by drivers/block/acsi.c */ - -void acsi_delay_start( void ); -void acsi_delay_end( long usec ); -int acsi_wait_for_IRQ( unsigned timeout ); -int acsi_wait_for_noIRQ( unsigned timeout ); -int acsicmd_nodma( const char *cmd, int enable); -int acsi_getstatus( void ); -int acsi_extstatus( char *buffer, int cnt ); -void acsi_end_extstatus( void ); -int acsi_extcmd( unsigned char *buffer, int cnt ); - -/* The ACSI buffer is guarantueed to reside in ST-RAM and may be used = by other - * drivers that work on the ACSI bus, too. It's data are valid only as= long as - * the ST-DMA is locked. */ -extern char *acsi_buffer; -extern unsigned long phys_acsi_buffer; - -/* Utility macros */ - -/* Send one data byte over the bus and set mode for next operation - * with one move.l -- Atari recommends this... - */ - -#define DMA_LONG_WRITE(data,mode) \ - do { \ - *((unsigned long *)&dma_wd.fdc_acces_seccount) =3D \ - ((data)<<16) | (mode); \ - } while(0) - -#define ENABLE_IRQ() atari_turnon_irq( IRQ_MFP_ACSI ) -#define DISABLE_IRQ() atari_turnoff_irq( IRQ_MFP_ACSI ) - -#endif /* _ASM_ATARI_ACSI_H */ --- linux-2.6.22-rc6-mm1/include/asm-m68k/atari_SLM.h 2007-04-26 05:08:= 32.000000000 +0200 +++ /dev/null 2006-09-19 00:45:31.000000000 +0200 @@ -1,28 +0,0 @@ - -#ifndef _ATARI_SLM_H -#define _ATARI_SLM_H - -/* Atari SLM laser printer specific ioctls */ - -#define SLMIOGSTAT 0xa100 -#define SLMIOGPSIZE 0xa101 -#define SLMIOGMFEED 0xa102 - -#define SLMIORESET 0xa140 - -#define SLMIOSPSIZE 0xa181 -#define SLMIOSMFEED 0xa182 - -/* Status returning structure (SLMIOGSTAT) */ -struct SLM_status { - int stat; /* numeric status code */ - char str[40]; /* status string */ -}; - -/* Paper size structure (SLMIO[GS]PSIZE) */ -struct SLM_paper_size { - int width; - int height; -}; - -#endif /* _ATARI_SLM_H */ --- linux-2.6.22-rc6-mm1/drivers/block/acsi_slm.c 2007-07-12 20:40:41.0= 00000000 +0200 +++ /dev/null 2006-09-19 00:45:31.000000000 +0200 @@ -1,1032 +0,0 @@ -/* - * acsi_slm.c -- Device driver for the Atari SLM laser printer - * - * Copyright 1995 Roman Hodek - * - * This file is subject to the terms and conditions of the GNU General= Public - * License. See the file COPYING in the main directory of this archiv= e for - * more details. - *=20 - */ - -/* - -Notes: - -The major number for SLM printers is 28 (like ACSI), but as a characte= r -device, not block device. The minor number is the number of the printe= r (if -you have more than one SLM; currently max. 2 (#define-constant) SLMs a= re -supported). The device can be opened for reading and writing. If readi= ng it, -you get some status infos (MODE SENSE data). Writing mode is used for = the data -to be printed. Some ioctls allow to get the printer status and to tune= printer -modes and some internal variables. - -A special problem of the SLM driver is the timing and thus the bufferi= ng of -the print data. The problem is that all the data for one page must be = present -in memory when printing starts, else --when swapping occurs-- the timi= ng could -not be guaranteed. There are several ways to assure this: - - 1) Reserve a buffer of 1196k (maximum page size) statically by - atari_stram_alloc(). The data are collected there until they're co= mplete, - and then printing starts. Since the buffer is reserved, no further - considerations about memory and swapping are needed. So this is the - simplest method, but it needs a lot of memory for just the SLM. - - An striking advantage of this method is (supposed the SLM_CONT_CNT= _REPROG - method works, see there), that there are no timing problems with the = DMA - anymore. -=09 - 2) The other method would be to reserve the buffer dynamically each t= ime - printing is required. I could think of looking at mem_map where th= e - largest unallocted ST-RAM area is, taking the area, and then extendin= g it - by swapping out the neighbored pages, until the needed size is reache= d. - This requires some mm hacking, but seems possible. The only obstacle = could - be pages that cannot be swapped out (reserved pages)... - - 3) Another possibility would be to leave the real data in user space = and to - work with two dribble buffers of about 32k in the driver: While th= e one - buffer is DMAed to the SLM, the other can be filled with new data. Bu= t - to keep the timing, that requires that the user data remain in memory= and - are not swapped out. Requires mm hacking, too, but maybe not so bad a= s - method 2). - -*/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#undef DEBUG - -/* Define this if the page data are continuous in physical memory. Tha= t - * requires less reprogramming of the ST-DMA */ -#define SLM_CONTINUOUS_DMA - -/* Use continuous reprogramming of the ST-DMA counter register. This i= s - * --strictly speaking-- not allowed, Atari recommends not to look at = the - * counter register while a DMA is going on. But I don't know if that = applies - * only for reading the register, or also writing to it. Writing only = works - * fine for me... The advantage is that the timing becomes absolutely - * uncritical: Just update each, say 200ms, the counter reg to its max= imum, - * and the DMA will work until the status byte interrupt occurs. - */ -#define SLM_CONT_CNT_REPROG - -#define CMDSET_TARG_LUN(cmd,targ,lun) \ - do { \ - cmd[0] =3D (cmd[0] & ~0xe0) | (targ)<<5; \ - cmd[1] =3D (cmd[1] & ~0xe0) | (lun)<<5; \ - } while(0) - -#define START_TIMER(to) mod_timer(&slm_timer, jiffies + (to)) -#define STOP_TIMER() del_timer(&slm_timer) - - -static char slmreqsense_cmd[6] =3D { 0x03, 0, 0, 0, 0, 0 }; -static char slmprint_cmd[6] =3D { 0x0a, 0, 0, 0, 0, 0 }; -static char slminquiry_cmd[6] =3D { 0x12, 0, 0, 0, 0, 0x80 }; -static char slmmsense_cmd[6] =3D { 0x1a, 0, 0, 0, 255, 0 }; -#if 0 -static char slmmselect_cmd[6] =3D { 0x15, 0, 0, 0, 0, 0 }; -#endif - - -#define MAX_SLM 2 - -static struct slm { - unsigned target; /* target number */ - unsigned lun; /* LUN in target controller */ - atomic_t wr_ok; /* set to 0 if output part busy */ - atomic_t rd_ok; /* set to 0 if status part busy */ -} slm_info[MAX_SLM]; - -int N_SLM_Printers =3D 0; - -/* printer buffer */ -static unsigned char *SLMBuffer; /* start of buffer */ -static unsigned char *BufferP; /* current position in buffer */ -static int BufferSize; /* length of buffer for page size */ - -typedef enum { IDLE, FILLING, PRINTING } SLMSTATE; -static SLMSTATE SLMState; -static int SLMBufOwner; /* SLM# currently using the buffer */ - -/* DMA variables */ -#ifndef SLM_CONT_CNT_REPROG -static unsigned long SLMCurAddr; /* current base addr of DMA chunk */ -static unsigned long SLMEndAddr; /* expected end addr */ -static unsigned long SLMSliceSize; /* size of one DMA chunk */ -#endif -static int SLMError; - -/* wait queues */ -static DECLARE_WAIT_QUEUE_HEAD(slm_wait); /* waiting for buffer */ -static DECLARE_WAIT_QUEUE_HEAD(print_wait); /* waiting for printing fi= nished */ - -/* status codes */ -#define SLMSTAT_OK 0x00 -#define SLMSTAT_ORNERY 0x02 -#define SLMSTAT_TONER 0x03 -#define SLMSTAT_WARMUP 0x04 -#define SLMSTAT_PAPER 0x05 -#define SLMSTAT_DRUM 0x06 -#define SLMSTAT_INJAM 0x07 -#define SLMSTAT_THRJAM 0x08 -#define SLMSTAT_OUTJAM 0x09 -#define SLMSTAT_COVER 0x0a -#define SLMSTAT_FUSER 0x0b -#define SLMSTAT_IMAGER 0x0c -#define SLMSTAT_MOTOR 0x0d -#define SLMSTAT_VIDEO 0x0e -#define SLMSTAT_SYSTO 0x10 -#define SLMSTAT_OPCODE 0x12 -#define SLMSTAT_DEVNUM 0x15 -#define SLMSTAT_PARAM 0x1a -#define SLMSTAT_ACSITO 0x1b /* driver defined */ -#define SLMSTAT_NOTALL 0x1c /* driver defined */ - -static char *SLMErrors[] =3D { - /* 0x00 */ "OK and ready", - /* 0x01 */ NULL, - /* 0x02 */ "ornery printer", - /* 0x03 */ "toner empty", - /* 0x04 */ "warming up", - /* 0x05 */ "paper empty", - /* 0x06 */ "drum empty", - /* 0x07 */ "input jam", - /* 0x08 */ "through jam", - /* 0x09 */ "output jam", - /* 0x0a */ "cover open", - /* 0x0b */ "fuser malfunction", - /* 0x0c */ "imager malfunction", - /* 0x0d */ "motor malfunction", - /* 0x0e */ "video malfunction", - /* 0x0f */ NULL, - /* 0x10 */ "printer system timeout", - /* 0x11 */ NULL, - /* 0x12 */ "invalid operation code", - /* 0x13 */ NULL, - /* 0x14 */ NULL, - /* 0x15 */ "invalid device number", - /* 0x16 */ NULL, - /* 0x17 */ NULL, - /* 0x18 */ NULL, - /* 0x19 */ NULL, - /* 0x1a */ "invalid parameter list", - /* 0x1b */ "ACSI timeout", - /* 0x1c */ "not all printed" -}; - -#define N_ERRORS (sizeof(SLMErrors)/sizeof(*SLMErrors)) - -/* real (driver caused) error? */ -#define IS_REAL_ERROR(x) (x > 0x10) - - -static struct { - char *name; - int w, h; -} StdPageSize[] =3D { - { "Letter", 2400, 3180 }, - { "Legal", 2400, 4080 }, - { "A4", 2336, 3386 }, - { "B5", 2016, 2914 } -}; - -#define N_STD_SIZES (sizeof(StdPageSize)/sizeof(*StdPageSize)) - -#define SLM_BUFFER_SIZE (2336*3386/8) /* A4 for now */ -#define SLM_DMA_AMOUNT 255 /* #sectors to program the DMA for */ - -#ifdef SLM_CONTINUOUS_DMA -# define SLM_DMA_INT_OFFSET 0 /* DMA goes until seccnt 0, no offs */ -# define SLM_DMA_END_OFFSET 32 /* 32 Byte ST-DMA FIFO */ -# define SLM_SLICE_SIZE(w) (255*512) -#else -# define SLM_DMA_INT_OFFSET 32 /* 32 Byte ST-DMA FIFO */ -# define SLM_DMA_END_OFFSET 32 /* 32 Byte ST-DMA FIFO */ -# define SLM_SLICE_SIZE(w) ((254*512)/(w/8)*(w/8)) -#endif - -/* calculate the number of jiffies to wait for 'n' bytes */ -#ifdef SLM_CONT_CNT_REPROG -#define DMA_TIME_FOR(n) 50 -#define DMA_STARTUP_TIME 0 -#else -#define DMA_TIME_FOR(n) (n/1400-1) -#define DMA_STARTUP_TIME 650 -#endif - -/***************************** Prototypes ****************************= */ - -static char *slm_errstr( int stat ); -static int slm_getstats( char *buffer, int device ); -static ssize_t slm_read( struct file* file, char *buf, size_t count, l= off_t - *ppos ); -static void start_print( int device ); -static irqreturn_t slm_interrupt(int irc, void *data); -static void slm_test_ready( unsigned long dummy ); -static void set_dma_addr( unsigned long paddr ); -static unsigned long get_dma_addr( void ); -static ssize_t slm_write( struct file *file, const char *buf, size_t c= ount, - loff_t *ppos ); -static int slm_ioctl( struct inode *inode, struct file *file, unsigned= int - cmd, unsigned long arg ); -static int slm_open( struct inode *inode, struct file *file ); -static int slm_release( struct inode *inode, struct file *file ); -static int slm_req_sense( int device ); -static int slm_mode_sense( int device, char *buffer, int abs_flag ); -#if 0 -static int slm_mode_select( int device, char *buffer, int len, int - default_flag ); -#endif -static int slm_get_pagesize( int device, int *w, int *h ); - -/************************* End of Prototypes *************************= */ - - -static DEFINE_TIMER(slm_timer, slm_test_ready, 0, 0); - -static const struct file_operations slm_fops =3D { - .owner =3D THIS_MODULE, - .read =3D slm_read, - .write =3D slm_write, - .ioctl =3D slm_ioctl, - .open =3D slm_open, - .release =3D slm_release, -}; - - -/* -------------------------------------------------------------------= --- */ -/* Status Functions */ - - -static char *slm_errstr( int stat ) - -{ char *p; - static char str[22]; - - stat &=3D 0x1f; - if (stat >=3D 0 && stat < N_ERRORS && (p =3D SLMErrors[stat])) - return( p ); - sprintf( str, "unknown status 0x%02x", stat ); - return( str ); -} - - -static int slm_getstats( char *buffer, int device ) - -{ int len =3D 0, stat, i, w, h; - unsigned char buf[256]; -=09 - stat =3D slm_mode_sense( device, buf, 0 ); - if (IS_REAL_ERROR(stat)) - return( -EIO ); -=09 -#define SHORTDATA(i) ((buf[i] << 8) | buf[i+1]) -#define BOOLDATA(i,mask) ((buf[i] & mask) ? "on" : "off") - - w =3D SHORTDATA( 3 ); - h =3D SHORTDATA( 1 ); - =09 - len +=3D sprintf( buffer+len, "Status\t\t%s\n", - slm_errstr( stat ) ); - len +=3D sprintf( buffer+len, "Page Size\t%dx%d", - w, h ); - - for( i =3D 0; i < N_STD_SIZES; ++i ) { - if (w =3D=3D StdPageSize[i].w && h =3D=3D StdPageSize[i].h) - break; - } - if (i < N_STD_SIZES) - len +=3D sprintf( buffer+len, " (%s)", StdPageSize[i].name ); - buffer[len++] =3D '\n'; - - len +=3D sprintf( buffer+len, "Top/Left Margin\t%d/%d\n", - SHORTDATA( 5 ), SHORTDATA( 7 ) ); - len +=3D sprintf( buffer+len, "Manual Feed\t%s\n", - BOOLDATA( 9, 0x01 ) ); - len +=3D sprintf( buffer+len, "Input Select\t%d\n", - (buf[9] >> 1) & 7 ); - len +=3D sprintf( buffer+len, "Auto Select\t%s\n", - BOOLDATA( 9, 0x10 ) ); - len +=3D sprintf( buffer+len, "Prefeed Paper\t%s\n", - BOOLDATA( 9, 0x20 ) ); - len +=3D sprintf( buffer+len, "Thick Pixels\t%s\n", - BOOLDATA( 9, 0x40 ) ); - len +=3D sprintf( buffer+len, "H/V Resol.\t%d/%d dpi\n", - SHORTDATA( 12 ), SHORTDATA( 10 ) ); - len +=3D sprintf( buffer+len, "System Timeout\t%d\n", - buf[14] ); - len +=3D sprintf( buffer+len, "Scan Time\t%d\n", - SHORTDATA( 15 ) ); - len +=3D sprintf( buffer+len, "Page Count\t%d\n", - SHORTDATA( 17 ) ); - len +=3D sprintf( buffer+len, "In/Out Cap.\t%d/%d\n", - SHORTDATA( 19 ), SHORTDATA( 21 ) ); - len +=3D sprintf( buffer+len, "Stagger Output\t%s\n", - BOOLDATA( 23, 0x01 ) ); - len +=3D sprintf( buffer+len, "Output Select\t%d\n", - (buf[23] >> 1) & 7 ); - len +=3D sprintf( buffer+len, "Duplex Print\t%s\n", - BOOLDATA( 23, 0x10 ) ); - len +=3D sprintf( buffer+len, "Color Sep.\t%s\n", - BOOLDATA( 23, 0x20 ) ); - - return( len ); -} - - -static ssize_t slm_read( struct file *file, char *buf, size_t count, - loff_t *ppos ) - -{ - struct inode *node =3D file->f_path.dentry->d_inode; - unsigned long page; - int length; - int end; - - if (!(page =3D __get_free_page( GFP_KERNEL ))) - return( -ENOMEM ); -=09 - length =3D slm_getstats( (char *)page, iminor(node) ); - if (length < 0) { - count =3D length; - goto out; - } - if (file->f_pos >=3D length) { - count =3D 0; - goto out; - } - if (count + file->f_pos > length) - count =3D length - file->f_pos; - end =3D count + file->f_pos; - if (copy_to_user(buf, (char *)page + file->f_pos, count)) { - count =3D -EFAULT; - goto out; - } - file->f_pos =3D end; -out: free_page( page ); - return( count ); -} - - -/* -------------------------------------------------------------------= --- */ -/* Printing */ - - -static void start_print( int device ) - -{ struct slm *sip =3D &slm_info[device]; - unsigned char *cmd; - unsigned long paddr; - int i; -=09 - stdma_lock( slm_interrupt, NULL ); - - CMDSET_TARG_LUN( slmprint_cmd, sip->target, sip->lun ); - cmd =3D slmprint_cmd; - paddr =3D virt_to_phys( SLMBuffer ); - dma_cache_maintenance( paddr, virt_to_phys(BufferP)-paddr, 1 ); - DISABLE_IRQ(); - - /* Low on A1 */ - dma_wd.dma_mode_status =3D 0x88; - MFPDELAY(); - - /* send the command bytes except the last */ - for( i =3D 0; i < 5; ++i ) { - DMA_LONG_WRITE( *cmd++, 0x8a ); - udelay(20); - if (!acsi_wait_for_IRQ( HZ/2 )) { - SLMError =3D 1; - return; /* timeout */ - } - } - /* last command byte */ - DMA_LONG_WRITE( *cmd++, 0x82 ); - MFPDELAY(); - /* set DMA address */ - set_dma_addr( paddr ); - /* program DMA for write and select sector counter reg */ - dma_wd.dma_mode_status =3D 0x192; - MFPDELAY(); - /* program for 255*512 bytes and start DMA */ - DMA_LONG_WRITE( SLM_DMA_AMOUNT, 0x112 ); - -#ifndef SLM_CONT_CNT_REPROG - SLMCurAddr =3D paddr; - SLMEndAddr =3D paddr + SLMSliceSize + SLM_DMA_INT_OFFSET; -#endif - START_TIMER( DMA_STARTUP_TIME + DMA_TIME_FOR( SLMSliceSize )); -#if !defined(SLM_CONT_CNT_REPROG) && defined(DEBUG) - printk( "SLM: CurAddr=3D%#lx EndAddr=3D%#lx timer=3D%ld\n", - SLMCurAddr, SLMEndAddr, DMA_TIME_FOR( SLMSliceSize ) ); -#endif -=09 - ENABLE_IRQ(); -} - - -/* Only called when an error happened or at the end of a page */ - -static irqreturn_t slm_interrupt(int irc, void *data) - -{ unsigned long addr; - int stat; -=09 - STOP_TIMER(); - addr =3D get_dma_addr(); - stat =3D acsi_getstatus(); - SLMError =3D (stat < 0) ? SLMSTAT_ACSITO : - (addr < virt_to_phys(BufferP)) ? SLMSTAT_NOTALL : - stat; - - dma_wd.dma_mode_status =3D 0x80; - MFPDELAY(); -#ifdef DEBUG - printk( "SLM: interrupt, addr=3D%#lx, error=3D%d\n", addr, SLMError )= ; -#endif - - wake_up( &print_wait ); - stdma_release(); - ENABLE_IRQ(); - return IRQ_HANDLED; -} - - -static void slm_test_ready( unsigned long dummy ) - -{ -#ifdef SLM_CONT_CNT_REPROG - /* program for 255*512 bytes again */ - dma_wd.fdc_acces_seccount =3D SLM_DMA_AMOUNT; - START_TIMER( DMA_TIME_FOR(0) ); -#ifdef DEBUG - printk( "SLM: reprogramming timer for %d jiffies, addr=3D%#lx\n", - DMA_TIME_FOR(0), get_dma_addr() ); -#endif -=09 -#else /* !SLM_CONT_CNT_REPROG */ - - unsigned long flags, addr; - int d, ti; -#ifdef DEBUG - struct timeval start_tm, end_tm; - int did_wait =3D 0; -#endif - - local_irq_save(flags); - - addr =3D get_dma_addr(); - if ((d =3D SLMEndAddr - addr) > 0) { - local_irq_restore(flags); - =09 - /* slice not yet finished, decide whether to start another timer or = to - * busy-wait */ - ti =3D DMA_TIME_FOR( d ); - if (ti > 0) { -#ifdef DEBUG - printk( "SLM: reprogramming timer for %d jiffies, rest %d bytes\n", - ti, d ); -#endif - START_TIMER( ti ); - return; - } - /* wait for desired end address to be reached */ -#ifdef DEBUG - do_gettimeofday( &start_tm ); - did_wait =3D 1; -#endif - local_irq_disable(); - while( get_dma_addr() < SLMEndAddr ) - barrier(); - } - - /* slice finished, start next one */ - SLMCurAddr +=3D SLMSliceSize; - -#ifdef SLM_CONTINUOUS_DMA - /* program for 255*512 bytes again */ - dma_wd.fdc_acces_seccount =3D SLM_DMA_AMOUNT; -#else - /* set DMA address; - * add 2 bytes for the ones in the SLM controller FIFO! */ - set_dma_addr( SLMCurAddr + 2 ); - /* toggle DMA to write and select sector counter reg */ - dma_wd.dma_mode_status =3D 0x92; - MFPDELAY(); - dma_wd.dma_mode_status =3D 0x192; - MFPDELAY(); - /* program for 255*512 bytes and start DMA */ - DMA_LONG_WRITE( SLM_DMA_AMOUNT, 0x112 ); -#endif -=09 - local_irq_restore(flags); - -#ifdef DEBUG - if (did_wait) { - int ms; - do_gettimeofday( &end_tm ); - ms =3D (end_tm.tv_sec*1000000+end_tm.tv_usec) - - (start_tm.tv_sec*1000000+start_tm.tv_usec);=20 - printk( "SLM: did %ld.%ld ms busy waiting for %d bytes\n", - ms/1000, ms%1000, d ); - } - else - printk( "SLM: didn't wait (!)\n" ); -#endif - - if ((unsigned char *)PTOV( SLMCurAddr + SLMSliceSize ) >=3D BufferP) = { - /* will be last slice, no timer necessary */ -#ifdef DEBUG - printk( "SLM: CurAddr=3D%#lx EndAddr=3D%#lx last slice -> no timer\n= ", - SLMCurAddr, SLMEndAddr ); -#endif - } - else { - /* not last slice */ - SLMEndAddr =3D SLMCurAddr + SLMSliceSize + SLM_DMA_INT_OFFSET; - START_TIMER( DMA_TIME_FOR( SLMSliceSize )); -#ifdef DEBUG - printk( "SLM: CurAddr=3D%#lx EndAddr=3D%#lx timer=3D%ld\n", - SLMCurAddr, SLMEndAddr, DMA_TIME_FOR( SLMSliceSize ) ); -#endif - } -#endif /* SLM_CONT_CNT_REPROG */ -} - - -static void set_dma_addr( unsigned long paddr ) - -{ unsigned long flags; - - local_irq_save(flags); - dma_wd.dma_lo =3D (unsigned char)paddr; - paddr >>=3D 8; - MFPDELAY(); - dma_wd.dma_md =3D (unsigned char)paddr; - paddr >>=3D 8; - MFPDELAY(); - if (ATARIHW_PRESENT( EXTD_DMA )) - st_dma_ext_dmahi =3D (unsigned short)paddr; - else - dma_wd.dma_hi =3D (unsigned char)paddr; - MFPDELAY(); - local_irq_restore(flags); -} - - -static unsigned long get_dma_addr( void ) - -{ unsigned long addr; -=09 - addr =3D dma_wd.dma_lo & 0xff; - MFPDELAY(); - addr |=3D (dma_wd.dma_md & 0xff) << 8; - MFPDELAY(); - addr |=3D (dma_wd.dma_hi & 0xff) << 16; - MFPDELAY(); - - return( addr ); -} - - -static ssize_t slm_write( struct file *file, const char *buf, size_t c= ount, - loff_t *ppos ) - -{ - struct inode *node =3D file->f_path.dentry->d_inode; - int device =3D iminor(node); - int n, filled, w, h; - - while( SLMState =3D=3D PRINTING || - (SLMState =3D=3D FILLING && SLMBufOwner !=3D device) ) { - interruptible_sleep_on( &slm_wait ); - if (signal_pending(current)) - return( -ERESTARTSYS ); - } - if (SLMState =3D=3D IDLE) { - /* first data of page: get current page size */ - if (slm_get_pagesize( device, &w, &h )) - return( -EIO ); - BufferSize =3D w*h/8; - if (BufferSize > SLM_BUFFER_SIZE) - return( -ENOMEM ); - - SLMState =3D FILLING; - SLMBufOwner =3D device; - } - - n =3D count; - filled =3D BufferP - SLMBuffer; - if (filled + n > BufferSize) - n =3D BufferSize - filled; - - if (copy_from_user(BufferP, buf, n)) - return -EFAULT; - BufferP +=3D n; - filled +=3D n; - - if (filled =3D=3D BufferSize) { - /* Check the paper size again! The user may have switched it in the - * time between starting the data and finishing them. Would end up i= n - * a trashy page... */ - if (slm_get_pagesize( device, &w, &h )) - return( -EIO ); - if (BufferSize !=3D w*h/8) { - printk( KERN_NOTICE "slm%d: page size changed while printing\n", - device ); - return( -EAGAIN ); - } - - SLMState =3D PRINTING; - /* choose a slice size that is a multiple of the line size */ -#ifndef SLM_CONT_CNT_REPROG - SLMSliceSize =3D SLM_SLICE_SIZE(w); -#endif - =09 - start_print( device ); - sleep_on( &print_wait ); - if (SLMError && IS_REAL_ERROR(SLMError)) { - printk( KERN_ERR "slm%d: %s\n", device, slm_errstr(SLMError) ); - n =3D -EIO; - } - - SLMState =3D IDLE; - BufferP =3D SLMBuffer; - wake_up_interruptible( &slm_wait ); - } -=09 - return( n ); -} - - -/* -------------------------------------------------------------------= --- */ -/* ioctl Functions */ - - -static int slm_ioctl( struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg ) - -{ int device =3D iminor(inode), err; -=09 - /* I can think of setting: - * - manual feed - * - paper format - * - copy count - * - ... - * but haven't implemented that yet :-) - * BTW, has anybody better docs about the MODE SENSE/MODE SELECT data= ? - */ - switch( cmd ) { - - case SLMIORESET: /* reset buffer, i.e. empty the buffer */ - if (!(file->f_mode & 2)) - return( -EINVAL ); - if (SLMState =3D=3D PRINTING) - return( -EBUSY ); - SLMState =3D IDLE; - BufferP =3D SLMBuffer; - wake_up_interruptible( &slm_wait ); - return( 0 ); - =09 - case SLMIOGSTAT: { /* get status */ - int stat; - char *str; - - stat =3D slm_req_sense( device ); - if (arg) { - str =3D slm_errstr( stat ); - if (put_user(stat, - (long *)&((struct SLM_status *)arg)->stat)) - return -EFAULT; - if (copy_to_user( ((struct SLM_status *)arg)->str, str, - strlen(str) + 1)) - return -EFAULT; - } - return( stat ); - } - =09 - case SLMIOGPSIZE: { /* get paper size */ - int w, h; - =09 - if ((err =3D slm_get_pagesize( device, &w, &h ))) return( err ); - =09 - if (put_user(w, (long *)&((struct SLM_paper_size *)arg)->wid= th)) - return -EFAULT; - if (put_user(h, (long *)&((struct SLM_paper_size *)arg)->height)) - return -EFAULT; - return( 0 ); - } - =09 - case SLMIOGMFEED: /* get manual feed */ - return( -EINVAL ); - - case SLMIOSPSIZE: /* set paper size */ - return( -EINVAL ); - - case SLMIOSMFEED: /* set manual feed */ - return( -EINVAL ); - - } - return( -EINVAL ); -} - - -/* -------------------------------------------------------------------= --- */ -/* Opening and Closing */ - - -static int slm_open( struct inode *inode, struct file *file ) - -{ int device; - struct slm *sip; -=09 - device =3D iminor(inode); - if (device >=3D N_SLM_Printers) - return( -ENXIO ); - sip =3D &slm_info[device]; - - if (file->f_mode & 2) { - /* open for writing is exclusive */ - if ( !atomic_dec_and_test(&sip->wr_ok) ) { - atomic_inc(&sip->wr_ok);=09 - return( -EBUSY ); - } - } - if (file->f_mode & 1) { - /* open for reading is exclusive */ - if ( !atomic_dec_and_test(&sip->rd_ok) ) { - atomic_inc(&sip->rd_ok); - return( -EBUSY ); - } - } - - return( 0 ); -} - - -static int slm_release( struct inode *inode, struct file *file ) - -{ int device; - struct slm *sip; -=09 - device =3D iminor(inode); - sip =3D &slm_info[device]; - - if (file->f_mode & 2) - atomic_inc( &sip->wr_ok ); - if (file->f_mode & 1) - atomic_inc( &sip->rd_ok ); -=09 - return( 0 ); -} - - -/* -------------------------------------------------------------------= --- */ -/* ACSI Primitives for the SLM */ - - -static int slm_req_sense( int device ) - -{ int stat, rv; - struct slm *sip =3D &slm_info[device]; -=09 - stdma_lock( NULL, NULL ); - - CMDSET_TARG_LUN( slmreqsense_cmd, sip->target, sip->lun ); - if (!acsicmd_nodma( slmreqsense_cmd, 0 ) || - (stat =3D acsi_getstatus()) < 0) - rv =3D SLMSTAT_ACSITO; - else - rv =3D stat & 0x1f; - - ENABLE_IRQ(); - stdma_release(); - return( rv ); -} - - -static int slm_mode_sense( int device, char *buffer, int abs_flag ) - -{ unsigned char stat, len; - int rv =3D 0; - struct slm *sip =3D &slm_info[device]; -=09 - stdma_lock( NULL, NULL ); - - CMDSET_TARG_LUN( slmmsense_cmd, sip->target, sip->lun ); - slmmsense_cmd[5] =3D abs_flag ? 0x80 : 0; - if (!acsicmd_nodma( slmmsense_cmd, 0 )) { - rv =3D SLMSTAT_ACSITO; - goto the_end; - } - - if (!acsi_extstatus( &stat, 1 )) { - acsi_end_extstatus(); - rv =3D SLMSTAT_ACSITO; - goto the_end; - } -=09 - if (!acsi_extstatus( &len, 1 )) { - acsi_end_extstatus(); - rv =3D SLMSTAT_ACSITO; - goto the_end; - } - buffer[0] =3D len; - if (!acsi_extstatus( buffer+1, len )) { - acsi_end_extstatus(); - rv =3D SLMSTAT_ACSITO; - goto the_end; - } -=09 - acsi_end_extstatus(); - rv =3D stat & 0x1f; - - the_end: - ENABLE_IRQ(); - stdma_release(); - return( rv ); -} - - -#if 0 -/* currently unused */ -static int slm_mode_select( int device, char *buffer, int len, - int default_flag ) - -{ int stat, rv; - struct slm *sip =3D &slm_info[device]; -=09 - stdma_lock( NULL, NULL ); - - CMDSET_TARG_LUN( slmmselect_cmd, sip->target, sip->lun ); - slmmselect_cmd[5] =3D default_flag ? 0x80 : 0; - if (!acsicmd_nodma( slmmselect_cmd, 0 )) { - rv =3D SLMSTAT_ACSITO; - goto the_end; - } - - if (!default_flag) { - unsigned char c =3D len; - if (!acsi_extcmd( &c, 1 )) { - rv =3D SLMSTAT_ACSITO; - goto the_end; - } - if (!acsi_extcmd( buffer, len )) { - rv =3D SLMSTAT_ACSITO; - goto the_end; - } - } -=09 - stat =3D acsi_getstatus(); - rv =3D (stat < 0 ? SLMSTAT_ACSITO : stat); - - the_end: - ENABLE_IRQ(); - stdma_release(); - return( rv ); -} -#endif - - -static int slm_get_pagesize( int device, int *w, int *h ) - -{ char buf[256]; - int stat; -=09 - stat =3D slm_mode_sense( device, buf, 0 ); - ENABLE_IRQ(); - stdma_release(); - - if (stat !=3D SLMSTAT_OK) - return( -EIO ); - - *w =3D (buf[3] << 8) | buf[4]; - *h =3D (buf[1] << 8) | buf[2]; - return( 0 ); -} - - -/* -------------------------------------------------------------------= --- */ -/* Initialization */ - - -int attach_slm( int target, int lun ) - -{ static int did_register; - int len; - - if (N_SLM_Printers >=3D MAX_SLM) { - printk( KERN_WARNING "Too much SLMs\n" ); - return( 0 ); - } -=09 - /* do an INQUIRY */ - udelay(100); - CMDSET_TARG_LUN( slminquiry_cmd, target, lun ); - if (!acsicmd_nodma( slminquiry_cmd, 0 )) { - inq_timeout: - printk( KERN_ERR "SLM inquiry command timed out.\n" ); - inq_fail: - acsi_end_extstatus(); - return( 0 ); - } - /* read status and header of return data */ - if (!acsi_extstatus( SLMBuffer, 6 )) - goto inq_timeout; - - if (SLMBuffer[1] !=3D 2) { /* device type =3D=3D printer? */ - printk( KERN_ERR "SLM inquiry returned device type !=3D printer\n" )= ; - goto inq_fail; - } - len =3D SLMBuffer[5]; -=09 - /* read id string */ - if (!acsi_extstatus( SLMBuffer, len )) - goto inq_timeout; - acsi_end_extstatus(); - SLMBuffer[len] =3D 0; - - if (!did_register) { - did_register =3D 1; - } - - slm_info[N_SLM_Printers].target =3D target; - slm_info[N_SLM_Printers].lun =3D lun; - atomic_set(&slm_info[N_SLM_Printers].wr_ok, 1 );=20 - atomic_set(&slm_info[N_SLM_Printers].rd_ok, 1 ); -=09 - printk( KERN_INFO " Printer: %s\n", SLMBuffer ); - printk( KERN_INFO "Detected slm%d at id %d lun %d\n", - N_SLM_Printers, target, lun ); - N_SLM_Printers++; - return( 1 ); -} - -int slm_init( void ) - -{ - int i; - if (register_chrdev( ACSI_MAJOR, "slm", &slm_fops )) { - printk( KERN_ERR "Unable to get major %d for ACSI SLM\n", ACSI_MAJOR= ); - return -EBUSY; - } -=09 - if (!(SLMBuffer =3D atari_stram_alloc( SLM_BUFFER_SIZE, "SLM" ))) { - printk( KERN_ERR "Unable to get SLM ST-Ram buffer.\n" ); - unregister_chrdev( ACSI_MAJOR, "slm" ); - return -ENOMEM; - } - BufferP =3D SLMBuffer; - SLMState =3D IDLE; -=09 - return 0; -} - -#ifdef MODULE - -/* from acsi.c */ -void acsi_attach_SLMs( int (*attach_func)( int, int ) ); - -int init_module(void) -{ - int err; - - if ((err =3D slm_init())) - return( err ); - /* This calls attach_slm() for every target/lun where acsi.c detected= a - * printer */ - acsi_attach_SLMs( attach_slm ); - return( 0 ); -} - -void cleanup_module(void) -{ - if (unregister_chrdev( ACSI_MAJOR, "slm" ) !=3D 0) - printk( KERN_ERR "acsi_slm: cleanup_module failed\n"); - atari_stram_free( SLMBuffer ); -} -#endif --- linux-2.6.22-rc6-mm1/drivers/net/atari_bionet.c 2007-06-28 14:53:05= =2E000000000 +0200 +++ /dev/null 2006-09-19 00:45:31.000000000 +0200 @@ -1,675 +0,0 @@ -/* bionet.c BioNet-100 device driver for linux68k. - * - * Version: @(#)bionet.c 1.0 02/06/96 - * - * Author: Hartmut Laue - * and Torsten Narjes - * - * Little adaptions for integration into pl7 by Roman Hodek - * - * Some changes in bionet_poll_rx by Karl-Heinz Lohner - * - What is it ? - ------------ - This driver controls the BIONET-100 LAN-Adapter which connects - an ATARI ST/TT via the ACSI-port to an Ethernet-based network. - - This version can be compiled as a loadable module (See the - compile command at the bottom of this file). - At load time, you can optionally set the debugging level and the - fastest response time on the command line of 'insmod'. - - 'bionet_debug' - controls the amount of diagnostic messages: - 0 : no messages - >0 : see code for meaning of printed messages - - 'bionet_min_poll_time' (always >=3D1) - gives the time (in jiffies) between polls. Low values - increase the system load (beware!) - - When loaded, a net device with the name 'bio0' becomes available, - which can be controlled with the usual 'ifconfig' command. - - It is possible to compile this driver into the kernel like other - (net) drivers. For this purpose, some source files (e.g. config-files - makefiles, Space.c) must be changed accordingly. (You may refer to - other drivers how to do it.) In this case, the device will be detecte= d - at boot time and (probably) appear as 'eth0'. - - This code is based on several sources: - - The driver code for a parallel port ethernet adapter by - Donald Becker (see file 'atp.c' from the PC linux distribution) - - The ACSI code by Roman Hodek for the ATARI-ACSI harddisk support - and DMA handling. - - Very limited information about moving packets in and out of the - BIONET-adapter from the TCP package for TOS by BioData GmbH. - - Theory of Operation - ------------------- - Because the ATARI DMA port is usually shared between several - devices (eg. harddisk, floppy) we cannot block the ACSI bus - while waiting for interrupts. Therefore we use a polling mechanism - to fetch packets from the adapter. For the same reason, we send - packets without checking that the previous packet has been sent to - the LAN. We rely on the higher levels of the networking code to detec= t - missing packets and resend them. - - Before we access the ATARI DMA controller, we check if another - process is using the DMA. If not, we lock the DMA, perform one or - more packet transfers and unlock the DMA before returning. - We do not use 'stdma_lock' unconditionally because it is unclear - if the networking code can be set to sleep, which will happen if - another (possibly slow) device is using the DMA controller. - - The polling is done via timer interrupts which periodically - 'simulate' an interrupt from the Ethernet adapter. The time (in jiffi= es) - between polls varies depending on an estimate of the net activity. - The allowed range is given by the variable 'bionet_min_poll_time' - for the lower (fastest) limit and the constant 'MAX_POLL_TIME' - for the higher (slowest) limit. - - Whenever a packet arrives, we switch to fastest response by setting - the polling time to its lowest limit. If the following poll fails, - because no packets have arrived, we increase the time for the next - poll. When the net activity is low, the polling time effectively - stays at its maximum value, resulting in the lowest load for the - machine. - */ - -#define MAX_POLL_TIME 10 - -static char version[] =3D - "bionet.c:v1.0 06-feb-96 (c) Hartmut Laue.\n"; - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* use 0 for production, 1 for verification, >2 for debug - */ -#ifndef NET_DEBUG -#define NET_DEBUG 0 -#endif -/* - * Global variable 'bionet_debug'. Can be set at load time by 'insmod' - */ -unsigned int bionet_debug =3D NET_DEBUG; -module_param(bionet_debug, int, 0); -MODULE_PARM_DESC(bionet_debug, "bionet debug level (0-2)"); -MODULE_LICENSE("GPL"); - -static unsigned int bionet_min_poll_time =3D 2; - - -/* Information that need to be kept for each board. - */ -struct net_local { - struct net_device_stats stats; - long open_time; /* for debugging */ - int poll_time; /* polling time varies with net load */ -}; - -static struct nic_pkt_s { /* packet format */ - unsigned char status; - unsigned char dummy; - unsigned char l_lo, l_hi; - unsigned char buffer[3000]; -} *nic_packet; -unsigned char *phys_nic_packet; - -/* Index to functions, as function prototypes. - */ -static int bionet_open(struct net_device *dev); -static int bionet_send_packet(struct sk_buff *skb, struct net_device *= dev); -static void bionet_poll_rx(struct net_device *); -static int bionet_close(struct net_device *dev); -static struct net_device_stats *net_get_stats(struct net_device *dev); -static void bionet_tick(unsigned long); - -static DEFINE_TIMER(bionet_timer, bionet_tick, 0, 0); - -#define STRAM_ADDR(a) (((a) & 0xff000000) =3D=3D 0) - -/* The following routines access the ethernet board connected to the - * ACSI port via the st_dma chip. - */ -#define NODE_ADR 0x60 - -#define C_READ 8 -#define C_WRITE 0x0a -#define C_GETEA 0x0f -#define C_SETCR 0x0e - -static int -sendcmd(unsigned int a0, unsigned int mod, unsigned int cmd) { - unsigned int c; - - dma_wd.dma_mode_status =3D (mod | ((a0) ? 2 : 0) | 0x88); - dma_wd.fdc_acces_seccount =3D cmd; - dma_wd.dma_mode_status =3D (mod | 0x8a); - - if( !acsi_wait_for_IRQ(HZ/2) ) /* wait for cmd ack */ - return -1; /* timeout */ - - c =3D dma_wd.fdc_acces_seccount; - return (c & 0xff); -} - - -static void -set_status(int cr) { - sendcmd(0,0x100,NODE_ADR | C_SETCR); /* CMD: SET CR */ - sendcmd(1,0x100,cr); - - dma_wd.dma_mode_status =3D 0x80; -} - -static int -get_status(unsigned char *adr) { - int i,c; - - DISABLE_IRQ(); - c =3D sendcmd(0,0x00,NODE_ADR | C_GETEA); /* CMD: GET ETH ADR*/ - if( c < 0 ) goto gsend; - - /* now read status bytes */ - - for (i=3D0; i<6; i++) { - dma_wd.fdc_acces_seccount =3D 0; /* request next byte */ - - if( !acsi_wait_for_IRQ(HZ/2) ) { /* wait for cmd ack */ - c =3D -1; - goto gsend; /* timeout */ - } - c =3D dma_wd.fdc_acces_seccount; - *adr++ =3D (unsigned char)c; - } - c =3D 1; -gsend: - dma_wd.dma_mode_status =3D 0x80; - return c; -} - -static irqreturn_t -bionet_intr(int irq, void *data) { - return IRQ_HANDLED; -} - - -static int -get_frame(unsigned long paddr, int odd) { - int c; - unsigned long flags; - - DISABLE_IRQ(); - local_irq_save(flags); - - dma_wd.dma_mode_status =3D 0x9a; - dma_wd.dma_mode_status =3D 0x19a; - dma_wd.dma_mode_status =3D 0x9a; - dma_wd.fdc_acces_seccount =3D 0x04; /* sector count (was 5) */ - dma_wd.dma_lo =3D (unsigned char)paddr; - paddr >>=3D 8; - dma_wd.dma_md =3D (unsigned char)paddr; - paddr >>=3D 8; - dma_wd.dma_hi =3D (unsigned char)paddr; - local_irq_restore(flags); - - c =3D sendcmd(0,0x00,NODE_ADR | C_READ); /* CMD: READ */ - if( c < 128 ) goto rend; - - /* now read block */ - - c =3D sendcmd(1,0x00,odd); /* odd flag for address shift */ - dma_wd.dma_mode_status =3D 0x0a; - - if( !acsi_wait_for_IRQ(100) ) { /* wait for DMA to complete */ - c =3D -1; - goto rend; - } - dma_wd.dma_mode_status =3D 0x8a; - dma_wd.dma_mode_status =3D 0x18a; - dma_wd.dma_mode_status =3D 0x8a; - c =3D dma_wd.fdc_acces_seccount; - - dma_wd.dma_mode_status =3D 0x88; - c =3D dma_wd.fdc_acces_seccount; - c =3D 1; - -rend: - dma_wd.dma_mode_status =3D 0x80; - udelay(40); - acsi_wait_for_noIRQ(20); - return c; -} - - -static int -hardware_send_packet(unsigned long paddr, int cnt) { - unsigned int c; - unsigned long flags; - - DISABLE_IRQ(); - local_irq_save(flags); - - dma_wd.dma_mode_status =3D 0x19a; - dma_wd.dma_mode_status =3D 0x9a; - dma_wd.dma_mode_status =3D 0x19a; - dma_wd.dma_lo =3D (unsigned char)paddr; - paddr >>=3D 8; - dma_wd.dma_md =3D (unsigned char)paddr; - paddr >>=3D 8; - dma_wd.dma_hi =3D (unsigned char)paddr; - - dma_wd.fdc_acces_seccount =3D 0x4; /* sector count */ - local_irq_restore(flags); - - c =3D sendcmd(0,0x100,NODE_ADR | C_WRITE); /* CMD: WRITE */ - c =3D sendcmd(1,0x100,cnt&0xff); - c =3D sendcmd(1,0x100,cnt>>8); - - /* now write block */ - - dma_wd.dma_mode_status =3D 0x10a; /* DMA enable */ - if( !acsi_wait_for_IRQ(100) ) /* wait for DMA to complete */ - goto end; - - dma_wd.dma_mode_status =3D 0x19a; /* DMA disable ! */ - c =3D dma_wd.fdc_acces_seccount; - -end: - c =3D sendcmd(1,0x100,0); - c =3D sendcmd(1,0x100,0); - - dma_wd.dma_mode_status =3D 0x180; - udelay(40); - acsi_wait_for_noIRQ(20); - return( c & 0x02); -} - - -/* Check for a network adaptor of this type, and return '0' if one exi= sts. - */ -struct net_device * __init bionet_probe(int unit) -{ - struct net_device *dev; - unsigned char station_addr[6]; - static unsigned version_printed; - static int no_more_found; /* avoid "Probing for..." printed 4 times *= / - int i; - int err; - - if (!MACH_IS_ATARI || no_more_found) - return ERR_PTR(-ENODEV); - - dev =3D alloc_etherdev(sizeof(struct net_local)); - if (!dev) - return ERR_PTR(-ENOMEM); - if (unit >=3D 0) { - sprintf(dev->name, "eth%d", unit); - netdev_boot_setup_check(dev); - } - SET_MODULE_OWNER(dev); - - printk("Probing for BioNet 100 Adapter...\n"); - - stdma_lock(bionet_intr, NULL); - i =3D get_status(station_addr); /* Read the station address PROM. */ - ENABLE_IRQ(); - stdma_release(); - - /* Check the first three octets of the S.A. for the manufactor's code= =2E - */ - - if( i < 0 - || station_addr[0] !=3D 'B' - || station_addr[1] !=3D 'I' - || station_addr[2] !=3D 'O' ) { - no_more_found =3D 1; - printk( "No BioNet 100 found.\n" ); - free_netdev(dev); - return ERR_PTR(-ENODEV); - } - - if (bionet_debug > 0 && version_printed++ =3D=3D 0) - printk(version); - - printk("%s: %s found, eth-addr: %02x-%02x-%02x:%02x-%02x-%02x.\n", - dev->name, "BioNet 100", - station_addr[0], station_addr[1], station_addr[2], - station_addr[3], station_addr[4], station_addr[5]); - - /* Initialize the device structure. */ - - nic_packet =3D (struct nic_pkt_s *)acsi_buffer; - phys_nic_packet =3D (unsigned char *)phys_acsi_buffer; - if (bionet_debug > 0) { - printk("nic_packet at 0x%p, phys at 0x%p\n", - nic_packet, phys_nic_packet ); - } - - dev->open =3D bionet_open; - dev->stop =3D bionet_close; - dev->hard_start_xmit =3D bionet_send_packet; - dev->get_stats =3D net_get_stats; - - /* Fill in the fields of the device structure with ethernet-generic - * values. This should be in a common file instead of per-driver. - */ - - for (i =3D 0; i < ETH_ALEN; i++) { -#if 0 - dev->broadcast[i] =3D 0xff; -#endif - dev->dev_addr[i] =3D station_addr[i]; - } - err =3D register_netdev(dev); - if (!err) - return dev; - free_netdev(dev); - return ERR_PTR(err); -} - -/* Open/initialize the board. This is called (in the current kernel) - sometime after booting when the 'ifconfig' program is run. - - This routine should set everything up anew at each open, even - registers that "should" only need to be set once at boot, so that - there is non-reboot way to recover if something goes wrong. - */ -static int -bionet_open(struct net_device *dev) { - struct net_local *lp =3D netdev_priv(dev); - - if (bionet_debug > 0) - printk("bionet_open\n"); - stdma_lock(bionet_intr, NULL); - - /* Reset the hardware here. - */ - set_status(4); - lp->open_time =3D 0; /*jiffies*/ - lp->poll_time =3D MAX_POLL_TIME; - - dev->tbusy =3D 0; - dev->interrupt =3D 0; - dev->start =3D 1; - - stdma_release(); - bionet_timer.data =3D (long)dev; - bionet_timer.expires =3D jiffies + lp->poll_time; - add_timer(&bionet_timer); - return 0; -} - -static int -bionet_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct net_local *lp =3D netdev_priv(dev); - unsigned long flags; - - /* Block a timer-based transmit from overlapping. This could better = be - * done with atomic_swap(1, dev->tbusy), but set_bit() works as well. - */ - local_irq_save(flags); - - if (stdma_islocked()) { - local_irq_restore(flags); - lp->stats.tx_errors++; - } - else { - int length =3D ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; - unsigned long buf =3D virt_to_phys(skb->data); - int stat; - - stdma_lock(bionet_intr, NULL); - local_irq_restore(flags); - if( !STRAM_ADDR(buf+length-1) ) { - skb_copy_from_linear_data(skb, nic_packet->buffer, - length); - buf =3D (unsigned long)&((struct nic_pkt_s *)phys_nic_packet)->buff= er; - } - - if (bionet_debug >1) { - u_char *data =3D nic_packet->buffer, *p; - int i; - - printk( "%s: TX pkt type 0x%4x from ", dev->name, - ((u_short *)data)[6]); - - for( p =3D &data[6], i =3D 0; i < 6; i++ ) - printk("%02x%s", *p++,i !=3D 5 ? ":" : "" ); - printk(" to "); - - for( p =3D data, i =3D 0; i < 6; i++ ) - printk("%02x%s", *p++,i !=3D 5 ? ":" : "" "\n" ); - - printk( "%s: ", dev->name ); - printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%0= 2x%02x %02x%02x%02x%02x" - " %02x%02x%02x%02x len %d\n", - data[12], data[13], data[14], data[15], data[16], data[17], data= [18], data[19], - data[20], data[21], data[22], data[23], data[24], data[25], data= [26], data[27], - data[28], data[29], data[30], data[31], data[32], data[33], - length ); - } - dma_cache_maintenance(buf, length, 1); - - stat =3D hardware_send_packet(buf, length); - ENABLE_IRQ(); - stdma_release(); - - dev->trans_start =3D jiffies; - dev->tbusy =3D 0; - lp->stats.tx_packets++; - lp->stats.tx_bytes+=3Dlength; - } - dev_kfree_skb(skb); - - return 0; -} - -/* We have a good packet(s), get it/them out of the buffers. - */ -static void -bionet_poll_rx(struct net_device *dev) { - struct net_local *lp =3D netdev_priv(dev); - int boguscount =3D 10; - int pkt_len, status; - unsigned long flags; - - local_irq_save(flags); - /* ++roman: Take care at locking the ST-DMA... This must be done with= ints - * off, since otherwise an int could slip in between the question and= the - * locking itself, and then we'd go to sleep... And locking itself is - * necessary to keep the floppy_change timer from working with ST-DMA - * registers. */ - if (stdma_islocked()) { - local_irq_restore(flags); - return; - } - stdma_lock(bionet_intr, NULL); - DISABLE_IRQ(); - local_irq_restore(flags); - - if( lp->poll_time < MAX_POLL_TIME ) lp->poll_time++; - - while(boguscount--) { - status =3D get_frame((unsigned long)phys_nic_packet, 0); - - if( status =3D=3D 0 ) break; - - /* Good packet... */ - - dma_cache_maintenance((unsigned long)phys_nic_packet, 1520, 0); - - pkt_len =3D (nic_packet->l_hi << 8) | nic_packet->l_lo; - - lp->poll_time =3D bionet_min_poll_time; /* fast poll */ - if( pkt_len >=3D 60 && pkt_len <=3D 1520 ) { - /* ^^^^ war 1514 KHL */ - /* Malloc up new buffer. - */ - struct sk_buff *skb =3D dev_alloc_skb( pkt_len + 2 ); - if (skb =3D=3D NULL) { - printk("%s: Memory squeeze, dropping packet.\n", - dev->name); - lp->stats.rx_dropped++; - break; - } - - skb_reserve( skb, 2 ); /* 16 Byte align */ - skb_put( skb, pkt_len ); /* make room */ - - /* 'skb->data' points to the start of sk_buff data area. - */ - skb_copy_to_linear_data(skb, nic_packet->buffer, - pkt_len); - skb->protocol =3D eth_type_trans( skb, dev ); - netif_rx(skb); - dev->last_rx =3D jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes+=3Dpkt_len; - - /* If any worth-while packets have been received, dev_rint() - has done a mark_bh(INET_BH) for us and will work on them - when we get to the bottom-half routine. - */ - - if (bionet_debug >1) { - u_char *data =3D nic_packet->buffer, *p; - int i; - - printk( "%s: RX pkt type 0x%4x from ", dev->name, - ((u_short *)data)[6]); - - - for( p =3D &data[6], i =3D 0; i < 6; i++ ) - printk("%02x%s", *p++,i !=3D 5 ? ":" : "" ); - printk(" to "); - for( p =3D data, i =3D 0; i < 6; i++ ) - printk("%02x%s", *p++,i !=3D 5 ? ":" : "" "\n" ); - - printk( "%s: ", dev->name ); - printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x= %02x%02x %02x%02x%02x%02x" - " %02x%02x%02x%02x len %d\n", - data[12], data[13], data[14], data[15], data[16], data[17], da= ta[18], data[19], - data[20], data[21], data[22], data[23], data[24], data[25], da= ta[26], data[27], - data[28], data[29], data[30], data[31], data[32], data[33], - pkt_len ); - } - } - else { - printk(" Packet has wrong length: %04d bytes\n", pkt_len); - lp->stats.rx_errors++; - } - } - stdma_release(); - ENABLE_IRQ(); - return; -} - -/* bionet_tick: called by bionet_timer. Reads packets from the adapter= , - * passes them to the higher layers and restarts the timer. - */ -static void -bionet_tick(unsigned long data) { - struct net_device *dev =3D (struct net_device *)data; - struct net_local *lp =3D netdev_priv(dev); - - if( bionet_debug > 0 && (lp->open_time++ & 7) =3D=3D 8 ) - printk("bionet_tick: %ld\n", lp->open_time); - - if( !stdma_islocked() ) bionet_poll_rx(dev); - - bionet_timer.expires =3D jiffies + lp->poll_time; - add_timer(&bionet_timer); -} - -/* The inverse routine to bionet_open(). - */ -static int -bionet_close(struct net_device *dev) { - struct net_local *lp =3D netdev_priv(dev); - - if (bionet_debug > 0) - printk("bionet_close, open_time=3D%ld\n", lp->open_time); - del_timer(&bionet_timer); - stdma_lock(bionet_intr, NULL); - - set_status(0); - lp->open_time =3D 0; - - dev->tbusy =3D 1; - dev->start =3D 0; - - stdma_release(); - return 0; -} - -/* Get the current statistics. - This may be called with the card open or closed. - */ -static struct net_device_stats *net_get_stats(struct net_device *dev) -{ - struct net_local *lp =3D netdev_priv(dev); - return &lp->stats; -} - - -#ifdef MODULE - -static struct net_device *bio_dev; - -int init_module(void) -{ - bio_dev =3D bionet_probe(-1); - if (IS_ERR(bio_dev)) - return PTR_ERR(bio_dev); - return 0; -} - -void cleanup_module(void) -{ - unregister_netdev(bio_dev); - free_netdev(bio_dev); -} - -#endif /* MODULE */ - -/* Local variables: - * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include - -b m68k-linuxaout -Wall -Wstrict-prototypes -O2 - -fomit-frame-pointer -pipe -DMODULE -I../../net/inet -c bionet.c" - * version-control: t - * kept-new-versions: 5 - * tab-width: 8 - * End: - */ --- linux-2.6.22-rc6-mm1/drivers/net/atari_pamsnet.c 2007-06-28 14:54:3= 1.000000000 +0200 +++ /dev/null 2006-09-19 00:45:31.000000000 +0200 @@ -1,878 +0,0 @@ -/* atari_pamsnet.c PAMsNet device driver for linux68k. - * - * Version: @(#)PAMsNet.c 0.2=EF=BF=BD 03/31/96 - * - * Author: Torsten Lang - * - * - * This driver is based on my driver PAMSDMA.c for MiNT-Net and - * on the driver bionet.c written by - * Hartmut Laue - * and Torsten Narjes - * - * Little adaptions for integration into pl7 by Roman Hodek - * - What is it ? - ------------ - This driver controls the PAMsNet LAN-Adapter which connects - an ATARI ST/TT via the ACSI-port to an Ethernet-based network. - - This version can be compiled as a loadable module (See the - compile command at the bottom of this file). - At load time, you can optionally set the debugging level and the - fastest response time on the command line of 'insmod'. - - 'pamsnet_debug' - controls the amount of diagnostic messages: - 0 : no messages - >0 : see code for meaning of printed messages - - 'pamsnet_min_poll_time' (always >=3D1) - gives the time (in jiffies) between polls. Low values - increase the system load (beware!) - - When loaded, a net device with the name 'eth?' becomes available, - which can be controlled with the usual 'ifconfig' command. - - It is possible to compile this driver into the kernel like other - (net) drivers. For this purpose, some source files (e.g. config-files - makefiles, Space.c) must be changed accordingly. (You may refer to - other drivers how to do it.) In this case, the device will be detecte= d - at boot time and (probably) appear as 'eth0'. - - Theory of Operation - ------------------- - Because the ATARI DMA port is usually shared between several - devices (eg. harddisk, floppy) we cannot block the ACSI bus - while waiting for interrupts. Therefore we use a polling mechanism - to fetch packets from the adapter. For the same reason, we send - packets without checking that the previous packet has been sent to - the LAN. We rely on the higher levels of the networking code to detec= t - missing packets and resend them. - - Before we access the ATARI DMA controller, we check if another - process is using the DMA. If not, we lock the DMA, perform one or - more packet transfers and unlock the DMA before returning. - We do not use 'stdma_lock' unconditionally because it is unclear - if the networking code can be set to sleep, which will happen if - another (possibly slow) device is using the DMA controller. - - The polling is done via timer interrupts which periodically - 'simulate' an interrupt from the Ethernet adapter. The time (in jiffi= es) - between polls varies depending on an estimate of the net activity. - The allowed range is given by the variable 'bionet_min_poll_time' - for the lower (fastest) limit and the constant 'MAX_POLL_TIME' - for the higher (slowest) limit. - - Whenever a packet arrives, we switch to fastest response by setting - the polling time to its lowest limit. If the following poll fails, - because no packets have arrived, we increase the time for the next - poll. When the net activity is low, the polling time effectively - stays at its maximum value, resulting in the lowest load for the - machine. - */ - -#define MAX_POLL_TIME 10 - -static char *version =3D - "pamsnet.c:v0.2beta 30-mar-96 (c) Torsten Lang.\n"; - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#undef READ -#undef WRITE - -/* use 0 for production, 1 for verification, >2 for debug - */ -#ifndef NET_DEBUG -#define NET_DEBUG 0 -#endif -/* - * Global variable 'pamsnet_debug'. Can be set at load time by 'insmod= ' - */ -unsigned int pamsnet_debug =3D NET_DEBUG; -module_param(pamsnet_debug, int, 0); -MODULE_PARM_DESC(pamsnet_debug, "pamsnet debug enable (0-1)"); -MODULE_LICENSE("GPL"); - -static unsigned int pamsnet_min_poll_time =3D 2; - - -/* Information that need to be kept for each board. - */ -struct net_local { - struct net_device_stats stats; - long open_time; /* for debugging */ - int poll_time; /* polling time varies with net load */ -}; - -static struct nic_pkt_s { /* packet format */ - unsigned char buffer[2048]; -} *nic_packet =3D 0; -unsigned char *phys_nic_packet; - -typedef unsigned char HADDR[6]; /* 6-byte hardware address of lance */ - -/* Index to functions, as function prototypes. - */ -static void start (int target); -static int stop (int target); -static int testpkt (int target); -static int sendpkt (int target, unsigned char *buffer, int length); -static int receivepkt (int target, unsigned char *buffer); -static int inquiry (int target, unsigned char *buffer); -static HADDR *read_hw_addr(int target, unsigned char *buffer); -static void setup_dma (void *address, unsigned rw_flag, int num_blocks= ); -static int send_first (int target, unsigned char byte); -static int send_1_5 (int lun, unsigned char *command, int dma); -static int get_status (void); -static int calc_received (void *start_address); - -static int pamsnet_open(struct net_device *dev); -static int pamsnet_send_packet(struct sk_buff *skb, struct net_device = *dev); -static void pamsnet_poll_rx(struct net_device *); -static int pamsnet_close(struct net_device *dev); -static struct net_device_stats *net_get_stats(struct net_device *dev); -static void pamsnet_tick(unsigned long); - -static irqreturn_t pamsnet_intr(int irq, void *data); - -static DEFINE_TIMER(pamsnet_timer, pamsnet_tick, 0, 0); - -#define STRAM_ADDR(a) (((a) & 0xff000000) =3D=3D 0) - -typedef struct -{ - unsigned char reserved1[0x38]; - HADDR hwaddr; - unsigned char reserved2[0x1c2]; -} DMAHWADDR; - -/* - * Definitions of commands understood by the PAMs DMA adaptor. - * - * In general the DMA adaptor uses LUN 0, 5, 6 and 7 on one ID changea= ble - * by the PAM's Net software. - * - * LUN 0 works as a harddisk. You can boot the PAM's Net driver there. - * LUN 5 works as a harddisk and lets you access the RAM and some I/O = HW - * area. In sector 0, bytes 0x38-0x3d you find the ethernet HW a= ddress - * of the adaptor. - * LUN 6 works as a harddisk and lets you access the firmware ROM. - * LUN 7 lets you send and receive packets. - * - * Some commands like the INQUIRY command work identical on all used L= UNs. - * - * UNKNOWN1 seems to read some data. - * Command length is 6 bytes. - * UNKNOWN2 seems to read some data (command byte 1 must be !=3D0). Th= e - * following bytes seem to be something like an allocation le= ngth. - * Command length is 6 bytes. - * READPKT reads a packet received by the DMA adaptor. - * Command length is 6 bytes. - * WRITEPKT sends a packet transferred by the following DMA phase. The= length - * of the packet is transferred in command bytes 3 and 4. - * The adaptor automatically replaces the src hw address in a= n ethernet - * packet by its own hw address. - * Command length is 6 bytes. - * INQUIRY has the same function as the INQUIRY command supported by = harddisks - * and other SCSI devices. It lets you detect which device yo= u found - * at a given address. - * Command length is 6 bytes. - * START initializes the DMA adaptor. After this command it is able= to send - * and receive packets. There is no status byte returned! - * Command length is 1 byte. - * NUMPKTS gives back the number of received packets waiting in the q= ueue in - * the status byte. - * Command length is 1 byte. - * UNKNOWN3 - * UNKNOWN4 Function of these three commands is unknown. - * UNKNOWN5 The command length of these three commands is 1 byte. - * DESELECT immediately deselects the DMA adaptor. May important with = interrupt - * driven operation. - * Command length is 1 byte. - * STOP resets the DMA adaptor. After this command packets can no = longer - * be received or transferred. - * Command length is 6 byte. - */ - -enum {UNKNOWN1=3D3, READPKT=3D8, UNKNOWN2, WRITEPKT=3D10, INQUIRY=3D18= , START, - NUMPKTS=3D22, UNKNOWN3, UNKNOWN4, UNKNOWN5, DESELECT, STOP}; - -#define READSECTOR READPKT -#define WRITESECTOR WRITEPKT - -u_char *inquire8=3D"MV PAM's NET/GK"; - -#define DMALOW dma_wd.dma_lo -#define DMAMID dma_wd.dma_md -#define DMAHIGH dma_wd.dma_hi -#define DACCESS dma_wd.fdc_acces_seccount - -#define MFP_GPIP mfp.par_dt_reg - -/* Some useful functions */ - -#define INT (!(MFP_GPIP & 0x20)) -#define DELAY ({MFP_GPIP; MFP_GPIP; MFP_GPIP;}) -#define WRITEMODE(value) \ - ({ u_short dummy =3D value; \ - __asm__ volatile("movew %0, 0xFFFF8606" : : "d"(dummy)); \ - DELAY; \ - }) -#define WRITEBOTH(value1, value2) \ - ({ u_long dummy =3D (u_long)(value1)<<16 | (u_short)(value2); \ - __asm__ volatile("movel %0, 0xFFFF8604" : : "d"(dummy)); \ - DELAY; \ - }) - -/* Definitions for DMODE */ - -#define READ 0x000 -#define WRITE 0x100 - -#define DMA_FDC 0x080 -#define DMA_ACSI 0x000 - -#define DMA_DISABLE 0x040 - -#define SEC_COUNT 0x010 -#define DMA_WINDOW 0x000 - -#define REG_ACSI 0x008 -#define REG_FDC 0x000 - -#define A1 0x002 - -/* Timeout constants */ - -#define TIMEOUTCMD HZ/2 /* ca. 500ms */ -#define TIMEOUTDMA HZ /* ca. 1s */ -#define COMMAND_DELAY 500 /* ca. 0.5ms */ - -unsigned rw; -int lance_target =3D -1; -int if_up =3D 0; - -/* The following routines access the ethernet board connected to the - * ACSI port via the st_dma chip. - */ - -/* The following lowlevel routines work on physical addresses only and= assume - * that eventually needed buffers are - * - completely located in ST RAM - * - are contigous in the physical address space - */ - -/* Setup the DMA counter */ - -static void -setup_dma (void *address, unsigned rw_flag, int num_blocks) -{ - WRITEMODE((unsigned) rw_flag | DMA_FDC | SEC_COUNT | REG_ACS= I | - A1); - WRITEMODE((unsigned)(rw_flag ^ WRITE) | DMA_FDC | SEC_COUNT | REG_ACS= I | - A1); - WRITEMODE((unsigned) rw_flag | DMA_FDC | SEC_COUNT | REG_ACS= I | - A1); - DMALOW =3D (unsigned char)((unsigned long)address & 0xFF); - DMAMID =3D (unsigned char)(((unsigned long)address >> 8) & 0xFF); - DMAHIGH =3D (unsigned char)(((unsigned long)address >> 16) & 0xFF); - WRITEBOTH((unsigned)num_blocks & 0xFF, - rw_flag | DMA_FDC | DMA_WINDOW | REG_ACSI | A1); - rw =3D rw_flag; -} - -/* Send the first byte of an command block */ - -static int -send_first (int target, unsigned char byte) -{ - rw =3D READ; - acsi_delay_end(COMMAND_DELAY); - /* - * wake up ACSI - */ - WRITEMODE(DMA_FDC | DMA_WINDOW | REG_ACSI); - /* - * write command byte - */ - WRITEBOTH((target << 5) | (byte & 0x1F), DMA_FDC | - DMA_WINDOW | REG_ACSI | A1); - return (!acsi_wait_for_IRQ(TIMEOUTCMD)); -} - -/* Send the rest of an command block */ - -static int -send_1_5 (int lun, unsigned char *command, int dma) -{ - int i, j; - - for (i=3D0; i<5; i++) { - WRITEBOTH((!i ? (((lun & 0x7) << 5) | (command[i] & 0x1F)) - : command[i]), - rw | REG_ACSI | DMA_WINDOW | - ((i < 4) ? DMA_FDC - : (dma ? DMA_ACSI - : DMA_FDC)) | A1); - if (i < 4 && (j =3D !acsi_wait_for_IRQ(TIMEOUTCMD))) - return (j); - } - return (0); -} - -/* Read a status byte */ - -static int -get_status (void) -{ - WRITEMODE(DMA_FDC | DMA_WINDOW | REG_ACSI | A1); - acsi_delay_start(); - return ((int)(DACCESS & 0xFF)); -} - -/* Calculate the number of received bytes */ - -static int -calc_received (void *start_address) -{ - return (int)( - (((unsigned long)DMAHIGH << 16) | ((unsigned)DMAMID << 8) | DMALOW) - - (unsigned long)start_address); -} - -/* The following midlevel routines still work on physical addresses ..= =2E */ - -/* start() starts the PAM's DMA adaptor */ - -static void -start (int target) -{ - send_first(target, START); -} - -/* stop() stops the PAM's DMA adaptor and returns a value of zero in c= ase of success */ - -static int -stop (int target) -{ - int ret =3D -1; - unsigned char cmd_buffer[5]; - - if (send_first(target, STOP)) - goto bad; - cmd_buffer[0] =3D cmd_buffer[1] =3D cmd_buffer[2] =3D - cmd_buffer[3] =3D cmd_buffer[4] =3D 0; - if (send_1_5(7, cmd_buffer, 0) || - !acsi_wait_for_IRQ(TIMEOUTDMA) || - get_status()) - goto bad; - ret =3D 0; -bad: - return (ret); -} - -/* testpkt() returns the number of received packets waiting in the que= ue */ - -static int -testpkt(int target) -{ - int ret =3D -1; - - if (send_first(target, NUMPKTS)) - goto bad; - ret =3D get_status(); -bad: - return (ret); -} - -/* inquiry() returns 0 when PAM's DMA found, -1 when timeout, -2 other= wise */ -/* Please note: The buffer is for internal use only but must be define= d! */ - -static int -inquiry (int target, unsigned char *buffer) -{ - int ret =3D -1; - unsigned char *vbuffer =3D phys_to_virt((unsigned long)buffer); - unsigned char cmd_buffer[5]; - - if (send_first(target, INQUIRY)) - goto bad; - setup_dma(buffer, READ, 1); - vbuffer[8] =3D vbuffer[27] =3D 0; /* Avoid confusion with previous re= ad data */ - cmd_buffer[0] =3D cmd_buffer[1] =3D cmd_buffer[2] =3D cmd_buffer[4] =3D= 0; - cmd_buffer[3] =3D 48; - if (send_1_5(5, cmd_buffer, 1) || - !acsi_wait_for_IRQ(TIMEOUTDMA) || - get_status() || - (calc_received(buffer) < 32)) - goto bad; - dma_cache_maintenance((unsigned long)(buffer+8), 20, 0); - if (memcmp(inquire8, vbuffer+8, 20)) - goto bad; - ret =3D 0; -bad: - if (!!NET_DEBUG) { - vbuffer[8+20]=3D0; - printk("inquiry of target %d: %s\n", target, vbuffer+8); - } - return (ret); -} - -/* - * read_hw_addr() reads the sector containing the hwaddr and returns - * a pointer to it (virtual address!) or 0 in case of an error - */ - -static HADDR -*read_hw_addr(int target, unsigned char *buffer) -{ - HADDR *ret =3D 0; - unsigned char cmd_buffer[5]; - - if (send_first(target, READSECTOR)) - goto bad; - setup_dma(buffer, READ, 1); - cmd_buffer[0] =3D cmd_buffer[1] =3D cmd_buffer[2] =3D cmd_buffer[4] =3D= 0; - cmd_buffer[3] =3D 1; - if (send_1_5(5, cmd_buffer, 1) || - !acsi_wait_for_IRQ(TIMEOUTDMA) || - get_status()) - goto bad; - ret =3D phys_to_virt((unsigned long)&(((DMAHWADDR *)buffer)->hwaddr))= ; - dma_cache_maintenance((unsigned long)buffer, 512, 0); -bad: - return (ret); -} - -static irqreturn_t -pamsnet_intr(int irq, void *data) -{ - return IRQ_HANDLED; -} - -/* receivepkt() loads a packet to a given buffer and returns its lengt= h */ - -static int -receivepkt (int target, unsigned char *buffer) -{ - int ret =3D -1; - unsigned char cmd_buffer[5]; - - if (send_first(target, READPKT)) - goto bad; - setup_dma(buffer, READ, 3); - cmd_buffer[0] =3D cmd_buffer[1] =3D cmd_buffer[2] =3D cmd_buffer[4] =3D= 0; - cmd_buffer[3] =3D 3; - if (send_1_5(7, cmd_buffer, 1) || - !acsi_wait_for_IRQ(TIMEOUTDMA) || - get_status()) - goto bad; - ret =3D calc_received(buffer); -bad: - return (ret); -} - -/* sendpkt() sends a packet and returns a value of zero when the packe= t was sent - successfully */ - -static int -sendpkt (int target, unsigned char *buffer, int length) -{ - int ret =3D -1; - unsigned char cmd_buffer[5]; - - if (send_first(target, WRITEPKT)) - goto bad; - setup_dma(buffer, WRITE, 3); - cmd_buffer[0] =3D cmd_buffer[1] =3D cmd_buffer[4] =3D 0; - cmd_buffer[2] =3D length >> 8; - cmd_buffer[3] =3D length & 0xFF; - if (send_1_5(7, cmd_buffer, 1) || - !acsi_wait_for_IRQ(TIMEOUTDMA) || - get_status()) - goto bad; - ret =3D 0; -bad: - return (ret); -} - -/* The following higher level routines work on virtual addresses and c= onvert them to - * physical addresses when passed to the lowlevel routines. It's up to= the higher level - * routines to copy data from Alternate RAM to ST RAM if neccesary! - */ - -/* Check for a network adaptor of this type, and return '0' if one exi= sts. - */ - -struct net_device * __init pamsnet_probe (int unit) -{ - struct net_device *dev; - int i; - HADDR *hwaddr; - int err; - - unsigned char station_addr[6]; - static unsigned version_printed; - /* avoid "Probing for..." printed 4 times - the driver is supporting = only one adapter now! */ - static int no_more_found; - - if (no_more_found) - return ERR_PTR(-ENODEV); - no_more_found =3D 1; - - dev =3D alloc_etherdev(sizeof(struct net_local)); - if (!dev) - return ERR_PTR(-ENOMEM); - if (unit >=3D 0) { - sprintf(dev->name, "eth%d", unit); - netdev_boot_setup_check(dev); - } - SET_MODULE_OWNER(dev); - - printk("Probing for PAM's Net/GK Adapter...\n"); - - /* Allocate the DMA buffer here since we need it for probing! */ - - nic_packet =3D (struct nic_pkt_s *)acsi_buffer; - phys_nic_packet =3D (unsigned char *)phys_acsi_buffer; - if (pamsnet_debug > 0) { - printk("nic_packet at 0x%p, phys at 0x%p\n", - nic_packet, phys_nic_packet ); - } - - stdma_lock(pamsnet_intr, NULL); - DISABLE_IRQ(); - - for (i=3D0; i<8; i++) { - /* Do two inquiries to cover cases with strange equipment on previou= s ID */ - /* blocking the ACSI bus (like the SLMC804 laser printer controller.= =2E. */ - inquiry(i, phys_nic_packet); - if (!inquiry(i, phys_nic_packet)) { - lance_target =3D i; - break; - } - } - - if (!!NET_DEBUG) - printk("ID: %d\n",i); - - if (lance_target >=3D 0) { - if (!(hwaddr =3D read_hw_addr(lance_target, phys_nic_packet))) - lance_target =3D -1; - else - memcpy (station_addr, hwaddr, ETH_ALEN); - } - - ENABLE_IRQ(); - stdma_release(); - - if (lance_target < 0) { - printk("No PAM's Net/GK found.\n"); - free_netdev(dev); - return ERR_PTR(-ENODEV); - } - - if (pamsnet_debug > 0 && version_printed++ =3D=3D 0) - printk(version); - - printk("%s: %s found on target %01d, eth-addr: %02x:%02x:%02x:%02x:%0= 2x:%02x.\n", - dev->name, "PAM's Net/GK", lance_target, - station_addr[0], station_addr[1], station_addr[2], - station_addr[3], station_addr[4], station_addr[5]); - - /* Initialize the device structure. */ - dev->open =3D pamsnet_open; - dev->stop =3D pamsnet_close; - dev->hard_start_xmit =3D pamsnet_send_packet; - dev->get_stats =3D net_get_stats; - - /* Fill in the fields of the device structure with ethernet-generic - * values. This should be in a common file instead of per-driver. - */ - - for (i =3D 0; i < ETH_ALEN; i++) { -#if 0 - dev->broadcast[i] =3D 0xff; -#endif - dev->dev_addr[i] =3D station_addr[i]; - } - err =3D register_netdev(dev); - if (!err) - return dev; - - free_netdev(dev); - return ERR_PTR(err); -} - -/* Open/initialize the board. This is called (in the current kernel) - sometime after booting when the 'ifconfig' program is run. - - This routine should set everything up anew at each open, even - registers that "should" only need to be set once at boot, so that - there is non-reboot way to recover if something goes wrong. - */ -static int -pamsnet_open(struct net_device *dev) -{ - struct net_local *lp =3D netdev_priv(dev); - - if (pamsnet_debug > 0) - printk("pamsnet_open\n"); - stdma_lock(pamsnet_intr, NULL); - DISABLE_IRQ(); - - /* Reset the hardware here. - */ - if (!if_up) - start(lance_target); - if_up =3D 1; - lp->open_time =3D 0; /*jiffies*/ - lp->poll_time =3D MAX_POLL_TIME; - - dev->tbusy =3D 0; - dev->interrupt =3D 0; - dev->start =3D 1; - - ENABLE_IRQ(); - stdma_release(); - pamsnet_timer.data =3D (long)dev; - pamsnet_timer.expires =3D jiffies + lp->poll_time; - add_timer(&pamsnet_timer); - return 0; -} - -static int -pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev) -{ - struct net_local *lp =3D netdev_priv(dev); - unsigned long flags; - - /* Block a timer-based transmit from overlapping. This could better = be - * done with atomic_swap(1, dev->tbusy), but set_bit() works as well. - */ - local_irq_save(flags); - - if (stdma_islocked()) { - local_irq_restore(flags); - lp->stats.tx_errors++; - } - else { - int length =3D ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; - unsigned long buf =3D virt_to_phys(skb->data); - int stat; - - stdma_lock(pamsnet_intr, NULL); - DISABLE_IRQ(); - - local_irq_restore(flags); - if( !STRAM_ADDR(buf+length-1) ) { - skb_copy_from_linear_data(skb, nic_packet->buffer, - length); - buf =3D (unsigned long)phys_nic_packet; - } - - dma_cache_maintenance(buf, length, 1); - - stat =3D sendpkt(lance_target, (unsigned char *)buf, length); - ENABLE_IRQ(); - stdma_release(); - - dev->trans_start =3D jiffies; - dev->tbusy =3D 0; - lp->stats.tx_packets++; - lp->stats.tx_bytes+=3Dlength; - } - dev_kfree_skb(skb); - - return 0; -} - -/* We have a good packet(s), get it/them out of the buffers. - */ -static void -pamsnet_poll_rx(struct net_device *dev) -{ - struct net_local *lp =3D netdev_priv(dev); - int boguscount; - int pkt_len; - struct sk_buff *skb; - unsigned long flags; - - local_irq_save(flags); - /* ++roman: Take care at locking the ST-DMA... This must be done with= ints - * off, since otherwise an int could slip in between the question and= the - * locking itself, and then we'd go to sleep... And locking itself is - * necessary to keep the floppy_change timer from working with ST-DMA - * registers. */ - if (stdma_islocked()) { - local_irq_restore(flags); - return; - } - stdma_lock(pamsnet_intr, NULL); - DISABLE_IRQ(); - local_irq_restore(flags); - - boguscount =3D testpkt(lance_target); - if( lp->poll_time < MAX_POLL_TIME ) lp->poll_time++; - - while(boguscount--) { - pkt_len =3D receivepkt(lance_target, phys_nic_packet); - - if( pkt_len < 60 ) break; - - /* Good packet... */ - - dma_cache_maintenance((unsigned long)phys_nic_packet, pkt_len, 0); - - lp->poll_time =3D pamsnet_min_poll_time; /* fast poll */ - if( pkt_len >=3D 60 && pkt_len <=3D 2048 ) { - if (pkt_len > 1514) - pkt_len =3D 1514; - - /* Malloc up new buffer. - */ - skb =3D alloc_skb(pkt_len, GFP_ATOMIC); - if (skb =3D=3D NULL) { - printk("%s: Memory squeeze, dropping packet.\n", - dev->name); - lp->stats.rx_dropped++; - break; - } - skb->len =3D pkt_len; - skb->dev =3D dev; - - /* 'skb->data' points to the start of sk_buff data area. - */ - skb_copy_to_linear_data(skb, nic_packet->buffer, - pkt_len); - netif_rx(skb); - dev->last_rx =3D jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes+=3Dpkt_len; - } - } - - /* If any worth-while packets have been received, dev_rint() - has done a mark_bh(INET_BH) for us and will work on them - when we get to the bottom-half routine. - */ - - ENABLE_IRQ(); - stdma_release(); - return; -} - -/* pamsnet_tick: called by pamsnet_timer. Reads packets from the adapt= er, - * passes them to the higher layers and restarts the timer. - */ -static void -pamsnet_tick(unsigned long data) -{ - struct net_device *dev =3D (struct net_device *)data; - struct net_local *lp =3D netdev_priv(dev); - - if( pamsnet_debug > 0 && (lp->open_time++ & 7) =3D=3D 8 ) - printk("pamsnet_tick: %ld\n", lp->open_time); - - pamsnet_poll_rx(dev); - - pamsnet_timer.expires =3D jiffies + lp->poll_time; - add_timer(&pamsnet_timer); -} - -/* The inverse routine to pamsnet_open(). - */ -static int -pamsnet_close(struct net_device *dev) -{ - struct net_local *lp =3D netdev_priv(dev); - - if (pamsnet_debug > 0) - printk("pamsnet_close, open_time=3D%ld\n", lp->open_time); - del_timer(&pamsnet_timer); - stdma_lock(pamsnet_intr, NULL); - DISABLE_IRQ(); - - if (if_up) - stop(lance_target); - if_up =3D 0; - - lp->open_time =3D 0; - - dev->tbusy =3D 1; - dev->start =3D 0; - - ENABLE_IRQ(); - stdma_release(); - return 0; -} - -/* Get the current statistics. - This may be called with the card open or closed. - */ -static struct net_device_stats *net_get_stats(struct net_device *dev) -{ - struct net_local *lp =3D netdev_priv(dev); - return &lp->stats; -} - - -#ifdef MODULE - -static struct net_device *pam_dev; - -int init_module(void) -{ - pam_dev =3D pamsnet_probe(-1); - if (IS_ERR(pam_dev)) - return PTR_ERR(pam_dev); - return 0; -} - -void cleanup_module(void) -{ - unregister_netdev(pam_dev); - free_netdev(pam_dev); -} - -#endif /* MODULE */ - -/* Local variables: - * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include - -b m68k-linuxaout -Wall -Wstrict-prototypes -O2 - -fomit-frame-pointer -pipe -DMODULE -I../../net/inet -c atari_pamsnet= =2Ec" - * version-control: t - * kept-new-versions: 5 - * tab-width: 8 - * End: - */