diff -u --recursive --new-file v2.3.13/linux/CREDITS linux/CREDITS --- v2.3.13/linux/CREDITS Mon Aug 9 14:59:18 1999 +++ linux/CREDITS Thu Aug 12 11:49:02 1999 @@ -176,9 +176,9 @@ N: Carlos Henrique Bauer E: chbauer@acm.org -E: bauer@atlas.unisinos.tche.br -D: A test for detection of EPP-1.7 and ECP/EPP parports. +E: bauer@atlas.unisinos.br D: Some new sysctl entries for the parport driver. +D: New sysctl function for handling unsigned longs S: Universidade do Vale do Rio dos Sinos - UNISINOS S: DSI/IDASI S: Av. Unisinos, 950 @@ -987,10 +987,6 @@ S: 160 00 Praha 6 S: Czech Republic -N: Andreas S. Krebs -E: akrebs@altavista.net -D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards - N: Niels Kristian Bech Jensen E: nkbj@image.dk W: http://www.image.dk/~nkbj @@ -1001,15 +997,6 @@ S: DK-8230 Åbyhøj S: Denmark -N: Andrzej M. Krzysztofowicz -E: ankry@mif.pg.gda.pl -D: XT disk driver -D: Aladdin 1533/1543(C) chipset IDE -D: PIIX chipset IDE -S: ul. Matemblewska 1B/10 -S: 80-283 Gdansk -S: Poland - N: Michael K. Johnson E: johnsonm@redhat.com W: http://www.redhat.com/~johnsonm @@ -1024,6 +1011,29 @@ S: Chapel Hill, North Carolina 27514-4818 S: USA +N: Dave Jones +E: dave@powertweak.com +W: http://linux.powertweak.com +D: Centaur/IDT Winchip/Winchip 2 tweaks +D: Misc clean ups and other random hacking. +S: 40, Heol Edward Lewis, +S: Gelligaer, Hengoed, +S: Mid Glamorgan, CF82 8EJ, +S: Wales, United Kingdom + +N: Andreas S. Krebs +E: akrebs@altavista.net +D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards + +N: Andrzej M. Krzysztofowicz +E: ankry@mif.pg.gda.pl +D: XT disk driver +D: Aladdin 1533/1543(C) chipset IDE +D: PIIX chipset IDE +S: ul. Matemblewska 1B/10 +S: 80-283 Gdansk +S: Poland + N: Bernhard Kaindl E: bkaindl@netway.at E: edv@bartelt.via.at @@ -1293,7 +1303,7 @@ D: SCSI Tape Driver N: Hamish Macdonald -E: hamish_macdonald@westendsys.com +E: hamishm@lucent.com D: Linux/68k port S: 32 Clydesdale Avenue S: Kanata, Ontario diff -u --recursive --new-file v2.3.13/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.3.13/linux/Documentation/Configure.help Mon Aug 9 14:59:18 1999 +++ linux/Documentation/Configure.help Wed Aug 18 10:10:06 1999 @@ -1,7 +1,7 @@ # Maintained by Axel Boldt (boldt@math.ucsb.edu) # # This version of the Linux kernel configuration help texts -# corresponds to the kernel versions 2.2.x. +# corresponds to the kernel versions 2.3.x. # # Translations of this file available on the WWW: # @@ -2009,10 +2009,12 @@ you have a Retina Z3 or plan to get one before you next recompile the kernel. -Amiga CLgen driver (EXPERIMENTAL) +Cirrus Logic generic driver (EXPERIMENTAL) CONFIG_FB_CLGEN This enables support for Cirrus Logic GD542x/543x based boards on Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum. + If you have a PCI-based system, this enables support for these chips: + GD-543x, GD-544x, GD-5480. Say N unless you have such a graphics board or plan to get one before you next recompile the kernel. @@ -2311,7 +2313,7 @@ VGA characters/attributes support CONFIG_FBCON_VGA This is the low level frame buffer console driver for VGA text mode; - it is used if you said Y to "VGA chipset support (text only)" above. + it is used by frame buffer device drivers that support VGA text mode. Parallel-port support CONFIG_PARPORT @@ -10262,6 +10264,20 @@ connections. See Documentation/isdn/README.x25 for more information if you are thinking about using this. +ISDN diversion services support +CONFIG_ISDN_DIVERSION + This option allows you to use some supplementary diversion + services in conjunction with the HiSax driver on an EURO/DSS1 + line. Supported options are CD (call deflection), CFU (Call + forward unconditional), CFB (Call forward when busy) and CFNR + (call forward not reachable). + Additionally the actual CFU, CFB and CFNR state may be + interrogated. The use of CFU, CFB, CFNR and interrogation may + be limited to some countries. The keypad protocol is still not + implemented. + CD should work in all countries if this service has been sub- + scribed. + ICN 2B and 4B support CONFIG_ISDN_DRV_ICN This enables support for two kinds of ISDN-cards made by a German @@ -10488,6 +10504,30 @@ you need to have access to a machine on the Internet that has a program like lynx or netscape). +Eicon.Diehl active card support +CONFIG_ISDN_DRV_EICON + Say Y here if you have an Eicon active ISDN card. In order to use + this card, additional firmware is necessary, which has to be loaded + into the card using the eiconctrl utility which is part of the latest + isdn4k-utils package. Please read the file + Documentation/isdn/README.eicon for more information. + +Eicon old-type card support +CONFIG_ISDN_DRV_EICON_ISA + Say Y here if you have an old-type Eicon active ISDN card. In order to + use this card, additional firmware is necessary, which has to be loaded + into the card using the eiconctrl utility which is part of the latest + isdn4k-utils package. Please read the file + Documentation/isdn/README.eicon for more information. + +Support AT-Fax Class 2 commands +CONFIG_ISDN_TTY_FAX + If you say Y here, the modem-emulator will support a subset of the + Fax Class 2 commands. Using a getty with fax-support + (mgetty+sendfax, hylafax), you will be able to use your Linux box + as an ISDN-fax-machine. This must be supported by the lowlevel driver + also. See Documentation/isdn/README.fax for more information. + AVM-B1 with CAPI2.0 support CONFIG_ISDN_DRV_AVMB1 This enables support for the AVM B1 ISDN networking cards. In @@ -10625,6 +10665,33 @@ If you anticipate running this kernel on a computer with a MC68060 processor, say Y. Otherwise, say N. +Math emulation support +CONFIG_M68KFPU_EMU + At some point in the future, this will cause floating-point math + instructions to be emulated by the kernel on machines that lack a + floating-point math coprocessor. Thrill-seekers and chronically + sleep-deprived psychotic hacker types can say Y now, everyone else + should probably wait a while. + +Math emulation only kernel +CONFIG_M68KFPU_EMU_ONLY + This option prevents any floating-point instructions from being + compiled into the kernel, thereby the kernel doesn't save any + floating point context anymore during task switches, so this + kernel will only be usable on machines without a floating-point + math coprocessor. This makes the kernel a bit faster as no tests + needs to be executed whether a floating-point instruction in the + kernel should be executed or not. + +Math emulation extra precision +CONFIG_M68KFPU_EMU_EXTRAPREC + The fpu uses normally a few bit more during calculations for + correct rounding, the emulator can (often) do the same but this + extra calculation can cost quite some time, so you can disable + it here. The emulator will then "only" calculate with a 64 bit + mantissa and round slightly incorrect, what is more then enough + for normal usage. + Advanced processor options CONFIG_ADVANCED_CPU This gives you access to some advanced options for the CPU. The @@ -11968,10 +12035,29 @@ mknod /dev/ttyACM2 c 166 2 mknod /dev/ttyACM3 c 166 3 +USB Printer Device Class support (Preliminary) +CONFIG_USB_PRINTER + This is a generic driver for USB printers. + USS720 parport driver CONFIG_USB_USS720 - This driver is for USB parallel port adapters that use the USS-720 - chip. + This driver is for USB parallel port adapters that use the + Lucent Technologies USS-720 chip. + + The chip has two modes: automatic mode and manual mode. + In automatic mode, it looks like a standard USB printer. Only + Printers may be connected to the USS-720 in this mode. + The generic USB printer driver (CONFIG_USB_PRINTER, above) + may be used in that mode. + + Manual mode is not limited to printers, any parallel port + device should work. This driver utilizes manual mode. + Note however that some operations are three orders of a magnitude + slower than on a PCI/ISA Parallel Port, so timing critical + applications might not work. + + Say Y or M if you own an USS-720 USB->Parport cable and + intend to connect anything other than a printer to it. USB /proc filesystem entry support (Preliminary) CONFIG_USB_PROC @@ -11991,6 +12077,21 @@ This is the parallel port equivalent of SCSI generic support (sg). It is safe to say N to this -- it is not needed for normal printing or parallel port CD-ROM/disk support. + +Kernel httpd acceleration (expirimental) +CONFIG_KHTTPD + The kernel httpd acceleration daemon (kHTTPd) is a (limited) + webserver build into the kernel. It is limited since it can only + serve files from the filesystem. Saying "M" here builds the + kHTTPd module; this is NOT enough to have a working kHTTPd. + For safety reasons, the module has to be activated by doing a + "echo 1 > /proc/sys/net/khttpd/start" after inserting the module. + + Before using this, read the README in /usr/src/linux/net/khttpd ! + + The kHTTPd is expirimental. Be careful when using it on a production + machine. Also note that kHTTPd doesn't support virtual servers yet. + # # A couple of things I keep forgetting: diff -u --recursive --new-file v2.3.13/linux/Documentation/fb/clgenfb.txt linux/Documentation/fb/clgenfb.txt --- v2.3.13/linux/Documentation/fb/clgenfb.txt Wed Dec 31 16:00:00 1969 +++ linux/Documentation/fb/clgenfb.txt Wed Aug 18 10:10:06 1999 @@ -0,0 +1,59 @@ + + Framebuffer driver for Cirrus Logic chipsets + Copyright 1999 Jeff Garzik + + + +{ just a little something to get people going; contributors welcome! } + + + +Chip families supported: + SD64 + Piccolo + Picasso + Spectrum + Picasso4 (GD-5446) + Alpine (GD-543x/4x) + GD-5480 + +Bus's supported: + PCI + Zorro + +Architectures supported: + i386 + Alpha + PPC (Motorola Powerstack) + m68k (Amiga) + + + +Default video modes +------------------- +At the moment, there are two kernel command line arguments supported: + +mode:640x480 + or +mode:1024x768 + +Full support for startup video modes (modedb) will be integrated soon. + + + +Version 1.9.4.1 +--------------- +Add compatibility support. Now requires a 2.1.x, 2.2.x or 2.3.x kernel. + + +Version 1.9.4 +------------- +Several enhancements, smaller memory footprint, a few bugfixes. +Requires kernel 2.3.14-pre1 or later. + + +Version 1.9.3 +------------- +Bundled with kernel 2.3.14-pre1 or later. + + diff -u --recursive --new-file v2.3.13/linux/Documentation/fb/modedb.txt linux/Documentation/fb/modedb.txt --- v2.3.13/linux/Documentation/fb/modedb.txt Wed Dec 31 16:00:00 1969 +++ linux/Documentation/fb/modedb.txt Wed Aug 18 10:10:06 1999 @@ -0,0 +1,48 @@ + + + modedb default video mode support + + +Currently all frame buffer device drivers have their own video mode databases, +which is a mess and a waste of resources. The main idea of modedb is to have + + - one routine to probe for video modes, which can be used by all frame buffer + devices + - one generic video mode database with a fair amount of standard videomodes + (taken from XFree86) + - the possibility to supply your own mode database for graphics hardware that + needs non-standard modes, like amifb and Mac frame buffer drivers (which + use macmodes.c) + +When a frame buffer device receives a video= option it doesn't know, it should +consider that to be a video mode option. If no frame buffer device is specified +in a video= option, fbmem considers that to be a global video mode option. + +Valid mode specifiers (mode_option argument): + + x[-][@] + [-][@] + +with , , and decimal numbers and a string. +Things between square brackets are optional. + +To find a suitable video mode, you just call + +int __init fb_find_mode(struct fb_var_screeninfo *var, + struct fb_info *info, const char *mode_option, + const struct fb_videomode *db, unsigned int dbsize, + const struct fb_videomode *default_mode, + unsigned int default_bpp) + +with db/dbsize your non-standard video mode database, or NULL to use the +standard video mode database. + +fb_find_mode() first tries the specified video mode (or any mode that matches, +e.g. there can be multiple 640x480 modes, each of them is tried). If that +fails, the default mode is tried. If that fails, it walks over all modes. + +BTW, only a few drivers use this at the moment. Others are to follow +(feel free to send patches). + + + diff -u --recursive --new-file v2.3.13/linux/Documentation/isapnp.txt linux/Documentation/isapnp.txt --- v2.3.13/linux/Documentation/isapnp.txt Wed Dec 31 16:00:00 1969 +++ linux/Documentation/isapnp.txt Sun Aug 15 11:50:35 1999 @@ -0,0 +1,147 @@ +ISA Plug & Play support by Jaroslav Kysela +========================================================= + +Interface /proc/isapnp +====================== + +Read commands: +-------------- + +No comment.. + +Write commands: +--------------- + +With the write interface you can simply activate or modify the configuration +for ISA Plug & Play devices. It is mainly useable for drivers which don't +use the ISA Plug & Play kernel support yet. + +card - select PnP device by vendor identification +csn - select PnP device by CSN +dev - select logical device +auto - run autoconfigure +activate - activate logical device +deactivate - deactivate logical device +port - set port 0-7 to value +irq - set IRQ 0-1 to value +dma - set DMA 0-1 to value +memory - set memory 0-3 to value +poke - poke configuration byte to selected register +pokew - poke configuration word to selected register +poked - poke configuration dword to selected register + +Explanation: + - variable begins with zero + - variable begins with one + - is in form 'PNP0000' + - is in form 'PNP0000' + +Example: + +cat > /proc/isapnp <prepare() only initialize the resource +members in the device structure. This structure contains all resources +set to auto configuration values after the initialization. The driver for +ISA PnP device may modify (or not) some resources to skip auto configuration +for the given resource. + +The function isapnp_configure does: + - resources which have the auto configuration value are configured + - the auto configuration is created using ISA PnP resource map + - the function writes configuration to ISA PnP configuration registers + - the function returns to the caller actual used resources + +Example (game port initialization) +================================== + +/*** initialization ***/ + + struct pci_dev *dev; + + /* find the first game port, use standard PnP IDs */ + dev = isapnp_find_dev(NULL, + ISAPNP_VENDOR('P','N','P'), + ISAPNP_FUNCTION(0xb02f), + NULL); + if (!dev) + return -ENODEV; + if (dev->prepare(dev)<0) + return -EAGAIN; + if (!dev->ro) { + /* override resource */ + if (user_port != USER_PORT_AUTO_VALUE) + dev->resource[0].start = user_port; + } + if (dev->activate(dev)<0) { + printk("isapnp configure failed (out of resources?)\n"); + return -ENOMEM; + } + user_port = dev->resource[0].start; /* get real port */ + +/*** deactivation ***/ + + /* to deactivate use: */ + if (dev) + dev->deactivate(dev); diff -u --recursive --new-file v2.3.13/linux/Documentation/isdn/CREDITS linux/Documentation/isdn/CREDITS --- v2.3.13/linux/Documentation/isdn/CREDITS Wed Jun 2 11:29:13 1999 +++ linux/Documentation/isdn/CREDITS Thu Aug 12 09:42:32 1999 @@ -24,7 +24,7 @@ Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) For his Sync-PPP-code. -Karsten Keil (isdn4@temic-ech.spacenet.de) +Karsten Keil (keil@isdn4linux.de) For adding 1TR6-support to the Teles-driver. For the HiSax-driver. diff -u --recursive --new-file v2.3.13/linux/Documentation/isdn/HiSax.cert linux/Documentation/isdn/HiSax.cert --- v2.3.13/linux/Documentation/isdn/HiSax.cert Sun May 23 10:03:41 1999 +++ linux/Documentation/isdn/HiSax.cert Thu Aug 12 09:42:33 1999 @@ -14,7 +14,8 @@ However, if you wish to modify the HiSax sources, please note the following: -HiSax has passed the ITU approval test suite with ELSA Quickstep ISDN cards. +HiSax has passed the ITU approval test suite with ELSA Quickstep ISDN cards +and Eicon Technology Diva 2.01 PCI card. The certification is only valid for the combination of the tested software version and the tested hardware. Any changes to the HiSax source code may therefore affect the certification. @@ -48,13 +49,14 @@ drivers/isdn/hisax/l3_1tr6.c drivers/isdn/hisax/cert.c drivers/isdn/hisax/elsa.c +drivers/isdn/hisax/diva.c Please send any changes, bugfixes and patches to me rather than implementing them directly into the HiSax sources. This does not reduce your rights granted by the GNU General Public License. If you wish to change the sources, go ahead; but note that then the -certification is invalid even if you use ELSA Quickstep cards. +certification is invalid even if you use one of the approved cards. Here are the certification registration numbers for ELSA Quickstep cards: German D133361J CETECOM ICT Services GmbH 0682 @@ -68,9 +70,9 @@ Version: 2.6.3i Charset: noconv -iQCVAwUBNj5OKDpxHvX/mS9tAQFHuQP/WeImlqCcDZ2d132yAvRBWFULlJoSf1P/ -c1lVTeaWvsSaY5Cu9hrKhXXhPzeEaitUbcUBPXdpzFWCA5CE902lnz7AhgRC+HF1 -0qiKgkZZyc/5HKasFymR1+IWSLw30GesP3Di/ZMR3NJi8SlY9PIjx7hnEMunGSRO -1ufPvfWWuu8= -=nGJk +iQCVAwUBN6xoKTpxHvX/mS9tAQF4DAP/efRWym6jvNOND1O9eaEFdP5fd2xKB3XD +Ifh6Iv0DvARcIuxXtEjT+z3FjjQk35eo/wX4C4tpRhYQYdgCxl+iv+5DzhVDpB95 +3QS9E5m0E1eIK3t8XiQTRgb+1JPCMYUThCrakYsX25o3ndGKyDipsCTfkyR38XwC +bUyTfcOYKAk= +=VKyL -----END PGP SIGNATURE----- diff -u --recursive --new-file v2.3.13/linux/Documentation/isdn/INTERFACE linux/Documentation/isdn/INTERFACE --- v2.3.13/linux/Documentation/isdn/INTERFACE Sun May 23 10:03:41 1999 +++ linux/Documentation/isdn/INTERFACE Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -$Id: INTERFACE,v 1.11 1999/03/02 12:14:51 armin Exp $ +$Id: INTERFACE,v 1.13 1999/08/11 20:30:26 armin Exp $ Description of the Interface between Linklevel and Hardwarelevel of isdn4linux: @@ -216,7 +216,7 @@ Until now, the following commands are defined: -***CHANGEI1.34: The parameter "num" has been replaced by a union "para" containing +***CHANGEI1.34: The parameter "num" has been replaced by a union "parm" containing the old "num" and a new setup_type struct used for ISDN_CMD_DIAL and ISDN_STAT_ICALL callback. @@ -235,7 +235,7 @@ driver = driver-Id. command = ISDN_CMD_IOCTL arg = Original ioctl-cmd - IIOCDRVCTL - para.num = first bytes filled with (unsigned long)arg + parm.num = first bytes filled with (unsigned long)arg Returnvalue: Depending on driver. @@ -251,10 +251,10 @@ command = ISDN_CMD_DIAL arg = channel-number locally to the driver. (starting with 0) - para.setup.phone = An ASCII-String containing the number to dial. - para.setup.eazmsn = An ASCII-Sting containing the own EAZ or MSN. - para.setup.si1 = The Service-Indicator. - para.setup.si2 = Additional Service-Indicator. + parm.setup.phone = An ASCII-String containing the number to dial. + parm.setup.eazmsn = An ASCII-Sting containing the own EAZ or MSN. + parm.setup.si1 = The Service-Indicator. + parm.setup.si2 = Additional Service-Indicator. If the Line has been designed as SPV (a special german feature, meaning semi-leased-line) the phone has to @@ -272,7 +272,7 @@ driver = driver-Id. command = ISDN_CMD_ACCEPTD arg = channel-number locally to the driver. (starting with 0) - para = unused. + parm = unused. ISDN_CMD_ACCEPTB: @@ -283,7 +283,7 @@ driver = driver-Id. command = ISDN_CMD_ACCEPTB arg = channel-number locally to the driver. (starting with 0) - para = unused. + parm = unused. ISDN_CMD_HANGUP: @@ -295,7 +295,7 @@ driver = driver-Id. command = ISDN_CMD_HANGUP arg = channel-number locally to the driver. (starting with 0) - para = unused. + parm = unused. ISDN_CMD_CLREAZ: @@ -306,7 +306,7 @@ driver = driver-Id. command = ISDN_CMD_CLREAZ arg = channel-number locally to the driver. (starting with 0) - para = unused. + parm = unused. ISDN_CMD_SETEAZ: @@ -317,7 +317,7 @@ driver = driver-Id. command = ISDN_CMD_SETEAZ arg = channel-number locally to the driver. (starting with 0) - para.num = ASCII-String, containing the desired EAZ's/MSN's + parm.num = ASCII-String, containing the desired EAZ's/MSN's (comma-separated). If an empty String is given, the HL-driver should respond to ALL incoming calls, regardless of the destination-address. @@ -332,7 +332,7 @@ driver = driver-Id. command = ISDN_CMD_GETEAZ arg = channel-number locally to the driver. (starting with 0) - para.num = ASCII-String, containing the current EAZ's/MSN's + parm.num = ASCII-String, containing the current EAZ's/MSN's ISDN_CMD_SETSIL: (currently unused) @@ -343,7 +343,7 @@ driver = driver-Id. command = ISDN_CMD_SETSIL arg = channel-number locally to the driver. (starting with 0) - para.num = ASCII-String, containing the desired Service-Indicators. + parm.num = ASCII-String, containing the desired Service-Indicators. ISDN_CMD_GETSIL: (currently unused) @@ -354,7 +354,7 @@ driver = driver-Id. command = ISDN_CMD_SETSIL arg = channel-number locally to the driver. (starting with 0) - para.num = ASCII-String, containing the current Service-Indicators. + parm.num = ASCII-String, containing the current Service-Indicators. ISDN_CMD_SETL2: @@ -369,7 +369,7 @@ arg = channel-number locally to the driver. (starting with 0) logical or'ed with (protocol-Id << 8) protocol-Id is one of the constants ISDN_PROTO_L2... - para = unused. + parm = unused. ISDN_CMD_GETL2: (currently unused) @@ -380,7 +380,7 @@ driver = driver-Id. command = ISDN_CMD_GETL2 arg = channel-number locally to the driver. (starting with 0) - para = unused. + parm = unused. Returnvalue: current protocol-Id (one of the constants ISDN_L2_PROTO) @@ -397,7 +397,7 @@ arg = channel-number locally to the driver. (starting with 0) logical or'ed with (protocol-Id << 8) protocol-Id is one of the constants ISDN_PROTO_L3... - para = unused. + parm.fax = Pointer to T30_s fax struct. (fax usage only) ISDN_CMD_GETL2: (currently unused) @@ -408,7 +408,7 @@ driver = driver-Id. command = ISDN_CMD_GETL3 arg = channel-number locally to the driver. (starting with 0) - para = unused. + parm = unused. Returnvalue: current protocol-Id (one of the constants ISDN_L3_PROTO) @@ -422,7 +422,7 @@ driver = driver-Id. command = ISDN_CMD_LOCK arg = unused. - para = unused. + parm = unused. ISDN_CMD_UNLOCK: @@ -434,7 +434,19 @@ driver = driver-Id. command = ISDN_CMD_UNLOCK arg = unused. - para = unused. + parm = unused. + + ISDN_CMD_FAXCMD: + + With this command the HL-driver receives a fax sub-command. + For details refer to INTERFACE.fax + + Parameter: + driver = driver-Id. + command = ISDN_CMD_FAXCMD + arg = channel-number locally to the driver. (starting with 0) + parm = unused. + 3. Description of the events to be signaled by the HL-driver to the LL. @@ -456,7 +468,7 @@ driver = driver-Id command = ISDN_STAT_STAVAIL arg = length of available data. - para = unused. + parm = unused. ISDN_STAT_ICALL: @@ -466,12 +478,12 @@ driver = driver-Id command = ISDN_STAT_ICALL arg = channel-number, locally to the driver. (starting with 0) - para.setup.phone = Callernumber. - para.setup.eazmsn = CalledNumber. - para.setup.si1 = Service Indicator. - para.setup.si2 = Additional Service Indicator. - para.setup.plan = octet 3 from Calling party number Information Element. - para.setup.screen = octet 3a from Calling party number Information Element. + parm.setup.phone = Callernumber. + parm.setup.eazmsn = CalledNumber. + parm.setup.si1 = Service Indicator. + parm.setup.si2 = Additional Service Indicator. + parm.setup.plan = octet 3 from Calling party number Information Element. + parm.setup.screen = octet 3a from Calling party number Information Element. Return: 0 = No device matching this call. @@ -497,7 +509,7 @@ driver = driver-Id command = ISDN_STAT_RUN arg = unused. - para = unused. + parm = unused. ISDN_STAT_STOP: @@ -508,7 +520,7 @@ driver = driver-Id command = ISDN_STAT_STOP arg = unused. - para = unused. + parm = unused. ISDN_STAT_DCONN: @@ -519,7 +531,7 @@ driver = driver-Id command = ISDN_STAT_DCONN arg = channel-number, locally to the driver. (starting with 0) - para = unused. + parm = unused. ISDN_STAT_BCONN: @@ -534,7 +546,7 @@ driver = driver-Id command = ISDN_STAT_BCONN arg = channel-number, locally to the driver. (starting with 0) - para.num = ASCII-String, containing type of connection (for analog + parm.num = ASCII-String, containing type of connection (for analog modem only). This will be appended to the CONNECT message e.g. 14400/V.32bis @@ -549,7 +561,7 @@ driver = driver-Id command = ISDN_STAT_DHUP arg = channel-number, locally to the driver. (starting with 0) - para = unused. + parm = unused. ISDN_STAT_BHUP: @@ -564,7 +576,7 @@ driver = driver-Id command = ISDN_STAT_BHUP arg = channel-number, locally to the driver. (starting with 0) - para = unused. + parm = unused. ISDN_STAT_CINF: @@ -575,7 +587,7 @@ driver = driver-Id command = ISDN_STAT_CINF arg = channel-number, locally to the driver. (starting with 0) - para.num = ASCII string containing charge-units (digits only). + parm.num = ASCII string containing charge-units (digits only). ISDN_STAT_LOAD: (currently unused) @@ -588,7 +600,7 @@ driver = driver-Id command = ISDN_STAT_UNLOAD arg = unused. - para = unused. + parm = unused. ISDN_STAT_BSENT: @@ -600,7 +612,7 @@ driver = driver-Id command = ISDN_STAT_BSENT arg = channel-number, locally to the driver. (starting with 0) - para.length = ***CHANGEI.1.21: New field. + parm.length = ***CHANGEI.1.21: New field. the driver has to set this to the original length of the skb at the time of receiving it from the linklevel. @@ -613,21 +625,21 @@ driver = driver-Id command = ISDN_STAT_NODCH arg = channel-number, locally to the driver. (starting with 0) - para = unused. + parm = unused. - ISDN_STAT_ADDCH: (currently unused) + ISDN_STAT_ADDCH: - This call is planned for HL-drivers, which are unable to check card-type + This call is for HL-drivers, which are unable to check card-type or numbers of supported channels before they have loaded any firmware - using ioctl. Those HL-driver simply set the channel-parameter to zero - or a minimum channel-number when registering, and later if they know + using ioctl. Those HL-driver simply set the channel-parameter to a + minimum channel-number when registering, and later if they know the real amount, perform this call, allocating additional channels. Parameter: driver = driver-Id command = ISDN_STAT_ADDCH - arg = to be defined. - para = to be defined. + arg = number of channels to be added. + parm = unused. ISDN_STAT_CAUSE: @@ -640,7 +652,7 @@ driver = driver-Id command = ISDN_STAT_NODCH arg = channel-number, locally to the driver. (starting with 0) - para.num = ASCII string containing CAUSE-message. + parm.num = ASCII string containing CAUSE-message. ISDN_STAT_L1ERR: @@ -653,5 +665,33 @@ driver = driver-Id command = ISDN_STAT_L1ERR arg = channel-number, locally to the driver. (starting with 0) - para.errcode= ISDN_STAT_L1ERR_SEND: Packet lost while sending. + parm.errcode= ISDN_STAT_L1ERR_SEND: Packet lost while sending. ISDN_STAT_L1ERR_RECV: Packet lost while receiving. + ISDN_STAT_DISCH: + + With this call, the HL-driver signals the LL to disable or enable the + use of supplied channel and driver. + The call may be used to reduce the available number of B-channels after + loading the driver. The LL has to ignore a disabled channel when searching + for free channels. The HL driver itself never delivers STAT callbacks for + disabled channels. + The LL returns a nonzero code if the operation was not successfull or the + selected channel is actually regarded as busy. + + Parameter: + driver = driver-Id + command = ISDN_STAT_DISCH + arg = channel-number, locally to the driver. (starting with 0) + parm.num[0] = 0 if channel shall be disabled, else enabled. + + ISDN_STAT_FAXIND: + + With this call the HL-driver signals a fax sub-command to the LL. + For details refer to INTERFACE.fax + + Parameter: + driver = driver-Id. + command = ISDN_STAT_FAXIND + arg = channel-number, locally to the driver. (starting with 0) + parm = unused. + diff -u --recursive --new-file v2.3.13/linux/Documentation/isdn/INTERFACE.fax linux/Documentation/isdn/INTERFACE.fax --- v2.3.13/linux/Documentation/isdn/INTERFACE.fax Wed Dec 31 16:00:00 1969 +++ linux/Documentation/isdn/INTERFACE.fax Thu Aug 12 09:42:33 1999 @@ -0,0 +1,163 @@ +$Id: INTERFACE.fax,v 1.1 1999/08/11 20:30:28 armin Exp $ + + +Description of the fax-subinterface between linklevel and hardwarelevel of + isdn4linux. + + The communication between linklevel (LL) and harwarelevel (HL) for fax + is based on the struct T30_s (defined in isdnif.h). + This struct is allocated in the LL. + In order to use fax, the LL provides the pointer to this struct with the + command ISDN_CMD_SETL3 (parm.fax). This pointer expires in case of hangup + and when a new channel to a new connection is assigned. + + +Data handling: + In send-mode the HL-driver has to handle the codes and the bit-order + conversion by itself. + In receive-mode the LL-driver takes care of the bit-order conversion + (specified by +FBOR) + +Structure T30_s description: + + This structure stores the values (set by AT-commands), the remote- + capability-values and the command-codes between LL and HL. + + If the HL-driver receives ISDN_CMD_FAXCMD, all needed information + is in this struct set by the LL. + To signal information to the LL, the HL-driver has to set the + the parameters and use ISDN_STAT_FAXIND. + (Please refer to INTERFACE) + +Structure T30_s: + + All members are 8-bit unsigned (__u8) + + - resolution + - rate + - width + - length + - compression + - ecm + - binary + - scantime + - id[] + Local faxmachine's parameters, set by +FDIS, +FDCS, +FLID, ... + + - r_resolution + - r_rate + - r_width + - r_length + - r_compression + - r_ecm + - r_binary + - r_scantime + - r_id[] + Remote faxmachine's parameters. To be set by HL-driver. + + - phase + Defines the actual state of fax connection. Set by HL or LL + depending on progress and type of connection. + If the phase changes because of an AT command, the LL driver + changes this value. Otherwise the HL-driver takes care of it, but + only neccessary on call establishment (from IDLE to PHASE_A). + (one of the constants ISDN_FAX_PHASE_[IDLE,A,B,C,D,E]) + + - direction + Defines outgoing/send or incoming/receive connection. + (ISDN_TTY_FAX_CONN_[IN,OUT]) + + - code + Commands from LL to HL; possible constants : + ISDN_TTY_FAX_DR signals +FDR command to HL + + ISDN_TTY_FAX_DT signals +FDT command to HL + + ISDN_TTY_FAX_ET signals +FET command to HL + + + Other than that the "code" is set with the hangup-code value at + the end of connection for the +FHNG message. + + - r_code + Commands from HL to LL; possible constants : + ISDN_TTY_FAX_CFR output of +FCFR message. + + ISDN_TTY_FAX_RID output of remote ID set in r_id[] + (+FCSI/+FTSI on send/receive) + + ISDN_TTY_FAX_DCS output of +FDCS and CONNECT message, + switching to phase C. + + ISDN_TTY_FAX_ET signals end of data, + switching to phase D. + + ISDN_TTY_FAX_FCON signals the established, outgoing connection, + switching to phase B. + + ISDN_TTY_FAX_FCON_I signals the established, incoming connection, + switching to phase B. + + ISDN_TTY_FAX_DIS output of +FDIS message and values. + + ISDN_TTY_FAX_SENT signals that all data has been sent + and is acknowledged, + OK message will be sent. + + ISDN_TTY_FAX_PTS signals a msg-confirmation (page sent successful), + depending on fet value: + 0: output OK message (more pages follow) + 1: switching to phase B (next document) + + ISDN_TTY_FAX_TRAIN_OK output of +FDCS and OK message (for receive mode). + + ISDN_TTY_FAX_EOP signals end of data in receive mode, + switching to phase D. + + ISDN_TTY_FAX_HNG output of the +FHNG and value set by code and + OK message, switching to phase E. + + + - badlin + Value of +FBADLIN + + - badmul + Value of +FBADMUL + + - bor + Value of +FBOR + + - fet + Value of +FET command in send-mode. + Set by HL in receive-mode for +FET message. + + - pollid[] + ID-string, set by +FCIG + + - cq + Value of +FCQ + + - cr + Value of +FCR + + - ctcrty + Value of +FCTCRTY + + - minsp + Value of +FMINSP + + - phcto + Value of +FPHCTO + + - rel + Value of +FREL + + - nbc + Value of +FNBC (0,1) + (+FNBC is not a known class 2 fax command, I added this to change the + automatic "best capabilities" connection in the eicon HL-driver) + + +Armin +mac@melware.de + diff -u --recursive --new-file v2.3.13/linux/Documentation/isdn/README linux/Documentation/isdn/README --- v2.3.13/linux/Documentation/isdn/README Sun May 23 10:03:41 1999 +++ linux/Documentation/isdn/README Thu Aug 12 09:42:33 1999 @@ -149,6 +149,8 @@ AT&X0 BTX-mode and T.70-mode off (default) AT&X1 BTX-mode on. (S13.1=1, S13.5=0 S14=0, S16=7, S18=7, S19=0) AT&X2 T.70-mode on. (S13.1=1, S13.5=1, S14=0, S16=7, S18=7, S19=0) + AT+Rx Resume a suspended call with CallID x (x = 1,2,3...) + AT+Sx Suspend a call with CallID x (x = 1,2,3...) For voice-mode commands refer to README.audio @@ -215,6 +217,9 @@ an incoming call happened (RING) and the remote party hung up before any local ATA was given. + Bit 7: 0 = Don't show display messages from net + 1 = Show display messages from net + (S12 Bit 1 must be 0 too) 14 0 Layer-2 protocol: 0 = X75/LAPB with I-frames 1 = X75/LAPB with UI-frames @@ -225,8 +230,11 @@ 8 = V.110, 19200 baud 9 = V.110, 38400 baud 10 = Analog Modem (only if hardware supports this) - 15 0 Layer-3 protocol: (at the moment always 0) + 11 = Fax G3 (only if hardware supports this) + 15 0 Layer-3 protocol: 0 = transparent + 1 = transparent with audio features (e.g. DSP) + 2 = Fax G3 (S14 has to be set to 11) 16 250 Send-Packet-size/16 17 8 Window-size (not yet implemented) 18 4 Bit coded register, Service-Octet-1 to accept, @@ -255,6 +263,9 @@ Set on incoming call (during RING) to octet 3a of calling party number IE (Screening info) See section 4.5.10 of ITU Q.931 + 23 0 Bit coded register: + Bit 0: 0 = Add CPN to RING message off + 1 = Add CPN to RING message on Last but not least a (at the moment fairly primitive) device to request the line-status (/dev/isdninfo) is made available. diff -u --recursive --new-file v2.3.13/linux/Documentation/isdn/README.HiSax linux/Documentation/isdn/README.HiSax --- v2.3.13/linux/Documentation/isdn/README.HiSax Sun May 23 10:03:41 1999 +++ linux/Documentation/isdn/README.HiSax Thu Aug 12 09:42:33 1999 @@ -42,6 +42,7 @@ ELSA PCMCIA ITK ix1-micro Rev.2 Eicon.Diehl Diva 2.0 ISA and PCI (S0 and U interface, no PRO version) +Eicon.Diehl Diva 2.01 ISA and PCI Eicon.Diehl Diva Piccola ASUSCOM NETWORK INC. ISDNLink 128K PC adapter (order code I-IN100-ST-D) Dynalink IS64PH (OEM version of ASUSCOM NETWORK INC. ISDNLink 128K adapter) @@ -54,6 +55,13 @@ ith Kommunikationstechnik GmbH MIC 16 ISA card Traverse Technologie NETjet PCI S0 card Dr. Neuhaus Niccy PnP/PCI +Siemens I-Surf +ACER P10 +HST Saphir +Berkom Telekom A4T +Scitel Quadro +Gazel ISDN cards +HFC-PCI based cards Note: PCF, PCF-Pro: up to now, only the ISDN part is supported PCC-8: not tested yet @@ -165,6 +173,14 @@ 27 AVM PnP (Fritz!PnP) irq, io (from isapnp setup) 27 AVM PCI (Fritz!PCI) no parameter 28 Sedlbauer Speed Fax+ irq, io (from isapnp setup) + 29 Siemens I-Surf irq, io, memory (from isapnp setup) + 30 ACER P10 irq, io (from isapnp setup) + 31 HST Saphir irq, io + 32 Telekom A4T none + 33 Scitel Quadro subcontroller (4*S0, subctrl 1...4) + 34 Gazel ISDN cards (ISA) irq,io + 34 Gazel ISDN cards (PCI) none + 35 HFC 2BDS0 PCI none At the moment IRQ sharing is only possible with PCI cards. Please make sure @@ -255,12 +271,19 @@ 22 Sedlbauer Speed Star (PCMCIA) pa=irq, pb=io (set with card manager) 24 Dr. Neuhaus Niccy PnP ONLY WORKS AS A MODULE ! 24 Dr. Neuhaus Niccy PCI no parameter - 25 Teles S0Box irq, io (of the used lpt port) - 26 AVM A1 PCMCIA (Fritz!) irq, io (set with card manager) + 25 Teles S0Box pa=irq, pb=io (of the used lpt port) + 26 AVM A1 PCMCIA (Fritz!) pa=irq, pb=io (set with card manager) 27 AVM PnP (Fritz!PnP) ONLY WORKS AS A MODULE ! 27 AVM PCI (Fritz!PCI) no parameter 28 Sedlbauer Speed Fax+ ONLY WORKS AS A MODULE ! - + 29 Siemens I-Surf ONLY WORKS AS A MODULE ! + 30 ACER P10 ONLY WORKS AS A MODULE ! + 31 HST Saphir pa=irq, pb=io + 32 Telekom A4T no parameter + 33 Scitel Quadro subcontroller (4*S0, subctrl 1...4) + 34 Gazel ISDN cards (ISA) pa=irq, pb=io + 34 Gazel ISDN cards (PCI) no parameter + 35 HFC 2BDS0 PCI no parameter Running the driver ------------------ @@ -515,8 +538,7 @@ /sbin/hisaxctrl HiSax 5 1 Remarks: -a) If you have a CISCO don't forget to switch off the KEEP ALIVE option! -b) Use state of the art isdn4k-utils +a) Use state of the art isdn4k-utils Here an example script: #!/bin/sh @@ -568,7 +590,7 @@ /sbin/isdnctrl encap isdn0s cisco-h fi fi - /sbin/isdnctrl dialmode isdn0 auto + /sbin/isdnctrl dialmode isdn0 manual # configure tcp/ip /sbin/ifconfig isdn0 ${LOCAL_IP} pointopoint ${REMOTE_IP} /sbin/route add -host ${REMOTE_IP} isdn0 @@ -578,6 +600,7 @@ /sbin/hisaxctrl HiSax 5 1 if [ ${I4L_LEASED_128K} = "yes" ]; then # B-CHANNEL 2 + sleep 10; /* Wait for master */ /sbin/hisaxctrl HiSax 5 2 fi ;; @@ -599,4 +622,3 @@ exit 1 esac exit 0 - diff -u --recursive --new-file v2.3.13/linux/Documentation/isdn/README.audio linux/Documentation/isdn/README.audio --- v2.3.13/linux/Documentation/isdn/README.audio Sun May 23 10:03:41 1999 +++ linux/Documentation/isdn/README.audio Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -$Id: README.audio,v 1.7 1998/07/26 18:45:34 armin Exp $ +$Id: README.audio,v 1.8 1999/07/11 17:17:29 armin Exp $ ISDN subsystem for Linux. Description of audio mode. @@ -57,6 +57,17 @@ of 0.1 second. (default 70) AT+VSD=? Report possible parameters. AT+VSD? Show current parameters. + + AT+VDD=x,y Set DTMF-detection parameters. + Only possible if online and during this connection. + Possible parameters: + x = 0 ... 15 sensitivity threshold level. + (default 0 , I4L soft-decode) + (1-15 soft-decode off, hardware on) + y = 0 ... 255 tone duration in units of 5ms. + Not for I4L soft decode (default 8, 40ms) + AT+VDD=? Report possible parameters. + AT+VDD? Show current parameters. AT+VSM=x Select audio data format. Possible parameters: diff -u --recursive --new-file v2.3.13/linux/Documentation/isdn/README.avmb1 linux/Documentation/isdn/README.avmb1 --- v2.3.13/linux/Documentation/isdn/README.avmb1 Tue Apr 28 14:22:04 1998 +++ linux/Documentation/isdn/README.avmb1 Thu Aug 12 09:42:33 1999 @@ -1,10 +1,22 @@ +Driver for active AVM Controller. + The driver provides a kernel capi2.0 Interface (kernelcapi) and on top of this a User-Level-CAPI2.0-interface (capi) and a driver to connect isdn4linux with CAPI2.0 (capidrv). +The lowlevel interface can be used to implement a CAPI2.0 +also for passive cards since July 1999. -The Author can be reached at calle@calle.in-berlin.de -The command avmcapictrl is part of the isdn4linux-utils. -t4-files can be found at ftp.avm.de. +The author can be reached at calle@calle.in-berlin.de. +The command avmcapictrl is part of the isdn4k-utils. +t4-files can be found at ftp://ftp.avm.de/cardware/b1/linux/firmware + +Currently supported cards: + B1 ISA (all versions) + B1 PCI + T1/T1B (HEMA card) + M1 + M2 + B1 PCMCIA Installing ---------- @@ -26,32 +38,145 @@ AVM GmbH provides several t4-files for the different D-channel protocols (b1.t4 for Euro-ISDN). Install these file in /lib/isdn. -If you do not compile the driver as modules, you have to add the -card(s) and load them after booting: - -avmcapictrl add 0x150 15 -avmcapictrl load /lib/isdn/b1.t4 1 - -if you configure as modules you have two possibilities: +if you configure as modules load the modules this way: insmod /lib/modules/current/misc/capiutil.o -insmod /lib/modules/current/misc/kernelcapi.o portbase=0x150 irq=15 +insmod /lib/modules/current/misc/b1.o +insmod /lib/modules/current/misc/kernelcapi.o insmod /lib/modules/current/misc/capidrv.o insmod /lib/modules/current/misc/capi.o -avmcapictrl load /lib/isdn/b1.t4 -or +if you have an B1-PCI card load the module b1pci.o +insmod /lib/modules/current/misc/b1pci.o +and load the firmware with +avmcapictrl load /lib/isdn/b1.t4 1 -insmod /lib/modules/current/misc/capiutil.o -insmod /lib/modules/current/misc/kernelcapi.o -insmod /lib/modules/current/misc/capidrv.o -insmod /lib/modules/current/misc/capi.o +if you have an B1-ISA card load the module b1isa.o +and add the card by calling avmcapictrl add 0x150 15 -avmcapictrl load /lib/isdn/b1.t4 +and load the firmware by calling +avmcapictrl load /lib/isdn/b1.t4 1 + +if you have an T1-ISA card load the module t1isa.o +and add the card by calling +avmcapictrl add 0x450 15 T1 0 +and load the firmware by calling +avmcapictrl load /lib/isdn/t1.t4 1 + +if you have an PCMCIA card (B1/M1/M2) load the module b1pcmcia.o +before you insert the card. + +Leased Lines with B1 +-------------------- +Init card and load firmware. +For an D64S use "FV: 1" as phone number +For an D64S2 use "FV: 1" and "FV: 2" for multilink +or "FV: 1,2" to use CAPI channel bundling. + +/proc-Interface +----------------- + +/proc/capi: + dr-xr-xr-x 2 root root 0 Jul 1 14:03 . + dr-xr-xr-x 82 root root 0 Jun 30 19:08 .. + -r--r--r-- 1 root root 0 Jul 1 14:03 applications + -r--r--r-- 1 root root 0 Jul 1 14:03 applstats + -r--r--r-- 1 root root 0 Jul 1 14:03 capi20 + -r--r--r-- 1 root root 0 Jul 1 14:03 capidrv + -r--r--r-- 1 root root 0 Jul 1 14:03 controller + -r--r--r-- 1 root root 0 Jul 1 14:03 contrstats + -r--r--r-- 1 root root 0 Jul 1 14:03 driver + -r--r--r-- 1 root root 0 Jul 1 14:03 ncci + -r--r--r-- 1 root root 0 Jul 1 14:03 users + +/proc/capi/applications: + applid level3cnt datablkcnt datablklen ncci-cnt recvqueuelen + level3cnt: capi_register parameter + datablkcnt: capi_register parameter + ncci-cnt: current number of nccis (connections) + recvqueuelen: number of messages on receive queue + for example: +1 -2 16 2048 1 0 +2 2 7 2048 1 0 + +/proc/capi/applstats: + applid recvctlmsg nrecvdatamsg nsentctlmsg nsentdatamsg + recvctlmsg: capi messages received without DATA_B3_IND + recvdatamsg: capi DATA_B3_IND received + sentctlmsg: capi messages sent without DATA_B3_REQ + sentdatamsg: capi DATA_B3_REQ sent + for example: +1 2057 1699 1721 1699 + +/proc/capi/capi20: statistics of capi.o (/dev/capi20) + minor nopen nrecvdropmsg nrecvctlmsg nrecvdatamsg sentctlmsg sentdatamsg + minor: minor device number of capi device + nopen: number of calls to devices open + nrecvdropmsg: capi messages dropped (messages in recvqueue in close) + nrecvctlmsg: capi messages received without DATA_B3_IND + nrecvdatamsg: capi DATA_B3_IND received + nsentctlmsg: capi messages sent without DATA_B3_REQ + nsentdatamsg: capi DATA_B3_REQ sent + + for example: +1 2 18 0 16 2 + +/proc/capi/capidrv: statistics of capidrv.o (capi messages) + nrecvctlmsg nrecvdatamsg sentctlmsg sentdatamsg + nrecvctlmsg: capi messages received without DATA_B3_IND + nrecvdatamsg: capi DATA_B3_IND received + nsentctlmsg: capi messages sent without DATA_B3_REQ + nsentdatamsg: capi DATA_B3_REQ sent + for example: +2780 2226 2256 2226 + +/proc/capi/controller: + controller drivername state cardname controllerinfo + for example: +1 b1pci running b1pci-e000 B1 3.07-01 0xe000 19 +2 t1isa running t1isa-450 B1 3.07-01 0x450 11 0 +3 b1pcmcia running m2-150 B1 3.07-01 0x150 5 + +/proc/capi/contrstats: + controller nrecvctlmsg nrecvdatamsg sentctlmsg sentdatamsg + nrecvctlmsg: capi messages received without DATA_B3_IND + nrecvdatamsg: capi DATA_B3_IND received + nsentctlmsg: capi messages sent without DATA_B3_REQ + nsentdatamsg: capi DATA_B3_REQ sent + for example: +1 2845 2272 2310 2274 +2 2 0 2 0 +3 2 0 2 0 + +/proc/capi/driver: + drivername ncontroller + for example: +b1pci 1 +t1isa 1 +b1pcmcia 1 +b1isa 0 + +/proc/capi/ncci: + apllid ncci winsize sendwindow + for example: +1 0x10101 8 0 + +/proc/capi/users: kernelmodules that use the kernelcapi. + name + for example: +capidrv +capi20 Questions --------- -Check out the FAQ (ftp.franken.de). +Check out the FAQ (ftp.franken.de) or subscribe to the +linux-avmb1@calle.in-berlin.de mailing list by sending +a mail to majordomo@calle.in-berlin.de with +subscribe linux-avmb1 +in the body. + +German documentaion and several scripts can be found at +ftp://ftp.avm.de/cardware/b1/linux/ Bugs ---- diff -u --recursive --new-file v2.3.13/linux/Documentation/isdn/README.concap linux/Documentation/isdn/README.concap --- v2.3.13/linux/Documentation/isdn/README.concap Sun May 23 10:03:41 1999 +++ linux/Documentation/isdn/README.concap Wed Aug 18 11:37:57 1999 @@ -118,7 +118,7 @@ or when the device driver resets the interface. All services of the encapsulation protocol may be used after this*/ int (*restart)(struct concap_proto *cprot, - struct device *ndev, + struct net_device *ndev, struct concap_device_ops *dops); /* deactivate an encapsulation protocol instance. The encapsulation @@ -174,7 +174,7 @@ An encapsulation protocol itself is actually the struct concap_proto{ - struct device *net_dev; /* net device using our service */ + struct net_device *net_dev; /* net device using our service */ struct concap_device_ops *dops; /* callbacks provided by device */ struct concap_proto_ops *pops; /* callbacks provided by us */ int flags; @@ -199,7 +199,7 @@ encapsulation services could look like this: struct concap_device{ - struct device net_dev; + struct net_device net_dev; struct my_priv /* device->local stuff */ /* the my_priv struct might contain a struct concap_device_ops *dops; @@ -225,9 +225,9 @@ If general linux network interfaces explicitly supported concap -protocols (e.g. by a member struct concap_proto* in struct device) +protocols (e.g. by a member struct concap_proto* in struct net_device) then the interface of the service function could be changed -by passing a pointer of type (struct device*) instead of +by passing a pointer of type (struct net_device*) instead of type (struct concap_proto*). Doing so would make many of the service functions compatible to network device support functions. @@ -237,7 +237,7 @@ we could have - int (*encap_and_xmit)(struct device *ndev, struct sk_buff *skb); + int (*encap_and_xmit)(struct net_device *ndev, struct sk_buff *skb); As this is compatible to the dev->hard_start_xmit() method, the device driver could directly register the concap protocol's encap_and_xmit() @@ -247,7 +247,7 @@ The device's data request function could also be defined as - int (*data_req)(struct device *ndev, struct sk_buff *skb); + int (*data_req)(struct net_device *ndev, struct sk_buff *skb); This might even allow for some protocol stacking. And the network interface might even register the same data_req() function directly diff -u --recursive --new-file v2.3.13/linux/Documentation/isdn/README.diversion linux/Documentation/isdn/README.diversion --- v2.3.13/linux/Documentation/isdn/README.diversion Wed Dec 31 16:00:00 1969 +++ linux/Documentation/isdn/README.diversion Thu Aug 12 09:42:33 1999 @@ -0,0 +1,127 @@ +The isdn diversion services are a supporting module working together with +the isdn4linux and the HiSax module for passive cards. +Active cards, TAs and cards using a own or other driver than the HiSax +module need to be adapted to the HL<->LL interface described in a separate +document. The diversion services may be used with all cards supported by +the HiSax driver. +The diversion kernel interface and controlling tool divertctrl were written +by Werner Cornelius (werner@isdn4linux.de or werner@titro.de) under the +GNU Public License. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Table of contents +================= + +1. Features of the i4l diversion services + (Or what can the i4l diversion services do for me) + +2. Required hard- and software + +3. Compiling, installing and loading/unloading the module + Tracing calling and diversion information + +4. Tracing calling and diversion information + +5. Format of the divert device ASCII output + + +1. Features of the i4l diversion services + (Or what can the i4l diversion services do for me) + + The i4l diversion services offers call forwarding and logging normally + only supported by isdn phones. Incoming calls may be diverted + unconditionally (CFU), when not reachable (CFNR) or on busy condition + (CFB). + The diversions may be invoked statically in the providers exchange + as normally done by isdn phones. In this case all incoming calls + with a special (or all) service identifiers are forwarded if the + forwarding reason is met. Activated static services may also be + interrogated (queried). + The i4l diversion services additionally offers a dynamic version of + call forwarding which is not preprogrammed inside the providers exchange + but dynamically activated by i4l. + In this case all incoming calls are checked by rules that may be + compared to the mechanism of ipfwadm or ipchains. If a given rule matches + the checking process is finished and the rule matching will be applied + to the call. + The rules include primary and secondary service indentifiers, called + number and subaddress, callers number and subaddress and whether the rule + matches to all filtered calls or only those when all B-channel resources + are exhausted. + Actions that may be invoked by a rule are ignore, proceed, reject, + direct divert or delayed divert of a call. + All incoming calls matching a rule except the ignore rule a reported and + logged as ASCII via the proc filesystem (/proc/net/isdn/divert). If proceed + is selected the call will be held in a proceeding state (without ringing) + for a certain amount of time to let an external program or client decide + how to handle the call. + + +2. Required hard- and software + + For using the i4l diversion services the isdn line must be of a EURO/DSS1 + type. Additionally the i4l services only work together with the HiSax + driver for passive isdn cards. All HiSax supported cards may be used for + the diversion purposes. + The static diversion services require the provider having static services + CFU, CFNR, CFB activated on an MSN-line. The static services may not be + used on a point-to-point connection. Further the static services are only + available in some countries (for example germany). Countries requiring the + keypad protocol for activating static diversions (like the netherlands) are + not supported but may use the tty devices for this purpose. + The dynamic diversion servives may be used in all countries if the provider + enables the feature CF (call forwarding). This should work on both MSN- and + point-to-point lines. + To add and delete rules the additional divertctrl program is needed. This + program is part of the isdn4kutils package. + +3. Compiling, installing and loading/unloading the module + Tracing calling and diversion information + + + To compile the i4l code with diversion support you need to say yes to the + DSS1 diversion services when selecting the i4l options in the kernel + config (menuconfig or config). + After having properly activated a make modules and make modules_install all + required modules will be correctly installed in the needed modules dirs. + As the diversion services are currently not included in the scripts of most + standard distributions you will have to add a "insmod dss1_divert" after + having loaded the global isdn module. + The module can be loaded without any command line parameters. + If the module is actually loaded and active may be checked with a + "cat /proc/modules" or "ls /proc/net/isdn/divert". The divert file is + dynamically created by the diversion module and removed when the module is + unloaded. + + +4. Tracing calling and diversion information + + You also may put a "cat /proc/net/isdn/divert" in the background with the + output redirected to a file. Then all actions of the module are logged. + The divert file in the proc system may be opened more than once, so in + conjunction with inetd and a small remote client on other machines inside + your network incoming calls and reactions by the module may be shown on + every listening machine. + If a call is reported as proceeding an external program or client may + specify during a certain amount of time (normally 4 to 10 seconds) what + to do with that call. + To unload the module all open files to the device in the proc system must + be closed. Otherwise the module (and isdn.o) may not be unloaded. + +5. Format of the divert device ASCII output + + To be done later + diff -u --recursive --new-file v2.3.13/linux/Documentation/isdn/README.eicon linux/Documentation/isdn/README.eicon --- v2.3.13/linux/Documentation/isdn/README.eicon Sun May 23 10:03:41 1999 +++ linux/Documentation/isdn/README.eicon Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -$Id: README.eicon,v 1.3 1999/03/29 11:10:04 armin Exp $ +$Id: README.eicon,v 1.4 1999/07/11 17:17:30 armin Exp $ (c) 1999 Cytronics & Melware @@ -21,11 +21,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -NOTE : Since the eicon driver is still experimental, this README file - may be incomplete and not up to date. - -However, the driver should work under following conditions : Supported Cards --------------- diff -u --recursive --new-file v2.3.13/linux/Documentation/isdn/README.fax linux/Documentation/isdn/README.fax --- v2.3.13/linux/Documentation/isdn/README.fax Wed Dec 31 16:00:00 1969 +++ linux/Documentation/isdn/README.fax Thu Aug 12 09:42:33 1999 @@ -0,0 +1,38 @@ + +Fax with isdn4linux +=================== + +When enabled during kernel configuration, the tty emulator +of the ISDN subsystem is capable of the Fax Class 2 commands. + +This only makes sense under the following conditions : + +- You need the commands as dummy, because you are using + hylafax (with patch) for AVM capi. +- You want to use the fax capabillities of your isdn-card. + (supported cards are listed below) + + +NOTE: This implementation does *not* support fax with passive + ISDN-cards (known as softfax). The low-level driver of + the ISDN-card and/or the card itself must support this. + + +Supported ISDN-Cards +-------------------- + +Eicon DIVA Server BRI/PCI (will be ready soon) +Eicon DIVA Server PRI/PCI (will be ready soon) + + + +The command set is known as Class 2 (not Class 2.0) and +can be activated by AT+FCLASS=2 + + +The interface between the link-level-module and the hardware-level driver +is described in the files INTERFACE.fax and INTERFACE. + +Armin +mac@melware.de + diff -u --recursive --new-file v2.3.13/linux/Documentation/isdn/README.hfc-pci linux/Documentation/isdn/README.hfc-pci --- v2.3.13/linux/Documentation/isdn/README.hfc-pci Wed Dec 31 16:00:00 1969 +++ linux/Documentation/isdn/README.hfc-pci Thu Aug 12 09:42:33 1999 @@ -0,0 +1,26 @@ +The driver for the HFC-PCI and HFC-PCI-A chips from CCD may be used +for many OEM cards using this chips. +Additionally the driver has a special feature which makes it possible +to read the echo-channel of the isdn bus. So all frames in both directions +may be logged. +When the echo logging feature is used the number of available B-channels +for a HFC-PCI card is reduced to 1. Of course this is only relevant to +the card, not to the isdn line. +To activate the echo mode the following ioctls must be entered: + +hisaxctrl 10 1 + +This reduces the available channels to 1. There must not be open connections +through this card when entering the command. +And then: + +hisaxctrl 12 1 + +This enables the echo mode. If Hex logging is activated the isdnctrlx +devices show a output with a line beginning of HEX: for the providers +exchange and ECHO: for isdn devices sending to the provider. + +Comments and reports to werner@isdn4linux.de or werner@titro.de . + + + diff -u --recursive --new-file v2.3.13/linux/Documentation/mca.txt linux/Documentation/mca.txt --- v2.3.13/linux/Documentation/mca.txt Sun Nov 8 13:29:31 1998 +++ linux/Documentation/mca.txt Wed Aug 18 11:37:51 1999 @@ -19,7 +19,7 @@ #include unsigned char pos2, pos3, pos4, pos5; - struct device* dev; + struct net_device* dev; int slot; if( MCA_bus ) { @@ -114,7 +114,7 @@ static int dev_getinfo( char* buf, int slot, void* d ) { - struct device* dev = (struct device*) d; + struct net_device* dev = (struct net_device*) d; int len = 0; len += sprintf( buf+len, "Device: %s\n", dev->name ); diff -u --recursive --new-file v2.3.13/linux/Documentation/networking/cs89x0.txt linux/Documentation/networking/cs89x0.txt --- v2.3.13/linux/Documentation/networking/cs89x0.txt Thu Jul 8 15:42:19 1999 +++ linux/Documentation/networking/cs89x0.txt Wed Aug 18 11:37:57 1999 @@ -323,20 +323,20 @@ d.) In /linux/drivers/net/Space.c file, add the line: -extern int cs89x0_probe(struct device *dev); +extern int cs89x0_probe(struct net_device *dev); Example: - extern int ultra_probe(struct device *dev); - extern int wd_probe(struct device *dev); - extern int el2_probe(struct device *dev); + extern int ultra_probe(struct net_device *dev); + extern int wd_probe(struct net_device *dev); + extern int el2_probe(struct net_device *dev); - extern int cs89x0_probe(struct device *dev); + extern int cs89x0_probe(struct net_device *dev); - extern int ne_probe(struct device *dev); - extern int hp_probe(struct device *dev); - extern int hp_plus_probe(struct device *dev); + extern int ne_probe(struct net_device *dev); + extern int hp_probe(struct net_device *dev); + extern int hp_plus_probe(struct net_device *dev); Also add: diff -u --recursive --new-file v2.3.13/linux/Documentation/parport.txt linux/Documentation/parport.txt --- v2.3.13/linux/Documentation/parport.txt Thu Jul 8 15:42:19 1999 +++ linux/Documentation/parport.txt Thu Aug 12 10:19:59 1999 @@ -139,8 +139,7 @@ peripherals. This is a port-wide setting, i.e. it applies to all devices on a particular port. -timeslice The number of jiffies (FIXME: this should be in - milliseconds or something) that a device driver is +timeslice The number of miliseconds that a device driver is allowed to keep a port claimed for. This is advisory, and driver can ignore it if it must. diff -u --recursive --new-file v2.3.13/linux/MAINTAINERS linux/MAINTAINERS --- v2.3.13/linux/MAINTAINERS Mon Aug 9 14:59:19 1999 +++ linux/MAINTAINERS Sun Aug 15 11:50:35 1999 @@ -377,7 +377,7 @@ HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series P: Jaroslav Kysela -M: perex@jcu.cz +M: perex@suse.cz S: Maintained IBM MCA SCSI SUBSYSTEM DRIVER @@ -433,6 +433,11 @@ L: linux-irda@list.uit.no W: http://www.cs.uit.no/linux-irda/ S: Maintained + +ISAPNP +P: Jaroslav Kysela +M: perex@suse.cz +S: Maintained ISDN SUBSYSTEM P: Fritz Elfert diff -u --recursive --new-file v2.3.13/linux/Makefile linux/Makefile --- v2.3.13/linux/Makefile Mon Aug 9 14:59:19 1999 +++ linux/Makefile Wed Aug 18 09:45:10 1999 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 3 -SUBLEVEL = 13 +SUBLEVEL = 14 EXTRAVERSION = ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) @@ -111,6 +111,7 @@ NETWORKS =net/network.a DRIVERS =drivers/block/block.a \ drivers/char/char.o \ + drivers/misc/misc.o \ drivers/parport/parport.a LIBS =$(TOPDIR)/lib/lib.a SUBDIRS =kernel drivers mm fs net ipc lib @@ -134,7 +135,7 @@ endif ifeq ($(CONFIG_SOUND),y) -DRIVERS := $(DRIVERS) drivers/sound/sound.a +DRIVERS := $(DRIVERS) drivers/sound/sounddrivers.o endif ifdef CONFIG_PCI @@ -178,7 +179,7 @@ endif ifdef CONFIG_HAMRADIO -DRIVERS := $(DRIVERS) drivers/net/hamradio/hamradio.a +DRIVERS := $(DRIVERS) drivers/net/hamradio/hamradio.o endif ifeq ($(CONFIG_TC),y) @@ -333,6 +334,7 @@ if [ -f VIDEO_MODULES ]; then inst_mod VIDEO_MODULES video; fi; \ if [ -f FC4_MODULES ]; then inst_mod FC4_MODULES fc4; fi; \ if [ -f IRDA_MODULES ]; then inst_mod IRDA_MODULES net; fi; \ + if [ -f USB_MODULES ]; then inst_mod USB_MODULES usb; fi; \ \ ls *.o > $$MODLIB/.allmods; \ echo $$MODULES | tr ' ' '\n' | sort | comm -23 $$MODLIB/.allmods - > $$MODLIB/.misc; \ @@ -362,6 +364,8 @@ rm -f drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c rm -f drivers/char/conmakehash rm -f drivers/sound/bin2hex drivers/sound/hex2hex + rm -f net/khttpd/make_times_h + rm -f net/khttpd/times.h if [ -d modules ]; then \ rm -f core `find modules/ -type f -print`; \ fi diff -u --recursive --new-file v2.3.13/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c --- v2.3.13/linux/arch/alpha/kernel/bios32.c Mon Aug 9 14:59:19 1999 +++ linux/arch/alpha/kernel/bios32.c Fri Aug 13 11:53:50 1999 @@ -522,7 +522,6 @@ Cypress. */ if (dev->vendor == PCI_VENDOR_ID_CONTAQ && dev->device == PCI_DEVICE_ID_CONTAQ_82C693 - && dev->class >> 8 == PCI_CLASS_BRIDGE_ISA && idx < 2) { continue; } diff -u --recursive --new-file v2.3.13/linux/arch/alpha/kernel/core_apecs.c linux/arch/alpha/kernel/core_apecs.c --- v2.3.13/linux/arch/alpha/kernel/core_apecs.c Sun Sep 6 10:34:33 1998 +++ linux/arch/alpha/kernel/core_apecs.c Fri Aug 13 11:53:50 1999 @@ -17,6 +17,7 @@ #include #include +#include #define __EXTERN_INLINE inline #include @@ -35,19 +36,16 @@ * BIOS32-style PCI interface: */ -#ifdef DEBUG -# define DBG(args) printk args +#define DEBUG_CONFIG 0 + +#if DEBUG_CONFIG +# define DBGC(args) printk args #else -# define DBG(args) +# define DBGC(args) #endif #define vuip volatile unsigned int * -volatile unsigned int apecs_mcheck_expected = 0; -volatile unsigned int apecs_mcheck_taken = 0; -static unsigned int apecs_jd, apecs_jd1, apecs_jd2; - - /* * Given a bus, device, and function number, compute resulting * configuration space address and setup the APECS_HAXR2 register @@ -96,9 +94,9 @@ { unsigned long addr; - DBG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x," - " pci_addr=0x%p, type1=0x%p)\n", - bus, device_fn, where, pci_addr, type1)); + DBGC(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x," + " pci_addr=0x%p, type1=0x%p)\n", + bus, device_fn, where, pci_addr, type1)); if (bus == 0) { int device = device_fn >> 3; @@ -106,8 +104,8 @@ /* type 0 configuration cycle: */ if (device > 20) { - DBG(("mk_conf_addr: device (%d) > 20, returning -1\n", - device)); + DBGC(("mk_conf_addr: device (%d) > 20, returning -1\n", + device)); return -1; } @@ -119,7 +117,7 @@ addr = (bus << 16) | (device_fn << 8) | (where); } *pci_addr = addr; - DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr)); + DBGC(("mk_conf_addr: returning pci_addr 0x%lx\n", addr)); return 0; } @@ -132,25 +130,25 @@ __save_and_cli(flags); /* avoid getting hit by machine check */ - DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1)); + DBGC(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1)); /* Reset status register to avoid losing errors. */ stat0 = *(vuip)APECS_IOC_DCSR; *(vuip)APECS_IOC_DCSR = stat0; mb(); - DBG(("conf_read: APECS DCSR was 0x%x\n", stat0)); + DBGC(("conf_read: APECS DCSR was 0x%x\n", stat0)); /* If Type1 access, must set HAE #2. */ if (type1) { haxr2 = *(vuip)APECS_IOC_HAXR2; mb(); *(vuip)APECS_IOC_HAXR2 = haxr2 | 1; - DBG(("conf_read: TYPE1 access\n")); + DBGC(("conf_read: TYPE1 access\n")); } draina(); - apecs_mcheck_expected = 1; - apecs_mcheck_taken = 0; + mcheck_expected(0) = 1; + mcheck_taken(0) = 0; mb(); /* Access configuration space. */ @@ -159,12 +157,12 @@ asm volatile("ldl %0,%1; mb; mb" : "=r"(value) : "m"(*(vuip)addr) : "$9", "$10", "$11", "$12", "$13", "$14", "memory"); - if (apecs_mcheck_taken) { - apecs_mcheck_taken = 0; + if (mcheck_taken(0)) { + mcheck_taken(0) = 0; value = 0xffffffffU; mb(); } - apecs_mcheck_expected = 0; + mcheck_expected(0) = 0; mb(); #if 1 @@ -178,7 +176,7 @@ /* Now look for any errors. */ stat0 = *(vuip)APECS_IOC_DCSR; - DBG(("conf_read: APECS DCSR after read 0x%x\n", stat0)); + DBGC(("conf_read: APECS DCSR after read 0x%x\n", stat0)); /* Is any error bit set? */ if (stat0 & 0xffe0U) { @@ -228,14 +226,14 @@ } draina(); - apecs_mcheck_expected = 1; + mcheck_expected(0) = 1; mb(); /* Access configuration space. */ *(vuip)addr = value; mb(); mb(); /* magic */ - apecs_mcheck_expected = 0; + mcheck_expected(0) = 0; mb(); #if 1 @@ -438,20 +436,21 @@ *(vuip)APECS_IOC_HAXR2 = 0; mb(); } -int +void apecs_pci_clr_err(void) { - apecs_jd = *(vuip)APECS_IOC_DCSR; - if (apecs_jd & 0xffe0L) { - apecs_jd1 = *(vuip)APECS_IOC_SEAR; - *(vuip)APECS_IOC_DCSR = apecs_jd | 0xffe1L; - apecs_jd = *(vuip)APECS_IOC_DCSR; + unsigned int jd; + + jd = *(vuip)APECS_IOC_DCSR; + if (jd & 0xffe0L) { + *(vuip)APECS_IOC_SEAR; + *(vuip)APECS_IOC_DCSR = jd | 0xffe1L; mb(); + *(vuip)APECS_IOC_DCSR; } *(vuip)APECS_IOC_TBIA = (unsigned int)APECS_IOC_TBIA; - apecs_jd2 = *(vuip)APECS_IOC_TBIA; mb(); - return 0; + *(vuip)APECS_IOC_TBIA; } void @@ -461,8 +460,6 @@ struct el_common *mchk_header; struct el_apecs_procdata *mchk_procdata; struct el_apecs_sysdata_mcheck *mchk_sysdata; - unsigned long *ptr; - int i; mchk_header = (struct el_common *)la_ptr; @@ -473,66 +470,16 @@ mchk_sysdata = (struct el_apecs_sysdata_mcheck *) (la_ptr + mchk_header->sys_offset); -#ifdef DEBUG - printk("apecs_machine_check: vector=0x%lx la_ptr=0x%lx\n", - vector, la_ptr); - printk(" pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n", - regs->pc, mchk_header->size, mchk_header->proc_offset, - mchk_header->sys_offset); - printk("apecs_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n", - apecs_mcheck_expected, mchk_sysdata->epic_dcsr, - mchk_sysdata->epic_pear); - ptr = (unsigned long *)la_ptr; - for (i = 0; i < mchk_header->size / sizeof(long); i += 2) { - printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]); - } -#endif - /* - * Check if machine check is due to a badaddr() and if so, - * ignore the machine check. - */ + /* Clear the error before any reporting. */ + mb(); + mb(); /* magic */ + draina(); + apecs_pci_clr_err(); + wrmces(0x7); /* reset machine check pending flag */ + mb(); - if (apecs_mcheck_expected - && (mchk_sysdata->epic_dcsr & 0x0c00UL)) { - apecs_mcheck_expected = 0; - apecs_mcheck_taken = 1; - mb(); - mb(); /* magic */ - apecs_pci_clr_err(); - wrmces(0x7); - mb(); - draina(); - DBG(("apecs_machine_check: EXPECTED\n")); - } - else if (vector == 0x620 || vector == 0x630) { - /* Disable correctable from now on. */ - wrmces(0x1f); - mb(); - draina(); - printk("apecs_machine_check: HW correctable (0x%lx)\n", - vector); - } - else { - printk(KERN_CRIT "APECS machine check:\n"); - printk(KERN_CRIT " vector=0x%lx la_ptr=0x%lx\n", - vector, la_ptr); - printk(KERN_CRIT - " pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n", - regs->pc, mchk_header->size, mchk_header->proc_offset, - mchk_header->sys_offset); - printk(KERN_CRIT " expected %d DCSR 0x%lx PEAR 0x%lx\n", - apecs_mcheck_expected, mchk_sysdata->epic_dcsr, - mchk_sysdata->epic_pear); - - ptr = (unsigned long *)la_ptr; - for (i = 0; i < mchk_header->size / sizeof(long); i += 2) { - printk(KERN_CRIT " +%lx %lx %lx\n", - i*sizeof(long), ptr[i], ptr[i+1]); - } -#if 0 - /* doesn't work with MILO */ - show_regs(regs); -#endif - } + process_mcheck_info(vector, la_ptr, regs, "APECS", + (mcheck_expected(0) + && (mchk_sysdata->epic_dcsr & 0x0c00UL))); } diff -u --recursive --new-file v2.3.13/linux/arch/alpha/kernel/core_cia.c linux/arch/alpha/kernel/core_cia.c --- v2.3.13/linux/arch/alpha/kernel/core_cia.c Tue Jun 22 10:46:52 1999 +++ linux/arch/alpha/kernel/core_cia.c Fri Aug 13 11:53:50 1999 @@ -31,30 +31,12 @@ */ /* - * Machine check reasons. Defined according to PALcode sources - * (osf.h and platform.h). - */ -#define MCHK_K_TPERR 0x0080 -#define MCHK_K_TCPERR 0x0082 -#define MCHK_K_HERR 0x0084 -#define MCHK_K_ECC_C 0x0086 -#define MCHK_K_ECC_NC 0x0088 -#define MCHK_K_OS_BUGCHECK 0x008A -#define MCHK_K_PAL_BUGCHECK 0x0090 - -/* * BIOS32-style PCI interface: */ -#define DEBUG_MCHECK 0 #define DEBUG_CONFIG 0 -/* #define DEBUG_DUMP_REGS */ +#define DEBUG_DUMP_REGS 0 -#if DEBUG_MCHECK -# define DBGM(args) printk args -#else -# define DBGM(args) -#endif #if DEBUG_CONFIG # define DBGC(args) printk args #else @@ -63,11 +45,6 @@ #define vuip volatile unsigned int * -static volatile unsigned int CIA_mcheck_expected = 0; -static volatile unsigned int CIA_mcheck_taken = 0; -static unsigned int CIA_jd; - - /* * Given a bus, device, and function number, compute resulting * configuration space address and setup the CIA_HAXR2 register @@ -173,20 +150,20 @@ mb(); draina(); - CIA_mcheck_expected = 1; - CIA_mcheck_taken = 0; + mcheck_expected(0) = 1; + mcheck_taken(0) = 0; mb(); /* Access configuration space. */ value = *(vuip)addr; mb(); mb(); /* magic */ - if (CIA_mcheck_taken) { - CIA_mcheck_taken = 0; + if (mcheck_taken(0)) { + mcheck_taken(0) = 0; value = 0xffffffffU; mb(); } - CIA_mcheck_expected = 0; + mcheck_expected(0) = 0; mb(); #if 0 @@ -249,7 +226,7 @@ } draina(); - CIA_mcheck_expected = 1; + mcheck_expected(0) = 1; mb(); /* Access configuration space. */ @@ -257,7 +234,7 @@ mb(); mb(); /* magic */ - CIA_mcheck_expected = 0; + mcheck_expected(0) = 0; mb(); #if 0 @@ -395,7 +372,7 @@ { unsigned int cia_tmp; -#ifdef DEBUG_DUMP_REGS +#if DEBUG_DUMP_REGS { unsigned int temp; temp = *(vuip)CIA_IOC_CIA_REV; mb(); @@ -533,19 +510,26 @@ case 0: /* * Set up the PCI->physical memory translation windows. - * For now, windows 1,2 and 3 are disabled. In the future, + * For now, windows 2 and 3 are disabled. In the future, * we may want to use them to do scatter/gather DMA. * * Window 0 goes at 1 GB and is 1 GB large. + * Window 1 goes at 2 GB and is 1 GB large. */ - *(vuip)CIA_IOC_PCI_W0_BASE = 1U | (CIA_DMA_WIN_BASE_DEFAULT & 0xfff00000U); - *(vuip)CIA_IOC_PCI_W0_MASK = (CIA_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000U; - *(vuip)CIA_IOC_PCI_T0_BASE = 0; + *(vuip)CIA_IOC_PCI_W0_BASE = CIA_DMA_WIN0_BASE_DEFAULT | 1U; + *(vuip)CIA_IOC_PCI_W0_MASK = (CIA_DMA_WIN0_SIZE_DEFAULT - 1) & + 0xfff00000U; + *(vuip)CIA_IOC_PCI_T0_BASE = CIA_DMA_WIN0_TRAN_DEFAULT >> 2; + + *(vuip)CIA_IOC_PCI_W1_BASE = CIA_DMA_WIN1_BASE_DEFAULT | 1U; + *(vuip)CIA_IOC_PCI_W1_MASK = (CIA_DMA_WIN1_SIZE_DEFAULT - 1) & + 0xfff00000U; + *(vuip)CIA_IOC_PCI_T1_BASE = CIA_DMA_WIN1_TRAN_DEFAULT >> 2; - *(vuip)CIA_IOC_PCI_W1_BASE = 0x0; *(vuip)CIA_IOC_PCI_W2_BASE = 0x0; *(vuip)CIA_IOC_PCI_W3_BASE = 0x0; + mb(); break; } @@ -593,128 +577,28 @@ } } -static int +static inline void cia_pci_clr_err(void) { - CIA_jd = *(vuip)CIA_IOC_CIA_ERR; - DBGM(("CIA_pci_clr_err: CIA ERR after read 0x%x\n", CIA_jd)); - *(vuip)CIA_IOC_CIA_ERR = CIA_jd; + unsigned int jd; + + jd = *(vuip)CIA_IOC_CIA_ERR; + *(vuip)CIA_IOC_CIA_ERR = jd; mb(); - return 0; + *(vuip)CIA_IOC_CIA_ERR; /* re-read to force write. */ } void cia_machine_check(unsigned long vector, unsigned long la_ptr, struct pt_regs * regs) { - struct el_common *mchk_header; - struct el_CIA_procdata *mchk_procdata; - struct el_CIA_sysdata_mcheck *mchk_sysdata; - unsigned long * ptr; - const char * reason; - char buf[128]; - long i; - - mchk_header = (struct el_common *)la_ptr; - - mchk_procdata = (struct el_CIA_procdata *) - (la_ptr + mchk_header->proc_offset); - - mchk_sysdata = (struct el_CIA_sysdata_mcheck *) - (la_ptr + mchk_header->sys_offset); - - DBGM(("cia_machine_check: vector=0x%lx la_ptr=0x%lx\n", - vector, la_ptr)); - DBGM((" pc=0x%lx size=0x%x procoffset=0x%x " - "sysoffset 0x%x\n", regs->pc, mchk_header->size, - mchk_header->proc_offset, mchk_header->sys_offset)); - DBGM(("cia_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n", - CIA_mcheck_expected, mchk_sysdata->epic_dcsr, - mchk_sysdata->epic_pear)); - -#if DEBUG_MCHECK - { - unsigned long *ptr; - int i; - - ptr = (unsigned long *)la_ptr; - for (i = 0; i < mchk_header->size / sizeof(long); i += 2) { - printk(" +%lx %lx %lx\n", i*sizeof(long), - ptr[i], ptr[i+1]); - } - } -#endif - - /* - * Check if machine check is due to a badaddr() and if so, - * ignore the machine check. - */ - mb(); - mb(); /* magic */ - if (CIA_mcheck_expected) { - DBGM(("CIA machine check expected\n")); - CIA_mcheck_expected = 0; - CIA_mcheck_taken = 1; - mb(); - mb(); /* magic */ - draina(); - cia_pci_clr_err(); - wrmces(0x7); - mb(); - return; - } - - switch ((unsigned int) mchk_header->code) { - case MCHK_K_TPERR: reason = "tag parity error"; break; - case MCHK_K_TCPERR: reason = "tag control parity error"; break; - case MCHK_K_HERR: reason = "generic hard error"; break; - case MCHK_K_ECC_C: reason = "correctable ECC error"; break; - case MCHK_K_ECC_NC: reason = "uncorrectable ECC error"; break; - case MCHK_K_OS_BUGCHECK: reason = "OS-specific PAL bugcheck"; break; - case MCHK_K_PAL_BUGCHECK: reason = "callsys in kernel mode"; break; - case 0x96: reason = "i-cache read retryable error"; break; - case 0x98: reason = "processor detected hard error"; break; - - /* System specific (these are for Alcor, at least): */ - case 0x203: reason = "system detected uncorrectable ECC error"; break; - case 0x205: reason = "parity error detected by CIA"; break; - case 0x207: reason = "non-existent memory error"; break; - case 0x209: reason = "PCI SERR detected"; break; - case 0x20b: reason = "PCI data parity error detected"; break; - case 0x20d: reason = "PCI address parity error detected"; break; - case 0x20f: reason = "PCI master abort error"; break; - case 0x211: reason = "PCI target abort error"; break; - case 0x213: reason = "scatter/gather PTE invalid error"; break; - case 0x215: reason = "flash ROM write error"; break; - case 0x217: reason = "IOA timeout detected"; break; - case 0x219: reason = "IOCHK#, EISA add-in board parity or other catastrophic error"; break; - case 0x21b: reason = "EISA fail-safe timer timeout"; break; - case 0x21d: reason = "EISA bus time-out"; break; - case 0x21f: reason = "EISA software generated NMI"; break; - case 0x221: reason = "unexpected ev5 IRQ[3] interrupt"; break; - default: - sprintf(buf, "reason for machine-check unknown (0x%x)", - (unsigned int) mchk_header->code); - reason = buf; - break; - } + /* Clear the error before any reporting. */ mb(); mb(); /* magic */ draina(); cia_pci_clr_err(); - wrmces(rdmces()); /* reset machine check pending flag */ + wrmces(rdmces()); /* reset machine check pending flag. */ mb(); - printk(KERN_CRIT "CIA machine check: %s%s\n", - reason, mchk_header->retry ? " (retryable)" : ""); - printk(KERN_CRIT " vector=0x%lx la_ptr=0x%lx pc=0x%lx\n", - vector, la_ptr, regs->pc); - - /* Dump the logout area to give all info. */ - - ptr = (unsigned long *)la_ptr; - for (i = 0; i < mchk_header->size / sizeof(long); i += 2) { - printk(KERN_CRIT " +%8lx %016lx %016lx\n", - i*sizeof(long), ptr[i], ptr[i+1]); - } + process_mcheck_info(vector, la_ptr, regs, "CIA", mcheck_expected(0)); } diff -u --recursive --new-file v2.3.13/linux/arch/alpha/kernel/core_lca.c linux/arch/alpha/kernel/core_lca.c --- v2.3.13/linux/arch/alpha/kernel/core_lca.c Sun Sep 6 10:34:33 1998 +++ linux/arch/alpha/kernel/core_lca.c Fri Aug 13 11:53:50 1999 @@ -430,18 +430,18 @@ } void -lca_machine_check (unsigned long vector, unsigned long la, +lca_machine_check (unsigned long vector, unsigned long la_ptr, struct pt_regs *regs) { - unsigned long * ptr; const char * reason; union el_lca el; - char buf[128]; - long i; - printk(KERN_CRIT "lca: machine check (la=0x%lx,pc=0x%lx)\n", - la, regs->pc); - el.c = (struct el_common *) la; + el.c = (struct el_common *) la_ptr; + + wrmces(rdmces()); /* reset machine check pending flag */ + + printk(KERN_CRIT "LCA machine check: vector=%#lx pc=%#lx code=%#x\n", + vector, regs->pc, (unsigned int) el.c->code); /* * The first quadword after the common header always seems to @@ -450,13 +450,13 @@ * logout frame, the upper 32 bits is the machine check * revision level, which we ignore for now. */ - switch (el.c->code & 0xffffffff) { + switch ((unsigned int) el.c->code) { case MCHK_K_TPERR: reason = "tag parity error"; break; case MCHK_K_TCPERR: reason = "tag control parity error"; break; case MCHK_K_HERR: reason = "access to non-existent memory"; break; case MCHK_K_ECC_C: reason = "correctable ECC error"; break; case MCHK_K_ECC_NC: reason = "non-correctable ECC error"; break; - case MCHK_K_CACKSOFT: reason = "MCHK_K_CACKSOFT"; break; /* what's this? */ + case MCHK_K_CACKSOFT: reason = "MCHK_K_CACKSOFT"; break; case MCHK_K_BUGCHECK: reason = "illegal exception in PAL mode"; break; case MCHK_K_OS_BUGCHECK: reason = "callsys in kernel mode"; break; case MCHK_K_DCPERR: reason = "d-cache parity error"; break; @@ -465,19 +465,13 @@ case MCHK_K_SIO_IOCHK: reason = "SIO IOCHK occurred on ISA bus"; break; case MCHK_K_DCSR: reason = "MCHK_K_DCSR"; break; case MCHK_K_UNKNOWN: - default: - sprintf(buf, "reason for machine-check unknown (0x%lx)", - el.c->code & 0xffffffff); - reason = buf; - break; + default: reason = "unknown"; break; } - wrmces(rdmces()); /* reset machine check pending flag */ - switch (el.c->size) { case sizeof(struct el_lca_mcheck_short): printk(KERN_CRIT - " Reason: %s (short frame%s, dc_stat=%lx):\n", + " Reason: %s (short frame%s, dc_stat=%#lx):\n", reason, el.c->retry ? ", retryable" : "", el.s->dc_stat); if (el.s->esr & ESR_EAV) { @@ -492,9 +486,9 @@ printk(KERN_CRIT " Reason: %s (long frame%s):\n", reason, el.c->retry ? ", retryable" : ""); printk(KERN_CRIT - " reason: %lx exc_addr: %lx dc_stat: %lx\n", + " reason: %#lx exc_addr: %#lx dc_stat: %#lx\n", el.l->pt[0], el.l->exc_addr, el.l->dc_stat); - printk(KERN_CRIT " car: %lx\n", el.l->car); + printk(KERN_CRIT " car: %#lx\n", el.l->car); if (el.l->esr & ESR_EAV) { mem_error(el.l->esr, el.l->ear); } @@ -508,12 +502,16 @@ } /* Dump the logout area to give all info. */ - - ptr = (unsigned long *) la; - for (i = 0; i < el.c->size / sizeof(long); i += 2) { - printk(KERN_CRIT " +%8lx %016lx %016lx\n", - i*sizeof(long), ptr[i], ptr[i+1]); +#if DEBUG_MCHECK > 1 + { + unsigned long * ptr = (unsigned long *) la_ptr; + long i; + for (i = 0; i < el.c->size / sizeof(long); i += 2) { + printk(KERN_CRIT " +%8lx %016lx %016lx\n", + i*sizeof(long), ptr[i], ptr[i+1]); + } } +#endif } /* diff -u --recursive --new-file v2.3.13/linux/arch/alpha/kernel/core_mcpcia.c linux/arch/alpha/kernel/core_mcpcia.c --- v2.3.13/linux/arch/alpha/kernel/core_mcpcia.c Tue Jun 22 10:54:54 1999 +++ linux/arch/alpha/kernel/core_mcpcia.c Fri Aug 13 11:53:50 1999 @@ -37,27 +37,14 @@ * BIOS32-style PCI interface: */ -#undef DEBUG_CFG +#define DEBUG_CFG 0 -#ifdef DEBUG_CFG +#if DEBUG_CFG # define DBG_CFG(args) printk args #else # define DBG_CFG(args) #endif - -#define DEBUG_MCHECK - -#ifdef DEBUG_MCHECK -# define DBG_MCK(args) printk args -#else -# define DBG_MCK(args) -#endif - -static volatile unsigned int MCPCIA_mcheck_expected[NR_CPUS]; -static volatile unsigned int MCPCIA_mcheck_taken[NR_CPUS]; -static unsigned int MCPCIA_jd[NR_CPUS]; - #define MCPCIA_MAX_HOSES 2 @@ -126,8 +113,9 @@ mb(); draina(); - MCPCIA_mcheck_expected[cpu] = 1; - MCPCIA_mcheck_taken[cpu] = 0; + mcheck_expected(cpu) = 1; + mcheck_taken(cpu) = 0; + mcheck_hose(cpu) = hoseno; mb(); /* Access configuration space. */ @@ -135,12 +123,12 @@ mb(); mb(); /* magic */ - if (MCPCIA_mcheck_taken[cpu]) { - MCPCIA_mcheck_taken[cpu] = 0; + if (mcheck_taken(cpu)) { + mcheck_taken(cpu) = 0; value = 0xffffffffU; mb(); } - MCPCIA_mcheck_expected[cpu] = 0; + mcheck_expected(cpu) = 0; mb(); DBG_CFG(("conf_read(): finished\n")); @@ -168,7 +156,8 @@ DBG_CFG(("conf_write: MCPCIA CAP_ERR(%d) was 0x%x\n", hoseno, stat0)); draina(); - MCPCIA_mcheck_expected[cpu] = 1; + mcheck_expected(cpu) = 1; + mcheck_hose(cpu) = hoseno; mb(); /* Access configuration space. */ @@ -176,7 +165,7 @@ mb(); mb(); /* magic */ temp = *(vuip)MCPCIA_CAP_ERR(hoseno); /* read to force the write */ - MCPCIA_mcheck_expected[cpu] = 0; + mcheck_expected(cpu) = 0; mb(); DBG_CFG(("conf_write(): finished\n")); @@ -328,8 +317,8 @@ mb(); mb(); draina(); - MCPCIA_mcheck_expected[cpu] = 1; - MCPCIA_mcheck_taken[cpu] = 0; + mcheck_expected(cpu) = 1; + mcheck_taken(cpu) = 0; mb(); /* Access the bus revision word. */ @@ -337,12 +326,12 @@ mb(); mb(); /* magic */ - if (MCPCIA_mcheck_taken[cpu]) { - MCPCIA_mcheck_taken[cpu] = 0; + if (mcheck_taken(cpu)) { + mcheck_taken(cpu) = 0; pci_rev = 0xffffffff; mb(); } - MCPCIA_mcheck_expected[cpu] = 0; + mcheck_expected(cpu) = 0; mb(); #if 0 @@ -554,19 +543,13 @@ } } -static int -mcpcia_pci_clr_err(int h) +static void +mcpcia_pci_clr_err(int hose) { - unsigned int cpu = smp_processor_id(); - - MCPCIA_jd[cpu] = *(vuip)MCPCIA_CAP_ERR(h); -#if 0 - DBG_MCK(("MCPCIA_pci_clr_err: MCPCIA CAP_ERR(%d) after read 0x%x\n", - h, MCPCIA_jd[cpu])); -#endif - *(vuip)MCPCIA_CAP_ERR(h) = 0xffffffff; mb(); /* clear them all */ - MCPCIA_jd[cpu] = *(vuip)MCPCIA_CAP_ERR(h); - return 0; + *(vuip)MCPCIA_CAP_ERR(hose); + *(vuip)MCPCIA_CAP_ERR(hose) = 0xffffffff; /* Clear them all. */ + mb(); + *(vuip)MCPCIA_CAP_ERR(hose); /* Re-read for force write. */ } static void @@ -642,70 +625,33 @@ } void -mcpcia_machine_check(unsigned long type, unsigned long la_ptr, +mcpcia_machine_check(unsigned long vector, unsigned long la_ptr, struct pt_regs * regs) { -#if 0 - printk("mcpcia machine check ignored\n") ; -#else struct el_common *mchk_header; struct el_MCPCIA_uncorrected_frame_mcheck *mchk_logout; unsigned int cpu = smp_processor_id(); - int h = 0; mchk_header = (struct el_common *)la_ptr; mchk_logout = (struct el_MCPCIA_uncorrected_frame_mcheck *)la_ptr; -#if 0 - DBG_MCK(("mcpcia_machine_check: type=0x%lx la_ptr=0x%lx\n", - type, la_ptr)); - DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n", - regs->pc, mchk_header->size, mchk_header->proc_offset, - mchk_header->sys_offset)); -#endif - /* - * Check if machine check is due to a badaddr() and if so, - * ignore the machine check. - */ mb(); mb(); /* magic */ - if (MCPCIA_mcheck_expected[cpu]) { -#if 0 - DBG_MCK(("MCPCIA machine check expected\n")); -#endif - MCPCIA_mcheck_expected[cpu] = 0; - MCPCIA_mcheck_taken[cpu] = 1; - mb(); - mb(); /* magic */ - draina(); - mcpcia_pci_clr_err(h); - wrmces(0x7); - mb(); + draina(); + if (mcheck_expected(cpu)) { + mcpcia_pci_clr_err(mcheck_hose(cpu)); + } else { + /* FIXME: how do we figure out which hose the error was on? */ + mcpcia_pci_clr_err(0); + mcpcia_pci_clr_err(1); } -#if 1 - else { - printk("MCPCIA machine check NOT expected on CPU %d\n", cpu); - DBG_MCK(("mcpcia_machine_check: type=0x%lx pc=0x%lx" - " code=0x%lx\n", - type, regs->pc, mchk_header->code)); + wrmces(0x7); + mb(); - MCPCIA_mcheck_expected[cpu] = 0; - MCPCIA_mcheck_taken[cpu] = 1; - mb(); - mb(); /* magic */ - draina(); - mcpcia_pci_clr_err(h); - wrmces(0x7); - mb(); -#ifdef DEBUG_MCHECK_DUMP - if (type == 0x620) - printk("MCPCIA machine check: system CORRECTABLE!\n"); - else if (type == 0x630) - printk("MCPCIA machine check: processor CORRECTABLE!\n"); - else -#endif /* DEBUG_MCHECK_DUMP */ - mcpcia_print_uncorrectable(mchk_logout); + process_mcheck_info(vector, la_ptr, regs, "MCPCIA", + mcheck_expected(cpu)); + + if (vector != 0x620 && vector != 0x630) { + mcpcia_print_uncorrectable(mchk_logout); } -#endif -#endif } diff -u --recursive --new-file v2.3.13/linux/arch/alpha/kernel/core_polaris.c linux/arch/alpha/kernel/core_polaris.c --- v2.3.13/linux/arch/alpha/kernel/core_polaris.c Sun Jan 10 22:56:43 1999 +++ linux/arch/alpha/kernel/core_polaris.c Fri Aug 13 11:53:50 1999 @@ -26,23 +26,14 @@ * BIOS32-style PCI interface: */ -#ifdef DEBUG_CONFIG +#define DEBUG_CONFIG 0 + +#if DEBUG_CONFIG # define DBG_CFG(args) printk args #else # define DBG_CFG(args) #endif -#define DEBUG_MCHECK -#ifdef DEBUG_MCHECK -# define DBG_MCK(args) printk args -/* #define DEBUG_MCHECK_DUMP */ -#else -# define DBG_MCK(args) -#endif - -static volatile unsigned int POLARIS_mcheck_expected = 0; -static volatile unsigned int POLARIS_mcheck_taken = 0; -static volatile unsigned short POLARIS_jd = 0; /* * Given a bus, device, and function number, compute resulting @@ -195,81 +186,28 @@ #endif } -int polaris_pci_clr_err(void) +static inline void +polaris_pci_clr_err(void) { - POLARIS_jd = *((vusp)POLARIS_W_STATUS); - DBG_MCK(("POLARIS_pci_clr_err: POLARIS_W_STATUS after read 0x%x\n", - POLARIS_jd)); + *(vusp)POLARIS_W_STATUS; /* Write 1's to settable bits to clear errors */ - *((vusp)POLARIS_W_STATUS) = 0x7800; mb(); - POLARIS_jd = *((vusp)POLARIS_W_STATUS); - return 0; + *(vusp)POLARIS_W_STATUS = 0x7800; + mb(); + *(vusp)POLARIS_W_STATUS; } -void polaris_machine_check(unsigned long vector, unsigned long la_ptr, - struct pt_regs * regs) +void +polaris_machine_check(unsigned long vector, unsigned long la_ptr, + struct pt_regs * regs) { - struct el_common *mchk_header; - struct el_POLARIS_sysdata_mcheck *mchk_sysdata; - - mchk_header = (struct el_common *)la_ptr; - - mchk_sysdata = - (struct el_POLARIS_sysdata_mcheck *)(la_ptr+mchk_header->sys_offset); - -#if 0 - DBG_MCK(("polaris_machine_check: vector=0x%lx la_ptr=0x%lx\n", - vector, la_ptr)); - DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n", - regs->pc, mchk_header->size, mchk_header->proc_offset, - mchk_header->sys_offset)); - DBG_MCK(("polaris_machine_check: expected %d status 0x%lx\n", - POLARIS_mcheck_expected, mchk_sysdata->psc_status)); -#endif -#ifdef DEBUG_MCHECK_DUMP - { - unsigned long *ptr; - int i; - - ptr = (unsigned long *)la_ptr; - for (i = 0; i < mchk_header->size / sizeof(long); i += 2) { - printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]); - } - } -#endif /* DEBUG_MCHECK_DUMP */ - /* - * Check if machine check is due to a badaddr() and if so, - * ignore the machine check. - */ + /* Clear the error before any reporting. */ mb(); mb(); - if (POLARIS_mcheck_expected) { - DBG_MCK(("POLARIS machine check expected\n")); - POLARIS_mcheck_expected = 0; - POLARIS_mcheck_taken = 1; - mb(); - mb(); - draina(); - polaris_pci_clr_err(); - wrmces(0x7); - mb(); - } -#if 1 - else { - printk("POLARIS machine check NOT expected\n") ; - DBG_MCK(("polaris_machine_check: vector=0x%lx la_ptr=0x%lx\n", - vector, la_ptr)); - DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n", - regs->pc, mchk_header->size, mchk_header->proc_offset, - mchk_header->sys_offset)); - POLARIS_mcheck_expected = 0; - POLARIS_mcheck_taken = 1; - mb(); - mb(); - draina(); - polaris_pci_clr_err(); - wrmces(0x7); - mb(); - } -#endif + draina(); + polaris_pci_clr_err(); + wrmces(0x7); + mb(); + + process_mcheck_info(vector, la_ptr, regs, "POLARIS", + mcheck_expected(0)); } diff -u --recursive --new-file v2.3.13/linux/arch/alpha/kernel/core_pyxis.c linux/arch/alpha/kernel/core_pyxis.c --- v2.3.13/linux/arch/alpha/kernel/core_pyxis.c Wed Jul 21 15:46:48 1999 +++ linux/arch/alpha/kernel/core_pyxis.c Fri Aug 13 11:53:50 1999 @@ -32,7 +32,6 @@ */ #define DEBUG_CONFIG 0 -#define DEBUG_MCHECK 0 #if DEBUG_CONFIG # define DBG_CNF(args) printk args @@ -40,18 +39,6 @@ # define DBG_CNF(args) #endif -#if DEBUG_MCHECK -# define DBG_MCK(args) printk args -# define DEBUG_MCHECK_DUMP -#else -# define DBG_MCK(args) -#endif - - -static volatile unsigned int PYXIS_mcheck_expected = 0; -static volatile unsigned int PYXIS_mcheck_taken = 0; -static unsigned int PYXIS_jd; - /* * Given a bus, device, and function number, compute resulting @@ -132,8 +119,8 @@ mb(); draina(); - PYXIS_mcheck_expected = 1; - PYXIS_mcheck_taken = 0; + mcheck_expected(0) = 1; + mcheck_taken(0) = 0; mb(); /* Access configuration space. */ @@ -141,12 +128,12 @@ mb(); mb(); /* magic */ - if (PYXIS_mcheck_taken) { - PYXIS_mcheck_taken = 0; + if (mcheck_taken(0)) { + mcheck_taken(0) = 0; value = 0xffffffffU; mb(); } - PYXIS_mcheck_expected = 0; + mcheck_expected(0) = 0; mb(); /* If Type1 access, must reset IOC CFG so normal IO space ops work. */ @@ -186,15 +173,15 @@ mb(); draina(); - PYXIS_mcheck_expected = 1; - PYXIS_mcheck_taken = 0; + mcheck_expected(0) = 1; + mcheck_taken(0) = 0; mb(); /* Access configuration space. */ *(vuip)addr = value; mb(); temp = *(vuip)addr; /* read back to force the write */ - PYXIS_mcheck_expected = 0; + mcheck_expected(0) = 0; mb(); /* If Type1 access, must reset IOC CFG so normal IO space ops work. */ @@ -432,14 +419,13 @@ * Window 1 goes at 3 GB and is 1 GB large. */ - *(vuip)PYXIS_W0_BASE = PYXIS_DMA_WIN_BASE_DEFAULT | 1UL; - *(vuip)PYXIS_W0_MASK = (PYXIS_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000U; - *(vuip)PYXIS_T0_BASE = 0; - - *(vuip)PYXIS_W1_BASE = (PYXIS_DMA_WIN_BASE_DEFAULT + - PYXIS_DMA_WIN_SIZE_DEFAULT) | 1U; - *(vuip)PYXIS_W1_MASK = (PYXIS_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000U; - *(vuip)PYXIS_T1_BASE = PYXIS_DMA_WIN_SIZE_DEFAULT; + *(vuip)PYXIS_W0_BASE = PYXIS_DMA_WIN0_BASE_DEFAULT | 1U; + *(vuip)PYXIS_W0_MASK = (PYXIS_DMA_WIN0_SIZE_DEFAULT - 1) & 0xfff00000U; + *(vuip)PYXIS_T0_BASE = PYXIS_DMA_WIN0_TRAN_DEFAULT >> 2; + + *(vuip)PYXIS_W1_BASE = PYXIS_DMA_WIN1_BASE_DEFAULT | 1U; + *(vuip)PYXIS_W1_MASK = (PYXIS_DMA_WIN1_SIZE_DEFAULT - 1) & 0xfff00000U; + *(vuip)PYXIS_T1_BASE = PYXIS_DMA_WIN1_TRAN_DEFAULT >> 2; *(vuip)PYXIS_W2_BASE = 0x0; *(vuip)PYXIS_W3_BASE = 0x0; @@ -530,83 +516,26 @@ pyxis_finish_init_arch(); } -static int +static inline void pyxis_pci_clr_err(void) { - PYXIS_jd = *(vuip)PYXIS_ERR; - DBG_MCK(("PYXIS_pci_clr_err: PYXIS ERR after read 0x%x\n", PYXIS_jd)); - *(vuip)PYXIS_ERR = 0x0180; mb(); - PYXIS_jd = *(vuip)PYXIS_ERR; /* re-read to force write */ - return 0; + *(vuip)PYXIS_ERR; + *(vuip)PYXIS_ERR = 0x0180; + mb(); + *(vuip)PYXIS_ERR; /* re-read to force write */ } void pyxis_machine_check(unsigned long vector, unsigned long la_ptr, struct pt_regs * regs) { - struct el_common *mchk_header; - struct el_PYXIS_sysdata_mcheck *mchk_sysdata; - - mchk_header = (struct el_common *)la_ptr; - - mchk_sysdata = (struct el_PYXIS_sysdata_mcheck *) - (la_ptr + mchk_header->sys_offset); - -#if 0 - DBG_MCK(("pyxis_machine_check: vector=0x%lx la_ptr=0x%lx\n", - vector, la_ptr)); - DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n", - regs->pc, mchk_header->size, mchk_header->proc_offset, - mchk_header->sys_offset)); - DBG_MCK(("pyxis_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n", - PYXIS_mcheck_expected, mchk_sysdata->epic_dcsr, - mchk_sysdata->epic_pear)); -#endif - - /* - * Check if machine check is due to a badaddr() and if so, - * ignore the machine check. - */ + /* Clear the error before reporting anything. */ mb(); mb(); /* magic */ - if (PYXIS_mcheck_expected) { - DBG_MCK(("PYXIS machine check expected\n")); - PYXIS_mcheck_expected = 0; - PYXIS_mcheck_taken = 1; - mb(); - mb(); /* magic */ - draina(); - pyxis_pci_clr_err(); - wrmces(0x7); - mb(); - } - else { - printk("PYXIS machine check NOT expected\n") ; - DBG_MCK(("pyxis_machine_check: vector=0x%lx la_ptr=0x%lx\n", - vector, la_ptr)); - DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x" - " sysoffset 0x%x\n", - regs->pc, mchk_header->size, mchk_header->proc_offset, - mchk_header->sys_offset)); - PYXIS_mcheck_expected = 0; - PYXIS_mcheck_taken = 1; - mb(); - mb(); /* magic */ - draina(); - pyxis_pci_clr_err(); - wrmces(0x7); - mb(); + draina(); + pyxis_pci_clr_err(); + wrmces(0x7); + mb(); -#ifdef DEBUG_MCHECK_DUMP - { - unsigned long *ptr = (unsigned long *)la_ptr;; - long n = mchk_header->size / (2*sizeof(long)); - - do - printk(" +%lx %lx %lx\n", i*sizeof(long), - ptr[i], ptr[i+1]); - while (--i); - } -#endif - } + process_mcheck_info(vector, la_ptr, regs, "PYXIS", mcheck_expected(0)); } diff -u --recursive --new-file v2.3.13/linux/arch/alpha/kernel/core_t2.c linux/arch/alpha/kernel/core_t2.c --- v2.3.13/linux/arch/alpha/kernel/core_t2.c Sat Jan 9 19:08:21 1999 +++ linux/arch/alpha/kernel/core_t2.c Fri Aug 13 11:53:50 1999 @@ -33,36 +33,17 @@ */ /* - * Machine check reasons. Defined according to PALcode sources - * (osf.h and platform.h). - */ -#define MCHK_K_TPERR 0x0080 -#define MCHK_K_TCPERR 0x0082 -#define MCHK_K_HERR 0x0084 -#define MCHK_K_ECC_C 0x0086 -#define MCHK_K_ECC_NC 0x0088 -#define MCHK_K_OS_BUGCHECK 0x008A -#define MCHK_K_PAL_BUGCHECK 0x0090 - -/* * BIOS32-style PCI interface: */ -#ifdef DEBUG_CONF +#define DEBUG_CONFIG 0 + +#if DEBUG_CONFIG # define DBG(args) printk args #else # define DBG(args) #endif -#ifdef DEBUG_MCHECK -# define DBGMC(args) printk args -#else -# define DBGMC(args) -#endif - -static volatile unsigned int T2_mcheck_expected[NR_CPUS]; -static volatile unsigned int T2_mcheck_taken[NR_CPUS]; - /* * Given a bus, device, and function number, compute resulting @@ -173,8 +154,8 @@ mb(); draina(); - T2_mcheck_expected[cpu] = 1; - T2_mcheck_taken[cpu] = 0; + mcheck_expected(cpu) = 1; + mcheck_taken(cpu) = 0; mb(); /* Access configuration space. */ @@ -182,12 +163,12 @@ mb(); mb(); /* magic */ - if (T2_mcheck_taken[cpu]) { - T2_mcheck_taken[cpu] = 0; + if (mcheck_taken(cpu)) { + mcheck_taken(cpu) = 0; value = 0xffffffffU; mb(); } - T2_mcheck_expected[cpu] = 0; + mcheck_expected(cpu) = 0; mb(); /* If Type1 access, must reset T2 CFG so normal IO space ops work. */ @@ -233,7 +214,7 @@ mb(); draina(); - T2_mcheck_expected[cpu] = 1; + mcheck_expected(cpu) = 1; mb(); /* Access configuration space. */ @@ -241,7 +222,7 @@ mb(); mb(); /* magic */ - T2_mcheck_expected[cpu] = 0; + mcheck_expected(cpu) = 0; mb(); /* If Type1 access, must reset T2 CFG so normal IO space ops work. */ @@ -355,8 +336,8 @@ unsigned int i; for (i = 0; i < NR_CPUS; i++) { - T2_mcheck_expected[i] = 0; - T2_mcheck_taken[i] = 0; + mcheck_expected(i) = 0; + mcheck_taken(i) = 0; } #if 0 @@ -481,27 +462,22 @@ #define SIC_SEIC (1UL << 33) /* System Event Clear */ -static int -t2_clear_errors(void) +static void +t2_clear_errors(int cpu) { - unsigned int cpu = smp_processor_id(); - static struct sable_cpu_csr *cpu_regs = NULL; - - switch (cpu) - { - case 0: cpu_regs = (struct sable_cpu_csr *)T2_CPU0_BASE; break; - case 1: cpu_regs = (struct sable_cpu_csr *)T2_CPU1_BASE; break; - case 2: cpu_regs = (struct sable_cpu_csr *)T2_CPU2_BASE; break; - case 3: cpu_regs = (struct sable_cpu_csr *)T2_CPU3_BASE; break; - } - - DBGMC(("???????? t2_clear_errors\n")); + struct sable_cpu_csr *cpu_regs; + cpu_regs = (struct sable_cpu_csr *)T2_CPU0_BASE; + if (cpu == 1) + cpu_regs = (struct sable_cpu_csr *)T2_CPU1_BASE; + if (cpu == 2) + cpu_regs = (struct sable_cpu_csr *)T2_CPU2_BASE; + if (cpu == 3) + cpu_regs = (struct sable_cpu_csr *)T2_CPU3_BASE; + cpu_regs->sic &= ~SIC_SEIC; - /* - * clear CPU errors - */ + /* Clear CPU errors. */ cpu_regs->bcce |= cpu_regs->bcce; cpu_regs->cbe |= cpu_regs->cbe; cpu_regs->bcue |= cpu_regs->bcue; @@ -512,116 +488,21 @@ mb(); mb(); /* magic */ - return 0; } void t2_machine_check(unsigned long vector, unsigned long la_ptr, struct pt_regs * regs) { - struct el_t2_logout_header *mchk_header; - struct el_t2_procdata_mcheck *mchk_procdata; - struct el_t2_sysdata_mcheck *mchk_sysdata; - unsigned long * ptr; - const char * reason; - char buf[128]; - long i; - unsigned int cpu = smp_processor_id(); - - DBGMC(("t2_machine_check: vector=0x%lx la_ptr=0x%lx\n", - vector, la_ptr)); - - mchk_header = (struct el_t2_logout_header *)la_ptr; - - DBGMC(("t2_machine_check: susoffset=0x%lx procoffset=0x%lx\n", - mchk_header->elfl_sysoffset, mchk_header->elfl_procoffset)); - - mchk_sysdata = (struct el_t2_sysdata_mcheck *) - (la_ptr + mchk_header->elfl_sysoffset); - mchk_procdata = (struct el_t2_procdata_mcheck *) - (la_ptr + mchk_header->elfl_procoffset - sizeof(unsigned long)*32); - - DBGMC((" pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n", - regs->pc, mchk_header->elfl_size, mchk_header->elfl_procoffset, - mchk_header->elfl_sysoffset)); - DBGMC(("t2_machine_check: expected %d\n", T2_mcheck_expected[cpu])); + int cpu = smp_processor_id(); -#ifdef DEBUG_DUMP - { - unsigned long *ptr; - int i; - - ptr = (unsigned long *)la_ptr; - for (i = 0; i < mchk_header->elfl_size/sizeof(long); i += 2) { - printk(" +%lx %lx %lx\n", i*sizeof(long), - ptr[i], ptr[i+1]); - } - } -#endif /* DEBUG_DUMP */ - - /* - * Check if machine check is due to a badaddr() and if so, - * ignore the machine check. - */ + /* Clear the error before any reporting. */ mb(); mb(); /* magic */ - if (T2_mcheck_expected[cpu]) { - DBGMC(("T2 machine check expected\n")); - T2_mcheck_taken[cpu] = 1; - t2_clear_errors(); - T2_mcheck_expected[cpu] = 0; - mb(); - mb(); /* magic */ - wrmces(rdmces()|1);/* ??? */ - draina(); - return; - } - - switch ((unsigned int) mchk_header->elfl_error_type) { - case MCHK_K_TPERR: reason = "tag parity error"; break; - case MCHK_K_TCPERR: reason = "tag control parity error"; break; - case MCHK_K_HERR: reason = "generic hard error"; break; - case MCHK_K_ECC_C: reason = "correctable ECC error"; break; - case MCHK_K_ECC_NC: reason = "uncorrectable ECC error"; break; - case MCHK_K_OS_BUGCHECK: reason = "OS-specific PAL bugcheck"; break; - case MCHK_K_PAL_BUGCHECK: reason = "callsys in kernel mode"; break; - case 0x96: reason = "i-cache read retryable error"; break; - case 0x98: reason = "processor detected hard error"; break; - - /* System specific (these are for Alcor, at least): */ - case 0x203: reason = "system detected uncorrectable ECC error"; break; - case 0x205: reason = "parity error detected by T2"; break; - case 0x207: reason = "non-existent memory error"; break; - case 0x209: reason = "PCI SERR detected"; break; - case 0x20b: reason = "PCI data parity error detected"; break; - case 0x20d: reason = "PCI address parity error detected"; break; - case 0x20f: reason = "PCI master abort error"; break; - case 0x211: reason = "PCI target abort error"; break; - case 0x213: reason = "scatter/gather PTE invalid error"; break; - case 0x215: reason = "flash ROM write error"; break; - case 0x217: reason = "IOA timeout detected"; break; - case 0x219: reason = "IOCHK#, EISA add-in board parity or other catastrophic error"; break; - case 0x21b: reason = "EISA fail-safe timer timeout"; break; - case 0x21d: reason = "EISA bus time-out"; break; - case 0x21f: reason = "EISA software generated NMI"; break; - case 0x221: reason = "unexpected ev5 IRQ[3] interrupt"; break; - default: - sprintf(buf, "reason for machine-check unknown (0x%x)", - (unsigned int) mchk_header->elfl_error_type); - reason = buf; - break; - } - wrmces(rdmces()|1); /* reset machine check pending flag */ + draina(); + t2_clear_errors(cpu); + wrmces(rdmces()|1); /* ??? */ mb(); - printk(KERN_CRIT " T2 machine check: %s%s\n", - reason, mchk_header->elfl_retry ? " (retryable)" : ""); - - /* Dump the logout area to give all info. */ - - ptr = (unsigned long *)la_ptr; - for (i = 0; i < mchk_header->elfl_size / sizeof(long); i += 2) { - printk(KERN_CRIT " +%8lx %016lx %016lx\n", - i*sizeof(long), ptr[i], ptr[i+1]); - } + process_mcheck_info(vector, la_ptr, regs, "T2", mcheck_expected(cpu)); } diff -u --recursive --new-file v2.3.13/linux/arch/alpha/kernel/core_tsunami.c linux/arch/alpha/kernel/core_tsunami.c --- v2.3.13/linux/arch/alpha/kernel/core_tsunami.c Sun Jan 10 22:56:43 1999 +++ linux/arch/alpha/kernel/core_tsunami.c Fri Aug 13 11:53:50 1999 @@ -17,6 +17,7 @@ #include #include #include +#include #define __EXTERN_INLINE inline #include @@ -26,6 +27,8 @@ #include "proto.h" #include "bios32.h" +int TSUNAMI_bootcpu; + /* * NOTE: Herein lie back-to-back mb instructions. They are magic. * One plausible explanation is that the I/O controller does not properly @@ -36,24 +39,15 @@ * BIOS32-style PCI interface: */ -#ifdef DEBUG_CONFIG +#define DEBUG_MCHECK 0 /* 0 = minimal, 1 = debug, 2 = debug+dump. */ +#define DEBUG_CONFIG 0 + +#if DEBUG_CONFIG # define DBG_CFG(args) printk args #else # define DBG_CFG(args) #endif -#define DEBUG_MCHECK -#ifdef DEBUG_MCHECK -# define DBG_MCK(args) printk args -#define DEBUG_MCHECK_DUMP -#else -# define DBG_MCK(args) -#endif - -static volatile unsigned int TSUNAMI_mcheck_expected[NR_CPUS]; -static volatile unsigned int TSUNAMI_mcheck_taken[NR_CPUS]; -static unsigned int TSUNAMI_jd[NR_CPUS]; -int TSUNAMI_bootcpu; /* * Given a bus, device, and function number, compute resulting @@ -207,13 +201,14 @@ int cpu = smp_processor_id(); int s = swpipl(6); /* Block everything but machine checks. */ - TSUNAMI_mcheck_taken[cpu] = 0; - TSUNAMI_mcheck_expected[cpu] = 1; + mcheck_taken(cpu) = 0; + mcheck_expected(cpu) = 1; + mb(); dont_care = *vaddr; draina(); - TSUNAMI_mcheck_expected[cpu] = 0; - probe_result = !TSUNAMI_mcheck_taken[cpu]; - TSUNAMI_mcheck_taken[cpu] = 0; + mcheck_expected(cpu) = 0; + probe_result = !mcheck_taken(cpu); + mcheck_taken(cpu) = 0; setipl(s); printk("dont_care == 0x%lx\n", dont_care); @@ -302,20 +297,18 @@ * we may want to use them to do scatter/gather DMA. * * Window 0 goes at 1 GB and is 1 GB large, mapping to 0. + * Window 1 goes at 2 GB and is 1 GB large, mapping to 1GB. */ - pchip->wsba[0].csr = 1L | (TSUNAMI_DMA_WIN_BASE_DEFAULT & 0xfff00000U); - pchip->wsm[0].csr = (TSUNAMI_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000UL; - pchip->tba[0].csr = 0; - -#if 0 - pchip->wsba[1].csr = 0; -#else - /* make the second window at 2Gb for 1Gb mapping to 1Gb */ - pchip->wsba[1].csr = 1L | ((0x80000000U) & 0xfff00000U); - pchip->wsm[1].csr = (0x40000000UL - 1) & 0xfff00000UL; - pchip->tba[1].csr = 0x40000000; -#endif + pchip->wsba[0].csr = TSUNAMI_DMA_WIN0_BASE_DEFAULT | 1UL; + pchip->wsm[0].csr = (TSUNAMI_DMA_WIN0_SIZE_DEFAULT - 1) & + 0xfff00000UL; + pchip->tba[0].csr = TSUNAMI_DMA_WIN0_TRAN_DEFAULT; + + pchip->wsba[1].csr = TSUNAMI_DMA_WIN1_BASE_DEFAULT | 1UL; + pchip->wsm[1].csr = (TSUNAMI_DMA_WIN1_SIZE_DEFAULT - 1) & + 0xfff00000UL; + pchip->tba[1].csr = TSUNAMI_DMA_WIN1_TRAN_DEFAULT; pchip->wsba[2].csr = 0; pchip->wsba[3].csr = 0; @@ -364,107 +357,48 @@ /* Align memory to cache line; we'll be allocating from it. */ *mem_start = (*mem_start | 31) + 1; - /* Find how many hoses we have, and initialize them. */ + TSUNAMI_bootcpu = __hard_smp_processor_id(); + + /* Find how many hoses we have, and initialize them. TSUNAMI + and TYPHOON can have 2, but might only have 1 (DS10). */ tsunami_init_one_pchip(TSUNAMI_pchip0, 0, mem_start); - /* must change this for TYPHOON which may have 4 */ if (TSUNAMI_cchip->csc.csr & 1L<<14) tsunami_init_one_pchip(TSUNAMI_pchip1, 1, mem_start); } static inline void -tsunami_pci_clr_err_1(tsunami_pchip *pchip, int cpu) +tsunami_pci_clr_err_1(tsunami_pchip *pchip) { - TSUNAMI_jd[cpu] = pchip->perror.csr; - DBG_MCK(("TSUNAMI_pci_clr_err: PERROR after read 0x%x\n", - TSUNAMI_jd[cpu])); + unsigned int jd; + + jd = pchip->perror.csr; pchip->perror.csr = 0x040; mb(); - TSUNAMI_jd[cpu] = pchip->perror.csr; + jd = pchip->perror.csr; } -static int +static inline void tsunami_pci_clr_err(void) { - int cpu = smp_processor_id(); - tsunami_pci_clr_err_1(TSUNAMI_pchip0, cpu); - /* must change this for TYPHOON which may have 4 */ + tsunami_pci_clr_err_1(TSUNAMI_pchip0); + + /* TSUNAMI and TYPHOON can have 2, but might only have 1 (DS10) */ if (TSUNAMI_cchip->csc.csr & 1L<<14) - tsunami_pci_clr_err_1(TSUNAMI_pchip1, cpu); - return 0; + tsunami_pci_clr_err_1(TSUNAMI_pchip1); } void tsunami_machine_check(unsigned long vector, unsigned long la_ptr, struct pt_regs * regs) { -#if 0 - printk("TSUNAMI machine check ignored\n") ; -#else - struct el_common *mchk_header; - struct el_TSUNAMI_sysdata_mcheck *mchk_sysdata; - unsigned int cpu = smp_processor_id(); - - mb(); - mchk_header = (struct el_common *)la_ptr; - - mchk_sysdata = (struct el_TSUNAMI_sysdata_mcheck *) - (la_ptr + mchk_header->sys_offset); - -#if 0 - DBG_MCK(("tsunami_machine_check: vector=0x%lx la_ptr=0x%lx\n", - vector, la_ptr)); - DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n", - regs->pc, mchk_header->size, mchk_header->proc_offset, - mchk_header->sys_offset)); - DBG_MCK(("tsunami_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n", - TSUNAMI_mcheck_expected[cpu], mchk_sysdata->epic_dcsr, - mchk_sysdata->epic_pear)); -#endif -#ifdef DEBUG_MCHECK_DUMP - { - unsigned long *ptr; - int i; - - ptr = (unsigned long *)la_ptr; - for (i = 0; i < mchk_header->size / sizeof(long); i += 2) { - printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]); - } - } -#endif /* DEBUG_MCHECK_DUMP */ - /* - * Check if machine check is due to a badaddr() and if so, - * ignore the machine check. - */ + /* Clear error before any reporting. */ mb(); mb(); /* magic */ - if (TSUNAMI_mcheck_expected[cpu]) { - DBG_MCK(("TSUNAMI machine check expected\n")); - TSUNAMI_mcheck_expected[cpu] = 0; - TSUNAMI_mcheck_taken[cpu] = 1; - mb(); - mb(); /* magic */ - draina(); - tsunami_pci_clr_err(); - wrmces(0x7); - mb(); - } -#if 1 - else { - printk("TSUNAMI machine check NOT expected\n") ; - DBG_MCK(("tsunami_machine_check: vector=0x%lx la_ptr=0x%lx\n", - vector, la_ptr)); - DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n", - regs->pc, mchk_header->size, mchk_header->proc_offset, - mchk_header->sys_offset)); - TSUNAMI_mcheck_expected[cpu] = 0; - TSUNAMI_mcheck_taken[cpu] = 1; - mb(); - mb(); /* magic */ - draina(); - tsunami_pci_clr_err(); - wrmces(0x7); - mb(); - } -#endif -#endif + draina(); + tsunami_pci_clr_err(); + wrmces(0x7); + mb(); + + process_mcheck_info(vector, la_ptr, regs, "TSUNAMI", + mcheck_expected(smp_processor_id())); } diff -u --recursive --new-file v2.3.13/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c --- v2.3.13/linux/arch/alpha/kernel/irq.c Wed Jul 21 15:46:48 1999 +++ linux/arch/alpha/kernel/irq.c Fri Aug 13 11:53:50 1999 @@ -904,3 +904,99 @@ wrent(entInt, 0); alpha_mv.init_irq(); } + + +/* + */ +#define MCHK_K_TPERR 0x0080 +#define MCHK_K_TCPERR 0x0082 +#define MCHK_K_HERR 0x0084 +#define MCHK_K_ECC_C 0x0086 +#define MCHK_K_ECC_NC 0x0088 +#define MCHK_K_OS_BUGCHECK 0x008A +#define MCHK_K_PAL_BUGCHECK 0x0090 + +#ifndef __SMP__ +struct mcheck_info __mcheck_info; +#endif + +void +process_mcheck_info(unsigned long vector, unsigned long la_ptr, + struct pt_regs *regs, const char *machine, + int expected) +{ + struct el_common *mchk_header; + const char *reason; + + /* + * See if the machine check is due to a badaddr() and if so, + * ignore it. + */ + +#if DEBUG_MCHECK > 0 + printk(KERN_CRIT "%s machine check %s\n", machine, + expected ? "expected." : "NOT expected!!!"); +#endif + + if (expected) { + int cpu = smp_processor_id(); + mcheck_expected(cpu) = 0; + mcheck_taken(cpu) = 1; + return; + } + + mchk_header = (struct el_common *)la_ptr; + + printk(KERN_CRIT "%s machine check: vector=0x%lx pc=0x%lx code=0x%lx\n", + machine, vector, regs->pc, mchk_header->code); + + switch ((unsigned int) mchk_header->code) { + /* Machine check reasons. Defined according to PALcode sources. */ + case 0x80: reason = "tag parity error"; break; + case 0x82: reason = "tag control parity error"; break; + case 0x84: reason = "generic hard error"; break; + case 0x86: reason = "correctable ECC error"; break; + case 0x88: reason = "uncorrectable ECC error"; break; + case 0x8A: reason = "OS-specific PAL bugcheck"; break; + case 0x90: reason = "callsys in kernel mode"; break; + case 0x96: reason = "i-cache read retryable error"; break; + case 0x98: reason = "processor detected hard error"; break; + + /* System specific (these are for Alcor, at least): */ + case 0x203: reason = "system detected uncorrectable ECC error"; break; + case 0x204: reason = "SIO SERR occurred on PCI bus"; break; + case 0x205: reason = "parity error detected by CIA"; break; + case 0x206: reason = "SIO IOCHK occurred on ISA bus"; break; + case 0x207: reason = "non-existent memory error"; break; + case 0x208: reason = "MCHK_K_DCSR"; break; + case 0x209: reason = "PCI SERR detected"; break; + case 0x20b: reason = "PCI data parity error detected"; break; + case 0x20d: reason = "PCI address parity error detected"; break; + case 0x20f: reason = "PCI master abort error"; break; + case 0x211: reason = "PCI target abort error"; break; + case 0x213: reason = "scatter/gather PTE invalid error"; break; + case 0x215: reason = "flash ROM write error"; break; + case 0x217: reason = "IOA timeout detected"; break; + case 0x219: reason = "IOCHK#, EISA add-in board parity or other catastrophic error"; break; + case 0x21b: reason = "EISA fail-safe timer timeout"; break; + case 0x21d: reason = "EISA bus time-out"; break; + case 0x21f: reason = "EISA software generated NMI"; break; + case 0x221: reason = "unexpected ev5 IRQ[3] interrupt"; break; + default: reason = "unknown"; break; + } + + printk(KERN_CRIT "machine check type: %s%s\n", + reason, mchk_header->retry ? " (retryable)" : ""); + +#if DEBUG_MCHECK > 1 + { + /* Dump the logout area to give all info. */ + unsigned long *ptr = (unsigned long *)la_ptr; + long i; + for (i = 0; i < mchk_header->size / sizeof(long); i += 2) { + printk(KERN_CRIT " +%8lx %016lx %016lx\n", + i*sizeof(long), ptr[i], ptr[i+1]); + } + } +#endif +} diff -u --recursive --new-file v2.3.13/linux/arch/alpha/kernel/machvec.h linux/arch/alpha/kernel/machvec.h --- v2.3.13/linux/arch/alpha/kernel/machvec.h Mon Aug 9 14:59:19 1999 +++ linux/arch/alpha/kernel/machvec.h Mon Aug 16 10:33:58 1999 @@ -71,7 +71,8 @@ mv_writew: CAT(low1,_writew), \ mv_writel: CAT(low1,_writel), \ mv_writeq: CAT(low1,_writeq), \ - mv_dense_mem: CAT(low2,_dense_mem) + mv_ioremap: CAT(low2,_ioremap), \ + mv_is_ioaddr: CAT(low2,_is_ioaddr) #define IO(UP,low1,low2) \ IO_LITE(UP,low1,low2), \ diff -u --recursive --new-file v2.3.13/linux/arch/alpha/kernel/proto.h linux/arch/alpha/kernel/proto.h --- v2.3.13/linux/arch/alpha/kernel/proto.h Mon Aug 9 14:59:19 1999 +++ linux/arch/alpha/kernel/proto.h Fri Aug 13 11:53:50 1999 @@ -25,7 +25,7 @@ extern volatile unsigned int apecs_mcheck_expected; extern volatile unsigned int apecs_mcheck_taken; -extern int apecs_pci_clr_err(void); +extern void apecs_pci_clr_err(void); extern void apecs_machine_check(u64, u64, struct pt_regs *); /* core_cia.c */ @@ -202,3 +202,28 @@ /* ../mm/init.c */ void srm_paging_stop(void); + +/* irq.h */ + +#ifdef __SMP__ +#define mcheck_expected(cpu) (cpu_data[cpu].mcheck_expected) +#define mcheck_taken(cpu) (cpu_data[cpu].mcheck_taken) +#define mcheck_hose(cpu) (cpu_data[cpu].mcheck_hose) +#else +extern struct mcheck_info +{ + unsigned char expected __attribute__((aligned(8))); + unsigned char taken; + unsigned char hose; +} __mcheck_info; + +#define mcheck_expected(cpu) (__mcheck_info.expected) +#define mcheck_taken(cpu) (__mcheck_info.taken) +#define mcheck_hose(cpu) (__mcheck_info.hose) +#endif + +#define DEBUG_MCHECK 0 /* 0 = minimal, 1 = debug, 2 = debug+dump. */ + +extern void process_mcheck_info(unsigned long vector, unsigned long la_ptr, + struct pt_regs *regs, const char *machine, + int expected); diff -u --recursive --new-file v2.3.13/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c --- v2.3.13/linux/arch/alpha/kernel/setup.c Wed Jun 30 13:38:18 1999 +++ linux/arch/alpha/kernel/setup.c Fri Aug 13 11:53:50 1999 @@ -224,9 +224,15 @@ alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0; #endif - printk("Booting on %s%s%s using machine vector %s\n", + printk("Booting " +#ifdef CONFIG_ALPHA_GENERIC + "GENERIC " +#endif + "on %s%s%s using machine vector %s from %s\n", type_name, (*var_name ? " variation " : ""), - var_name, alpha_mv.vector_name); + var_name, alpha_mv.vector_name, + (alpha_using_srm ? "SRM" : "MILO")); + printk("Command line: %s\n", command_line); /* diff -u --recursive --new-file v2.3.13/linux/arch/alpha/kernel/smp.c linux/arch/alpha/kernel/smp.c --- v2.3.13/linux/arch/alpha/kernel/smp.c Mon Aug 9 14:59:19 1999 +++ linux/arch/alpha/kernel/smp.c Fri Aug 13 11:53:50 1999 @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include diff -u --recursive --new-file v2.3.13/linux/arch/alpha/kernel/sys_miata.c linux/arch/alpha/kernel/sys_miata.c --- v2.3.13/linux/arch/alpha/kernel/sys_miata.c Sun Feb 21 19:06:36 1999 +++ linux/arch/alpha/kernel/sys_miata.c Fri Aug 13 11:53:50 1999 @@ -271,6 +271,17 @@ es1888_init(); } +static void +miata_kill_arch (int mode, char *reboot_cmd) +{ + /* Who said DEC engineers have no sense of humor? ;-) */ + if (alpha_using_srm) { + *(vuip) PYXIS_RESET = 0x0000dead; + mb(); + } + generic_kill_arch(mode, reboot_cmd); +} + /* * The System Vector @@ -295,6 +306,6 @@ init_irq: miata_init_irq, init_pit: generic_init_pit, pci_fixup: miata_pci_fixup, - kill_arch: generic_kill_arch, + kill_arch: miata_kill_arch, }; ALIAS_MV(miata) diff -u --recursive --new-file v2.3.13/linux/arch/alpha/kernel/sys_mikasa.c linux/arch/alpha/kernel/sys_mikasa.c --- v2.3.13/linux/arch/alpha/kernel/sys_mikasa.c Sun Sep 6 10:34:33 1998 +++ linux/arch/alpha/kernel/sys_mikasa.c Fri Aug 13 11:53:50 1999 @@ -151,92 +151,34 @@ common_pci_fixup(mikasa_map_irq, common_swizzle); } +#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO) static void -mikasa_machine_check(unsigned long vector, unsigned long la_ptr, - struct pt_regs * regs) +mikasa_apecs_machine_check(unsigned long vector, unsigned long la_ptr, + struct pt_regs * regs) { #define MCHK_NO_DEVSEL 0x205L #define MCHK_NO_TABT 0x204L struct el_common *mchk_header; - struct el_apecs_procdata *mchk_procdata; - struct el_apecs_mikasa_sysdata_mcheck *mchk_sysdata; - unsigned long *ptr; - int i; + unsigned int code; mchk_header = (struct el_common *)la_ptr; - mchk_procdata = (struct el_apecs_procdata *) - (la_ptr + mchk_header->proc_offset - - sizeof(mchk_procdata->paltemp)); - - mchk_sysdata = (struct el_apecs_mikasa_sysdata_mcheck *) - (la_ptr + mchk_header->sys_offset); - -#ifdef DEBUG - printk("mikasa_machine_check: vector=0x%lx la_ptr=0x%lx\n", - vector, la_ptr); - printk(" pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n", - regs->pc, mchk_header->size, mchk_header->proc_offset, - mchk_header->sys_offset); - printk("mikasa_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n", - apecs_mcheck_expected, mchk_sysdata->epic_dcsr, - mchk_sysdata->epic_pear); - ptr = (unsigned long *)la_ptr; - for (i = 0; i < mchk_header->size / sizeof(long); i += 2) { - printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]); - } -#endif - - /* - * Check if machine check is due to a badaddr() and if so, - * ignore the machine check. - */ - - if (apecs_mcheck_expected - && ((unsigned int)mchk_header->code == MCHK_NO_DEVSEL - || (unsigned int)mchk_header->code == MCHK_NO_TABT)) { - apecs_mcheck_expected = 0; - apecs_mcheck_taken = 1; - mb(); - mb(); /* magic */ - apecs_pci_clr_err(); - wrmces(0x7); - mb(); - draina(); - } - else if (vector == 0x620 || vector == 0x630) { - /* Disable correctable from now on. */ - wrmces(0x1f); - mb(); - draina(); - printk("mikasa_machine_check: HW correctable (0x%lx)\n", - vector); - } - else { - printk(KERN_CRIT "APECS machine check:\n"); - printk(KERN_CRIT " vector=0x%lx la_ptr=0x%lx\n", - vector, la_ptr); - printk(KERN_CRIT - " pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n", - regs->pc, mchk_header->size, mchk_header->proc_offset, - mchk_header->sys_offset); - printk(KERN_CRIT " expected %d DCSR 0x%lx PEAR 0x%lx\n", - apecs_mcheck_expected, mchk_sysdata->epic_dcsr, - mchk_sysdata->epic_pear); - - ptr = (unsigned long *)la_ptr; - for (i = 0; i < mchk_header->size / sizeof(long); i += 2) { - printk(KERN_CRIT " +%lx %lx %lx\n", - i*sizeof(long), ptr[i], ptr[i+1]); - } -#if 0 - /* doesn't work with MILO */ - show_regs(regs); -#endif - } + /* Clear the error before any reporting. */ + mb(); + mb(); /* magic */ + draina(); + apecs_pci_clr_err(); + wrmces(0x7); + mb(); + + code = mchk_header->code; + process_mcheck_info(vector, la_ptr, regs, "MIKASA APECS", + (mcheck_expected(0) + && (code == MCHK_NO_DEVSEL + || code == MCHK_NO_TABT))); } - +#endif /* * The System Vector @@ -249,7 +191,7 @@ DO_DEFAULT_RTC, DO_APECS_IO, DO_APECS_BUS, - machine_check: mikasa_machine_check, + machine_check: mikasa_apecs_machine_check, max_dma_address: ALPHA_MAX_DMA_ADDRESS, nr_irqs: 32, @@ -274,7 +216,7 @@ DO_DEFAULT_RTC, DO_CIA_IO, DO_CIA_BUS, - machine_check: mikasa_machine_check, + machine_check: cia_machine_check, max_dma_address: ALPHA_MAX_DMA_ADDRESS, nr_irqs: 32, diff -u --recursive --new-file v2.3.13/linux/arch/alpha/kernel/sys_rx164.c linux/arch/alpha/kernel/sys_rx164.c --- v2.3.13/linux/arch/alpha/kernel/sys_rx164.c Sun Jan 24 21:29:53 1999 +++ linux/arch/alpha/kernel/sys_rx164.c Fri Aug 13 11:53:50 1999 @@ -45,10 +45,10 @@ outb(mask, 0x21); /* ISA PIC1 */ } +#if 0 static void rx164_srm_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p) { -#if 0 if (irq >= 16) { if (unmask_p) cserve_ena(irq - 16); @@ -59,8 +59,8 @@ outb(mask >> 8, 0xA1); /* ISA PIC2 */ else outb(mask, 0x21); /* ISA PIC1 */ -#endif } +#endif static void rx164_isa_device_interrupt(unsigned long vector, struct pt_regs * regs) @@ -107,7 +107,8 @@ printk("PLD 0x%lx\n", pld); #endif - if (pld & 0xffffffff00000000UL) pld &= 0x00000000ffffffffUL; + if (pld & 0xffffffff00000000UL) + pld &= 0x00000000ffffffffUL; /* * Now for every possible bit set, work through them and call diff -u --recursive --new-file v2.3.13/linux/arch/alpha/lib/io.c linux/arch/alpha/lib/io.c --- v2.3.13/linux/arch/alpha/lib/io.c Thu Apr 15 05:42:31 1999 +++ linux/arch/alpha/lib/io.c Mon Aug 16 10:33:58 1999 @@ -37,45 +37,96 @@ __outl(b, addr); } +unsigned long ___raw_readb(unsigned long addr) +{ + return __readb(addr); +} + +unsigned long ___raw_readw(unsigned long addr) +{ + return __readw(addr); +} + +unsigned long ___raw_readl(unsigned long addr) +{ + return __readl(addr); +} + +unsigned long ___raw_readq(unsigned long addr) +{ + return __readq(addr); +} unsigned long _readb(unsigned long addr) { - return __readb(addr); + unsigned long r = __readb(addr); + mb(); + return r; } unsigned long _readw(unsigned long addr) { - return __readw(addr); + unsigned long r = __readw(addr); + mb(); + return r; } unsigned long _readl(unsigned long addr) { - return __readl(addr); + unsigned long r = __readl(addr); + mb(); + return r; } unsigned long _readq(unsigned long addr) { - return __readq(addr); + unsigned long r = __readq(addr); + mb(); + return r; +} + +void ___raw_writeb(unsigned char b, unsigned long addr) +{ + __writeb(b, addr); +} + +void ___raw_writeb(unsigned short b, unsigned long addr) +{ + __writew(b, addr); +} + +void ___raw_writel(unsigned int b, unsigned long addr) +{ + __writel(b, addr); +} + +void ___raw_writeq(unsigned long b, unsigned long addr) +{ + __writeq(b, addr); } void _writeb(unsigned char b, unsigned long addr) { __writeb(b, addr); + mb(); } void _writew(unsigned short b, unsigned long addr) { __writew(b, addr); + mb(); } void _writel(unsigned int b, unsigned long addr) { __writel(b, addr); + mb(); } void _writeq(unsigned long b, unsigned long addr) { __writeq(b, addr); + mb(); } /* @@ -363,7 +414,7 @@ if (count >= 8 && ((long)to & 7) == (from & 7)) { count -= 8; do { - *(u64 *)to = readq(from); + *(u64 *)to = __raw_readq(from); count -= 8; to += 8; from += 8; @@ -374,7 +425,7 @@ if (count >= 4 && ((long)to & 3) == (from & 3)) { count -= 4; do { - *(u32 *)to = readl(from); + *(u32 *)to = __raw_readl(from); count -= 4; to += 4; from += 4; @@ -385,7 +436,7 @@ if (count >= 2 && ((long)to & 1) == (from & 1)) { count -= 2; do { - *(u16 *)to = readw(from); + *(u16 *)to = __raw_readw(from); count -= 2; to += 2; from += 2; @@ -394,7 +445,7 @@ } while (count > 0) { - *(u8 *) to = readb(from); + *(u8 *) to = __raw_readb(from); count--; to++; from++; @@ -414,7 +465,7 @@ if (count >= 8 && (to & 7) == ((long)from & 7)) { count -= 8; do { - writeq(*(const u64 *)from, to); + __raw_writeq(*(const u64 *)from, to); count -= 8; to += 8; from += 8; @@ -425,7 +476,7 @@ if (count >= 4 && (to & 3) == ((long)from & 3)) { count -= 4; do { - writel(*(const u32 *)from, to); + __raw_writel(*(const u32 *)from, to); count -= 4; to += 4; from += 4; @@ -436,7 +487,7 @@ if (count >= 2 && (to & 1) == ((long)from & 1)) { count -= 2; do { - writew(*(const u16 *)from, to); + __raw_writeb(*(const u16 *)from, to); count -= 2; to += 2; from += 2; @@ -445,11 +496,12 @@ } while (count > 0) { - writeb(*(const u8 *) from, to); + __raw_writeb(*(const u8 *) from, to); count--; to++; from++; } + mb(); } /* @@ -459,21 +511,21 @@ { /* Handle any initial odd byte */ if (count > 0 && (to & 1)) { - writeb(c, to); + __raw_writeb(c, to); to++; count--; } /* Handle any initial odd halfword */ if (count >= 2 && (to & 2)) { - writew(c, to); + __raw_writeb(c, to); to += 2; count -= 2; } /* Handle any initial odd word */ if (count >= 4 && (to & 4)) { - writel(c, to); + __raw_writel(c, to); to += 4; count -= 4; } @@ -483,7 +535,7 @@ count -= 8; if (count >= 0) { do { - writeq(c, to); + __raw_writeq(c, to); to += 8; count -= 8; } while (count >= 0); @@ -492,20 +544,21 @@ /* The tail is word-aligned if we still have count >= 4 */ if (count >= 4) { - writel(c, to); + __raw_writel(c, to); to += 4; count -= 4; } /* The tail is half-word aligned if we have count >= 2 */ if (count >= 2) { - writew(c, to); + __raw_writeb(c, to); to += 2; count -= 2; } /* And finally, one last byte.. */ if (count) { - writeb(c, to); + __raw_writeb(c, to); } + mb(); } diff -u --recursive --new-file v2.3.13/linux/arch/alpha/mm/fault.c linux/arch/alpha/mm/fault.c --- v2.3.13/linux/arch/alpha/mm/fault.c Mon Aug 9 14:59:19 1999 +++ linux/arch/alpha/mm/fault.c Fri Aug 13 11:53:50 1999 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff -u --recursive --new-file v2.3.13/linux/arch/i386/Makefile linux/arch/i386/Makefile --- v2.3.13/linux/arch/i386/Makefile Wed Jul 21 15:46:48 1999 +++ linux/arch/i386/Makefile Thu Aug 12 11:53:22 1999 @@ -35,8 +35,8 @@ endif ifdef CONFIG_M486 -CFLAGS := $(CFLAGS) -m486 -DCPU=486 -CFLAGS += $(shell if $(CC) -march=i486 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i486"; fi) +CFLAGS := $(CFLAGS) -DCPU=486 +CFLAGS += $(shell if $(CC) -march=i486 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i486"; else echo "-m486"; fi) AFLAGS := $(AFLAGS) -DCPU=486 endif @@ -111,6 +111,7 @@ @$(MAKEBOOT) clean archmrproper: + rm -f arch/i386/vmlinux.lds archdep: @$(MAKEBOOT) dep diff -u --recursive --new-file v2.3.13/linux/arch/i386/boot/bootsect.S linux/arch/i386/boot/bootsect.S --- v2.3.13/linux/arch/i386/boot/bootsect.S Tue Jun 8 10:47:57 1999 +++ linux/arch/i386/boot/bootsect.S Wed Aug 18 10:03:05 1999 @@ -98,7 +98,7 @@ * fs = 0, gs is unused. */ -! cx contains 0 from rep movsw above +! cx contains 0 from rep movsd above mov fs,cx mov bx,#0x78 ! fs:bx is parameter table address diff -u --recursive --new-file v2.3.13/linux/arch/i386/config.in linux/arch/i386/config.in --- v2.3.13/linux/arch/i386/config.in Mon Aug 9 14:59:19 1999 +++ linux/arch/i386/config.in Wed Aug 18 11:18:11 1999 @@ -167,6 +167,8 @@ source drivers/usb/Config.in +source drivers/misc/Config.in + source fs/Config.in if [ "$CONFIG_VT" = "y" ]; then diff -u --recursive --new-file v2.3.13/linux/arch/i386/defconfig linux/arch/i386/defconfig --- v2.3.13/linux/arch/i386/defconfig Mon Aug 9 14:59:19 1999 +++ linux/arch/i386/defconfig Sun Aug 15 16:02:03 1999 @@ -70,6 +70,12 @@ # CONFIG_I2O_PROC is not set # +# Plug and Play configuration +# +CONFIG_PNP=y +CONFIG_ISAPNP=y + +# # Block devices # CONFIG_BLK_DEV_FD=y @@ -331,6 +337,10 @@ # CONFIG_USB is not set # +# Misc devices +# + +# # Filesystems # # CONFIG_QUOTA is not set @@ -366,10 +376,9 @@ # # Partition Types # -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MAC_PARTITION is not set +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y # CONFIG_SMD_DISKLABEL is not set -# CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_SGI_DISKLABEL is not set # CONFIG_NLS is not set diff -u --recursive --new-file v2.3.13/linux/arch/i386/kernel/Makefile linux/arch/i386/kernel/Makefile --- v2.3.13/linux/arch/i386/kernel/Makefile Mon Aug 9 14:59:19 1999 +++ linux/arch/i386/kernel/Makefile Wed Aug 18 11:11:15 1999 @@ -14,7 +14,7 @@ O_TARGET := kernel.o O_OBJS := process.o signal.o entry.o traps.o irq.o vm86.o \ - ptrace.o ioport.o ldt.o setup.o time.o sys_i386.o + ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o OX_OBJS := i386_ksyms.o MX_OBJS := diff -u --recursive --new-file v2.3.13/linux/arch/i386/kernel/apm.c linux/arch/i386/kernel/apm.c --- v2.3.13/linux/arch/i386/kernel/apm.c Mon Aug 9 14:59:19 1999 +++ linux/arch/i386/kernel/apm.c Thu Aug 12 11:53:22 1999 @@ -288,7 +288,7 @@ /* * Local variables */ -static asmlinkage struct { +static struct { unsigned long offset; unsigned short segment; } apm_bios_entry; diff -u --recursive --new-file v2.3.13/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c --- v2.3.13/linux/arch/i386/kernel/bios32.c Mon Aug 9 14:59:19 1999 +++ linux/arch/i386/kernel/bios32.c Wed Aug 18 11:24:23 1999 @@ -93,7 +93,7 @@ #include #include -#include "irq.h" +#include #undef DEBUG @@ -353,7 +353,7 @@ * This should be close to trivial, but it isn't, because there are buggy * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID. */ -__initfunc(int pci_sanity_check(struct pci_access *a)) +int __init pci_sanity_check(struct pci_access *a) { u16 dfn, x; @@ -373,7 +373,7 @@ return 0; } -__initfunc(static struct pci_access *pci_check_direct(void)) +static struct pci_access * __init pci_check_direct(void) { unsigned int tmp; unsigned long flags; @@ -528,7 +528,7 @@ static int pci_bios_present; -__initfunc(static int check_pcibios(void)) +static int __init check_pcibios(void) { u32 signature, eax, ebx, ecx; u8 status, major_ver, minor_ver, hw_mech, last_bus; @@ -602,8 +602,8 @@ #endif -__initfunc(static int pci_bios_find_device (unsigned short vendor, unsigned short device_id, - unsigned short index, unsigned char *bus, unsigned char *device_fn)) +static int __init pci_bios_find_device (unsigned short vendor, unsigned short device_id, + unsigned short index, unsigned char *bus, unsigned char *device_fn) { unsigned short bx; unsigned short ret; @@ -756,7 +756,7 @@ * Try to find PCI BIOS. */ -__initfunc(static struct pci_access *pci_find_bios(void)) +static struct pci_access * __init pci_find_bios(void) { union bios32 *check; unsigned char sum; @@ -1194,7 +1194,7 @@ * Arch-dependent fixups. */ -__initfunc(void pcibios_fixup(void)) +void __init pcibios_fixup(void) { if (!(pci_probe & PCI_NO_PEER_FIXUP)) pcibios_fixup_peer_bridges(); @@ -1206,7 +1206,7 @@ #endif } -__initfunc(void pcibios_fixup_bus(struct pci_bus *b)) +void __init pcibios_fixup_bus(struct pci_bus *b) { pcibios_fixup_ghosts(b); pcibios_scan_buglist(b); @@ -1219,7 +1219,7 @@ * compatible with 2.0.X. This should go away in 2.3. */ -__initfunc(void pcibios_init(void)) +void __init pcibios_init(void) { struct pci_access *bios = NULL; struct pci_access *dir = NULL; diff -u --recursive --new-file v2.3.13/linux/arch/i386/kernel/i8259.c linux/arch/i386/kernel/i8259.c --- v2.3.13/linux/arch/i386/kernel/i8259.c Wed Dec 31 16:00:00 1969 +++ linux/arch/i386/kernel/i8259.c Wed Aug 18 11:23:31 1999 @@ -0,0 +1,410 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +/* + * Intel specific no controller code + * odd that no-controller should be architecture dependent + * but see the ifdef __SMP__ + */ + +static void enable_none(unsigned int irq) { } +static unsigned int startup_none(unsigned int irq) { return 0; } +static void disable_none(unsigned int irq) { } +static void ack_none(unsigned int irq) +{ +#ifdef __SMP__ + /* + * [currently unexpected vectors happen only on SMP and APIC. + * if we want to have non-APIC and non-8259A controllers + * in the future with unexpected vectors, this ack should + * probably be made controller-specific.] + */ + ack_APIC_irq(); +#endif +} + +/* startup is the same as "enable", shutdown is same as "disable" */ +#define shutdown_none disable_none +#define end_none enable_none + +struct hw_interrupt_type no_irq_type = { + "none", + startup_none, + shutdown_none, + enable_none, + disable_none, + ack_none, + end_none +}; + + +/* + * This is the 'legacy' 8259A Programmable Interrupt Controller, + * present in the majority of PC/AT boxes. + * plus some generic x86 specific things if generic specifics makes + * any sense at all. + * this file should become arch/i386/kernel/irq.c when the old irq.c + * moves to arch independent land + */ +/* + * This builds up the IRQ handler stubs using some ugly macros in irq.h + * + * These macros create the low-level assembly IRQ routines that save + * register context and call do_IRQ(). do_IRQ() then does all the + * operations that are needed to keep the AT (or SMP IOAPIC) + * interrupt-controller happy. + */ + + +BUILD_COMMON_IRQ() + +#define BI(x,y) \ + BUILD_IRQ(##x##y) + +#define BUILD_16_IRQS(x) \ + BI(x,0) BI(x,1) BI(x,2) BI(x,3) \ + BI(x,4) BI(x,5) BI(x,6) BI(x,7) \ + BI(x,8) BI(x,9) BI(x,a) BI(x,b) \ + BI(x,c) BI(x,d) BI(x,e) BI(x,f) + +/* + * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts: + * (these are usually mapped to vectors 0x20-0x30) + */ +BUILD_16_IRQS(0x0) + +#ifdef CONFIG_X86_IO_APIC +/* + * The IO-APIC gives us many more interrupt sources. Most of these + * are unused but an SMP system is supposed to have enough memory ... + * sometimes (mostly wrt. hw bugs) we get corrupted vectors all + * across the spectrum, so we really want to be prepared to get all + * of these. Plus, more powerful systems might have more than 64 + * IO-APIC registers. + * + * (these are usually mapped into the 0x30-0xff vector range) + */ + BUILD_16_IRQS(0x1) BUILD_16_IRQS(0x2) BUILD_16_IRQS(0x3) +BUILD_16_IRQS(0x4) BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7) +BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb) +BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) +#endif + +#undef BUILD_16_IRQS +#undef BI + + +#ifdef __SMP__ +/* + * The following vectors are part of the Linux architecture, there + * is no hardware IRQ pin equivalent for them, they are triggered + * through the ICC by us (IPIs) + */ +BUILD_SMP_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) +BUILD_SMP_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR) +BUILD_SMP_INTERRUPT(stop_cpu_interrupt,STOP_CPU_VECTOR) +BUILD_SMP_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) +BUILD_SMP_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) + +/* + * every pentium local APIC has two 'local interrupts', with a + * soft-definable vector attached to both interrupts, one of + * which is a timer interrupt, the other one is error counter + * overflow. Linux uses the local APIC timer interrupt to get + * a much simpler SMP time architecture: + */ +BUILD_SMP_TIMER_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR) + +#endif + +#define IRQ(x,y) \ + IRQ##x##y##_interrupt + +#define IRQLIST_16(x) \ + IRQ(x,0), IRQ(x,1), IRQ(x,2), IRQ(x,3), \ + IRQ(x,4), IRQ(x,5), IRQ(x,6), IRQ(x,7), \ + IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \ + IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f) + +static void (*interrupt[NR_IRQS])(void) = { + IRQLIST_16(0x0), + +#ifdef CONFIG_X86_IO_APIC + IRQLIST_16(0x1), IRQLIST_16(0x2), IRQLIST_16(0x3), + IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7), + IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb), + IRQLIST_16(0xc), IRQLIST_16(0xd) +#endif +}; + +#undef IRQ +#undef IRQLIST_16 + + + + +static void enable_8259A_irq(unsigned int irq); +void disable_8259A_irq(unsigned int irq); + +/* shutdown is same as "disable" */ +#define end_8259A_irq enable_8259A_irq +#define shutdown_8259A_irq disable_8259A_irq + +static void mask_and_ack_8259A(unsigned int); + +static unsigned int startup_8259A_irq(unsigned int irq) +{ + enable_8259A_irq(irq); + return 0; /* never anything pending */ +} + +static struct hw_interrupt_type i8259A_irq_type = { + "XT-PIC", + startup_8259A_irq, + shutdown_8259A_irq, + enable_8259A_irq, + disable_8259A_irq, + mask_and_ack_8259A, + end_8259A_irq +}; + +/* + * 8259A PIC functions to handle ISA devices: + */ + +/* + * This contains the irq mask for both 8259A irq controllers, + */ +static unsigned int cached_irq_mask = 0xffff; + +#define __byte(x,y) (((unsigned char *)&(y))[x]) +#define cached_21 (__byte(0,cached_irq_mask)) +#define cached_A1 (__byte(1,cached_irq_mask)) + +/* + * Not all IRQs can be routed through the IO-APIC, eg. on certain (older) + * boards the timer interrupt is not connected to any IO-APIC pin, it's + * fed to the CPU IRQ line directly. + * + * Any '1' bit in this mask means the IRQ is routed through the IO-APIC. + * this 'mixed mode' IRQ handling costs nothing because it's only used + * at IRQ setup time. + */ +unsigned long io_apic_irqs = 0; + +/* + * These have to be protected by the irq controller spinlock + * before being called. + */ +void disable_8259A_irq(unsigned int irq) +{ + unsigned int mask = 1 << irq; + cached_irq_mask |= mask; + if (irq & 8) { + outb(cached_A1,0xA1); + } else { + outb(cached_21,0x21); + } +} + +static void enable_8259A_irq(unsigned int irq) +{ + unsigned int mask = ~(1 << irq); + cached_irq_mask &= mask; + if (irq & 8) { + outb(cached_A1,0xA1); + } else { + outb(cached_21,0x21); + } +} + +int i8259A_irq_pending(unsigned int irq) +{ + unsigned int mask = 1<> 8)); +} + +void make_8259A_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + io_apic_irqs &= ~(1<> 8 , 0x40); /* MSB */ + +#ifndef CONFIG_VISWS + setup_irq(2, &irq2); + setup_irq(13, &irq13); +#endif +} + +#ifdef CONFIG_X86_IO_APIC +void __init init_IRQ_SMP(void) +{ + int i; + for (i = 0; i < NR_IRQS ; i++) + if (IO_APIC_VECTOR(i) > 0) + set_intr_gate(IO_APIC_VECTOR(i), interrupt[i]); +} +#endif diff -u --recursive --new-file v2.3.13/linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c --- v2.3.13/linux/arch/i386/kernel/io_apic.c Mon Aug 9 14:59:19 1999 +++ linux/arch/i386/kernel/io_apic.c Wed Aug 18 11:11:15 1999 @@ -19,7 +19,7 @@ #include #include -#include "irq.h" +#include /* * volatile is justified in this case, IO-APIC register contents @@ -957,24 +957,13 @@ * better to do it this way as thus we do not have to be aware of * 'pending' interrupts in the IRQ path, except at this point. */ -static inline void self_IPI(unsigned int irq) -{ - irq_desc_t *desc = irq_desc + irq; - unsigned int status = desc->status; - - if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { - desc->status = status | IRQ_REPLAY; - send_IPI_self(IO_APIC_VECTOR(irq)); - } -} - /* * Edge triggered needs to resend any interrupt - * that was delayed. + * that was delayed but this is now handled in the device + * independent code. */ static void enable_edge_ioapic_irq(unsigned int irq) { - self_IPI(irq); enable_IO_APIC_irq(irq); } @@ -987,129 +976,52 @@ * Starting up a edge-triggered IO-APIC interrupt is * nasty - we need to make sure that we get the edge. * If it is already asserted for some reason, we need - * to fake an edge by marking it IRQ_PENDING.. + * return 1 to indicate that is was pending. * * This is not complete - we should be able to fake * an edge even if it isn't on the 8259A... */ -static void startup_edge_ioapic_irq(unsigned int irq) +static unsigned int startup_edge_ioapic_irq(unsigned int irq) { + int was_pending = 0; if (irq < 16) { disable_8259A_irq(irq); if (i8259A_irq_pending(irq)) - irq_desc[irq].status |= IRQ_PENDING; + was_pending = 1; } enable_edge_ioapic_irq(irq); + return was_pending; } #define shutdown_edge_ioapic_irq disable_edge_ioapic_irq +void static ack_edge_ioapic_irq(unsigned int i) +{ + ack_APIC_irq(); +} +void static end_edge_ioapic_irq(unsigned int i){} + /* * Level triggered interrupts can just be masked, * and shutting down and starting up the interrupt - * is the same as enabling and disabling them. + * is the same as enabling and disabling them -- except + * with a startup need to return a "was pending" value. */ -#define startup_level_ioapic_irq unmask_IO_APIC_irq -#define shutdown_level_ioapic_irq mask_IO_APIC_irq -#define enable_level_ioapic_irq unmask_IO_APIC_irq -#define disable_level_ioapic_irq mask_IO_APIC_irq - -static void do_edge_ioapic_IRQ(unsigned int irq, struct pt_regs * regs) +static unsigned int startup_level_ioapic_irq(unsigned int irq) { - irq_desc_t *desc = irq_desc + irq; - struct irqaction * action; - unsigned int status; - - spin_lock(&irq_controller_lock); - - /* - * Edge triggered IRQs can be acknowledged immediately - * and do not need to be masked. - */ - ack_APIC_irq(); - status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING); - status |= IRQ_PENDING; - - /* - * If the IRQ is disabled for whatever reason, we cannot - * use the action we have. - */ - action = NULL; - if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { - action = desc->action; - status &= ~IRQ_PENDING; - status |= IRQ_INPROGRESS; - } - desc->status = status; - spin_unlock(&irq_controller_lock); - - /* - * If there is no IRQ handler or it was disabled, exit early. - */ - if (!action) - return; - - /* - * Edge triggered interrupts need to remember - * pending events. - */ - for (;;) { - handle_IRQ_event(irq, regs, action); - - spin_lock(&irq_controller_lock); - if (!(desc->status & IRQ_PENDING)) - break; - desc->status &= ~IRQ_PENDING; - spin_unlock(&irq_controller_lock); - } - desc->status &= ~IRQ_INPROGRESS; - spin_unlock(&irq_controller_lock); + unmask_IO_APIC_irq(irq); + return 0; /* don't check for pending */ } -static void do_level_ioapic_IRQ(unsigned int irq, struct pt_regs * regs) +#define shutdown_level_ioapic_irq mask_IO_APIC_irq +#define enable_level_ioapic_irq unmask_IO_APIC_irq +#define disable_level_ioapic_irq mask_IO_APIC_irq +#define end_level_ioapic_irq unmask_IO_APIC_irq +void static mask_and_ack_level_ioapic_irq(unsigned int i) { - irq_desc_t *desc = irq_desc + irq; - struct irqaction * action; - unsigned int status; - - spin_lock(&irq_controller_lock); - /* - * In the level triggered case we first disable the IRQ - * in the IO-APIC, then we 'early ACK' the IRQ, then we - * handle it and enable the IRQ when finished. - * - * disable has to happen before the ACK, to avoid IRQ storms. - * So this all has to be within the spinlock. - */ - mask_IO_APIC_irq(irq); - status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING); - - /* - * If the IRQ is disabled for whatever reason, we must - * not enter the IRQ action. - */ - action = NULL; - if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { - action = desc->action; - status |= IRQ_INPROGRESS; - } - desc->status = status; - + mask_IO_APIC_irq(i); ack_APIC_irq(); - spin_unlock(&irq_controller_lock); - - /* Exit early if we had no action or it was disabled */ - if (!action) - return; - - handle_IRQ_event(irq, regs, action); - - spin_lock(&irq_controller_lock); - desc->status &= ~IRQ_INPROGRESS; - if (!(desc->status & IRQ_DISABLED)) - unmask_IO_APIC_irq(irq); - spin_unlock(&irq_controller_lock); } /* @@ -1125,18 +1037,20 @@ "IO-APIC-edge", startup_edge_ioapic_irq, shutdown_edge_ioapic_irq, - do_edge_ioapic_IRQ, enable_edge_ioapic_irq, - disable_edge_ioapic_irq + disable_edge_ioapic_irq, + ack_edge_ioapic_irq, + end_edge_ioapic_irq }; static struct hw_interrupt_type ioapic_level_irq_type = { "IO-APIC-level", startup_level_ioapic_irq, shutdown_level_ioapic_irq, - do_level_ioapic_IRQ, enable_level_ioapic_irq, - disable_level_ioapic_irq + disable_level_ioapic_irq, + mask_and_ack_level_ioapic_irq, + end_level_ioapic_irq }; static inline void init_IO_APIC_traps(void) diff -u --recursive --new-file v2.3.13/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c --- v2.3.13/linux/arch/i386/kernel/irq.c Mon Aug 9 14:59:19 1999 +++ linux/arch/i386/kernel/irq.c Wed Aug 18 11:17:37 1999 @@ -1,3 +1,8 @@ +/* mostly architecture independent + some moved to i8259.c + the beautiful visws architecture code needs to be updated too. + and, finally, the BUILD_IRQ and SMP_BUILD macros in irq.h need fixed. + */ /* * linux/arch/i386/kernel/irq.c * @@ -32,14 +37,14 @@ #include #include -#include #include #include #include #include #include +#include +#include -#include "irq.h" unsigned int local_bh_count[NR_CPUS]; unsigned int local_irq_count[NR_CPUS]; @@ -67,334 +72,18 @@ * system. We never hold this lock when we call the actual * IRQ handler. */ -spinlock_t irq_controller_lock; - -/* - * Dummy controller type for unused interrupts - */ -static void do_none(unsigned int irq, struct pt_regs * regs) -{ - /* - * we are careful. While for ISA irqs it's common to happen - * outside of any driver (think autodetection), this is not - * at all nice for PCI interrupts. So we are stricter and - * print a warning when such spurious interrupts happen. - * Spurious interrupts can confuse other drivers if the PCI - * IRQ line is shared. - * - * Such spurious interrupts are either driver bugs, or - * sometimes hw (chipset) bugs. - */ - printk("unexpected IRQ vector %d on CPU#%d!\n",irq, smp_processor_id()); - -#ifdef __SMP__ - /* - * [currently unexpected vectors happen only on SMP and APIC. - * if we want to have non-APIC and non-8259A controllers - * in the future with unexpected vectors, this ack should - * probably be made controller-specific.] - */ - ack_APIC_irq(); -#endif -} -static void enable_none(unsigned int irq) { } -static void disable_none(unsigned int irq) { } - -/* startup is the same as "enable", shutdown is same as "disable" */ -#define startup_none enable_none -#define shutdown_none disable_none - -struct hw_interrupt_type no_irq_type = { - "none", - startup_none, - shutdown_none, - do_none, - enable_none, - disable_none -}; - -/* - * This is the 'legacy' 8259A Programmable Interrupt Controller, - * present in the majority of PC/AT boxes. - */ - -static void do_8259A_IRQ(unsigned int irq, struct pt_regs * regs); -static void enable_8259A_irq(unsigned int irq); -void disable_8259A_irq(unsigned int irq); - -/* startup is the same as "enable", shutdown is same as "disable" */ -#define startup_8259A_irq enable_8259A_irq -#define shutdown_8259A_irq disable_8259A_irq - -static struct hw_interrupt_type i8259A_irq_type = { - "XT-PIC", - startup_8259A_irq, - shutdown_8259A_irq, - do_8259A_IRQ, - enable_8259A_irq, - disable_8259A_irq -}; - +spinlock_t irq_controller_lock ={0}; /* * Controller mappings for all interrupt sources: */ irq_desc_t irq_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = { 0, &no_irq_type, }}; - -/* - * 8259A PIC functions to handle ISA devices: - */ - -/* - * This contains the irq mask for both 8259A irq controllers, - */ -static unsigned int cached_irq_mask = 0xffff; - -#define __byte(x,y) (((unsigned char *)&(y))[x]) -#define cached_21 (__byte(0,cached_irq_mask)) -#define cached_A1 (__byte(1,cached_irq_mask)) - -/* - * Not all IRQs can be routed through the IO-APIC, eg. on certain (older) - * boards the timer interrupt is not connected to any IO-APIC pin, it's - * fed to the CPU IRQ line directly. - * - * Any '1' bit in this mask means the IRQ is routed through the IO-APIC. - * this 'mixed mode' IRQ handling costs nothing because it's only used - * at IRQ setup time. - */ -unsigned long io_apic_irqs = 0; - -/* - * These have to be protected by the irq controller spinlock - * before being called. - */ -void disable_8259A_irq(unsigned int irq) -{ - unsigned int mask = 1 << irq; - cached_irq_mask |= mask; - if (irq & 8) { - outb(cached_A1,0xA1); - } else { - outb(cached_21,0x21); - } -} - -static void enable_8259A_irq(unsigned int irq) -{ - unsigned int mask = ~(1 << irq); - cached_irq_mask &= mask; - if (irq & 8) { - outb(cached_A1,0xA1); - } else { - outb(cached_21,0x21); - } -} - -int i8259A_irq_pending(unsigned int irq) -{ - unsigned int mask = 1<> 8)); -} - -void make_8259A_irq(unsigned int irq) -{ - disable_irq_nosync(irq); - io_apic_irqs &= ~(1<status & ~(IRQ_REPLAY | IRQ_WAITING); - action = NULL; - if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { - action = desc->action; - status |= IRQ_INPROGRESS; - } - desc->status = status; - } - spin_unlock(&irq_controller_lock); - - /* Exit early if we had no action or it was disabled */ - if (!action) - return; - - handle_IRQ_event(irq, regs, action); - - spin_lock(&irq_controller_lock); - { - unsigned int status = desc->status & ~IRQ_INPROGRESS; - desc->status = status; - if (!(status & IRQ_DISABLED)) - enable_8259A_irq(irq); - } - spin_unlock(&irq_controller_lock); -} - -/* - * This builds up the IRQ handler stubs using some ugly macros in irq.h - * - * These macros create the low-level assembly IRQ routines that save - * register context and call do_IRQ(). do_IRQ() then does all the - * operations that are needed to keep the AT (or SMP IOAPIC) - * interrupt-controller happy. - */ - - -BUILD_COMMON_IRQ() - -#define BI(x,y) \ - BUILD_IRQ(##x##y) - -#define BUILD_16_IRQS(x) \ - BI(x,0) BI(x,1) BI(x,2) BI(x,3) \ - BI(x,4) BI(x,5) BI(x,6) BI(x,7) \ - BI(x,8) BI(x,9) BI(x,a) BI(x,b) \ - BI(x,c) BI(x,d) BI(x,e) BI(x,f) - -/* - * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts: - * (these are usually mapped to vectors 0x20-0x30) - */ -BUILD_16_IRQS(0x0) - -#ifdef CONFIG_X86_IO_APIC -/* - * The IO-APIC gives us many more interrupt sources. Most of these - * are unused but an SMP system is supposed to have enough memory ... - * sometimes (mostly wrt. hw bugs) we get corrupted vectors all - * across the spectrum, so we really want to be prepared to get all - * of these. Plus, more powerful systems might have more than 64 - * IO-APIC registers. - * - * (these are usually mapped into the 0x30-0xff vector range) - */ - BUILD_16_IRQS(0x1) BUILD_16_IRQS(0x2) BUILD_16_IRQS(0x3) -BUILD_16_IRQS(0x4) BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7) -BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb) -BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) -#endif - -#undef BUILD_16_IRQS -#undef BI - - -#ifdef __SMP__ -/* - * The following vectors are part of the Linux architecture, there - * is no hardware IRQ pin equivalent for them, they are triggered - * through the ICC by us (IPIs) - */ -BUILD_SMP_INTERRUPT(reschedule_interrupt) -BUILD_SMP_INTERRUPT(invalidate_interrupt) -BUILD_SMP_INTERRUPT(stop_cpu_interrupt) -BUILD_SMP_INTERRUPT(call_function_interrupt) -BUILD_SMP_INTERRUPT(spurious_interrupt) - -/* - * every pentium local APIC has two 'local interrupts', with a - * soft-definable vector attached to both interrupts, one of - * which is a timer interrupt, the other one is error counter - * overflow. Linux uses the local APIC timer interrupt to get - * a much simpler SMP time architecture: - */ -BUILD_SMP_TIMER_INTERRUPT(apic_timer_interrupt) - -#endif - -#define IRQ(x,y) \ - IRQ##x##y##_interrupt - -#define IRQLIST_16(x) \ - IRQ(x,0), IRQ(x,1), IRQ(x,2), IRQ(x,3), \ - IRQ(x,4), IRQ(x,5), IRQ(x,6), IRQ(x,7), \ - IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \ - IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f) - -static void (*interrupt[NR_IRQS])(void) = { - IRQLIST_16(0x0), - -#ifdef CONFIG_X86_IO_APIC - IRQLIST_16(0x1), IRQLIST_16(0x2), IRQLIST_16(0x3), - IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7), - IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb), - IRQLIST_16(0xc), IRQLIST_16(0xd) -#endif -}; - -#undef IRQ -#undef IRQLIST_16 - - /* * Special irq handlers. */ void no_action(int cpl, void *dev_id, struct pt_regs *regs) { } -#ifndef CONFIG_VISWS -/* - * Note that on a 486, we don't want to do a SIGFPE on an irq13 - * as the irq is unreliable, and exception 16 works correctly - * (ie as explained in the intel literature). On a 386, you - * can't use exception 16 due to bad IBM design, so we have to - * rely on the less exact irq13. - * - * Careful.. Not only is IRQ13 unreliable, but it is also - * leads to races. IBM designers who came up with it should - * be shot. - */ - -static void math_error_irq(int cpl, void *dev_id, struct pt_regs *regs) -{ - outb(0,0xF0); - if (ignore_irq13 || !boot_cpu_data.hard_math) - return; - math_error(); -} - -static struct irqaction irq13 = { math_error_irq, 0, 0, "fpu", NULL, NULL }; - -/* - * IRQ2 is cascade interrupt to second interrupt controller - */ - -static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL}; -#endif - /* * Generic, controller-independent functions: */ @@ -780,10 +469,16 @@ spin_lock_irqsave(&irq_controller_lock, flags); switch (irq_desc[irq].depth) { - case 1: - irq_desc[irq].status &= ~IRQ_DISABLED; + case 1: { + unsigned int status = irq_desc[irq].status & ~IRQ_DISABLED; + irq_desc[irq].status = status; + if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { + irq_desc[irq].status = status | IRQ_REPLAY; + hw_resend_irq(irq_desc[irq].handler,irq); + } irq_desc[irq].handler->enable(irq); - /* fall throught */ + /* fall-through */ + } default: irq_desc[irq].depth--; break; @@ -799,7 +494,7 @@ * SMP cross-CPU interrupts have their own specific * handlers). */ -asmlinkage void do_IRQ(struct pt_regs regs) +asmlinkage unsigned int do_IRQ(struct pt_regs regs) { /* * We ack quickly, we don't want the irq controller @@ -811,76 +506,81 @@ * 0 return value means that this irq is already being * handled by some other CPU. (or is disabled) */ - int irq = regs.orig_eax & 0xff; /* subtle, see irq.h */ + int irq = regs.orig_eax & 0xff; /* high bits used in ret_from_ code */ int cpu = smp_processor_id(); + irq_desc_t *desc; + struct irqaction * action; + unsigned int status; kstat.irqs[cpu][irq]++; - irq_desc[irq].handler->handle(irq, ®s); + desc = irq_desc + irq; + spin_lock(&irq_controller_lock); + irq_desc[irq].handler->ack(irq); + /* + REPLAY is when Linux resends an IRQ that was dropped earlier + WAITING is used by probe to mark irqs that are being tested + */ + status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING); + status |= IRQ_PENDING; /* we _want_ to handle it */ /* - * This should be conditional: we should really get - * a return code from the irq handler to tell us - * whether the handler wants us to do software bottom - * half handling or not.. + * If the IRQ is disabled for whatever reason, we cannot + * use the action we have. */ - if (1) { - if (bh_active & bh_mask) - do_bottom_half(); + action = NULL; + if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + action = desc->action; + status &= ~IRQ_PENDING; /* we commit to handling */ + status |= IRQ_INPROGRESS; /* we are handling it */ } -} - -int setup_x86_irq(unsigned int irq, struct irqaction * new) -{ - int shared = 0; - struct irqaction *old, **p; - unsigned long flags; + desc->status = status; + spin_unlock(&irq_controller_lock); /* - * Some drivers like serial.c use request_irq() heavily, - * so we have to be careful not to interfere with a - * running system. + * If there is no IRQ handler or it was disabled, exit early. + Since we set PENDING, if another processor is handling + a different instance of this same irq, the other processor + will take care of it. */ - if (new->flags & SA_SAMPLE_RANDOM) { - /* - * This function might sleep, we want to call it first, - * outside of the atomic block. - * Yes, this might clear the entropy pool if the wrong - * driver is attempted to be loaded, without actually - * installing a new handler, but is this really a problem, - * only the sysadmin is able to do this. - */ - rand_initialize_irq(irq); - } + if (!action) + return 1; /* - * The following block of code has to be executed atomically + * Edge triggered interrupts need to remember + * pending events. + * This applies to any hw interrupts that allow a second + * instance of the same irq to arrive while we are in do_IRQ + * or in the handler. But the code here only handles the _second_ + * instance of the irq, not the third or fourth. So it is mostly + * useful for irq hardware that does not mask cleanly in an + * SMP environment. */ - spin_lock_irqsave(&irq_controller_lock,flags); - p = &irq_desc[irq].action; - if ((old = *p) != NULL) { - /* Can't share interrupts unless both agree to */ - if (!(old->flags & new->flags & SA_SHIRQ)) { - spin_unlock_irqrestore(&irq_controller_lock,flags); - return -EBUSY; - } - - /* add new interrupt at end of irq queue */ - do { - p = &old->next; - old = *p; - } while (old); - shared = 1; + for (;;) { + handle_IRQ_event(irq, ®s, action); + spin_lock(&irq_controller_lock); + + if (!(desc->status & IRQ_PENDING)) + break; + desc->status &= ~IRQ_PENDING; + spin_unlock(&irq_controller_lock); + } + desc->status &= ~IRQ_INPROGRESS; + if (!(desc->status & IRQ_DISABLED)){ + irq_desc[irq].handler->end(irq); } + spin_unlock(&irq_controller_lock); - *p = new; - - if (!shared) { - irq_desc[irq].depth = 0; - irq_desc[irq].status &= ~IRQ_DISABLED; - irq_desc[irq].handler->startup(irq); + /* + * This should be conditional: we should really get + * a return code from the irq handler to tell us + * whether the handler wants us to do software bottom + * half handling or not.. + */ + if (1) { + if (bh_active & bh_mask) + do_bottom_half(); } - spin_unlock_irqrestore(&irq_controller_lock,flags); - return 0; + return 1; } int request_irq(unsigned int irq, @@ -909,8 +609,7 @@ action->next = NULL; action->dev_id = dev_id; - retval = setup_x86_irq(irq, action); - + retval = setup_irq(irq, action); if (retval) kfree(action); return retval; @@ -935,13 +634,6 @@ irq_desc[irq].status |= IRQ_DISABLED; irq_desc[irq].handler->shutdown(irq); } - spin_unlock_irqrestore(&irq_controller_lock,flags); - - /* Wait to make sure it's not being used on another CPU */ - while (irq_desc[irq].status & IRQ_INPROGRESS) - barrier(); - kfree(action); - return; } printk("Trying to free free IRQ%d\n",irq); spin_unlock_irqrestore(&irq_controller_lock,flags); @@ -967,7 +659,8 @@ for (i = NR_IRQS-1; i > 0; i--) { if (!irq_desc[i].action) { irq_desc[i].status |= IRQ_AUTODETECT | IRQ_WAITING; - irq_desc[i].handler->startup(i); + if(irq_desc[i].handler->startup(i)) + irq_desc[i].status |= IRQ_PENDING; } } spin_unlock_irq(&irq_controller_lock); @@ -1030,100 +723,58 @@ return irq_found; } -void init_ISA_irqs (void) +/* this was setup_x86_irq but it seems pretty generic */ +int setup_irq(unsigned int irq, struct irqaction * new) { - int i; - - for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 0; - - if (i < 16) { - /* - * 16 old-style INTA-cycle interrupts: - */ - irq_desc[i].handler = &i8259A_irq_type; - } else { - /* - * 'high' PCI IRQs filled in on demand - */ - irq_desc[i].handler = &no_irq_type; - } - } -} - -__initfunc(void init_IRQ(void)) -{ - int i; + int shared = 0; + struct irqaction *old, **p; + unsigned long flags; -#ifndef CONFIG_X86_VISWS_APIC - init_ISA_irqs(); -#else - init_VISWS_APIC_irqs(); -#endif /* - * Cover the whole vector space, no vector can escape - * us. (some of these will be overridden and become - * 'special' SMP interrupts) + * Some drivers like serial.c use request_irq() heavily, + * so we have to be careful not to interfere with a + * running system. */ - for (i = 0; i < NR_IRQS; i++) { - int vector = FIRST_EXTERNAL_VECTOR + i; - if (vector != SYSCALL_VECTOR) - set_intr_gate(vector, interrupt[i]); + if (new->flags & SA_SAMPLE_RANDOM) { + /* + * This function might sleep, we want to call it first, + * outside of the atomic block. + * Yes, this might clear the entropy pool if the wrong + * driver is attempted to be loaded, without actually + * installing a new handler, but is this really a problem, + * only the sysadmin is able to do this. + */ + rand_initialize_irq(irq); } -#ifdef __SMP__ - - /* - IRQ0 must be given a fixed assignment and initialized - before init_IRQ_SMP. - */ - set_intr_gate(IRQ0_TRAP_VECTOR, interrupt[0]); - /* - * The reschedule interrupt is a CPU-to-CPU reschedule-helper - * IPI, driven by wakeup. + * The following block of code has to be executed atomically */ - set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); - - /* IPI for invalidation */ - set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt); - - /* IPI for CPU halt */ - set_intr_gate(STOP_CPU_VECTOR, stop_cpu_interrupt); - - /* self generated IPI for local APIC timer */ - set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); - - /* IPI for generic function call */ - set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); + spin_lock_irqsave(&irq_controller_lock,flags); + p = &irq_desc[irq].action; + if ((old = *p) != NULL) { + /* Can't share interrupts unless both agree to */ + if (!(old->flags & new->flags & SA_SHIRQ)) { + spin_unlock_irqrestore(&irq_controller_lock,flags); + return -EBUSY; + } - /* IPI vector for APIC spurious interrupts */ - set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); -#endif + /* add new interrupt at end of irq queue */ + do { + p = &old->next; + old = *p; + } while (old); + shared = 1; + } - /* - * Set the clock to 100 Hz, we already have a valid - * vector now: - */ - outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */ - outb_p(LATCH & 0xff , 0x40); /* LSB */ - outb(LATCH >> 8 , 0x40); /* MSB */ - -#ifndef CONFIG_VISWS - setup_x86_irq(2, &irq2); - setup_x86_irq(13, &irq13); -#endif -} + *p = new; -#ifdef CONFIG_X86_IO_APIC -__initfunc(void init_IRQ_SMP(void)) -{ - int i; - for (i = 0; i < NR_IRQS ; i++) - if (IO_APIC_VECTOR(i) > 0) - set_intr_gate(IO_APIC_VECTOR(i), interrupt[i]); + if (!shared) { + irq_desc[irq].depth = 0; + irq_desc[irq].status &= ~IRQ_DISABLED; + irq_desc[irq].handler->startup(irq); + } + spin_unlock_irqrestore(&irq_controller_lock,flags); + return 0; } -#endif diff -u --recursive --new-file v2.3.13/linux/arch/i386/kernel/irq.h linux/arch/i386/kernel/irq.h --- v2.3.13/linux/arch/i386/kernel/irq.h Wed Jul 28 14:47:42 1999 +++ linux/arch/i386/kernel/irq.h Wed Dec 31 16:00:00 1969 @@ -1,253 +0,0 @@ -#ifndef __irq_h -#define __irq_h - -#include - -/* - * Interrupt controller descriptor. This is all we need - * to describe about the low-level hardware. - */ -struct hw_interrupt_type { - const char * typename; - void (*startup)(unsigned int irq); - void (*shutdown)(unsigned int irq); - void (*handle)(unsigned int irq, struct pt_regs * regs); - void (*enable)(unsigned int irq); - void (*disable)(unsigned int irq); -}; - -extern struct hw_interrupt_type no_irq_type; - -/* - * IRQ line status. - */ -#define IRQ_INPROGRESS 1 /* IRQ handler active - do not enter! */ -#define IRQ_DISABLED 2 /* IRQ disabled - do not enter! */ -#define IRQ_PENDING 4 /* IRQ pending - replay on enable */ -#define IRQ_REPLAY 8 /* IRQ has been replayed but not acked yet */ -#define IRQ_AUTODETECT 16 /* IRQ is being autodetected */ -#define IRQ_WAITING 32 /* IRQ not yet seen - for autodetection */ - -/* - * This is the "IRQ descriptor", which contains various information - * about the irq, including what kind of hardware handling it has, - * whether it is disabled etc etc. - * - * Pad this out to 32 bytes for cache and indexing reasons. - */ -typedef struct { - unsigned int status; /* IRQ status - IRQ_INPROGRESS, IRQ_DISABLED */ - struct hw_interrupt_type *handler; /* handle/enable/disable functions */ - struct irqaction *action; /* IRQ action list */ - unsigned int depth; /* Disable depth for nested irq disables */ -} irq_desc_t; - -/* - * IDT vectors usable for external interrupt sources start - * at 0x20: - */ -#define FIRST_EXTERNAL_VECTOR 0x20 - -#define SYSCALL_VECTOR 0x80 - -/* - * Vectors 0x20-0x2f are used for ISA interrupts. - */ - -/* - * Special IRQ vectors used by the SMP architecture: - * - * (some of the following vectors are 'rare', they are merged - * into a single vector (FUNCTION_VECTOR) to save vector space. - * TLB, reschedule and local APIC vectors are performance-critical.) - */ -#define RESCHEDULE_VECTOR 0x30 -#define INVALIDATE_TLB_VECTOR 0x31 -#define STOP_CPU_VECTOR 0x40 -#define LOCAL_TIMER_VECTOR 0x41 -#define CALL_FUNCTION_VECTOR 0x50 - -/* - * First APIC vector available to drivers: (vectors 0x51-0xfe) - */ -#define IRQ0_TRAP_VECTOR 0x51 - -/* - * This IRQ should never happen, but we print a message nevertheless. - */ -#define SPURIOUS_APIC_VECTOR 0xff - -extern irq_desc_t irq_desc[NR_IRQS]; -extern int irq_vector[NR_IRQS]; -#define IO_APIC_VECTOR(irq) irq_vector[irq] - -extern void init_IRQ_SMP(void); -extern int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *); -extern int setup_x86_irq(unsigned int, struct irqaction *); - -/* - * Various low-level irq details needed by irq.c, process.c, - * time.c, io_apic.c and smp.c - * - * Interrupt entry/exit code at both C and assembly level - */ - -extern void no_action(int cpl, void *dev_id, struct pt_regs *regs); -extern void mask_irq(unsigned int irq); -extern void unmask_irq(unsigned int irq); -extern void disable_8259A_irq(unsigned int irq); -extern int i8259A_irq_pending(unsigned int irq); -extern void ack_APIC_irq(void); -extern void FASTCALL(send_IPI_self(int vector)); -extern void init_VISWS_APIC_irqs(void); -extern void setup_IO_APIC(void); -extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn); -extern void make_8259A_irq(unsigned int irq); -extern void send_IPI(int dest, int vector); -extern void init_pic_mode(void); -extern void print_IO_APIC(void); - -extern unsigned long io_apic_irqs; - -extern char _stext, _etext; - -#define MAX_IRQ_SOURCES 128 -#define MAX_MP_BUSSES 32 -enum mp_bustype { - MP_BUS_ISA, - MP_BUS_EISA, - MP_BUS_PCI -}; -extern int mp_bus_id_to_type [MAX_MP_BUSSES]; -extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES]; - -extern spinlock_t irq_controller_lock; - -#ifdef __SMP__ - -#include - -static inline void irq_enter(int cpu, unsigned int irq) -{ - hardirq_enter(cpu); - while (test_bit(0,&global_irq_lock)) { - /* nothing */; - } -} - -static inline void irq_exit(int cpu, unsigned int irq) -{ - hardirq_exit(cpu); -} - -#define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs)) - -#else - -#define irq_enter(cpu, irq) (++local_irq_count[cpu]) -#define irq_exit(cpu, irq) (--local_irq_count[cpu]) - -#define IO_APIC_IRQ(x) (0) - -#endif - -#define __STR(x) #x -#define STR(x) __STR(x) - -#define SAVE_ALL \ - "cld\n\t" \ - "pushl %es\n\t" \ - "pushl %ds\n\t" \ - "pushl %eax\n\t" \ - "pushl %ebp\n\t" \ - "pushl %edi\n\t" \ - "pushl %esi\n\t" \ - "pushl %edx\n\t" \ - "pushl %ecx\n\t" \ - "pushl %ebx\n\t" \ - "movl $" STR(__KERNEL_DS) ",%edx\n\t" \ - "movl %dx,%ds\n\t" \ - "movl %dx,%es\n\t" - -#define IRQ_NAME2(nr) nr##_interrupt(void) -#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) - -#define GET_CURRENT \ - "movl %esp, %ebx\n\t" \ - "andl $-8192, %ebx\n\t" - -#ifdef __SMP__ - -/* - * SMP has a few special interrupts for IPI messages - */ - -#define BUILD_SMP_INTERRUPT(x) \ -asmlinkage void x(void); \ -__asm__( \ -"\n"__ALIGN_STR"\n" \ -SYMBOL_NAME_STR(x) ":\n\t" \ - "pushl $-1\n\t" \ - SAVE_ALL \ - "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \ - "jmp ret_from_intr\n"); - -#define BUILD_SMP_TIMER_INTERRUPT(x) \ -asmlinkage void x(struct pt_regs * regs); \ -__asm__( \ -"\n"__ALIGN_STR"\n" \ -SYMBOL_NAME_STR(x) ":\n\t" \ - "pushl $-1\n\t" \ - SAVE_ALL \ - "movl %esp,%eax\n\t" \ - "pushl %eax\n\t" \ - "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \ - "addl $4,%esp\n\t" \ - "jmp ret_from_intr\n"); - -#endif /* __SMP__ */ - -#define BUILD_COMMON_IRQ() \ -__asm__( \ - "\n" __ALIGN_STR"\n" \ - "common_interrupt:\n\t" \ - SAVE_ALL \ - "pushl $ret_from_intr\n\t" \ - "jmp "SYMBOL_NAME_STR(do_IRQ)); - -/* - * subtle. orig_eax is used by the signal code to distinct between - * system calls and interrupted 'random user-space'. Thus we have - * to put a negative value into orig_eax here. (the problem is that - * both system calls and IRQs want to have small integer numbers in - * orig_eax, and the syscall code has won the optimization conflict ;) - */ -#define BUILD_IRQ(nr) \ -asmlinkage void IRQ_NAME(nr); \ -__asm__( \ -"\n"__ALIGN_STR"\n" \ -SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \ - "pushl $"#nr"-256\n\t" \ - "jmp common_interrupt"); - -/* - * x86 profiling function, SMP safe. We might want to do this in - * assembly totally? - */ -static inline void x86_do_profile (unsigned long eip) -{ - if (prof_buffer) { - eip -= (unsigned long) &_stext; - eip >>= prof_shift; - /* - * Don't ignore out-of-bounds EIP values silently, - * put them into the last histogram slot, so if - * present, they will show up as a sharp peak. - */ - if (eip > prof_len-1) - eip = prof_len-1; - atomic_inc((atomic_t *)&prof_buffer[eip]); - } -} - -#endif diff -u --recursive --new-file v2.3.13/linux/arch/i386/kernel/mca.c linux/arch/i386/kernel/mca.c --- v2.3.13/linux/arch/i386/kernel/mca.c Wed Jul 21 15:46:48 1999 +++ linux/arch/i386/kernel/mca.c Wed Aug 18 11:25:29 1999 @@ -222,7 +222,7 @@ #define MCA_STANDARD_RESOURCES (sizeof(mca_standard_resources)/sizeof(struct resource)) -__initfunc(void mca_init(void)) +void __init mca_init(void) { unsigned int i, j; unsigned long flags; @@ -698,7 +698,7 @@ /*--------------------------------------------------------------------*/ -__initfunc(void mca_do_proc_init(void)) +void __init mca_do_proc_init(void) { int i; struct proc_dir_entry* node = NULL; diff -u --recursive --new-file v2.3.13/linux/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c --- v2.3.13/linux/arch/i386/kernel/mtrr.c Wed Jun 30 13:38:18 1999 +++ linux/arch/i386/kernel/mtrr.c Wed Aug 18 11:27:04 1999 @@ -235,7 +235,7 @@ #include #include -#include "irq.h" +#include #define MTRR_VERSION "1.35 (19990512)" @@ -731,8 +731,8 @@ /* Get the MSR pair relating to a var range */ -__initfunc(static void get_mtrr_var_range (unsigned int index, - struct mtrr_var_range *vr)) +static void __init get_mtrr_var_range (unsigned int index, + struct mtrr_var_range *vr) { rdmsr (MTRRphysBase_MSR (index), vr->base_lo, vr->base_hi); rdmsr (MTRRphysMask_MSR (index), vr->mask_lo, vr->mask_hi); @@ -741,8 +741,8 @@ /* Set the MSR pair relating to a var range. Returns TRUE if changes are made */ -__initfunc(static int set_mtrr_var_range_testing (unsigned int index, - struct mtrr_var_range *vr)) +static int __init set_mtrr_var_range_testing (unsigned int index, + struct mtrr_var_range *vr) { unsigned int lo, hi; int changed = FALSE; @@ -764,7 +764,7 @@ return changed; } /* End Function set_mtrr_var_range_testing */ -__initfunc(static void get_fixed_ranges(mtrr_type *frs)) +static void __init get_fixed_ranges(mtrr_type *frs) { unsigned long *p = (unsigned long *)frs; int i; @@ -777,7 +777,7 @@ rdmsr(MTRRfix4K_C0000_MSR + i, p[6 + i*2], p[7 + i*2]); } /* End Function get_fixed_ranges */ -__initfunc(static int set_fixed_ranges_testing(mtrr_type *frs)) +static int __init set_fixed_ranges_testing(mtrr_type *frs) { unsigned long *p = (unsigned long *)frs; int changed = FALSE; @@ -819,7 +819,7 @@ /* Grab all of the MTRR state for this CPU into *state */ -__initfunc(static void get_mtrr_state(struct mtrr_state *state)) +static void __init get_mtrr_state(struct mtrr_state *state) { unsigned int nvrs, i; struct mtrr_var_range *vrs; @@ -842,14 +842,14 @@ /* Free resources associated with a struct mtrr_state */ -__initfunc(static void finalize_mtrr_state(struct mtrr_state *state)) +static void __init finalize_mtrr_state(struct mtrr_state *state) { if (state->var_ranges) kfree (state->var_ranges); } /* End Function finalize_mtrr_state */ -__initfunc(static unsigned long set_mtrr_state (struct mtrr_state *state, - struct set_mtrr_context *ctxt)) +static unsigned long __init set_mtrr_state (struct mtrr_state *state, + struct set_mtrr_context *ctxt) /* [SUMMARY] Set the MTRR state for this CPU. The MTRR state information to read. Some relevant CPU context. @@ -948,7 +948,7 @@ /* Some BIOS's are fucked and don't set all MTRRs the same! */ -__initfunc(static void mtrr_state_warn (unsigned long mask)) +static void __init mtrr_state_warn(unsigned long mask) { if (!mask) return; if (mask & MTRR_CHANGE_MASK_FIXED) @@ -1532,7 +1532,7 @@ unsigned char ccr_state[7] __initdata = { 0, 0, 0, 0, 0, 0, 0 }; -__initfunc(static void cyrix_arr_init_secondary(void)) +static void __init cyrix_arr_init_secondary(void) { struct set_mtrr_context ctxt; int i; @@ -1565,7 +1565,7 @@ * - (maybe) disable ARR3 * Just to be sure, we enable ARR usage by the processor (CCR5 bit 5 set) */ -__initfunc(static void cyrix_arr_init(void)) +static void __init cyrix_arr_init(void) { struct set_mtrr_context ctxt; unsigned char ccr[7]; @@ -1631,7 +1631,7 @@ if ( ccrc[6] ) printk ("mtrr: ARR3 was write protected, unprotected\n"); } /* End Function cyrix_arr_init */ -__initfunc(static void centaur_mcr_init (void)) +static void __init centaur_mcr_init(void) { unsigned i; struct set_mtrr_context ctxt; @@ -1655,7 +1655,7 @@ set_mtrr_done (&ctxt); } /* End Function centaur_mcr_init */ -__initfunc(static void mtrr_setup (void)) +static void __init mtrr_setup(void) { printk ("mtrr: v%s Richard Gooch (rgooch@atnf.csiro.au)\n", MTRR_VERSION); switch (boot_cpu_data.x86_vendor) @@ -1685,7 +1685,7 @@ static volatile unsigned long smp_changes_mask __initdata = 0; static struct mtrr_state smp_mtrr_state __initdata = {0, 0}; -__initfunc(void mtrr_init_boot_cpu (void)) +void __init mtrr_init_boot_cpu(void) { if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return; mtrr_setup (); @@ -1703,7 +1703,7 @@ } } /* End Function mtrr_init_boot_cpu */ -__initfunc(static void intel_mtrr_init_secondary_cpu (void)) +static void __init intel_mtrr_init_secondary_cpu(void) { unsigned long mask, count; struct set_mtrr_context ctxt; @@ -1722,7 +1722,7 @@ } } /* End Function intel_mtrr_init_secondary_cpu */ -__initfunc(void mtrr_init_secondary_cpu (void)) +void __init mtrr_init_secondary_cpu(void) { if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return; switch (boot_cpu_data.x86_vendor) @@ -1746,7 +1746,7 @@ } /* End Function mtrr_init_secondary_cpu */ #endif /* __SMP__ */ -__initfunc(int mtrr_init(void)) +int __init mtrr_init(void) { if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return 0; # ifdef __SMP__ diff -u --recursive --new-file v2.3.13/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c --- v2.3.13/linux/arch/i386/kernel/process.c Mon Aug 9 14:59:19 1999 +++ linux/arch/i386/kernel/process.c Wed Aug 18 11:11:15 1999 @@ -45,7 +45,7 @@ #include #endif -#include "irq.h" +#include spinlock_t semaphore_wake_lock = SPIN_LOCK_UNLOCKED; @@ -63,53 +63,10 @@ hlt_counter--; } -static void default_idle(void) -{ - while (1) { - while (!current->need_resched) { - if (!current_cpu_data.hlt_works_ok) - continue; - if (hlt_counter) - continue; - asm volatile("sti ; hlt" : : : "memory"); - } - schedule(); - check_pgt_cache(); - } -} - -void (*idle)(void) = default_idle; - -#if 1 - -#include - -static int __init piix4_idle_init(void) -{ - /* This is the PIIX4 ACPI device */ - struct pci_dev *dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL); - - if (dev) { - u32 base; - - printk("Found PIIX4 ACPI device\n"); - pci_read_config_dword(dev, 0x40, &base); - printk(" Base address %04x\n", base); -#ifdef __SMP__ - /* - * We can't really do idle things with multiple CPU's, I'm - * afraid. We'd need a per-CPU ACPI device. - */ - if (smp_num_cpus > 1) - return 0; -#endif - } - return 0; -} - -__initcall(piix4_idle_init); - -#endif +/* + * Powermanagement idle function, if any.. + */ +void (*acpi_idle)(void) = NULL; /* * The idle thread. There's no useful work to be @@ -123,7 +80,20 @@ init_idle(); current->priority = 0; current->counter = -100; - idle(); + + while (1) { + while (!current->need_resched) { + if (!current_cpu_data.hlt_works_ok) + continue; + if (hlt_counter) + continue; + asm volatile("sti ; hlt" : : : "memory"); + } + schedule(); + check_pgt_cache(); + if (acpi_idle) + acpi_idle(); + } } /* diff -u --recursive --new-file v2.3.13/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c --- v2.3.13/linux/arch/i386/kernel/setup.c Mon Aug 9 14:59:19 1999 +++ linux/arch/i386/kernel/setup.c Wed Aug 18 11:25:12 1999 @@ -14,6 +14,9 @@ * Bart Hartgers , May 1999. * * Intel Mobile Pentium II detection fix. Sean Gilley, June 1999. + * + * IDT Winchip tweaks, misc clean ups. + * Dave Jones , August 1999 */ /* @@ -90,7 +93,7 @@ #endif extern int root_mountflags; -extern int _etext, _edata, _end; +extern int _text, _etext, _edata, _end; extern unsigned long cpu_hz; /* @@ -248,7 +251,7 @@ static char command_line[COMMAND_LINE_SIZE] = { 0, }; char saved_command_line[COMMAND_LINE_SIZE]; -struct resource standard_resources[] = { +struct resource standard_io_resources[] = { { "dma1", 0x00, 0x1f }, { "pic1", 0x20, 0x3f }, { "timer", 0x40, 0x5f }, @@ -259,14 +262,90 @@ { "fpu", 0xf0, 0xff } }; -/* For demonstration purposes only.. */ -#define keyboard_resources (standard_resources+3) -struct resource kbd_status_resource = { "status", 0x60, 0x60 }; +#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource)) -#define STANDARD_RESOURCES (sizeof(standard_resources)/sizeof(struct resource)) +/* System RAM - interrupted by the 640kB-1M hole */ +#define code_resource (ram_resources[3]) +#define data_resource (ram_resources[4]) +static struct resource ram_resources[] = { + { "System RAM", 0x000000, 0x09ffff, IORESOURCE_BUSY }, + { "System RAM", 0x100000, 0x100000, IORESOURCE_BUSY }, + { "Video RAM area", 0x0a0000, 0x0bffff }, + { "Kernel code", 0x100000, 0 }, + { "Kernel data", 0, 0 } +}; + +/* System ROM resources */ +#define MAXROMS 6 +static struct resource rom_resources[MAXROMS] = { + { "System ROM", 0xF0000, 0xFFFFF, IORESOURCE_BUSY }, + { "Video ROM", 0xc0000, 0xc7fff } +}; + +#define romsignature(x) (*(unsigned short *)(x) == 0xaa55) + +static void __init probe_roms(void) +{ + int roms = 1; + unsigned long base; + unsigned char *romstart; + + request_resource(&iomem_resource, rom_resources+0); + + /* Video ROM is standard at C000:0000 - C7FF:0000, check signature */ + for (base = 0xC0000; base < 0xE0000; base += 2048) { + romstart = bus_to_virt(base); + if (!romsignature(romstart)) + continue; + request_resource(&iomem_resource, rom_resources + roms); + roms++; + break; + } + + /* Extension roms at C800:0000 - DFFF:0000 */ + for (base = 0xC8000; base < 0xE0000; base += 2048) { + unsigned long length; + + romstart = bus_to_virt(base); + if (!romsignature(romstart)) + continue; + length = romstart[2] * 512; + if (length) { + unsigned int i; + unsigned char chksum; + + chksum = 0; + for (i = 0; i < length; i++) + chksum += romstart[i]; + + /* Good checksum? */ + if (!chksum) { + rom_resources[roms].start = base; + rom_resources[roms].end = base + length - 1; + rom_resources[roms].name = "Extension ROM"; + + request_resource(&iomem_resource, rom_resources + roms); + roms++; + if (roms >= MAXROMS) + return; + } + } + } + + /* Final check for motherboard extension rom at E000:0000 */ + base = 0xE0000; + romstart = bus_to_virt(base); + + if (romsignature(romstart)) { + rom_resources[roms].start = base; + rom_resources[roms].end = base + 65535; + rom_resources[roms].name = "Extension ROM"; -__initfunc(void setup_arch(char **cmdline_p, - unsigned long * memory_start_p, unsigned long * memory_end_p)) + request_resource(&iomem_resource, rom_resources + roms); + } +} + +void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p) { unsigned long memory_start, memory_end; char c = ' ', *to = command_line, *from = COMMAND_LINE; @@ -298,6 +377,8 @@ } #endif + ram_resources[1].end = memory_end-1; + memory_end &= PAGE_MASK; #ifdef CONFIG_BLK_DEV_RAM rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK; @@ -307,11 +388,16 @@ if (!MOUNT_ROOT_RDONLY) root_mountflags &= ~MS_RDONLY; memory_start = (unsigned long) &_end; - init_mm.start_code = PAGE_OFFSET; + init_mm.start_code = (unsigned long) &_text; init_mm.end_code = (unsigned long) &_etext; init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) &_end; + code_resource.start = virt_to_bus(&_text); + code_resource.end = virt_to_bus(&_etext)-1; + data_resource.start = virt_to_bus(&_etext); + data_resource.end = virt_to_bus(&_edata)-1; + /* Save unparsed command line copy for /proc/cmdline */ memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; @@ -336,6 +422,8 @@ memory_end = memory_end << 20; from++; } + if (memory_end > ram_resources[1].end) + ram_resources[1].end = memory_end-1; } } c = *(from++); @@ -348,6 +436,14 @@ *to = '\0'; *cmdline_p = command_line; + /* Request the standard RAM and ROM resources - they eat up PCI memory space */ + request_resource(&iomem_resource, ram_resources+0); + request_resource(&iomem_resource, ram_resources+1); + request_resource(&iomem_resource, ram_resources+2); + request_resource(ram_resources+1, &code_resource); + request_resource(ram_resources+1, &data_resource); + probe_roms(); + #define VMALLOC_RESERVE (128 << 20) /* 128MB for vmalloc and initrd */ #define MAXMEM ((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE)) @@ -383,9 +479,8 @@ #endif /* request I/O space for devices used on all i[345]86 PCs */ - for (i = 0; i < STANDARD_RESOURCES; i++) - request_resource(&ioport_resource, standard_resources+i); - request_resource(keyboard_resources, &kbd_status_resource); + for (i = 0; i < STANDARD_IO_RESOURCES; i++) + request_resource(&ioport_resource, standard_io_resources+i); #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) @@ -396,7 +491,7 @@ #endif } -__initfunc(static int get_model_name(struct cpuinfo_x86 *c)) +static int __init get_model_name(struct cpuinfo_x86 *c) { unsigned int n, dummy, *v; @@ -424,7 +519,7 @@ return 1; } -__initfunc(static int amd_model(struct cpuinfo_x86 *c)) +static int __init amd_model(struct cpuinfo_x86 *c) { u32 l, h; unsigned long flags; @@ -553,7 +648,7 @@ static char cyrix_model_mult1[] __initdata = "12??43"; static char cyrix_model_mult2[] __initdata = "12233445"; -__initfunc(static void cyrix_model(struct cpuinfo_x86 *c)) +static void __init cyrix_model(struct cpuinfo_x86 *c) { unsigned char dir0, dir0_msn, dir0_lsn, dir1 = 0; char *buf = c->x86_model_id; @@ -661,7 +756,7 @@ return; } -__initfunc(void get_cpu_vendor(struct cpuinfo_x86 *c)) +void __init get_cpu_vendor(struct cpuinfo_x86 *c) { char *v = c->x86_vendor_id; @@ -721,7 +816,7 @@ NULL, NULL, NULL, NULL, NULL, NULL, NULL }}, }; -__initfunc(void identify_cpu(struct cpuinfo_x86 *c)) +void __init identify_cpu(struct cpuinfo_x86 *c) { int i; char *p = NULL; @@ -818,7 +913,6 @@ p = "Celeron (Dixon)"; } } - } if (p) { @@ -833,7 +927,7 @@ * Perform early boot up checks for a valid TSC. See arch/i386/kernel/time.c */ -__initfunc(void dodgy_tsc(void)) +void __init dodgy_tsc(void) { get_cpu_vendor(&boot_cpu_data); @@ -850,7 +944,7 @@ "Intel", "Cyrix", "AMD", "UMC", "NexGen", "Centaur" }; -__initfunc(void print_cpu_info(struct cpuinfo_x86 *c)) +void __init print_cpu_info(struct cpuinfo_x86 *c) { char *vendor = NULL; @@ -868,22 +962,25 @@ printk("%s", c->x86_model_id); if (c->x86_mask || c->cpuid_level>=0) - printk(" stepping %02x", c->x86_mask); + printk(" stepping %02x\n", c->x86_mask); - if(c->x86_vendor == X86_VENDOR_CENTAUR) - { + if(c->x86_vendor == X86_VENDOR_CENTAUR) { u32 hv,lv; rdmsr(0x107, lv, hv); - printk("\nCentaur FSR was 0x%X ",lv); - lv|=(1<<8); - lv|=(1<<7); + printk("Centaur FSR was 0x%X ",lv); + lv|=(1<<1 | 1<<2 | 1<<7); /* lv|=(1<<6); - may help too if the board can cope */ - printk("now 0x%X", lv); + printk("now 0x%X\n", lv); wrmsr(0x107, lv, hv); /* Emulate MTRRs using Centaur's MCR. */ - c->x86_capability |= X86_FEATURE_MTRR; + c->x86_capability |= X86_FEATURE_MTRR; + + /* Set 3DNow! on Winchip 2 and above. */ + if (c->x86_model >=8) + c->x86_capability |= X86_FEATURE_AMD3D; + + c->x86_capability |=X86_FEATURE_CX8; } - printk("\n"); } /* @@ -918,7 +1015,7 @@ c->x86 + '0', c->x86_model, c->x86_model_id[0] ? c->x86_model_id : "unknown"); - + if (c->x86_mask || c->cpuid_level >= 0) p += sprintf(p, "stepping\t: %d\n", c->x86_mask); else @@ -934,14 +1031,20 @@ p += sprintf(p, "cache size\t: %d KB\n", c->x86_cache_size); /* Modify the capabilities according to chip type */ - if (c->x86_vendor == X86_VENDOR_CYRIX) { + switch (c->x86_vendor) { + + case X86_VENDOR_CYRIX: x86_cap_flags[24] = "cxmmx"; - } else if (c->x86_vendor == X86_VENDOR_AMD) { - x86_cap_flags[16] = "fcmov"; - x86_cap_flags[31] = "3dnow"; + break; + + case X86_VENDOR_AMD: if (c->x86 == 5 && c->x86_model == 6) x86_cap_flags[10] = "sep"; - } else if (c->x86_vendor == X86_VENDOR_INTEL) { + x86_cap_flags[16] = "fcmov"; + x86_cap_flags[31] = "3dnow"; + break; + + case X86_VENDOR_INTEL: x86_cap_flags[6] = "pae"; x86_cap_flags[9] = "apic"; x86_cap_flags[14] = "mca"; @@ -949,6 +1052,16 @@ x86_cap_flags[17] = "pse36"; x86_cap_flags[18] = "psn"; x86_cap_flags[24] = "osfxsr"; + break; + + case X86_VENDOR_CENTAUR: + if (c->x86_model >=8) /* Only Winchip2 and above */ + x86_cap_flags[31] = "3dnow"; + break; + + default: + /* Unknown CPU manufacturer. Transmeta ? :-) */ + break; } sep_bug = c->x86_vendor == X86_VENDOR_INTEL && diff -u --recursive --new-file v2.3.13/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c --- v2.3.13/linux/arch/i386/kernel/smp.c Mon Aug 9 14:59:19 1999 +++ linux/arch/i386/kernel/smp.c Wed Aug 18 11:34:50 1999 @@ -42,7 +42,7 @@ #include #include -#include "irq.h" +#include #define JIFFIE_TIMEOUT 100 @@ -164,14 +164,6 @@ * SMP mode to . */ -void __init smp_setup(char *str, int *ints) -{ - if (ints && ints[0] > 0) - max_cpus = ints[1]; - else - max_cpus = 0; -} - static int __init nosmp(char *str) { max_cpus = 0; @@ -186,7 +178,7 @@ return 1; } -__setup("maxcpus", maxcpus); +__setup("maxcpus=", maxcpus); void ack_APIC_irq(void) { @@ -935,6 +927,14 @@ unsigned short ss; } stack_start; +static int __init fork_by_hand(void) +{ + struct pt_regs regs; + /* don't care about the eip and regs settings since we'll never + reschedule the forked task. */ + return do_fork(CLONE_VM|CLONE_PID, 0, ®s); +} + static void __init do_boot_cpu(int i) { unsigned long cfg; @@ -944,11 +944,11 @@ int timeout, num_starts, j; unsigned long start_eip; - /* - * We need an idle process for each processor. - */ - kernel_thread(start_secondary, NULL, CLONE_PID); cpucount++; + /* We can't use kernel_thread since we must _avoid_ to reschedule + the child. */ + if (fork_by_hand() < 0) + panic("failed fork for CPU %d", i); /* * We remove it from the pidhash and the runqueue diff -u --recursive --new-file v2.3.13/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c --- v2.3.13/linux/arch/i386/kernel/time.c Thu Apr 29 11:53:41 1999 +++ linux/arch/i386/kernel/time.c Wed Aug 18 11:27:23 1999 @@ -59,7 +59,7 @@ /* * for x86_do_profile() */ -#include "irq.h" +#include unsigned long cpu_hz; /* Detected as we calibrate the TSC */ @@ -547,7 +547,7 @@ #define CALIBRATE_LATCH (5 * LATCH) #define CALIBRATE_TIME (5 * 1000020/HZ) -__initfunc(static unsigned long calibrate_tsc(void)) +static unsigned long __init calibrate_tsc(void) { /* Set the Gate high, disable speaker */ outb((inb(0x61) & ~0x02) | 0x01, 0x61); @@ -612,7 +612,7 @@ return 0; } -__initfunc(void time_init(void)) +void __init time_init(void) { xtime.tv_sec = get_cmos_time(); xtime.tv_usec = 0; @@ -681,8 +681,8 @@ co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK); /* Wire cpu IDT entry to s/w handler (and Cobalt APIC to IDT) */ - setup_x86_irq(CO_IRQ_TIMER, &irq0); + setup_irq(CO_IRQ_TIMER, &irq0); #else - setup_x86_irq(0, &irq0); + setup_irq(0, &irq0); #endif } diff -u --recursive --new-file v2.3.13/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c --- v2.3.13/linux/arch/i386/kernel/traps.c Wed Jul 21 15:46:48 1999 +++ linux/arch/i386/kernel/traps.c Wed Aug 18 11:27:34 1999 @@ -42,7 +42,7 @@ #include #endif -#include "irq.h" +#include asmlinkage int system_call(void); asmlinkage void lcall7(void); @@ -480,7 +480,7 @@ #endif /* CONFIG_MATH_EMULATION */ -__initfunc(void trap_init_f00f_bug(void)) +void __init trap_init_f00f_bug(void) { unsigned long page; pgd_t * pgd; diff -u --recursive --new-file v2.3.13/linux/arch/i386/vmlinux.lds linux/arch/i386/vmlinux.lds --- v2.3.13/linux/arch/i386/vmlinux.lds Mon Aug 9 14:59:19 1999 +++ linux/arch/i386/vmlinux.lds Wed Dec 31 16:00:00 1969 @@ -1,75 +0,0 @@ -/* ld script to make i386 Linux kernel - * Written by Martin Mares ; - */ -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") -OUTPUT_ARCH(i386) -ENTRY(_start) -SECTIONS -{ - . = 0xC0000000 + 0x100000; - _text = .; /* Text and read-only data */ - .text : { - *(.text) - *(.fixup) - *(.gnu.warning) - } = 0x9090 - .text.lock : { *(.text.lock) } /* out-of-line lock text */ - .rodata : { *(.rodata) } - .kstrtab : { *(.kstrtab) } - - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - __start___ksymtab = .; /* Kernel symbol table */ - __ksymtab : { *(__ksymtab) } - __stop___ksymtab = .; - - _etext = .; /* End of text section */ - - .data : { /* Data */ - *(.data) - CONSTRUCTORS - } - - _edata = .; /* End of data section */ - - . = ALIGN(8192); /* init_task */ - .data.init_task : { *(.data.init_task) } - - . = ALIGN(4096); /* Init code and data */ - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(16); - __setup_start = .; - .setup.init : { *(.setup.init) } - __setup_end = .; - __initcall_start = .; - .initcall.init : { *(.initcall.init) } - __initcall_end = .; - . = ALIGN(4096); - __init_end = .; - - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - - . = ALIGN(32); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - __bss_start = .; /* BSS */ - .bss : { - *(.bss) - } - _end = . ; - - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } -} diff -u --recursive --new-file v2.3.13/linux/arch/m68k/Makefile linux/arch/m68k/Makefile --- v2.3.13/linux/arch/m68k/Makefile Tue May 11 09:57:14 1999 +++ linux/arch/m68k/Makefile Sun Aug 15 11:47:29 1999 @@ -116,6 +116,11 @@ SUBDIRS := $(SUBDIRS) arch/m68k/ifpsp060 endif +ifdef CONFIG_M68KFPU_EMU +CORE_FILES := $(CORE_FILES) arch/m68k/math-emu/mathemu.o +SUBDIRS := $(SUBDIRS) arch/m68k/math-emu +endif + lilo: vmlinux if [ -f $(INSTALL_PATH)/vmlinux ]; then mv -f $(INSTALL_PATH)/vmlinux $(INSTALL_PATH)/vmlinux.old; fi if [ -f $(INSTALL_PATH)/System.map ]; then mv -f $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi diff -u --recursive --new-file v2.3.13/linux/arch/m68k/amiga/amiints.c linux/arch/m68k/amiga/amiints.c --- v2.3.13/linux/arch/m68k/amiga/amiints.c Thu Jan 7 08:41:55 1999 +++ linux/arch/m68k/amiga/amiints.c Sun Aug 15 11:47:29 1999 @@ -19,6 +19,20 @@ * called again. * The whole interrupt handling for CIAs is moved to cia.c * /Roman Zippel + * + * 07/08/99: rewamp of the interrupt handling - we now have two types of + * interrupts, normal and fast handlers, fast handlers being + * marked with SA_INTERRUPT and runs with all other interrupts + * disabled. Normal interrupts disable their own source but + * run with all other interrupt sources enabled. + * PORTS and EXTER interrupts are always shared even if the + * drivers do not explicitly mark this when calling + * request_irq which they really should do. + * This is similar to the way interrupts are handled on all + * other architectures and makes a ton of sense besides + * having the advantage of making it easier to share + * drivers. + * /Jes */ #include @@ -70,7 +84,7 @@ * the amiga IRQ handling routines. */ -__initfunc(void amiga_init_IRQ(void)) +void __init amiga_init_IRQ(void) { int i; @@ -81,7 +95,7 @@ } else { ami_irq_list[i] = new_irq_node(); ami_irq_list[i]->handler = ami_badint; - ami_irq_list[i]->flags = IRQ_FLG_STD; + ami_irq_list[i]->flags = 0; ami_irq_list[i]->dev_id = NULL; ami_irq_list[i]->devname = NULL; ami_irq_list[i]->next = NULL; @@ -117,19 +131,18 @@ cur = *list; - if (node->flags & IRQ_FLG_FAST) { - node->flags &= ~IRQ_FLG_SLOW; - while (cur && cur->flags & IRQ_FLG_FAST) { - list = &cur->next; - cur = cur->next; - } - } else if (node->flags & IRQ_FLG_SLOW) { - while (cur) { + if (node->flags & SA_INTERRUPT) { + if (node->flags & SA_SHIRQ) + return; + /* + * There should never be more than one + */ + while (cur && cur->flags & SA_INTERRUPT) { list = &cur->next; cur = cur->next; } } else { - while (cur && !(cur->flags & IRQ_FLG_SLOW)) { + while (cur) { list = &cur->next; cur = cur->next; } @@ -168,13 +181,15 @@ * If the addition was successful, it returns 0. */ -int amiga_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), +int amiga_request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { irq_node_t *node; if (irq >= AMI_IRQS) { - printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname); + printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, + irq, devname); return -ENXIO; } @@ -190,6 +205,11 @@ return cia_request_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, handler, flags, devname, dev_id); + /* + * IRQ_AMIGA_PORTS & IRQ_AMIGA_EXTER defaults to shared, + * we could add a check here for the SA_SHIRQ flag but all drivers + * should be aware of sharing anyway. + */ if (ami_servers[irq]) { if (!(node = new_irq_node())) return -ENOMEM; @@ -200,18 +220,6 @@ node->next = NULL; amiga_insert_irq(&ami_irq_list[irq], node); } else { - if (!(ami_irq_list[irq]->flags & IRQ_FLG_STD)) { - if (ami_irq_list[irq]->flags & IRQ_FLG_LOCK) { - printk("%s: IRQ %d from %s is not replaceable\n", - __FUNCTION__, irq, ami_irq_list[irq]->devname); - return -EBUSY; - } - if (!(flags & IRQ_FLG_REPLACE)) { - printk("%s: %s can't replace IRQ %d from %s\n", - __FUNCTION__, devname, irq, ami_irq_list[irq]->devname); - return -EBUSY; - } - } ami_irq_list[irq]->handler = handler; ami_irq_list[irq]->flags = flags; ami_irq_list[irq]->dev_id = dev_id; @@ -255,7 +263,7 @@ printk("%s: removing probably wrong IRQ %d from %s\n", __FUNCTION__, irq, ami_irq_list[irq]->devname); ami_irq_list[irq]->handler = ami_badint; - ami_irq_list[irq]->flags = IRQ_FLG_STD; + ami_irq_list[irq]->flags = 0; ami_irq_list[irq]->dev_id = NULL; ami_irq_list[irq]->devname = NULL; custom.intena = ami_intena_vals[irq]; @@ -345,37 +353,58 @@ void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server) { irq_node_t *node, *slow_nodes; - unsigned short flags; + unsigned short flags, intena; kstat.irqs[0][SYS_IRQS + irq]++; if (server->count++) server->reentrance = 1; - /* serve first fast and normal handlers */ - for (node = ami_irq_list[irq]; - node && (!(node->flags & IRQ_FLG_SLOW)); - node = node->next) - node->handler(irq, node->dev_id, fp); - custom.intreq = ami_intena_vals[irq]; + + intena = ami_intena_vals[irq]; + custom.intreq = intena; + + /* serve first fast handlers - there can only be one of these */ + node = ami_irq_list[irq]; + + /* + * Timer interrupts show up like this + */ if (!node) { server->count--; return; } + + if (node && (node->flags & SA_INTERRUPT)) { + save_flags(flags); + cli(); + node->handler(irq, node->dev_id, fp); + restore_flags(flags); + + server->count--; + return; + } + + /* + * Disable the interrupt source in question and reenable all + * other interrupts. No interrupt handler should ever touch + * the intena flags directly! + */ + custom.intena = intena; save_flags(flags); - restore_flags((flags & ~0x0700) | (fp->sr & 0x0700)); - /* if slow handlers exists, serve them now */ + sti(); + slow_nodes = node; for (;;) { for (; node; node = node->next) node->handler(irq, node->dev_id, fp); - /* if reentrance occurred, serve slow handlers again */ - custom.intena = ami_intena_vals[irq]; + if (!server->reentrance) { server->count--; - custom.intena = IF_SETCLR | ami_intena_vals[irq]; + restore_flags(flags); + custom.intena = IF_SETCLR | intena; return; } + server->reentrance = 0; - custom.intena = IF_SETCLR | ami_intena_vals[irq]; node = slow_nodes; } } @@ -493,24 +522,13 @@ for (i = 0; i < AMI_STD_IRQS; i++) { if (!(node = ami_irq_list[i])) continue; - if (node->flags & IRQ_FLG_STD) - continue; len += sprintf(buf+len, "ami %2d: %10u ", i, kstat.irqs[0][SYS_IRQS + i]); do { - if (ami_servers[i]) { - if (node->flags & IRQ_FLG_FAST) - len += sprintf(buf+len, "F "); - else if (node->flags & IRQ_FLG_SLOW) - len += sprintf(buf+len, "S "); - else - len += sprintf(buf+len, " "); - } else { - if (node->flags & IRQ_FLG_LOCK) - len += sprintf(buf+len, "L "); - else - len += sprintf(buf+len, " "); - } + if (node->flags & SA_INTERRUPT) + len += sprintf(buf+len, "F "); + else + len += sprintf(buf+len, " "); len += sprintf(buf+len, "%s\n", node->devname); if ((node = node->next)) len += sprintf(buf+len, " "); diff -u --recursive --new-file v2.3.13/linux/arch/m68k/amiga/cia.c linux/arch/m68k/amiga/cia.c --- v2.3.13/linux/arch/m68k/amiga/cia.c Thu Feb 12 16:30:12 1998 +++ linux/arch/m68k/amiga/cia.c Sun Aug 15 11:47:29 1999 @@ -94,20 +94,6 @@ { u_char mask; - if (!(base->irq_list[irq].flags & IRQ_FLG_STD)) { - if (base->irq_list[irq].flags & IRQ_FLG_LOCK) { - printk("%s: IRQ %i from %s is not replaceable\n", - __FUNCTION__, base->cia_irq + irq, - base->irq_list[irq].devname); - return -EBUSY; - } - if (!(flags & IRQ_FLG_REPLACE)) { - printk("%s: %s can't replace IRQ %i from %s\n", __FUNCTION__, - devname, base->cia_irq + irq, - base->irq_list[irq].devname); - return -EBUSY; - } - } base->irq_list[irq].handler = handler; base->irq_list[irq].flags = flags; base->irq_list[irq].dev_id = dev_id; @@ -128,7 +114,7 @@ base->irq_list[irq].devname); base->irq_list[irq].handler = NULL; - base->irq_list[irq].flags = IRQ_FLG_STD; + base->irq_list[irq].flags = 0; cia_able_irq(base, 1 << irq); } @@ -153,14 +139,14 @@ amiga_do_irq_list(base->server_irq, fp, &base->server); } -__initfunc(void cia_init_IRQ(struct ciabase *base)) +void __init cia_init_IRQ(struct ciabase *base) { int i; /* init isr handlers */ for (i = 0; i < CIA_IRQS; i++) { base->irq_list[i].handler = NULL; - base->irq_list[i].flags = IRQ_FLG_STD; + base->irq_list[i].flags = 0; } /* clear any pending interrupt and turn off all interrupts */ @@ -168,7 +154,7 @@ cia_able_irq(base, CIA_ICR_ALL); /* install CIA handler */ - request_irq(base->handler_irq, cia_handler, IRQ_FLG_LOCK, base->name, base); + request_irq(base->handler_irq, cia_handler, 0, base->name, base); custom.intena = IF_SETCLR | base->int_mask; } @@ -179,15 +165,10 @@ j = base->cia_irq; for (i = 0; i < CIA_IRQS; i++) { - if (!(base->irq_list[i].flags & IRQ_FLG_STD)) { - len += sprintf(buf+len, "cia %2d: %10d ", j + i, - kstat.irqs[0][SYS_IRQS + j + i]); - if (base->irq_list[i].flags & IRQ_FLG_LOCK) - len += sprintf(buf+len, "L "); - else - len += sprintf(buf+len, " "); - len += sprintf(buf+len, "%s\n", base->irq_list[i].devname); - } + len += sprintf(buf+len, "cia %2d: %10d ", j + i, + kstat.irqs[0][SYS_IRQS + j + i]); + len += sprintf(buf+len, " "); + len += sprintf(buf+len, "%s\n", base->irq_list[i].devname); } return len; } diff -u --recursive --new-file v2.3.13/linux/arch/m68k/amiga/config.c linux/arch/m68k/amiga/config.c --- v2.3.13/linux/arch/m68k/amiga/config.c Tue Jan 19 10:58:26 1999 +++ linux/arch/m68k/amiga/config.c Sun Aug 15 11:47:29 1999 @@ -173,7 +173,7 @@ * Identify builtin hardware */ -__initfunc(static void amiga_identify(void)) +static void __init amiga_identify(void) { /* Fill in some default values, if necessary */ if (amiga_eclock == 0) @@ -334,7 +334,7 @@ * Setup the Amiga configuration info */ -__initfunc(void config_amiga(void)) +void __init config_amiga(void) { amiga_debug_init(); amiga_identify(); @@ -446,8 +446,8 @@ static unsigned short jiffy_ticks; -__initfunc(static void amiga_sched_init(void (*timer_routine)(int, void *, - struct pt_regs *))) +static void __init amiga_sched_init(void (*timer_routine)(int, void *, + struct pt_regs *)) { jiffy_ticks = (amiga_eclock+HZ/2)/HZ; @@ -460,8 +460,7 @@ * Please don't change this to use ciaa, as it interferes with the * SCSI code. We'll have to take a look at this later */ - request_irq(IRQ_AMIGA_CIAB_TA, timer_routine, IRQ_FLG_LOCK, - "timer", NULL); + request_irq(IRQ_AMIGA_CIAB_TA, timer_routine, 0, "timer", NULL); /* start timer */ ciab.cra |= 0x11; } @@ -880,7 +879,7 @@ } #endif -__initfunc(static void amiga_debug_init(void)) +static void __init amiga_debug_init(void) { if (!strcmp( m68k_debug_device, "ser" )) { /* no initialization required (?) */ diff -u --recursive --new-file v2.3.13/linux/arch/m68k/config.in linux/arch/m68k/config.in --- v2.3.13/linux/arch/m68k/config.in Mon Aug 9 14:59:19 1999 +++ linux/arch/m68k/config.in Sun Aug 15 11:47:29 1999 @@ -58,6 +58,13 @@ bool '68030 support' CONFIG_M68030 bool '68040 support' CONFIG_M68040 bool '68060 support' CONFIG_M68060 +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool 'Math emulation support' CONFIG_M68KFPU_EMU + if [ "$CONFIG_M68KFPU_EMU" = "y" ]; then + bool 'Math emulation extra precision' CONFIG_M68KFPU_EMU_EXTRAPREC + bool 'Math emulation only kernel' CONFIG_M68KFPU_EMU_ONLY + fi +fi bool 'Advanced configuration options' CONFIG_ADVANCED if [ "$CONFIG_ADVANCED" = "y" ]; then bool 'Use read-modify-write instructions' CONFIG_RMW_INSNS diff -u --recursive --new-file v2.3.13/linux/arch/m68k/kernel/entry.S linux/arch/m68k/kernel/entry.S --- v2.3.13/linux/arch/m68k/kernel/entry.S Mon Aug 9 14:59:19 1999 +++ linux/arch/m68k/kernel/entry.S Sun Aug 15 11:47:29 1999 @@ -164,6 +164,36 @@ addql #4,%sp jra 5b + +#if 0 +#if CONFIG_AMIGA +SYMBOL_NAME_LABEL(ami_inthandler) + addql #1,SYMBOL_NAME(local_irq_count) + SAVE_ALL_INT + GET_CURRENT(%d0) + + bfextu %sp@(PT_VECTOR){#4,#12},%d0 + movel %d0,%a0 + addql #1,%a0@(SYMBOL_NAME(kstat)+STAT_IRQ-VECOFF(VEC_SPUR)) + movel %a0@(SYMBOL_NAME(autoirq_list)-VECOFF(VEC_SPUR)),%a0 + +| amiga vector int handler get the req mask instead of irq vector + lea CUSTOMBASE,%a1 + movew %a1@(C_INTREQR),%d0 + andw %a1@(C_INTENAR),%d0 + +| prepare stack (push frame pointer, dev_id & req mask) + pea %sp@ + movel %a0@(IRQ_DEVID),%sp@- + movel %d0,%sp@- + pea %pc@(SYMBOL_NAME(ret_from_interrupt):w) + jbra @(IRQ_HANDLER,%a0)@(0) + +ENTRY(nmi_handler) + rte +#endif +#endif + /* ** This is the main interrupt handler, responsible for calling process_int() */ @@ -183,7 +213,7 @@ jbeq 1f jbsr SYMBOL_NAME(floppy_hardint) jbra 3f -1: +1: #endif jbsr SYMBOL_NAME(process_int)| process the IRQ 3: addql #8,%sp | pop parameters off stack @@ -191,7 +221,7 @@ SYMBOL_NAME_LABEL(ret_from_interrupt) subql #1,SYMBOL_NAME(local_irq_count) jeq 1f -2: +2: RESTORE_ALL 1: #if 1 @@ -295,6 +325,11 @@ movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save floating point context */ +#ifndef CONFIG_M68KFPU_EMU_ONLY +#ifdef CONFIG_M68KFPU_EMU + tstl SYMBOL_NAME(m68k_fputype) + jeq 3f +#endif fsave %a0@(TASK_THREAD+THREAD_FPSTATE) #if defined(CONFIG_M68060) @@ -316,6 +351,7 @@ 2: fmovemx %fp0-%fp7,%a0@(TASK_THREAD+THREAD_FPREG) fmoveml %fpcr/%fpsr/%fpiar,%a0@(TASK_THREAD+THREAD_FPCNTL) 3: +#endif /* CONFIG_M68KFPU_EMU_ONLY */ /* Return previous task in %d1 */ movel %curptr,%d1 @@ -323,7 +359,11 @@ movel %a1,%curptr /* restore floating point context */ - +#ifndef CONFIG_M68KFPU_EMU_ONLY +#ifdef CONFIG_M68KFPU_EMU + tstl SYMBOL_NAME(m68k_fputype) + jeq 4f +#endif #if defined(CONFIG_M68060) #if !defined(CPU_M68060_ONLY) btst #3,SYMBOL_NAME(m68k_cputype)+3 @@ -343,6 +383,8 @@ 2: fmovemx %a1@(TASK_THREAD+THREAD_FPREG),%fp0-%fp7 fmoveml %a1@(TASK_THREAD+THREAD_FPCNTL),%fpcr/%fpsr/%fpiar 3: frestore %a1@(TASK_THREAD+THREAD_FPSTATE) +4: +#endif /* CONFIG_M68KFPU_EMU_ONLY */ /* restore the kernel stack pointer */ movel %a1@(TASK_THREAD+THREAD_KSP),%sp diff -u --recursive --new-file v2.3.13/linux/arch/m68k/kernel/head.S linux/arch/m68k/kernel/head.S --- v2.3.13/linux/arch/m68k/kernel/head.S Tue May 11 09:57:14 1999 +++ linux/arch/m68k/kernel/head.S Sun Aug 15 11:47:29 1999 @@ -503,10 +503,18 @@ .macro puts string #if defined(CONSOLE) || defined(SERIAL_DEBUG) +/* The __INITDATA stuff is a no-op when ftrace or kgdb are turned on */ +#if defined(CONFIG_FTRACE) || defined(CONFIG_KGDB) + bra 1f +#endif __INITDATA .Lstr\@: .string "\string" __FINIT +#if defined(CONFIG_FTRACE) || defined(CONFIG_KGDB) + .align 2 +1: +#endif pea %pc@(.Lstr\@) func_call puts addql #4,%sp diff -u --recursive --new-file v2.3.13/linux/arch/m68k/kernel/ints.c linux/arch/m68k/kernel/ints.c --- v2.3.13/linux/arch/m68k/kernel/ints.c Wed May 12 08:50:00 1999 +++ linux/arch/m68k/kernel/ints.c Sun Aug 15 11:47:29 1999 @@ -86,14 +86,14 @@ * the IRQ handling routines. */ -__initfunc(void init_IRQ(void)) +void __init init_IRQ(void) { int i; for (i = 0; i < SYS_IRQS; i++) { if (mach_default_handler) irq_list[i].handler = (*mach_default_handler)[i]; - irq_list[i].flags = IRQ_FLG_STD; + irq_list[i].flags = 0; irq_list[i].dev_id = NULL; irq_list[i].devname = default_names[i]; } @@ -144,6 +144,7 @@ return -ENXIO; } +#if 0 if (!(irq_list[irq].flags & IRQ_FLG_STD)) { if (irq_list[irq].flags & IRQ_FLG_LOCK) { printk("%s: IRQ %d from %s is not replaceable\n", @@ -156,6 +157,8 @@ return -EBUSY; } } +#endif + irq_list[irq].handler = handler; irq_list[irq].flags = flags; irq_list[irq].dev_id = dev_id; @@ -175,7 +178,7 @@ __FUNCTION__, irq, irq_list[irq].devname); irq_list[irq].handler = (*mach_default_handler)[irq]; - irq_list[irq].flags = IRQ_FLG_STD; + irq_list[irq].flags = 0; irq_list[irq].dev_id = NULL; irq_list[irq].devname = default_names[irq]; } @@ -250,9 +253,6 @@ for (i = 0; i < SYS_IRQS; i++) { len += sprintf(buf+len, "auto %2d: %10u ", i, i ? kstat.irqs[0][i] : num_spurious); - if (irq_list[i].flags & IRQ_FLG_LOCK) - len += sprintf(buf+len, "L "); - else len += sprintf(buf+len, " "); len += sprintf(buf+len, "%s\n", irq_list[i].devname); } diff -u --recursive --new-file v2.3.13/linux/arch/m68k/kernel/m68k_defs.h linux/arch/m68k/kernel/m68k_defs.h --- v2.3.13/linux/arch/m68k/kernel/m68k_defs.h Tue May 11 09:57:14 1999 +++ linux/arch/m68k/kernel/m68k_defs.h Sun Aug 15 11:47:29 1999 @@ -7,19 +7,29 @@ #define TASK_FLAGS 4 #define TASK_SIGPENDING 8 #define TASK_NEEDRESCHED 20 -#define TASK_TSS 470 -#define TASK_MM 622 -#define TSS_KSP 0 -#define TSS_USP 4 -#define TSS_SR 8 -#define TSS_FS 10 -#define TSS_CRP 12 -#define TSS_ESP0 20 -#define TSS_FPREG 24 -#define TSS_FPCNTL 120 -#define TSS_FPSTATE 132 +#define TASK_THREAD 482 +#define TASK_MM 634 +#define TASK_ACTIVE_MM 638 +#define THREAD_KSP 0 +#define THREAD_USP 4 +#define THREAD_SR 8 +#define THREAD_FS 10 +#define THREAD_CRP 12 +#define THREAD_ESP0 20 +#define THREAD_FPREG 24 +#define THREAD_FPCNTL 120 +#define THREAD_FPSTATE 132 #define PT_D0 32 #define PT_ORIG_D0 36 +#define PT_D1 0 +#define PT_D2 4 +#define PT_D3 8 +#define PT_D4 12 +#define PT_D5 16 +#define PT_A0 20 +#define PT_A1 24 +#define PT_A2 28 +#define PT_PC 46 #define PT_SR 44 #define PT_VECTOR 50 #define IRQ_HANDLER 0 @@ -35,6 +45,10 @@ #define FBCON_FONT_DESC_HEIGHT 12 #define FBCON_FONT_DESC_DATA 16 #define FBCON_FONT_DESC_PREF 20 +#define SIGSEGV 11 +#define SEGV_MAPERR 1 +#define SIGTRAP 5 +#define TRAP_TRACE 2 #define CUSTOMBASE -2132807680 #define C_INTENAR 28 #define C_INTREQR 30 diff -u --recursive --new-file v2.3.13/linux/arch/m68k/kernel/process.c linux/arch/m68k/kernel/process.c --- v2.3.13/linux/arch/m68k/kernel/process.c Mon Aug 9 14:59:19 1999 +++ linux/arch/m68k/kernel/process.c Sun Aug 15 11:47:29 1999 @@ -58,7 +58,7 @@ { while(1) { if (!current->need_resched) -#ifdef MACH_ATARI_ONLY +#if defined(MACH_ATARI_ONLY) && !defined(CONFIG_HADES) /* block out HSYNC on the atari (falcon) */ __asm__("stop #0x2200" : : : "cc"); #else @@ -161,9 +161,10 @@ unsigned long zero = 0; set_fs(USER_DS); current->thread.fs = __USER_DS; - asm volatile (".chip 68k/68881\n\t" - "frestore %0@\n\t" - ".chip 68k" : : "a" (&zero)); + if (!FPU_IS_EMU) + asm volatile (".chip 68k/68881\n\t" + "frestore %0@\n\t" + ".chip 68k" : : "a" (&zero)); } /* @@ -224,16 +225,18 @@ */ p->thread.fs = get_fs().seg; - /* Copy the current fpu state */ - asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory"); - - if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2]) - asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t" - "fmoveml %/fpiar/%/fpcr/%/fpsr,%1" - : : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0]) - : "memory"); - /* Restore the state in case the fpu was busy */ - asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0])); + if (!FPU_IS_EMU) { + /* Copy the current fpu state */ + asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory"); + + if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2]) + asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t" + "fmoveml %/fpiar/%/fpcr/%/fpsr,%1" + : : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0]) + : "memory"); + /* Restore the state in case the fpu was busy */ + asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0])); + } return 0; } @@ -244,18 +247,32 @@ { char fpustate[216]; - /* First dump the fpu context to avoid protocol violation. */ - asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory"); - if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2]) - return 0; + if (FPU_IS_EMU) { + int i; + + memcpy(fpu->fpcntl, current->thread.fpcntl, 12); + memcpy(fpu->fpregs, current->thread.fp, 96); + /* Convert internal fpu reg representation + * into long double format + */ + for (i = 0; i < 24; i += 3) + fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) | + ((fpu->fpregs[i] & 0x0000ffff) << 16); + return 1; + } + + /* First dump the fpu context to avoid protocol violation. */ + asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory"); + if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2]) + return 0; - asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0" + asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0" :: "m" (fpu->fpcntl[0]) : "memory"); - asm volatile ("fmovemx %/fp0-%/fp7,%0" + asm volatile ("fmovemx %/fp0-%/fp7,%0" :: "m" (fpu->fpregs[0]) : "memory"); - return 1; + return 1; } /* diff -u --recursive --new-file v2.3.13/linux/arch/m68k/kernel/ptrace.c linux/arch/m68k/kernel/ptrace.c --- v2.3.13/linux/arch/m68k/kernel/ptrace.c Mon Aug 9 14:59:19 1999 +++ linux/arch/m68k/kernel/ptrace.c Sun Aug 15 11:47:29 1999 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -384,10 +385,17 @@ tmp = get_reg(child, addr); if (addr == PT_SR) tmp >>= 16; - } - else if (addr >= 21 && addr < 49) + } else if (addr >= 21 && addr < 49) { tmp = child->thread.fp[addr - 21]; - else +#ifdef CONFIG_M68KFPU_EMU + /* Convert internal fpu reg representation + * into long double format + */ + if (FPU_IS_EMU && (addr < 45) && !(addr % 3)) + tmp = ((tmp & 0xffff0000) << 15) | + ((tmp & 0x0000ffff) << 16); +#endif + } else goto out; ret = put_user(tmp,(unsigned long *) data); goto out; @@ -423,6 +431,16 @@ } if (addr >= 21 && addr < 48) { +#ifdef CONFIG_M68KFPU_EMU + /* Convert long double format + * into internal fpu reg representation + */ + if (FPU_IS_EMU && (addr < 45) && !(addr % 3)) { + data = (unsigned long)data << 15; + data = (data & 0xffff0000) | + ((data & 0x0000ffff) >> 1); + } +#endif child->thread.fp[addr - 21] = data; ret = 0; } diff -u --recursive --new-file v2.3.13/linux/arch/m68k/kernel/signal.c linux/arch/m68k/kernel/signal.c --- v2.3.13/linux/arch/m68k/kernel/signal.c Mon Aug 9 14:59:19 1999 +++ linux/arch/m68k/kernel/signal.c Sun Aug 15 11:47:29 1999 @@ -14,6 +14,10 @@ * 68060 fixes by Jesper Skov * * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab + * + * mathemu support by Roman Zippel + * (Note: fpstate in the signal context is completly ignored for the emulator + * and the internal floating point format is put on stack) */ /* @@ -190,6 +194,13 @@ { int err = 1; + if (FPU_IS_EMU) { + /* restore registers */ + memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12); + memcpy(current->thread.fp, sc->sc_fpregs, 24); + return 0; + } + if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { /* Verify the frame format. */ if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version)) @@ -242,6 +253,18 @@ fpregset_t fpregs; int err = 1; + if (FPU_IS_EMU) { + /* restore fpu control register */ + if (__copy_from_user(current->thread.fpcntl, + &uc->uc_mcontext.fpregs.f_pcr, 12)) + goto out; + /* restore all other fpu register */ + if (__copy_from_user(current->thread.fp, + uc->uc_mcontext.fpregs.f_fpregs, 96)) + goto out; + return 0; + } + if (__get_user(*(long *)fpstate, (long *)&uc->uc_fpstate)) goto out; if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { @@ -539,6 +562,13 @@ static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs) { + if (FPU_IS_EMU) { + /* save registers */ + memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12); + memcpy(sc->sc_fpregs, current->thread.fp, 24); + return; + } + __asm__ volatile (".chip 68k/68881\n\t" "fsave %0\n\t" ".chip 68k" @@ -569,6 +599,16 @@ unsigned char fpstate[FPCONTEXT_SIZE]; int context_size = CPU_IS_060 ? 8 : 0; int err = 0; + + if (FPU_IS_EMU) { + /* save fpu control register */ + err |= copy_to_user(&uc->uc_mcontext.fpregs.f_pcr, + current->thread.fpcntl, 12); + /* save all other fpu register */ + err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs, + current->thread.fp, 96); + return err; + } __asm__ volatile (".chip 68k/68881\n\t" "fsave %0\n\t" diff -u --recursive --new-file v2.3.13/linux/arch/m68k/kernel/traps.c linux/arch/m68k/kernel/traps.c --- v2.3.13/linux/arch/m68k/kernel/traps.c Mon Aug 9 14:59:19 1999 +++ linux/arch/m68k/kernel/traps.c Sun Aug 15 11:47:29 1999 @@ -47,6 +47,7 @@ asmlinkage void trap(void); asmlinkage void inthandler(void); asmlinkage void nmihandler(void); +asmlinkage void fpu_emu(void); e_vector vectors[256] = { 0, 0, buserr, trap, trap, trap, trap, trap, @@ -65,12 +66,12 @@ __ALIGN_STR "\n" SYMBOL_NAME_STR(nmihandler) ": rte"); -__initfunc(void base_trap_init(void)) +void __init base_trap_init(void) { /* setup the exception vector table */ __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors)); - if (CPU_IS_040) { + if (CPU_IS_040 && !FPU_IS_EMU) { /* set up FPSP entry points */ asmlinkage void dz_vec(void) asm ("dz"); asmlinkage void inex_vec(void) asm ("inex"); @@ -93,6 +94,12 @@ vectors[VEC_FPUNSUP] = unsupp_vec; } if (CPU_IS_060) { + /* set up ISP entry points */ + asmlinkage void unimp_vec(void) asm ("_060_isp_unimp"); + + vectors[VEC_UNIMPII] = unimp_vec; + } + if (CPU_IS_060 && !FPU_IS_EMU) { /* set up IFPSP entry points */ asmlinkage void snan_vec(void) asm ("_060_fpsp_snan"); asmlinkage void operr_vec(void) asm ("_060_fpsp_operr"); @@ -104,8 +111,6 @@ asmlinkage void unsupp_vec(void) asm ("_060_fpsp_unsupp"); asmlinkage void effadd_vec(void) asm ("_060_fpsp_effadd"); - asmlinkage void unimp_vec(void) asm ("_060_isp_unimp"); - vectors[VEC_FPNAN] = snan_vec; vectors[VEC_FPOE] = operr_vec; vectors[VEC_FPOVER] = ovfl_vec; @@ -115,14 +120,10 @@ vectors[VEC_LINE11] = fline_vec; vectors[VEC_FPUNSUP] = unsupp_vec; vectors[VEC_UNIMPEA] = effadd_vec; - - /* set up ISP entry points */ - - vectors[VEC_UNIMPII] = unimp_vec; } } -__initfunc(void trap_init (void)) +void __init trap_init (void) { int i; @@ -133,18 +134,17 @@ for (i = 64; i < 256; i++) vectors[i] = inthandler; +#ifdef CONFIG_M68KFPU_EMU + if (FPU_IS_EMU) + vectors[VEC_LINE11] = fpu_emu; +#endif + /* if running on an amiga, make the NMI interrupt do nothing */ if (MACH_IS_AMIGA) { vectors[VEC_INT7] = nmihandler; } } -void set_evector(int vecnum, void (*handler)(void)) -{ - if (vecnum >= 0 && vecnum <= 256) - vectors[vecnum] = handler; -} - static inline void console_verbose(void) { @@ -152,6 +152,7 @@ console_loglevel = 15; } + static char *vec_names[] = { "RESET SP", "RESET PC", "BUS ERROR", "ADDRESS ERROR", "ILLEGAL INSTRUCTION", "ZERO DIVIDE", "CHK", "TRAPcc", @@ -180,7 +181,6 @@ }; - void die_if_kernel(char *,struct pt_regs *,int); asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, unsigned long error_code); @@ -507,44 +507,6 @@ else asm volatile ("ploadr %1,%0@" : /* no outputs */ : "a" (addr), "d" (ssw)); - -#if 0 - /* If this was a data fault due to an invalid page and a - prefetch is pending on the same page, simulate it (but - only if the page is now valid). Otherwise we'll get an - weird insn access. */ - if ((ssw & RB) && (mmusr & MMU_I)) - { - unsigned long iaddr; - - if ((fp->ptregs.format) == 0xB) - iaddr = fp->un.fmtb.baddr; - else - iaddr = fp->ptregs.pc + 4; - if (((addr ^ iaddr) & PAGE_MASK) == 0) - { - /* We only need to check the ATC as the entry has - already been set up above. */ - asm volatile ("ptestr #1,%1@,#0\n\t" - "pmove %/psr,%0@" - : : "a" (&temp), "a" (iaddr)); - mmusr = temp; -#ifdef DEBUG - printk ("prefetch iaddr=%#lx ssw=%#x mmusr=%#x\n", - iaddr, ssw, mmusr); -#endif - if (!(mmusr & MMU_I)) - { - unsigned short insn; - asm volatile ("movesw %1@,%0" - : "=r" (insn) - : "a" (iaddr)); - fp->un.fmtb.isb = insn; - fp->un.fmtb.ssw &= ~RB; - } - } - } -#endif } /* Now handle the instruction fault. */ @@ -598,43 +560,6 @@ die_if_kernel("Oops",&fp->ptregs,mmusr); force_sig(SIGSEGV, current); return; - } else { -#if 0 /* stale ATC entry?? Ignore it */ - -#ifdef DEBUG - static volatile long tlong; -#endif - - printk ("weird insn access at %#lx from pc %#lx (ssw is %#x)\n", - addr, fp->ptregs.pc, ssw); - asm volatile ("ptestr #1,%1@,#0\n\t" - "pmove %/psr,%0@" - : /* no outputs */ - : "a" (&temp), "a" (addr)); - mmusr = temp; - - printk ("level 0 mmusr is %#x\n", mmusr); -#ifdef DEBUG - if (m68k_cputype & CPU_68030) { - asm volatile ("pmove %/tt0,%0@" - : /* no outputs */ - : "a" (&tlong)); - printk ("tt0 is %#lx, ", tlong); - asm volatile ("pmove %/tt1,%0@" - : /* no outputs */ - : "a" (&tlong)); - printk ("tt1 is %#lx\n", tlong); - } - -#endif - -#if DEBUG - printk("Unknown SIGSEGV - 3\n"); -#endif - die_if_kernel("Oops",&fp->ptregs,mmusr); - force_sig(SIGSEGV, current); - return; -#endif } create_atc_entry: @@ -990,3 +915,16 @@ { do_exit(SIGSEGV); } + +#ifdef CONFIG_M68KFPU_EMU +asmlinkage void fpemu_signal(int signal, int code, void *addr) +{ + siginfo_t info; + + info.si_signo = signal; + info.si_errno = 0; + info.si_code = code; + info.si_addr = addr; + force_sig_info(signal, &info, current); +} +#endif diff -u --recursive --new-file v2.3.13/linux/arch/m68k/math-emu/Makefile linux/arch/m68k/math-emu/Makefile --- v2.3.13/linux/arch/m68k/math-emu/Makefile Wed Dec 31 16:00:00 1969 +++ linux/arch/m68k/math-emu/Makefile Sun Aug 15 11:47:29 1999 @@ -0,0 +1,19 @@ +# +# Makefile for the linux kernel. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile... + +.S.o: + $(CC) $(EXTRA_CFLAGS) -D__ASSEMBLY__ -traditional -c $< -o $*.o + +#EXTRA_CFLAGS=-DFPU_EMU_DEBUG + +O_TARGET := mathemu.o +O_OBJS := fp_entry.o fp_scan.o fp_util.o fp_move.o fp_movem.o \ + fp_cond.o fp_arith.o fp_log.o fp_trig.o + +include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.3.13/linux/arch/m68k/math-emu/fp_arith.c linux/arch/m68k/math-emu/fp_arith.c --- v2.3.13/linux/arch/m68k/math-emu/fp_arith.c Wed Dec 31 16:00:00 1969 +++ linux/arch/m68k/math-emu/fp_arith.c Sun Aug 15 11:47:29 1999 @@ -0,0 +1,700 @@ +/* + + fp_arith.c: floating-point math routines for the Linux-m68k + floating point emulator. + + Copyright (c) 1998-1999 David Huggins-Daines. + + Somewhat based on the AlphaLinux floating point emulator, by David + Mosberger-Tang. + + You may copy, modify, and redistribute this file under the terms of + the GNU General Public License, version 2, or any later version, at + your convenience. + */ + +#include "fp_emu.h" +#include "multi_arith.h" +#include "fp_arith.h" + +const struct fp_ext fp_QNaN = +{ + 0, 0, 0x7fff, { ~0 } +}; + +const struct fp_ext fp_Inf = +{ + 0, 0, 0x7fff, { 0 } +}; + +/* let's start with the easy ones */ + +struct fp_ext * +fp_fabs(struct fp_ext *dest, struct fp_ext *src) +{ + dprint(PINSTR, "fabs\n"); + + fp_monadic_check(dest, src); + + dest->sign = 0; + + return dest; +} + +struct fp_ext * +fp_fneg(struct fp_ext *dest, struct fp_ext *src) +{ + dprint(PINSTR, "fneg\n"); + + fp_monadic_check(dest, src); + + dest->sign = !dest->sign; + + return dest; +} + +/* Now, the slightly harder ones */ + +/* fp_fadd: Implements the kernel of the FADD, FSADD, FDADD, FSUB, + FDSUB, and FCMP instructions. */ + +struct fp_ext * +fp_fadd(struct fp_ext *dest, struct fp_ext *src) +{ + int diff; + + dprint(PINSTR, "fadd\n"); + + fp_dyadic_check(dest, src); + + if (IS_INF(dest)) { + /* infinity - infinity == NaN */ + if (IS_INF(src) && (src->sign != dest->sign)) + fp_set_nan(dest); + return dest; + } + if (IS_INF(src)) { + fp_copy_ext(dest, src); + return dest; + } + + if (IS_ZERO(dest)) { + if (IS_ZERO(src)) { + if (src->sign != dest->sign) { + if (FPDATA->rnd == FPCR_ROUND_RM) + dest->sign = 1; + else + dest->sign = 0; + } + } else + fp_copy_ext(dest, src); + return dest; + } + + dest->lowmant = src->lowmant = 0; + + if ((diff = dest->exp - src->exp) > 0) + fp_denormalize(src, diff); + else if ((diff = -diff) > 0) + fp_denormalize(dest, diff); + + if (dest->sign == src->sign) { + if (fp_addmant(dest, src)) + if (!fp_addcarry(dest)) + return dest; + } else { + if (dest->mant.m64 < src->mant.m64) { + fp_submant(dest, src, dest); + dest->sign = !dest->sign; + } else + fp_submant(dest, dest, src); + } + + return dest; +} + +/* fp_fsub: Implementes the kernel of the FSUB, FSSUB, and FDSUB + instructions. + + Remember that the arguments are in assembler-syntax order! */ + +struct fp_ext * +fp_fsub(struct fp_ext *dest, struct fp_ext *src) +{ + dprint(PINSTR, "fsub "); + + src->sign = !src->sign; + return fp_fadd(dest, src); +} + + +struct fp_ext * +fp_fcmp(struct fp_ext *dest, struct fp_ext *src) +{ + dprint(PINSTR, "fcmp "); + + FPDATA->temp[1] = *dest; + src->sign = !src->sign; + return fp_fadd(&FPDATA->temp[1], src); +} + +struct fp_ext * +fp_ftst(struct fp_ext *dest, struct fp_ext *src) +{ + dprint(PINSTR, "ftst\n"); + + (void)dest; + + return src; +} + +struct fp_ext * +fp_fmul(struct fp_ext *dest, struct fp_ext *src) +{ + union fp_mant128 temp; + int exp; + + dprint(PINSTR, "fmul\n"); + + fp_dyadic_check(dest, src); + + /* calculate the correct sign now, as it's necessary for infinities */ + dest->sign = src->sign ^ dest->sign; + + /* Handle infinities */ + if (IS_INF(dest)) { + if (IS_ZERO(src)) + fp_set_nan(dest); + return dest; + } + if (IS_INF(src)) { + if (IS_ZERO(dest)) + fp_set_nan(dest); + else + fp_copy_ext(dest, src); + return dest; + } + + /* Of course, as we all know, zero * anything = zero. You may + not have known that it might be a positive or negative + zero... */ + if (IS_ZERO(dest) || IS_ZERO(src)) { + dest->exp = 0; + dest->mant.m64 = 0; + dest->lowmant = 0; + + return dest; + } + + exp = dest->exp + src->exp - 0x3ffe; + + /* shift up the mantissa for denormalized numbers, + so that the highest bit is set, this makes the + shift of the result below easier */ + if ((long)dest->mant.m32[0] >= 0) + exp -= fp_overnormalize(dest); + if ((long)src->mant.m32[0] >= 0) + exp -= fp_overnormalize(src); + + /* now, do a 64-bit multiply with expansion */ + fp_multiplymant(&temp, dest, src); + + /* normalize it back to 64 bits and stuff it back into the + destination struct */ + if ((long)temp.m32[0] > 0) { + exp--; + fp_putmant128(dest, &temp, 1); + } else + fp_putmant128(dest, &temp, 0); + + if (exp >= 0x7fff) { + fp_set_ovrflw(dest); + return dest; + } + dest->exp = exp; + if (exp < 0) { + fp_set_sr(FPSR_EXC_UNFL); + fp_denormalize(dest, -exp); + } + + return dest; +} + +/* fp_fdiv: Implements the "kernel" of the FDIV, FSDIV, FDDIV and + FSGLDIV instructions. + + Note that the order of the operands is counter-intuitive: instead + of src / dest, the result is actually dest / src. */ + +struct fp_ext * +fp_fdiv(struct fp_ext *dest, struct fp_ext *src) +{ + union fp_mant128 temp; + int exp; + + dprint(PINSTR, "fdiv\n"); + + fp_dyadic_check(dest, src); + + /* calculate the correct sign now, as it's necessary for infinities */ + dest->sign = src->sign ^ dest->sign; + + /* Handle infinities */ + if (IS_INF(dest)) { + /* infinity / infinity = NaN (quiet, as always) */ + if (IS_INF(src)) + fp_set_nan(dest); + /* infinity / anything else = infinity (with approprate sign) */ + return dest; + } + if (IS_INF(src)) { + /* anything / infinity = zero (with appropriate sign) */ + dest->exp = 0; + dest->mant.m64 = 0; + dest->lowmant = 0; + + return dest; + } + + /* zeroes */ + if (IS_ZERO(dest)) { + /* zero / zero = NaN */ + if (IS_ZERO(src)) + fp_set_nan(dest); + /* zero / anything else = zero */ + return dest; + } + if (IS_ZERO(src)) { + /* anything / zero = infinity (with appropriate sign) */ + fp_set_sr(FPSR_EXC_DZ); + dest->exp = 0x7fff; + dest->mant.m64 = 0; + + return dest; + } + + exp = dest->exp - src->exp + 0x3fff; + + /* shift up the mantissa for denormalized numbers, + so that the highest bit is set, this makes lots + of things below easier */ + if ((long)dest->mant.m32[0] >= 0) + exp -= fp_overnormalize(dest); + if ((long)src->mant.m32[0] >= 0) + exp -= fp_overnormalize(src); + + /* now, do the 64-bit divide */ + fp_dividemant(&temp, dest, src); + + /* normalize it back to 64 bits and stuff it back into the + destination struct */ + if (!temp.m32[0]) { + exp--; + fp_putmant128(dest, &temp, 32); + } else + fp_putmant128(dest, &temp, 31); + + if (exp >= 0x7fff) { + fp_set_ovrflw(dest); + return dest; + } + dest->exp = exp; + if (exp < 0) { + fp_set_sr(FPSR_EXC_UNFL); + fp_denormalize(dest, -exp); + } + + return dest; +} + +struct fp_ext * +fp_fsglmul(struct fp_ext *dest, struct fp_ext *src) +{ + int exp; + + dprint(PINSTR, "fsglmul\n"); + + fp_dyadic_check(dest, src); + + /* calculate the correct sign now, as it's necessary for infinities */ + dest->sign = src->sign ^ dest->sign; + + /* Handle infinities */ + if (IS_INF(dest)) { + if (IS_ZERO(src)) + fp_set_nan(dest); + return dest; + } + if (IS_INF(src)) { + if (IS_ZERO(dest)) + fp_set_nan(dest); + else + fp_copy_ext(dest, src); + return dest; + } + + /* Of course, as we all know, zero * anything = zero. You may + not have known that it might be a positive or negative + zero... */ + if (IS_ZERO(dest) || IS_ZERO(src)) { + dest->exp = 0; + dest->mant.m64 = 0; + dest->lowmant = 0; + + return dest; + } + + exp = dest->exp + src->exp - 0x3ffe; + + /* do a 32-bit multiply */ + fp_mul64(dest->mant.m32[0], dest->mant.m32[1], + dest->mant.m32[0] & 0xffffff00, + src->mant.m32[0] & 0xffffff00); + + if (exp >= 0x7fff) { + fp_set_ovrflw(dest); + return dest; + } + dest->exp = exp; + if (exp < 0) { + fp_set_sr(FPSR_EXC_UNFL); + fp_denormalize(dest, -exp); + } + + return dest; +} + +struct fp_ext * +fp_fsgldiv(struct fp_ext *dest, struct fp_ext *src) +{ + int exp; + unsigned long quot, rem; + + dprint(PINSTR, "fsgldiv\n"); + + fp_dyadic_check(dest, src); + + /* calculate the correct sign now, as it's necessary for infinities */ + dest->sign = src->sign ^ dest->sign; + + /* Handle infinities */ + if (IS_INF(dest)) { + /* infinity / infinity = NaN (quiet, as always) */ + if (IS_INF(src)) + fp_set_nan(dest); + /* infinity / anything else = infinity (with approprate sign) */ + return dest; + } + if (IS_INF(src)) { + /* anything / infinity = zero (with appropriate sign) */ + dest->exp = 0; + dest->mant.m64 = 0; + dest->lowmant = 0; + + return dest; + } + + /* zeroes */ + if (IS_ZERO(dest)) { + /* zero / zero = NaN */ + if (IS_ZERO(src)) + fp_set_nan(dest); + /* zero / anything else = zero */ + return dest; + } + if (IS_ZERO(src)) { + /* anything / zero = infinity (with appropriate sign) */ + fp_set_sr(FPSR_EXC_DZ); + dest->exp = 0x7fff; + dest->mant.m64 = 0; + + return dest; + } + + exp = dest->exp - src->exp + 0x3fff; + + dest->mant.m32[0] &= 0xffffff00; + src->mant.m32[0] &= 0xffffff00; + + /* do the 32-bit divide */ + if (dest->mant.m32[0] >= src->mant.m32[0]) { + fp_sub64(dest->mant, src->mant); + fp_div64(quot, rem, dest->mant.m32[0], 0, src->mant.m32[0]); + dest->mant.m32[0] = 0x80000000 | (quot >> 1); + dest->mant.m32[1] = (quot & 1) | rem; /* only for rounding */ + } else { + fp_div64(quot, rem, dest->mant.m32[0], 0, src->mant.m32[0]); + dest->mant.m32[0] = quot; + dest->mant.m32[1] = rem; /* only for rounding */ + exp--; + } + + if (exp >= 0x7fff) { + fp_set_ovrflw(dest); + return dest; + } + dest->exp = exp; + if (exp < 0) { + fp_set_sr(FPSR_EXC_UNFL); + fp_denormalize(dest, -exp); + } + + return dest; +} + +/* fp_roundint: Internal rounding function for use by several of these + emulated instructions. + + This one rounds off the fractional part using the rounding mode + specified. */ + +static void fp_roundint(struct fp_ext *dest, int mode) +{ + union fp_mant64 oldmant; + unsigned long mask; + + if (!fp_normalize_ext(dest)) + return; + + /* infinities and zeroes */ + if (IS_INF(dest) || IS_ZERO(dest)) + return; + + /* first truncate the lower bits */ + oldmant = dest->mant; + switch (dest->exp) { + case 0 ... 0x3ffe: + dest->mant.m64 = 0; + break; + case 0x3fff ... 0x401e: + dest->mant.m32[0] &= 0xffffffffU << (0x401e - dest->exp); + dest->mant.m32[1] = 0; + if (oldmant.m64 == dest->mant.m64) + return; + break; + case 0x401f ... 0x403e: + dest->mant.m32[1] &= 0xffffffffU << (0x403e - dest->exp); + if (oldmant.m32[1] == dest->mant.m32[1]) + return; + break; + default: + return; + } + fp_set_sr(FPSR_EXC_INEX2); + + /* We might want to normalize upwards here... however, since + we know that this is only called on the output of fp_fdiv, + or with the input to fp_fint or fp_fintrz, and the inputs + to all these functions are either normal or denormalized + (no subnormals allowed!), there's really no need. + + In the case of fp_fdiv, observe that 0x80000000 / 0xffff = + 0xffff8000, and the same holds for 128-bit / 64-bit. (i.e. the + smallest possible normal dividend and the largest possible normal + divisor will still produce a normal quotient, therefore, (normal + << 64) / normal is normal in all cases) */ + + switch (mode) { + case FPCR_ROUND_RN: + switch (dest->exp) { + case 0 ... 0x3ffd: + return; + case 0x3ffe: + /* As noted above, the input is always normal, so the + guard bit (bit 63) is always set. therefore, the + only case in which we will NOT round to 1.0 is when + the input is exactly 0.5. */ + if (oldmant.m64 == (1ULL << 63)) + return; + break; + case 0x3fff ... 0x401d: + mask = 1 << (0x401d - dest->exp); + if (!(oldmant.m32[0] & mask)) + return; + if (oldmant.m32[0] & (mask << 1)) + break; + if (!(oldmant.m32[0] << (dest->exp - 0x3ffd)) && + !oldmant.m32[1]) + return; + break; + case 0x401e: + if (!(oldmant.m32[1] >= 0)) + return; + if (oldmant.m32[0] & 1) + break; + if (!(oldmant.m32[1] << 1)) + return; + break; + case 0x401f ... 0x403d: + mask = 1 << (0x403d - dest->exp); + if (!(oldmant.m32[1] & mask)) + return; + if (oldmant.m32[1] & (mask << 1)) + break; + if (!(oldmant.m32[1] << (dest->exp - 0x401d))) + return; + break; + default: + return; + } + break; + case FPCR_ROUND_RZ: + return; + default: + if (dest->sign ^ (mode - FPCR_ROUND_RM)) + break; + return; + } + + switch (dest->exp) { + case 0 ... 0x3ffe: + dest->exp = 0x3fff; + dest->mant.m64 = 1ULL << 63; + break; + case 0x3fff ... 0x401e: + mask = 1 << (0x401e - dest->exp); + if (dest->mant.m32[0] += mask) + break; + dest->mant.m32[0] = 0x80000000; + dest->exp++; + break; + case 0x401f ... 0x403e: + mask = 1 << (0x403e - dest->exp); + if (dest->mant.m32[1] += mask) + break; + if (dest->mant.m32[0] += 1) + break; + dest->mant.m32[0] = 0x80000000; + dest->exp++; + break; + } +} + +/* modrem_kernel: Implementation of the FREM and FMOD instructions + (which are exactly the same, except for the rounding used on the + intermediate value) */ + +static struct fp_ext * +modrem_kernel(struct fp_ext *dest, struct fp_ext *src, int mode) +{ + struct fp_ext tmp; + + fp_dyadic_check(dest, src); + + /* Infinities and zeros */ + if (IS_INF(dest) || IS_ZERO(src)) { + fp_set_nan(dest); + return dest; + } + if (IS_ZERO(dest) || IS_INF(src)) + return dest; + + /* FIXME: there is almost certainly a smarter way to do this */ + fp_copy_ext(&tmp, dest); + fp_fdiv(&tmp, src); /* NOTE: src might be modified */ + fp_roundint(&tmp, mode); + fp_fmul(&tmp, src); + fp_fsub(dest, &tmp); + + /* set the quotient byte */ + fp_set_quotient((dest->mant.m64 & 0x7f) | (dest->sign << 7)); + return dest; +} + +/* fp_fmod: Implements the kernel of the FMOD instruction. + + Again, the argument order is backwards. The result, as defined in + the Motorola manuals, is: + + fmod(src,dest) = (dest - (src * floor(dest / src))) */ + +struct fp_ext * +fp_fmod(struct fp_ext *dest, struct fp_ext *src) +{ + dprint(PINSTR, "fmod\n"); + return modrem_kernel(dest, src, FPCR_ROUND_RZ); +} + +/* fp_frem: Implements the kernel of the FREM instruction. + + frem(src,dest) = (dest - (src * round(dest / src))) + */ + +struct fp_ext * +fp_frem(struct fp_ext *dest, struct fp_ext *src) +{ + dprint(PINSTR, "frem\n"); + return modrem_kernel(dest, src, FPCR_ROUND_RN); +} + +struct fp_ext * +fp_fint(struct fp_ext *dest, struct fp_ext *src) +{ + dprint(PINSTR, "fint\n"); + + fp_copy_ext(dest, src); + + fp_roundint(dest, FPDATA->rnd); + + return dest; +} + +struct fp_ext * +fp_fintrz(struct fp_ext *dest, struct fp_ext *src) +{ + dprint(PINSTR, "fintrz\n"); + + fp_copy_ext(dest, src); + + fp_roundint(dest, FPCR_ROUND_RZ); + + return dest; +} + +struct fp_ext * +fp_fscale(struct fp_ext *dest, struct fp_ext *src) +{ + int scale, oldround; + + dprint(PINSTR, "fscale\n"); + + fp_dyadic_check(dest, src); + + /* Infinities */ + if (IS_INF(src)) { + fp_set_nan(dest); + return dest; + } + if (IS_INF(dest)) + return dest; + + /* zeroes */ + if (IS_ZERO(src) || IS_ZERO(dest)) + return dest; + + /* Source exponent out of range */ + if (src->exp >= 0x400c) { + fp_set_ovrflw(dest); + return dest; + } + + /* src must be rounded with round to zero. */ + oldround = FPDATA->rnd; + FPDATA->rnd = FPCR_ROUND_RZ; + scale = fp_conv_ext2long(src); + FPDATA->rnd = oldround; + + /* new exponent */ + scale += dest->exp; + + if (scale >= 0x7fff) { + fp_set_ovrflw(dest); + } else if (scale <= 0) { + fp_set_sr(FPSR_EXC_UNFL); + fp_denormalize(dest, -scale); + } else + dest->exp = scale; + + return dest; +} + diff -u --recursive --new-file v2.3.13/linux/arch/m68k/math-emu/fp_arith.h linux/arch/m68k/math-emu/fp_arith.h --- v2.3.13/linux/arch/m68k/math-emu/fp_arith.h Wed Dec 31 16:00:00 1969 +++ linux/arch/m68k/math-emu/fp_arith.h Sun Aug 15 11:47:29 1999 @@ -0,0 +1,52 @@ +/* + + fp_arith.h: floating-point math routines for the Linux-m68k + floating point emulator. + + Copyright (c) 1998 David Huggins-Daines. + + Somewhat based on the AlphaLinux floating point emulator, by David + Mosberger-Tang. + + You may copy, modify, and redistribute this file under the terms of + the GNU General Public License, version 2, or any later version, at + your convenience. + + */ + +#ifndef FP_ARITH_H +#define FP_ARITH_H + +/* easy ones */ +struct fp_ext * +fp_fabs(struct fp_ext *dest, struct fp_ext *src); +struct fp_ext * +fp_fneg(struct fp_ext *dest, struct fp_ext *src); + +/* straightforward arithmetic */ +struct fp_ext * +fp_fadd(struct fp_ext *dest, struct fp_ext *src); +struct fp_ext * +fp_fsub(struct fp_ext *dest, struct fp_ext *src); +struct fp_ext * +fp_fcmp(struct fp_ext *dest, struct fp_ext *src); +struct fp_ext * +fp_ftst(struct fp_ext *dest, struct fp_ext *src); +struct fp_ext * +fp_fmul(struct fp_ext *dest, struct fp_ext *src); +struct fp_ext * +fp_fdiv(struct fp_ext *dest, struct fp_ext *src); + +/* ones that do rounding and integer conversions */ +struct fp_ext * +fp_fmod(struct fp_ext *dest, struct fp_ext *src); +struct fp_ext * +fp_frem(struct fp_ext *dest, struct fp_ext *src); +struct fp_ext * +fp_fint(struct fp_ext *dest, struct fp_ext *src); +struct fp_ext * +fp_fintrz(struct fp_ext *dest, struct fp_ext *src); +struct fp_ext * +fp_fscale(struct fp_ext *dest, struct fp_ext *src); + +#endif /* FP_ARITH__H */ diff -u --recursive --new-file v2.3.13/linux/arch/m68k/math-emu/fp_cond.S linux/arch/m68k/math-emu/fp_cond.S --- v2.3.13/linux/arch/m68k/math-emu/fp_cond.S Wed Dec 31 16:00:00 1969 +++ linux/arch/m68k/math-emu/fp_cond.S Sun Aug 15 11:47:29 1999 @@ -0,0 +1,334 @@ +/* + * fp_cond.S + * + * Copyright Roman Zippel, 1997. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fp_emu.h" +#include "fp_decode.h" + + .globl fp_fscc, fp_fbccw, fp_fbccl + +#ifdef FPU_EMU_DEBUG +fp_fnop: + printf PDECODE,"fnop\n" + jra fp_end +#else +#define fp_fnop fp_end +#endif + +fp_fbccw: + tst.w %d2 + jeq fp_fnop + printf PDECODE,"fbccw " + fp_get_pc %a0 + lea (-2,%a0,%d2.w),%a0 + jra 1f + +fp_fbccl: + printf PDECODE,"fbccl " + fp_get_pc %a0 + move.l %d2,%d0 + swap %d0 + fp_get_instr_word %d0,fp_err_ua1 + lea (-2,%a0,%d0.l),%a0 +1: printf PDECODE,"%x",1,%a0 + move.l %d2,%d0 + swap %d0 + jsr fp_compute_cond + tst.l %d0 + jeq 1f + fp_put_pc %a0,1 +1: printf PDECODE,"\n" + jra fp_end + +fp_fdbcc: + printf PDECODE,"fdbcc " + fp_get_pc %a1 | calculate new pc + fp_get_instr_word %d0,fp_err_ua1 + add.w %d0,%a1 + fp_decode_addr_reg + printf PDECODE,"d%d,%x\n",2,%d0,%a1 + swap %d1 | test condition in %d1 + tst.w %d1 + jne 2f + move.l %d0,%d1 + jsr fp_get_data_reg + subq.w #1,%d0 + jcs 1f + fp_put_pc %a1,1 +1: jsr fp_put_data_reg +2: jra fp_end + +| set flags for decode macros for fs +do_fscc=1 +do_no_pc_mode=1 + +fp_fscc: + printf PDECODE,"fscc " + move.l %d2,%d0 + jsr fp_compute_cond + move.w %d0,%d1 + swap %d1 + + | decode addressing mode + fp_decode_addr_mode + + .long fp_data, fp_fdbcc + .long fp_indirect, fp_postinc + .long fp_predecr, fp_disp16 + .long fp_extmode0, fp_extmode1 + + | addressing mode: data register direct +fp_data: + fp_mode_data_direct + move.w %d0,%d1 | save register nr + jsr fp_get_data_reg + swap %d1 + move.b %d1,%d0 + swap %d1 + jsr fp_put_data_reg + printf PDECODE,"\n" + jra fp_end + +fp_indirect: + fp_mode_addr_indirect + jra fp_do_scc + +fp_postinc: + fp_mode_addr_indirect_postinc + jra fp_do_scc + +fp_predecr: + fp_mode_addr_indirect_predec + jra fp_do_scc + +fp_disp16: + fp_mode_addr_indirect_disp16 + jra fp_do_scc + +fp_extmode0: + fp_mode_addr_indirect_extmode0 + jra fp_do_scc + +fp_extmode1: + bfextu %d2{#13,#3},%d0 + jmp ([0f:w,%pc,%d0*4]) + + .align 4 +0: + .long fp_absolute_short, fp_absolute_long + .long fp_ill, fp_ill | NOTE: jump here to ftrap.x + .long fp_ill, fp_ill + .long fp_ill, fp_ill + +fp_absolute_short: + fp_mode_abs_short + jra fp_do_scc + +fp_absolute_long: + fp_mode_abs_long +| jra fp_do_scc + +fp_do_scc: + swap %d1 + putuser.b %d1,(%a0),fp_err_ua1,%a0 + printf PDECODE,"\n" + jra fp_end + + +#define tst_NAN btst #24,%d1 +#define tst_Z btst #26,%d1 +#define tst_N btst #27,%d1 + +fp_compute_cond: + move.l (FPD_FPSR,FPDATA),%d1 + btst #4,%d0 + jeq 1f + tst_NAN + jeq 1f + bset #15,%d1 + bset #7,%d1 + move.l %d1,(FPD_FPSR,FPDATA) +1: and.w #0xf,%d0 + jmp ([0f:w,%pc,%d0.w*4]) + + .align 4 +0: + .long fp_f , fp_eq , fp_ogt, fp_oge + .long fp_olt, fp_ole, fp_ogl, fp_or + .long fp_un , fp_ueq, fp_ugt, fp_uge + .long fp_ult, fp_ule, fp_ne , fp_t + +fp_f: + moveq #0,%d0 + rts + +fp_eq: + moveq #0,%d0 + tst_Z + jeq 1f + moveq #-1,%d0 +1: rts + +fp_ogt: + moveq #0,%d0 + tst_NAN + jne 1f + tst_Z + jne 1f + tst_N + jne 1f + moveq #-1,%d0 +1: rts + +fp_oge: + moveq #-1,%d0 + tst_Z + jne 2f + tst_NAN + jne 1f + tst_N + jeq 2f +1: moveq #0,%d0 +2: rts + +fp_olt: + moveq #0,%d0 + tst_NAN + jne 1f + tst_Z + jne 1f + tst_N + jeq 1f + moveq #-1,%d0 +1: rts + +fp_ole: + moveq #-1,%d0 + tst_Z + jne 2f + tst_NAN + jne 1f + tst_N + jne 2f +1: moveq #0,%d0 +2: rts + +fp_ogl: + moveq #0,%d0 + tst_NAN + jne 1f + tst_Z + jne 1f + moveq #-1,%d0 +1: rts + +fp_or: + moveq #0,%d0 + tst_NAN + jne 1f + moveq #-1,%d0 +1: rts + +fp_un: + moveq #0,%d0 + tst_NAN + jeq 1f + moveq #-1,%d0 + rts + +fp_ueq: + moveq #-1,%d0 + tst_NAN + jne 1f + tst_Z + jne 1f + moveq #0,%d0 +1: rts + +fp_ugt: + moveq #-1,%d0 + tst_NAN + jne 2f + tst_N + jne 1f + tst_Z + jeq 2f +1: moveq #0,%d0 +2: rts + +fp_uge: + moveq #-1,%d0 + tst_NAN + jne 1f + tst_Z + jne 1f + tst_N + jeq 1f + moveq #0,%d0 +1: rts + +fp_ult: + moveq #-1,%d0 + tst_NAN + jne 2f + tst_Z + jne 1f + tst_N + jne 2f +1: moveq #0,%d0 +2: rts + +fp_ule: + moveq #-1,%d0 + tst_NAN + jne 1f + tst_Z + jne 1f + tst_N + jne 1f + moveq #0,%d0 +1: rts + +fp_ne: + moveq #0,%d0 + tst_Z + jne 1f + moveq #-1,%d0 +1: rts + +fp_t: + moveq #-1,%d0 + rts diff -u --recursive --new-file v2.3.13/linux/arch/m68k/math-emu/fp_decode.h linux/arch/m68k/math-emu/fp_decode.h --- v2.3.13/linux/arch/m68k/math-emu/fp_decode.h Wed Dec 31 16:00:00 1969 +++ linux/arch/m68k/math-emu/fp_decode.h Sun Aug 15 11:47:29 1999 @@ -0,0 +1,417 @@ +/* + * fp_decode.h + * + * Copyright Roman Zippel, 1997. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FP_DECODE_H +#define _FP_DECODE_H + +/* These macros do the dirty work of the instr decoding, several variables + * can be defined in the source file to modify the work of these macros, + * currently the following variables are used: + * ... + * The register usage: + * d0 - will contain source operand for data direct mode, + * otherwise scratch register + * d1 - upper 16bit are reserved for caller + * lower 16bit may contain further arguments, + * is destroyed during decoding + * d2 - contains first two instruction words, + * first word will be used for extension word + * a0 - will point to source/dest operand for any indirect mode + * otherwise scratch register + * a1 - scratch register + * a2 - base addr to the task structure + * + * the current implementation doesn't check for every disallowed + * addressing mode (e.g. pc relative modes as destination), as long + * as it only means a new addressing mode, which should not appear + * in a program and that doesn't crash the emulation, I think it's + * not a problem to allow these modes. + */ + +do_fmovem=0 +do_fmovem_cr=0 +do_no_pc_mode=0 +do_fscc=0 + +| first decoding of the instr type +| this seperates the conditional instr +.macro fp_decode_cond_instr_type + bfextu %d2{#8,#2},%d0 + jmp ([0f:w,%pc,%d0*4]) + + .align 4 +0: +| .long "f","fscc/fdbcc" +| .long "fbccw","fbccl" +.endm + +| second decoding of the instr type +| this seperates most move instr +.macro fp_decode_move_instr_type + bfextu %d2{#16,#3},%d0 + jmp ([0f:w,%pc,%d0*4]) + + .align 4 +0: +| .long "f fpx,fpx","invalid instr" +| .long "f ,fpx","fmove fpx," +| .long "fmovem ,fpcr","fmovem ,fpx" +| .long "fmovem fpcr,","fmovem fpx," +.endm + +| extract the source specifier, specifies +| either source fp register or data format +.macro fp_decode_sourcespec + bfextu %d2{#19,#3},%d0 +.endm + +| decode destination format for fmove reg,ea +.macro fp_decode_dest_format + bfextu %d2{#19,#3},%d0 +.endm + +| decode source register for fmove reg,ea +.macro fp_decode_src_reg + bfextu %d2{#22,#3},%d0 +.endm + +| extract the addressing mode +| it depends on the instr which of the modes is valid +.macro fp_decode_addr_mode + bfextu %d2{#10,#3},%d0 + jmp ([0f:w,%pc,%d0*4]) + + .align 4 +0: +| .long "data register direct","addr register direct" +| .long "addr register indirect" +| .long "addr register indirect postincrement" +| .long "addr register indirect predecrement" +| .long "addr register + index16" +| .long "extension mode1","extension mode2" +.endm + +| extract the register for the addressing mode +.macro fp_decode_addr_reg + bfextu %d2{#13,#3},%d0 +.endm + +| decode the 8bit diplacement from the brief extension word +.macro fp_decode_disp8 + move.b %d2,%d0 + ext.w %d0 +.endm + +| decode the index of the brief/full extension word +.macro fp_decode_index + bfextu %d2{#17,#3},%d0 | get the register nr + btst #15,%d2 | test for data/addr register + jne 1\@f + printf PDECODE,"d%d",1,%d0 + jsr fp_get_data_reg + jra 2\@f +1\@: printf PDECODE,"a%d",1,%d0 + jsr fp_get_addr_reg + move.l %a0,%d0 +2\@: +debug lea "'l'.w,%a0" + btst #11,%d2 | 16/32 bit size? + jne 3\@f +debug lea "'w'.w,%a0" + ext.l %d0 +3\@: printf PDECODE,":%c",1,%a0 + move.w %d2,%d1 | scale factor + rol.w #7,%d1 + and.w #3,%d1 +debug move.l "%d1,-(%sp)" +debug ext.l "%d1" + printf PDECODE,":%d",1,%d1 +debug move.l "(%sp)+,%d1" + lsl.l %d1,%d0 +.endm + +| decode the base displacement size +.macro fp_decode_basedisp + bfextu %d2{#26,#2},%d0 + jmp ([0f:w,%pc,%d0*4]) + + .align 4 +0: +| .long "reserved","null displacement" +| .long "word displacement","long displacement" +.endm + +.macro fp_decode_outerdisp + bfextu %d2{#30,#2},%d0 + jmp ([0f:w,%pc,%d0*4]) + + .align 4 +0: +| .long "no memory indirect action/reserved","null outer displacement" +| .long "word outer displacement","long outer displacement" +.endm + +| get the extension word and test for brief or full extension type +.macro fp_get_test_extword label + fp_get_instr_word %d2,fp_err_ua1 + btst #8,%d2 + jne \label +.endm + + +| test if %pc is the base register for the indirect addr mode +.macro fp_test_basereg_d16 label + btst #20,%d2 + jeq \label +.endm + +| test if %pc is the base register for one of the extended modes +.macro fp_test_basereg_ext label + btst #19,%d2 + jeq \label +.endm + +.macro fp_test_suppr_index label + btst #6,%d2 + jne \label +.endm + + +| addressing mode: data register direct +.macro fp_mode_data_direct + fp_decode_addr_reg + printf PDECODE,"d%d",1,%d0 +.endm + +| addressing mode: address register indirect +.macro fp_mode_addr_indirect + fp_decode_addr_reg + printf PDECODE,"(a%d)",1,%d0 + jsr fp_get_addr_reg +.endm + +| adjust stack for byte moves from/to stack +.macro fp_test_sp_byte_move + .if !do_fmovem + .if do_fscc + move.w #6,%d1 + .endif + cmp.w #7,%d0 + jne 1\@f + .if !do_fscc + cmp.w #6,%d1 + jne 1\@f + .endif + move.w #4,%d1 +1\@: + .endif +.endm + +| addressing mode: address register indirect with postincrement +.macro fp_mode_addr_indirect_postinc + fp_decode_addr_reg + printf PDECODE,"(a%d)+",1,%d0 + fp_test_sp_byte_move + jsr fp_get_addr_reg + move.l %a0,%a1 | save addr + .if do_fmovem + lea (%a0,%d1.w*4),%a0 + .if !do_fmovem_cr + lea (%a0,%d1.w*8),%a0 + .endif + .else + add.w (fp_datasize,%d1.w*2),%a0 + .endif + jsr fp_put_addr_reg + move.l %a1,%a0 +.endm + +| addressing mode: address register indirect with predecrement +.macro fp_mode_addr_indirect_predec + fp_decode_addr_reg + printf PDECODE,"-(a%d)",1,%d0 + fp_test_sp_byte_move + jsr fp_get_addr_reg + .if do_fmovem + .if !do_fmovem_cr + lea (-12,%a0),%a1 | setup to addr of 1st reg to move + neg.w %d1 + lea (%a0,%d1.w*4),%a0 + add.w %d1,%d1 + lea (%a0,%d1.w*4),%a0 + jsr fp_put_addr_reg + move.l %a1,%a0 + .else + neg.w %d1 + lea (%a0,%d1.w*4),%a0 + jsr fp_put_addr_reg + .endif + .else + sub.w (fp_datasize,%d1.w*2),%a0 + jsr fp_put_addr_reg + .endif +.endm + +| addressing mode: address register/programm counter indirect +| with 16bit displacement +.macro fp_mode_addr_indirect_disp16 + .if !do_no_pc_mode + fp_test_basereg_d16 1f + printf PDECODE,"pc" + fp_get_pc %a0 + jra 2f + .endif +1: fp_decode_addr_reg + printf PDECODE,"a%d",1,%d0 + jsr fp_get_addr_reg +2: fp_get_instr_word %a1,fp_err_ua1 + printf PDECODE,"@(%x)",1,%a1 + add.l %a1,%a0 +.endm + +| perform preindex (if I/IS == 0xx and xx != 00) +.macro fp_do_preindex + moveq #3,%d0 + and.w %d2,%d0 + jeq 1f + btst #2,%d2 + jne 1f + printf PDECODE,")@(" + getuser.l (%a1),%a1,fp_err_ua1,%a1 +debug jra "2f" +1: printf PDECODE,"," +2: +.endm + +| perform postindex (if I/IS == 1xx) +.macro fp_do_postindex + btst #2,%d2 + jeq 1f + printf PDECODE,")@(" + getuser.l (%a1),%a1,fp_err_ua1,%a1 +debug jra "2f" +1: printf PDECODE,"," +2: +.endm + +| all other indirect addressing modes will finally end up here +.macro fp_mode_addr_indirect_extmode0 + .if !do_no_pc_mode + fp_test_basereg_ext 1f + printf PDECODE,"pc" + fp_get_pc %a0 + jra 2f + .endif +1: fp_decode_addr_reg + printf PDECODE,"a%d",1,%d0 + jsr fp_get_addr_reg +2: move.l %a0,%a1 + swap %d2 + fp_get_test_extword 3f + | addressing mode: address register/programm counter indirect + | with index and 8bit displacement + fp_decode_disp8 +debug ext.l "%d0" + printf PDECODE,"@(%x,",1,%d0 + add.w %d0,%a1 + fp_decode_index + add.l %d0,%a1 + printf PDECODE,")" + jra 9f +3: | addressing mode: address register/programm counter memory indirect + | with base and/or outer displacement + btst #7,%d2 | base register suppressed? + jeq 1f + printf PDECODE,"!" + sub.l %a1,%a1 +1: printf PDECODE,"@(" + fp_decode_basedisp + + .long fp_ill,1f + .long 2f,3f + +#ifdef FPU_EMU_DEBUG +1: printf PDECODE,"0" | null base displacement + jra 1f +#endif +2: fp_get_instr_word %a0,fp_err_ua1 | 16bit base displacement + printf PDECODE,"%x:w",1,%a0 + jra 4f +3: fp_get_instr_long %a0,fp_err_ua1 | 32bit base displacement + printf PDECODE,"%x:l",1,%a0 +4: add.l %a0,%a1 +1: + fp_do_postindex + fp_test_suppr_index 1f + fp_decode_index + add.l %d0,%a1 +1: fp_do_preindex + + fp_decode_outerdisp + + .long 5f,1f + .long 2f,3f + +#ifdef FPU_EMU_DEBUG +1: printf PDECODE,"0" | null outer displacement + jra 1f +#endif +2: fp_get_instr_word %a0,fp_err_ua1 | 16bit outer displacement + printf PDECODE,"%x:w",1,%a0 + jra 4f +3: fp_get_instr_long %a0,fp_err_ua1 | 32bit outer displacement + printf PDECODE,"%x:l",1,%a0 +4: add.l %a0,%a1 +1: +5: printf PDECODE,")" +9: move.l %a1,%a0 + swap %d2 +.endm + +| get the absolute short address from user space +.macro fp_mode_abs_short + fp_get_instr_word %a0,fp_err_ua1 + printf PDECODE,"%x.w",1,%a0 +.endm + +| get the absolute long address from user space +.macro fp_mode_abs_long + fp_get_instr_long %a0,fp_err_ua1 + printf PDECODE,"%x.l",1,%a0 +.endm + +#endif /* _FP_DECODE_H */ diff -u --recursive --new-file v2.3.13/linux/arch/m68k/math-emu/fp_emu.h linux/arch/m68k/math-emu/fp_emu.h --- v2.3.13/linux/arch/m68k/math-emu/fp_emu.h Wed Dec 31 16:00:00 1969 +++ linux/arch/m68k/math-emu/fp_emu.h Sun Aug 15 11:47:29 1999 @@ -0,0 +1,137 @@ +/* + * fp_emu.h + * + * Copyright Roman Zippel, 1997. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FP_EMU_H +#define _FP_EMU_H + +#ifndef __ASSEMBLY__ + +#include + +#define IS_INF(a) ((a)->exp == 0x7fff) +#define IS_ZERO(a) ((a)->mant.m64 == 0) + + +#define fp_set_sr(bit) ({ \ + FPDATA->fpsr |= 1 << (bit); \ +}) + +#define fp_set_quotient(quotient) ({ \ + FPDATA->fpsr &= 0xff00ffff; \ + FPDATA->fpsr |= ((quotient) & 0xff) << 16; \ +}) + +/* linkage for several useful functions */ + +/* Normalize the extended struct, return 0 for a NaN */ +#define fp_normalize_ext(fpreg) ({ \ + register struct fp_ext *reg asm ("a0") = fpreg; \ + register int res asm ("d0"); \ + \ + asm volatile ("jsr fp_conv_ext2ext" \ + : "=d" (res) : "a" (reg) \ + : "a1", "d1", "d2", "memory"); \ + res; \ +}) + +#define fp_copy_ext(dest, src) ({ \ + *dest = *src; \ +}) + +#define fp_monadic_check(dest, src) ({ \ + fp_copy_ext(dest, src); \ + if (!fp_normalize_ext(dest)) \ + return dest; \ +}) + +#define fp_dyadic_check(dest, src) ({ \ + if (!fp_normalize_ext(dest)) \ + return dest; \ + if (!fp_normalize_ext(src)) { \ + fp_copy_ext(dest, src); \ + return dest; \ + } \ +}) + +extern const struct fp_ext fp_QNaN; +extern const struct fp_ext fp_Inf; + +#define fp_set_nan(dest) ({ \ + fp_set_sr(FPSR_EXC_OPERR); \ + *dest = fp_QNaN; \ +}) + +/* TODO check rounding mode? */ +#define fp_set_ovrflw(dest) ({ \ + fp_set_sr(FPSR_EXC_OVFL); \ + dest->exp = 0x7fff; \ + dest->mant.m64 = 0; \ +}) + +#define fp_conv_ext2long(src) ({ \ + register struct fp_ext *__src asm ("a0") = src; \ + register int __res asm ("d0"); \ + \ + asm volatile ("jsr fp_conv_ext2long" \ + : "=d" (__res) : "a" (__src) \ + : "a1", "d1", "d2", "memory"); \ + __res; \ +}) + +#else /* __ASSEMBLY__ */ + +#include "../kernel/m68k_defs.h" +#include + +/* + * set, reset or clear a bit in the fp status register + */ +.macro fp_set_sr bit + bset #(\bit&7),(FPD_FPSR+3-(\bit/8),FPDATA) +.endm + +.macro fp_clr_sr bit + bclr #(\bit&7),(FPD_FPSR+3-(\bit/8),FPDATA) +.endm + +.macro fp_tst_sr bit + btst #(\bit&7),(FPD_FPSR+3-(\bit/8),FPDATA) +.endm + +#endif /* __ASSEMBLY__ */ + +#endif /* _FP_EMU_H */ diff -u --recursive --new-file v2.3.13/linux/arch/m68k/math-emu/fp_entry.S linux/arch/m68k/math-emu/fp_entry.S --- v2.3.13/linux/arch/m68k/math-emu/fp_entry.S Wed Dec 31 16:00:00 1969 +++ linux/arch/m68k/math-emu/fp_entry.S Tue Aug 17 10:39:02 1999 @@ -0,0 +1,325 @@ +/* + * fp_emu.S + * + * Copyright Roman Zippel, 1997. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include "fp_emu.h" + + .globl SYMBOL_NAME(fpu_emu) + .globl fp_debugprint + .globl fp_err_ua1,fp_err_ua2 + + .text +SYMBOL_NAME_LABEL(fpu_emu) + SAVE_ALL_INT + GET_CURRENT(%d0) + +#if defined(CPU_M68020_OR_M68030) && defined(CPU_M68040_OR_M68060) + tst.l SYMBOL_NAME(m68k_is040or060) + jeq 1f +#endif +#if defined(CPU_M68040_OR_M68060) + move.l (FPS_PC2,%sp),(FPS_PC,%sp) +#endif +1: + | emulate the instruction + jsr fp_scan + +#if defined(CONFIG_M68060) +#if !defined(CPU_M68060_ONLY) + btst #3,SYMBOL_NAME(m68k_cputype)+3 + jeq 1f +#endif + btst #7,(FPS_SR,%sp) + jne fp_sendtrace060 +#endif +1: + | emulation successful? + tst.l %d0 + jeq SYMBOL_NAME(ret_from_exception) + + | send some signal to program here + + jra SYMBOL_NAME(ret_from_exception) + + | we jump here after an access error while trying to access + | user space, we correct stackpointer and send a SIGSEGV to + | the user process +fp_err_ua2: + addq.l #4,%sp +fp_err_ua1: + addq.l #4,%sp + move.l %a0,-(%sp) + pea SEGV_MAPERR + pea SIGSEGV + jsr SYMBOL_NAME(fpemu_signal) + add.w #12,%sp + jra SYMBOL_NAME(ret_from_exception) + +#if defined(CONFIG_M68060) + | send a trace signal if we are debugged + | it does not really belong here, but... +fp_sendtrace060: + move.l (FPS_PC,%sp),-(%sp) + pea TRAP_TRACE + pea SIGTRAP + jsr SYMBOL_NAME(fpemu_signal) + add.w #12,%sp + jra SYMBOL_NAME(ret_from_exception) +#endif + + .globl fp_get_data_reg, fp_put_data_reg + .globl fp_get_addr_reg, fp_put_addr_reg + + | Entry points to get/put a register. Some of them can be get/put + | directly, others are on the stack, as we read/write the stack + | directly here, these function may only be called from within + | instruction decoding, otherwise the stack pointer is incorrect + | and the stack gets corrupted. +fp_get_data_reg: + jmp ([0f:w,%pc,%d0.w*4]) + + .align 4 +0: + .long fp_get_d0, fp_get_d1 + .long fp_get_d2, fp_get_d3 + .long fp_get_d4, fp_get_d5 + .long fp_get_d6, fp_get_d7 + +fp_get_d0: + move.l (PT_D0+8,%sp),%d0 + printf PREGISTER,"{d0->%08x}",1,%d0 + rts + +fp_get_d1: + move.l (PT_D1+8,%sp),%d0 + printf PREGISTER,"{d1->%08x}",1,%d0 + rts + +fp_get_d2: + move.l (PT_D2+8,%sp),%d0 + printf PREGISTER,"{d2->%08x}",1,%d0 + rts + +fp_get_d3: + move.l %d3,%d0 + printf PREGISTER,"{d3->%08x}",1,%d0 + rts + +fp_get_d4: + move.l %d4,%d0 + printf PREGISTER,"{d4->%08x}",1,%d0 + rts + +fp_get_d5: + move.l %d5,%d0 + printf PREGISTER,"{d5->%08x}",1,%d0 + rts + +fp_get_d6: + move.l %d6,%d0 + printf PREGISTER,"{d6->%08x}",1,%d0 + rts + +fp_get_d7: + move.l %d7,%d0 + printf PREGISTER,"{d7->%08x}",1,%d0 + rts + +fp_put_data_reg: + jmp ([0f:w,%pc,%d1.w*4]) + + .align 4 +0: + .long fp_put_d0, fp_put_d1 + .long fp_put_d2, fp_put_d3 + .long fp_put_d4, fp_put_d5 + .long fp_put_d6, fp_put_d7 + +fp_put_d0: + printf PREGISTER,"{d0<-%08x}",1,%d0 + move.l %d0,(PT_D0+8,%sp) + rts + +fp_put_d1: + printf PREGISTER,"{d1<-%08x}",1,%d0 + move.l %d0,(PT_D1+8,%sp) + rts + +fp_put_d2: + printf PREGISTER,"{d2<-%08x}",1,%d0 + move.l %d0,(PT_D2+8,%sp) + rts + +fp_put_d3: + printf PREGISTER,"{d3<-%08x}",1,%d0 +| move.l %d0,%d3 + move.l %d0,(PT_D3+8,%sp) + rts + +fp_put_d4: + printf PREGISTER,"{d4<-%08x}",1,%d0 +| move.l %d0,%d4 + move.l %d0,(PT_D4+8,%sp) + rts + +fp_put_d5: + printf PREGISTER,"{d5<-%08x}",1,%d0 +| move.l %d0,%d5 + move.l %d0,(PT_D5+8,%sp) + rts + +fp_put_d6: + printf PREGISTER,"{d6<-%08x}",1,%d0 + move.l %d0,%d6 + rts + +fp_put_d7: + printf PREGISTER,"{d7<-%08x}",1,%d0 + move.l %d0,%d7 + rts + +fp_get_addr_reg: + jmp ([0f:w,%pc,%d0.w*4]) + + .align 4 +0: + .long fp_get_a0, fp_get_a1 + .long fp_get_a2, fp_get_a3 + .long fp_get_a4, fp_get_a5 + .long fp_get_a6, fp_get_a7 + +fp_get_a0: + move.l (PT_A0+8,%sp),%a0 + printf PREGISTER,"{a0->%08x}",1,%a0 + rts + +fp_get_a1: + move.l (PT_A1+8,%sp),%a0 + printf PREGISTER,"{a1->%08x}",1,%a0 + rts + +fp_get_a2: + move.l (PT_A2+8,%sp),%a0 + printf PREGISTER,"{a2->%08x}",1,%a0 + rts + +fp_get_a3: + move.l %a3,%a0 + printf PREGISTER,"{a3->%08x}",1,%a0 + rts + +fp_get_a4: + move.l %a4,%a0 + printf PREGISTER,"{a4->%08x}",1,%a0 + rts + +fp_get_a5: + move.l %a5,%a0 + printf PREGISTER,"{a5->%08x}",1,%a0 + rts + +fp_get_a6: + move.l %a6,%a0 + printf PREGISTER,"{a6->%08x}",1,%a0 + rts + +fp_get_a7: + move.l %usp,%a0 + printf PREGISTER,"{a7->%08x}",1,%a0 + rts + +fp_put_addr_reg: + jmp ([0f:w,%pc,%d0.w*4]) + + .align 4 +0: + .long fp_put_a0, fp_put_a1 + .long fp_put_a2, fp_put_a3 + .long fp_put_a4, fp_put_a5 + .long fp_put_a6, fp_put_a7 + +fp_put_a0: + printf PREGISTER,"{a0<-%08x}",1,%a0 + move.l %a0,(PT_A0+8,%sp) + rts + +fp_put_a1: + printf PREGISTER,"{a1<-%08x}",1,%a0 + move.l %a0,(PT_A1+8,%sp) + rts + +fp_put_a2: + printf PREGISTER,"{a2<-%08x}",1,%a0 + move.l %a0,(PT_A2+8,%sp) + rts + +fp_put_a3: + printf PREGISTER,"{a3<-%08x}",1,%a0 + move.l %a0,%a3 + rts + +fp_put_a4: + printf PREGISTER,"{a4<-%08x}",1,%a0 + move.l %a0,%a4 + rts + +fp_put_a5: + printf PREGISTER,"{a5<-%08x}",1,%a0 + move.l %a0,%a5 + rts + +fp_put_a6: + printf PREGISTER,"{a6<-%08x}",1,%a0 + move.l %a0,%a6 + rts + +fp_put_a7: + printf PREGISTER,"{a7<-%08x}",1,%a0 + move.l %a0,%usp + rts + + .data + .align 4 + +fp_debugprint: +| .long PMDECODE + .long PMINSTR+PMDECODE+PMCONV+PMNORM +| .long PMCONV+PMNORM+PMINSTR +| .long 0 diff -u --recursive --new-file v2.3.13/linux/arch/m68k/math-emu/fp_log.c linux/arch/m68k/math-emu/fp_log.c --- v2.3.13/linux/arch/m68k/math-emu/fp_log.c Wed Dec 31 16:00:00 1969 +++ linux/arch/m68k/math-emu/fp_log.c Sun Aug 15 11:47:29 1999 @@ -0,0 +1,142 @@ +/* + + fp_trig.c: floating-point math routines for the Linux-m68k + floating point emulator. + + Copyright (c) 1998-1999 David Huggins-Daines / Roman Zippel. + + I hereby give permission, free of charge, to copy, modify, and + redistribute this software, in source or binary form, provided that + the above copyright notice and the following disclaimer are included + in all such copies. + + THIS SOFTWARE IS PROVIDED "AS IS", WITH ABSOLUTELY NO WARRANTY, REAL + OR IMPLIED. + +*/ + +#include "fp_emu.h" + +struct fp_ext * +fp_fsqrt(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fsqrt\n"); + + fp_monadic_check(dest, src); + + if (IS_ZERO(dest)) + return dest; + + if (dest->sign) { + fp_set_nan(dest); + return dest; + } + if (IS_INF(dest)) + return dest; + + return dest; +} + +struct fp_ext * +fp_fetoxm1(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fetoxm1\n"); + + fp_monadic_check(dest, src); + + if (IS_ZERO(dest)) + return dest; + + return dest; +} + +struct fp_ext * +fp_fetox(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fetox\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_ftwotox(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("ftwotox\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_ftentox(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("ftentox\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_flogn(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("flogn\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_flognp1(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("flognp1\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_flog10(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("flog10\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_flog2(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("flog2\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_fgetexp(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fgetexp\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_fgetman(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fgetman\n"); + + fp_monadic_check(dest, src); + + return dest; +} + diff -u --recursive --new-file v2.3.13/linux/arch/m68k/math-emu/fp_move.S linux/arch/m68k/math-emu/fp_move.S --- v2.3.13/linux/arch/m68k/math-emu/fp_move.S Wed Dec 31 16:00:00 1969 +++ linux/arch/m68k/math-emu/fp_move.S Sun Aug 15 11:47:29 1999 @@ -0,0 +1,244 @@ +/* + * fp_move.S + * + * Copyright Roman Zippel, 1997. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fp_emu.h" +#include "fp_decode.h" + +do_no_pc_mode=1 + + .globl fp_fmove_fp2mem + +fp_fmove_fp2mem: + clr.b (2+FPD_FPSR,FPDATA) + fp_decode_dest_format + move.w %d0,%d1 | store data size twice in %d1 + swap %d1 | one can be trashed below + move.w %d0,%d1 +#ifdef FPU_EMU_DEBUG + lea 0f,%a0 + clr.l %d0 + move.b (%a0,%d1.w),%d0 + printf PDECODE,"fmove.%c ",1,%d0 + fp_decode_src_reg + printf PDECODE,"fp%d,",1,%d0 + + .data +0: .byte 'l','s','x','p','w','d','b','p' + .previous +#endif + + | encode addressing mode for dest + fp_decode_addr_mode + + .long fp_data, fp_ill + .long fp_indirect, fp_postinc + .long fp_predecr, fp_disp16 + .long fp_extmode0, fp_extmode1 + + | addressing mode: data register direct +fp_data: + fp_mode_data_direct + move.w %d0,%d1 + fp_decode_src_reg + fp_get_fp_reg + lea (FPD_TEMPFP1,FPDATA),%a1 + move.l (%a0)+,(%a1)+ + move.l (%a0)+,(%a1)+ + move.l (%a0),(%a1) + lea (-8,%a1),%a0 + swap %d1 + move.l %d1,%d2 + printf PDECODE,"\n" + jmp ([0f:w,%pc,%d1.w*4]) + + .align 4 +0: + .long fp_data_long, fp_data_single + .long fp_ill, fp_ill + .long fp_data_word, fp_ill + .long fp_data_byte, fp_ill + +fp_data_byte: + jsr fp_normalize_ext + jsr fp_conv_ext2byte + move.l %d0,%d1 + swap %d2 + move.w %d2,%d0 + jsr fp_get_data_reg + move.b %d1,%d0 + move.w %d2,%d1 + jsr fp_put_data_reg + jra fp_final + +fp_data_word: + jsr fp_normalize_ext + jsr fp_conv_ext2short + move.l %d0,%d1 + swap %d2 + move.w %d2,%d0 + jsr fp_get_data_reg + move.w %d1,%d0 + move.l %d2,%d1 + jsr fp_put_data_reg + jra fp_final + +fp_data_long: + jsr fp_normalize_ext + jsr fp_conv_ext2long + swap %d2 + move.w %d2,%d1 + jsr fp_put_data_reg + jra fp_final + +fp_data_single: + jsr fp_normalize_ext + jsr fp_conv_ext2single + swap %d2 + move.w %d2,%d1 + jsr fp_put_data_reg + jra fp_final + + | addressing mode: address register indirect +fp_indirect: + fp_mode_addr_indirect + jra fp_putdest + + | addressing mode: address register indirect with postincrement +fp_postinc: + fp_mode_addr_indirect_postinc + jra fp_putdest + + | addressing mode: address register indirect with predecrement +fp_predecr: + fp_mode_addr_indirect_predec + jra fp_putdest + + | addressing mode: address register indirect with 16bit displacement +fp_disp16: + fp_mode_addr_indirect_disp16 + jra fp_putdest + +fp_extmode0: + fp_mode_addr_indirect_extmode0 + jra fp_putdest + +fp_extmode1: + fp_decode_addr_reg + jmp ([0f:w,%pc,%d0*4]) + + .align 4 +0: + .long fp_abs_short, fp_abs_long + .long fp_ill, fp_ill + .long fp_ill, fp_ill + .long fp_ill, fp_ill + +fp_abs_short: + fp_mode_abs_short + jra fp_putdest + +fp_abs_long: + fp_mode_abs_long + jra fp_putdest + +fp_putdest: + move.l %a0,%a1 + fp_decode_src_reg + move.l %d1,%d2 | save size + fp_get_fp_reg + printf PDECODE,"\n" + addq.l #8,%a0 + move.l (%a0),-(%sp) + move.l -(%a0),-(%sp) + move.l -(%a0),-(%sp) + move.l %sp,%a0 + jsr fp_normalize_ext + + swap %d2 + jmp ([0f:w,%pc,%d2.w*4]) + + .align 4 +0: + .long fp_format_long, fp_format_single + .long fp_format_extended, fp_format_packed + .long fp_format_word, fp_format_double + .long fp_format_byte, fp_format_packed + +fp_format_long: + jsr fp_conv_ext2long + putuser.l %d0,(%a1),fp_err_ua1,%a1 + jra fp_finish_move + +fp_format_single: + jsr fp_conv_ext2single + putuser.l %d0,(%a1),fp_err_ua1,%a1 + jra fp_finish_move + +fp_format_extended: + move.l (%a0)+,%d0 + lsl.w #1,%d0 + lsl.l #7,%d0 + lsl.l #8,%d0 + putuser.l %d0,(%a1)+,fp_err_ua1,%a1 + move.l (%a0)+,%d0 + putuser.l %d0,(%a1)+,fp_err_ua1,%a1 + move.l (%a0),%d0 + putuser.l %d0,(%a1),fp_err_ua1,%a1 + jra fp_finish_move + +fp_format_packed: + /* not supported yet */ + lea (12,%sp),%sp + jra fp_ill + +fp_format_word: + jsr fp_conv_ext2short + putuser.w %d0,(%a1),fp_err_ua1,%a1 + jra fp_finish_move + +fp_format_double: + jsr fp_conv_ext2double + jra fp_finish_move + +fp_format_byte: + jsr fp_conv_ext2byte + putuser.b %d0,(%a1),fp_err_ua1,%a1 +| jra fp_finish_move + +fp_finish_move: + lea (12,%sp),%sp + jra fp_final diff -u --recursive --new-file v2.3.13/linux/arch/m68k/math-emu/fp_movem.S linux/arch/m68k/math-emu/fp_movem.S --- v2.3.13/linux/arch/m68k/math-emu/fp_movem.S Wed Dec 31 16:00:00 1969 +++ linux/arch/m68k/math-emu/fp_movem.S Sun Aug 15 11:47:29 1999 @@ -0,0 +1,368 @@ +/* + * fp_movem.S + * + * Copyright Roman Zippel, 1997. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fp_emu.h" +#include "fp_decode.h" + +| set flags for decode macros for fmovem +do_fmovem=1 + + .globl fp_fmovem_fp, fp_fmovem_cr + +| %d1 contains the mask and count of the register list +| for other register usage see fp_decode.h + +fp_fmovem_fp: + printf PDECODE,"fmovem.x " + | get register list and count them + btst #11,%d2 + jne 1f + bfextu %d2{#24,#8},%d0 | static register list + jra 2f +1: bfextu %d2{#25,#3},%d0 | dynamic register list + jsr fp_get_data_reg +2: move.l %d0,%d1 + swap %d1 + jra 2f +1: addq.w #1,%d1 | count the # of registers in +2: lsr.b #1,%d0 | register list and keep it in %d1 + jcs 1b + jne 2b + printf PDECODE,"#%08x",1,%d1 +#ifdef FPU_EMU_DEBUG + btst #12,%d2 + jne 1f + printf PDECODE,"-" | decremental move + jra 2f +1: printf PDECODE,"+" | incremental move +2: btst #13,%d2 + jeq 1f + printf PDECODE,"->" | fpu -> cpu + jra 2f +1: printf PDECODE,"<-" | fpu <- cpu +2: +#endif + + | decode address mode + fp_decode_addr_mode + + .long fp_ill, fp_ill + .long fpr_indirect, fpr_postinc + .long fpr_predecr, fpr_disp16 + .long fpr_extmode0, fpr_extmode1 + + | addressing mode: address register indirect +fpr_indirect: + fp_mode_addr_indirect + jra fpr_do_movem + + | addressing mode: address register indirect with postincrement +fpr_postinc: + fp_mode_addr_indirect_postinc + jra fpr_do_movem + +fpr_predecr: + fp_mode_addr_indirect_predec + jra fpr_do_movem + + | addressing mode: address register/programm counter indirect + | with 16bit displacement +fpr_disp16: + fp_mode_addr_indirect_disp16 + jra fpr_do_movem + +fpr_extmode0: + fp_mode_addr_indirect_extmode0 + jra fpr_do_movem + +fpr_extmode1: + fp_decode_addr_reg + jmp ([0f:w,%pc,%d0*4]) + + .align 4 +0: + .long fpr_absolute_short, fpr_absolute_long + .long fpr_disp16, fpr_extmode0 + .long fp_ill, fp_ill + .long fp_ill, fp_ill + +fpr_absolute_short: + fp_mode_abs_short + jra fpr_do_movem + +fpr_absolute_long: + fp_mode_abs_long +| jra fpr_do_movem + +fpr_do_movem: + swap %d1 | get fpu register list + lea (FPD_FPREG,FPDATA),%a1 + moveq #12,%d0 + btst #12,%d2 + jne 1f + lea (-12,%a1,%d0*8),%a1 + neg.l %d0 +1: btst #13,%d2 + jne 4f + | move register from memory into fpu + jra 3f +1: printf PMOVEM,"(%p>%p)",2,%a0,%a1 + getuser.l (%a0)+,%d2,fp_err_ua1,%a0 + lsr.l #8,%d2 + lsr.l #7,%d2 + lsr.w #1,%d2 + move.l %d2,(%a1)+ + getuser.l (%a0)+,%d2,fp_err_ua1,%a0 + move.l %d2,(%a1)+ + getuser.l (%a0),%d2,fp_err_ua1,%a0 + move.l %d2,(%a1) + subq.l #8,%a0 + subq.l #8,%a1 + add.l %d0,%a0 +2: add.l %d0,%a1 +3: lsl.b #1,%d1 + jcs 1b + jne 2b + jra 5f + | move register from fpu into memory +1: printf PMOVEM,"(%p>%p)",2,%a1,%a0 + move.l (%a1)+,%d2 + lsl.w #1,%d2 + lsl.l #7,%d2 + lsl.l #8,%d2 + putuser.l %d2,(%a0)+,fp_err_ua1,%a0 + move.l (%a1)+,%d2 + putuser.l %d2,(%a0)+,fp_err_ua1,%a0 + move.l (%a1),%d2 + putuser.l %d2,(%a0),fp_err_ua1,%a0 + subq.l #8,%a1 + subq.l #8,%a0 + add.l %d0,%a0 +2: add.l %d0,%a1 +4: lsl.b #1,%d1 + jcs 1b + jne 2b +5: + printf PDECODE,"\n" +#if 0 + lea (FPD_FPREG,FPDATA),%a0 + printf PMOVEM,"fp:" + printx PMOVEM,%a0@(0) + printx PMOVEM,%a0@(12) + printf PMOVEM,"\n " + printx PMOVEM,%a0@(24) + printx PMOVEM,%a0@(36) + printf PMOVEM,"\n " + printx PMOVEM,%a0@(48) + printx PMOVEM,%a0@(60) + printf PMOVEM,"\n " + printx PMOVEM,%a0@(72) + printx PMOVEM,%a0@(84) + printf PMOVEM,"\n" +#endif + jra fp_end + +| set flags for decode macros for fmovem control register +do_fmovem=1 +do_fmovem_cr=1 + +fp_fmovem_cr: + printf PDECODE,"fmovem.cr " + | get register list and count them + bfextu %d2{#19,#3},%d0 + move.l %d0,%d1 + swap %d1 + jra 2f +1: addq.w #1,%d1 +2: lsr.l #1,%d0 + jcs 1b + jne 2b + printf PDECODE,"#%08x",1,%d1 +#ifdef FPU_EMU_DEBUG + btst #13,%d2 + jeq 1f + printf PDECODE,"->" | fpu -> cpu + jra 2f +1: printf PDECODE,"<-" | fpu <- cpu +2: +#endif + + | decode address mode + fp_decode_addr_mode + + .long fpc_data, fpc_addr + .long fpc_indirect, fpc_postinc + .long fpc_predecr, fpc_disp16 + .long fpc_extmode0, fpc_extmode1 + +fpc_data: + fp_mode_data_direct + move.w %d0,%d1 + bfffo %d2{#19,#3},%d0 + sub.w #19,%d0 + lea (FPD_FPCR,FPDATA,%d0.w*4),%a1 + btst #13,%d2 + jne 1f + move.w %d1,%d0 + jsr fp_get_data_reg + move.l %d0,(%a1) + jra fpc_movem_fin +1: move.l (%a1),%d0 + jsr fp_put_data_reg + jra fpc_movem_fin + +fpc_addr: + fp_decode_addr_reg + printf PDECODE,"a%d",1,%d0 + btst #13,%d2 + jne 1f + jsr fp_get_addr_reg + move.l %a0,(FPD_FPIAR,FPDATA) + jra fpc_movem_fin +1: move.l (FPD_FPIAR,FPDATA),%a0 + jsr fp_put_addr_reg + jra fpc_movem_fin + +fpc_indirect: + fp_mode_addr_indirect + jra fpc_do_movem + +fpc_postinc: + fp_mode_addr_indirect_postinc + jra fpc_do_movem + +fpc_predecr: + fp_mode_addr_indirect_predec + jra fpc_do_movem + +fpc_disp16: + fp_mode_addr_indirect_disp16 + jra fpc_do_movem + +fpc_extmode0: + fp_mode_addr_indirect_extmode0 + jra fpc_do_movem + +fpc_extmode1: + fp_decode_addr_reg + jmp ([0f:w,%pc,%d0*4]) + + .align 4 +0: + .long fpc_absolute_short, fpc_absolute_long + .long fpc_disp16, fpc_extmode0 + .long fpc_immediate, fp_ill + .long fp_ill, fp_ill + +fpc_absolute_short: + fp_mode_abs_short + jra fpc_do_movem + +fpc_absolute_long: + fp_mode_abs_long + jra fpc_do_movem + +fpc_immediate: + fp_get_pc %a0 + lea (%a0,%d1.w*4),%a1 + fp_put_pc %a1 + printf PDECODE,"#imm" +| jra fpc_do_movem +#if 0 + swap %d1 + lsl.l #5,%d1 + lea (FPD_FPCR,FPDATA),%a0 + jra 3f +1: move.l %d0,(%a0) +2: addq.l #4,%a0 +3: lsl.b #1,%d1 + jcs 1b + jne 2b + jra fpc_movem_fin +#endif + +fpc_do_movem: + swap %d1 | get fpu register list + lsl.l #5,%d1 + lea (FPD_FPCR,FPDATA),%a1 +1: btst #13,%d2 + jne 4f + + | move register from memory into fpu + jra 3f +1: printf PMOVEM,"(%p>%p)",2,%a0,%a1 + getuser.l (%a0)+,%d0,fp_err_ua1,%a0 + move.l %d0,(%a1) +2: addq.l #4,%a1 +3: lsl.b #1,%d1 + jcs 1b + jne 2b + jra fpc_movem_fin + + | move register from fpu into memory +1: printf PMOVEM,"(%p>%p)",2,%a1,%a0 + move.l (%a1),%d0 + putuser.l %d0,(%a0)+,fp_err_ua1,%a0 +2: addq.l #4,%a1 +4: lsl.b #1,%d1 + jcs 1b + jne 2b + +fpc_movem_fin: + and.l #0x0000fff0,(FPD_FPCR,FPDATA) + and.l #0x0ffffff8,(FPD_FPSR,FPDATA) + move.l (FPD_FPCR,FPDATA),%d0 + lsr.l #4,%d0 + moveq #3,%d1 + and.l %d0,%d1 + move.w %d1,(FPD_RND,FPDATA) + lsr.l #2,%d0 + moveq #3,%d1 + and.l %d0,%d1 + move.w %d1,(FPD_PREC,FPDATA) + printf PDECODE,"\n" +#if 0 + printf PMOVEM,"fpcr : %08x\n",1,FPDATA@(FPD_FPCR) + printf PMOVEM,"fpsr : %08x\n",1,FPDATA@(FPD_FPSR) + printf PMOVEM,"fpiar: %08x\n",1,FPDATA@(FPD_FPIAR) + clr.l %d0 + move.w (FPD_PREC,FPDATA),%d0 + printf PMOVEM,"prec : %04x\n",1,%d0 + move.w (FPD_RND,FPDATA),%d0 + printf PMOVEM,"rnd : %04x\n",1,%d0 +#endif + jra fp_end diff -u --recursive --new-file v2.3.13/linux/arch/m68k/math-emu/fp_scan.S linux/arch/m68k/math-emu/fp_scan.S --- v2.3.13/linux/arch/m68k/math-emu/fp_scan.S Wed Dec 31 16:00:00 1969 +++ linux/arch/m68k/math-emu/fp_scan.S Sun Aug 15 11:47:29 1999 @@ -0,0 +1,478 @@ +/* + * fp_scan.S + * + * Copyright Roman Zippel, 1997. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fp_emu.h" +#include "fp_decode.h" + + .globl fp_scan, fp_datasize + + .data + +| %d2 - first two instr words +| %d1 - operand size + +/* operand formats are: + + Long = 0, i.e. fmove.l + Single, i.e. fmove.s + Extended, i.e. fmove.x + Packed-BCD, i.e. fmove.p + Word, i.e. fmove.w + Double, i.e. fmove.d +*/ + + .text + +| On entry: +| FPDATA - base of emulated FPU registers + +fp_scan: +| normal fpu instruction? (this excludes fsave/frestore) + fp_get_pc %a0 + printf PDECODE,"%08x: ",1,%a0 + getuser.b (%a0),%d0,fp_err_ua1,%a0 +#if 1 + cmp.b #0xf2,%d0 | cpid = 1 +#else + cmp.b #0xfc,%d0 | cpid = 6 +#endif + jne fp_nonstd +| first two instruction words are kept in %d2 + getuser.l (%a0)+,%d2,fp_err_ua1,%a0 + fp_put_pc %a0 +fp_decode_cond: | seperate conditional instr + fp_decode_cond_instr_type + + .long fp_decode_move, fp_fscc + .long fp_fbccw, fp_fbccl + +fp_decode_move: | seperate move instr + fp_decode_move_instr_type + + .long fp_fgen_fp, fp_ill + .long fp_fgen_ea, fp_fmove_fp2mem + .long fp_fmovem_cr, fp_fmovem_cr + .long fp_fmovem_fp, fp_fmovem_fp + +| now all arithmetic instr and a few move instr are left +fp_fgen_fp: | source is a fpu register + clr.b (FPD_FPSR+2,FPDATA) | clear the exception byte + fp_decode_sourcespec + printf PDECODE,"f.x fp%d",1,%d0 + fp_get_fp_reg + lea (FPD_TEMPFP1,FPDATA),%a1 | copy src into a temp location + move.l (%a0)+,(%a1)+ + move.l (%a0)+,(%a1)+ + move.l (%a0),(%a1) + lea (-8,%a1),%a0 + jra fp_getdest + +fp_fgen_ea: | source is + clr.b (FPD_FPSR+2,FPDATA) | clear the exception byte + | sort out fmovecr, keep data size in %d1 + fp_decode_sourcespec + cmp.w #7,%d0 + jeq fp_fmovecr + move.w %d0,%d1 | store data size twice in %d1 + swap %d1 | one can be trashed below + move.w %d0,%d1 +#ifdef FPU_EMU_DEBUG + lea 0f,%a0 + clr.l %d0 + move.b (%a0,%d1.w),%d0 + printf PDECODE,"f.%c ",1,%d0 + + .data +0: .byte 'l','s','x','p','w','d','b',0 + .previous +#endif + +/* + fp_getsource, fp_getdest + + basically, we end up with a pointer to the source operand in + %a1, and a pointer to the destination operand in %a0. both + are, of course, 96-bit extended floating point numbers. +*/ + +fp_getsource: + | decode addressing mode for source + fp_decode_addr_mode + + .long fp_data, fp_ill + .long fp_indirect, fp_postinc + .long fp_predecr, fp_disp16 + .long fp_extmode0, fp_extmode1 + + | addressing mode: data register direct +fp_data: + fp_mode_data_direct + jsr fp_get_data_reg + lea (FPD_TEMPFP1,FPDATA),%a0 + jmp ([0f:w,%pc,%d1.w*4]) + + .align 4 +0: + .long fp_data_long, fp_data_single + .long fp_ill, fp_ill + .long fp_data_word, fp_ill + .long fp_data_byte, fp_ill + + | data types that fit in an integer data register +fp_data_byte: + extb.l %d0 + jra fp_data_long + +fp_data_word: + ext.l %d0 + +fp_data_long: + jsr fp_conv_long2ext + jra fp_getdest + +fp_data_single: + jsr fp_conv_single2ext + jra fp_getdest + + | addressing mode: address register indirect +fp_indirect: + fp_mode_addr_indirect + jra fp_fetchsource + + | addressing mode: address register indirect with postincrement +fp_postinc: + fp_mode_addr_indirect_postinc + jra fp_fetchsource + + | addressing mode: address register indirect with predecrement +fp_predecr: + fp_mode_addr_indirect_predec + jra fp_fetchsource + + | addressing mode: address register/programm counter indirect + | with 16bit displacement +fp_disp16: + fp_mode_addr_indirect_disp16 + jra fp_fetchsource + + | all other indirect addressing modes will finally end up here +fp_extmode0: + fp_mode_addr_indirect_extmode0 + jra fp_fetchsource + +| all pc relative addressing modes and immediate/absolute modes end up here +| the first ones are sent to fp_extmode0 or fp_disp16 +| and only the latter are handled here +fp_extmode1: + fp_decode_addr_reg + jmp ([0f:w,%pc,%d0*4]) + + .align 4 +0: + .long fp_abs_short, fp_abs_long + .long fp_disp16, fp_extmode0 + .long fp_immediate, fp_ill + .long fp_ill, fp_ill + + | addressing mode: absolute short +fp_abs_short: + fp_mode_abs_short + jra fp_fetchsource + + | addressing mode: absolute long +fp_abs_long: + fp_mode_abs_long + jra fp_fetchsource + + | addressing mode: immediate data +fp_immediate: + printf PDECODE,"#" + fp_get_pc %a0 + move.w (fp_datasize,%d1.w*2),%d0 + addq.w #1,%d0 + and.w #-2,%d0 +#ifdef FPU_EMU_DEBUG + movem.l %d0/%d1,-(%sp) + movel %a0,%a1 + clr.l %d1 + jra 2f +1: getuser.b (%a1)+,%d1,fp_err_ua1,%a1 + printf PDECODE,"%02x",1,%d1 +2: dbra %d0,1b + movem.l (%sp)+,%d0/%d1 +#endif + lea (%a0,%d0.w),%a1 + fp_put_pc %a1 +| jra fp_fetchsource + +fp_fetchsource: + move.l %a0,%a1 + swap %d1 + lea (FPD_TEMPFP1,FPDATA),%a0 + jmp ([0f:w,%pc,%d1.w*4]) + + .align 4 +0: .long fp_long, fp_single + .long fp_ext, fp_pack + .long fp_word, fp_double + .long fp_byte, fp_ill + +fp_long: + getuser.l (%a1),%d0,fp_err_ua1,%a1 + jsr fp_conv_long2ext + jra fp_getdest + +fp_single: + getuser.l (%a1),%d0,fp_err_ua1,%a1 + jsr fp_conv_single2ext + jra fp_getdest + +fp_ext: + getuser.l (%a1)+,%d0,fp_err_ua1,%a1 + lsr.l #8,%d0 + lsr.l #7,%d0 + lsr.w #1,%d0 + move.l %d0,(%a0)+ + getuser.l (%a1)+,%d0,fp_err_ua1,%a1 + move.l %d0,(%a0)+ + getuser.l (%a1),%d0,fp_err_ua1,%a1 + move.l %d0,(%a0) + subq.l #8,%a0 + jra fp_getdest + +fp_pack: + /* not supported yet */ + jra fp_ill + +fp_word: + getuser.w (%a1),%d0,fp_err_ua1,%a1 + ext.l %d0 + jsr fp_conv_long2ext + jra fp_getdest + +fp_double: + jsr fp_conv_double2ext + jra fp_getdest + +fp_byte: + getuser.b (%a1),%d0,fp_err_ua1,%a1 + extb.l %d0 + jsr fp_conv_long2ext +| jra fp_getdest + +fp_getdest: + move.l %a0,%a1 + bfextu %d2{#22,#3},%d0 + printf PDECODE,",fp%d\n",1,%d0 + fp_get_fp_reg + movem.l %a0/%a1,-(%sp) + pea fp_finalrounding + bfextu %d2{#25,#7},%d0 + jmp ([0f:w,%pc,%d0*4]) + + .align 4 +0: + .long fp_fmove_mem2fp, fp_fint, fp_fsinh, fp_fintrz + .long fp_fsqrt, fp_ill, fp_flognp1, fp_ill + .long fp_fetoxm1, fp_ftanh, fp_fatan, fp_ill + .long fp_fasin, fp_fatanh, fp_fsin, fp_ftan + .long fp_fetox, fp_ftwotox, fp_ftentox, fp_ill + .long fp_flogn, fp_flog10, fp_flog2, fp_ill + .long fp_fabs, fp_fcosh, fp_fneg, fp_ill + .long fp_facos, fp_fcos, fp_fgetexp, fp_fgetman + .long fp_fdiv, fp_fmod, fp_fadd, fp_fmul + .long fpa_fsgldiv, fp_frem, fp_fscale, fpa_fsglmul + .long fp_fsub, fp_ill, fp_ill, fp_ill + .long fp_ill, fp_ill, fp_ill, fp_ill + .long fp_fsincos0, fp_fsincos1, fp_fsincos2, fp_fsincos3 + .long fp_fsincos4, fp_fsincos5, fp_fsincos6, fp_fsincos7 + .long fp_fcmp, fp_ill, fp_ftst, fp_ill + .long fp_ill, fp_ill, fp_ill, fp_ill + .long fp_fsmove, fp_fssqrt, fp_ill, fp_ill + .long fp_fdmove, fp_fdsqrt, fp_ill, fp_ill + .long fp_ill, fp_ill, fp_ill, fp_ill + .long fp_ill, fp_ill, fp_ill, fp_ill + .long fp_ill, fp_ill, fp_ill, fp_ill + .long fp_ill, fp_ill, fp_ill, fp_ill + .long fp_fsabs, fp_ill, fp_fsneg, fp_ill + .long fp_fdabs, fp_ill, fp_fdneg, fp_ill + .long fp_fsdiv, fp_ill, fp_fsadd, fp_fsmul + .long fp_fddiv, fp_ill, fp_fdadd, fp_fdmul + .long fp_fssub, fp_ill, fp_ill, fp_ill + .long fp_fdsub, fp_ill, fp_ill, fp_ill + .long fp_ill, fp_ill, fp_ill, fp_ill + .long fp_ill, fp_ill, fp_ill, fp_ill + .long fp_ill, fp_ill, fp_ill, fp_ill + .long fp_ill, fp_ill, fp_ill, fp_ill + + | Instructions follow + + | Move an (emulated) ROM constant +fp_fmovecr: + bfextu %d2{#27,#5},%d0 + printf PINSTR,"fp_fmovecr #%d",1,%d0 + move.l %d0,%d1 + add.l %d0,%d0 + add.l %d1,%d0 + lea (fp_constants,%d0*4),%a0 + move.l #0x801cc0ff,%d0 + addq.l #1,%d1 + lsl.l %d1,%d0 + jcc 1f + fp_set_sr FPSR_EXC_INEX2 | INEX2 exception +1: moveq #-128,%d0 | continue with fmove + and.l %d0,%d2 + jra fp_getdest + + .data + .align 4 +fp_constants: + .long 0x00004000,0xc90fdaa2,0x2168c235 | pi + .extend 0,0,0,0,0,0,0,0,0,0 + .long 0x00003ffd,0x9a209a84,0xfbcff798 | log10(2) + .long 0x00004000,0xadf85458,0xa2bb4a9a | e + .long 0x00003fff,0xb8aa3b29,0x5c17f0bc | log2(e) + .long 0x00003ffd,0xde5bd8a9,0x37287195 | log10(e) + .long 0x00000000,0x00000000,0x00000000 | 0.0 + .long 0x00003ffe,0xb17217f7,0xd1cf79ac | 1n(2) + .long 0x00004000,0x935d8ddd,0xaaa8ac17 | 1n(10) + | read this as "1.0 * 2^0" - note the high bit in the mantissa + .long 0x00003fff,0x80000000,0x00000000 | 10^0 + .long 0x00004002,0xa0000000,0x00000000 | 10^1 + .long 0x00004005,0xc8000000,0x00000000 | 10^2 + .long 0x0000400c,0x9c400000,0x00000000 | 10^4 + .long 0x00004019,0xbebc2000,0x00000000 | 10^8 + .long 0x00004034,0x8e1bc9bf,0x04000000 | 10^16 + .long 0x00004069,0x9dc5ada8,0x2b70b59e | 10^32 + .long 0x000040d3,0xc2781f49,0xffcfa6d5 | 10^64 + .long 0x000041a8,0x93ba47c9,0x80e98ce0 | 10^128 + .long 0x00004351,0xaa7eebfb,0x9df9de8e | 10^256 + .long 0x000046a3,0xe319a0ae,0xa60e91c7 | 10^512 + .long 0x00004d48,0xc9767586,0x81750c17 | 10^1024 + .long 0x00005a92,0x9e8b3b5d,0xc53d5de5 | 10^2048 + .long 0x00007525,0xc4605202,0x8a20979b | 10^4096 + .previous + +fp_fmove_mem2fp: + printf PINSTR,"fmove %p,%p\n",2,%a0,%a1 + move.l (%a1)+,(%a0)+ + move.l (%a1)+,(%a0)+ + move.l (%a1),(%a0) + subq.l #8,%a0 + rts + +fpa_fsglmul: + move.l #fp_finalrounding_single_fast,(%sp) + jra fp_fsglmul + +fpa_fsgldiv: + move.l #fp_finalrounding_single_fast,(%sp) + jra fp_fsgldiv + +.macro fp_dosingleprec instr + printf PINSTR,"single " + move.l #fp_finalrounding_single,(%sp) + jra \instr +.endm + +.macro fp_dodoubleprec instr + printf PINSTR,"double " + move.l #fp_finalrounding_double,(%sp) + jra \instr +.endm + +fp_fsmove: + fp_dosingleprec fp_fmove_mem2fp + +fp_fssqrt: + fp_dosingleprec fp_fsqrt + +fp_fdmove: + fp_dodoubleprec fp_fmove_mem2fp + +fp_fdsqrt: + fp_dodoubleprec fp_fsqrt + +fp_fsabs: + fp_dosingleprec fp_fabs + +fp_fsneg: + fp_dosingleprec fp_fneg + +fp_fdabs: + fp_dodoubleprec fp_fabs + +fp_fdneg: + fp_dodoubleprec fp_fneg + +fp_fsdiv: + fp_dosingleprec fp_fdiv + +fp_fsadd: + fp_dosingleprec fp_fadd + +fp_fsmul: + fp_dosingleprec fp_fmul + +fp_fddiv: + fp_dodoubleprec fp_fdiv + +fp_fdadd: + fp_dodoubleprec fp_fadd + +fp_fdmul: + fp_dodoubleprec fp_fmul + +fp_fssub: + fp_dosingleprec fp_fsub + +fp_fdsub: + fp_dodoubleprec fp_fsub + +fp_nonstd: + fp_get_pc %a0 + getuser.l (%a0),%d0,fp_err_ua1,%a0 + printf ,"nonstd ((%08x)=%08x)\n",2,%a0,%d0 + moveq #-1,%d0 + rts + + .data + .align 4 + + | data sizes corresponding to the operand formats +fp_datasize: + .word 4, 4, 12, 12, 2, 8, 1, 0 diff -u --recursive --new-file v2.3.13/linux/arch/m68k/math-emu/fp_trig.c linux/arch/m68k/math-emu/fp_trig.c --- v2.3.13/linux/arch/m68k/math-emu/fp_trig.c Wed Dec 31 16:00:00 1969 +++ linux/arch/m68k/math-emu/fp_trig.c Sun Aug 15 11:47:29 1999 @@ -0,0 +1,183 @@ +/* + + fp_trig.c: floating-point math routines for the Linux-m68k + floating point emulator. + + Copyright (c) 1998-1999 David Huggins-Daines / Roman Zippel. + + I hereby give permission, free of charge, to copy, modify, and + redistribute this software, in source or binary form, provided that + the above copyright notice and the following disclaimer are included + in all such copies. + + THIS SOFTWARE IS PROVIDED "AS IS", WITH ABSOLUTELY NO WARRANTY, REAL + OR IMPLIED. + +*/ + +#include "fp_emu.h" +#include "fp_trig.h" + +struct fp_ext * +fp_fsin(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fsin\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_fcos(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fcos\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_ftan(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("ftan\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_fasin(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fasin\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_facos(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("facos\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_fatan(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fatan\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_fsinh(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fsinh\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_fcosh(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fcosh\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_ftanh(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("ftanh\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_fatanh(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fatanh\n"); + + fp_monadic_check(dest, src); + + return dest; +} + +struct fp_ext * +fp_fsincos0(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fsincos0\n"); + + return dest; +} + +struct fp_ext * +fp_fsincos1(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fsincos1\n"); + + return dest; +} + +struct fp_ext * +fp_fsincos2(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fsincos2\n"); + + return dest; +} + +struct fp_ext * +fp_fsincos3(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fsincos3\n"); + + return dest; +} + +struct fp_ext * +fp_fsincos4(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fsincos4\n"); + + return dest; +} + +struct fp_ext * +fp_fsincos5(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fsincos5\n"); + + return dest; +} + +struct fp_ext * +fp_fsincos6(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fsincos6\n"); + + return dest; +} + +struct fp_ext * +fp_fsincos7(struct fp_ext *dest, struct fp_ext *src) +{ + uprint("fsincos7\n"); + + return dest; +} diff -u --recursive --new-file v2.3.13/linux/arch/m68k/math-emu/fp_trig.h linux/arch/m68k/math-emu/fp_trig.h --- v2.3.13/linux/arch/m68k/math-emu/fp_trig.h Wed Dec 31 16:00:00 1969 +++ linux/arch/m68k/math-emu/fp_trig.h Sun Aug 15 11:47:29 1999 @@ -0,0 +1,32 @@ +/* + + fp_trig.h: floating-point math routines for the Linux-m68k + floating point emulator. + + Copyright (c) 1998 David Huggins-Daines. + + I hereby give permission, free of charge, to copy, modify, and + redistribute this software, in source or binary form, provided that + the above copyright notice and the following disclaimer are included + in all such copies. + + THIS SOFTWARE IS PROVIDED "AS IS", WITH ABSOLUTELY NO WARRANTY, REAL + OR IMPLIED. + +*/ + +#ifndef FP_TRIG_H +#define FP_TRIG_H + +#include "fp_emu.h" + +/* floating point trigonometric instructions: + + the arguments to these are in the "internal" extended format, that + is, an "exploded" version of the 96-bit extended fp format used by + the 68881. + + they return a status code, which should end up in %d0, if all goes + well. */ + +#endif /* FP_TRIG__H */ diff -u --recursive --new-file v2.3.13/linux/arch/m68k/math-emu/fp_util.S linux/arch/m68k/math-emu/fp_util.S --- v2.3.13/linux/arch/m68k/math-emu/fp_util.S Wed Dec 31 16:00:00 1969 +++ linux/arch/m68k/math-emu/fp_util.S Tue Aug 17 10:39:17 1999 @@ -0,0 +1,1456 @@ +/* + * fp_util.S + * + * Copyright Roman Zippel, 1997. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include "fp_emu.h" + +/* + * Here are lots of conversion and normalization functions mainly + * used by fp_scan.S + * Note that these functions are optimized for "normal" numbers, + * these are handled first and exit as fast as possible, this is + * especially important for fp_normalize_ext/fp_conv_ext2ext, as + * it's called very often. + * The register usage is optimized for fp_scan.S and which register + * is currently at that time unused, be careful if you want change + * something here. %d0 and %d1 is always usable, sometimes %d2 (or + * only the lower half) most function have to return the %a0 + * unmodified, so that the caller can immediatly reuse it. + */ + + .globl fp_ill, fp_end + + | exits from fp_scan: + | illegal instruction +fp_ill: + printf ,"fp_illegal\n" + rts + | completed instruction +fp_end: + tst.l (TASK_MM-8,%a2) + jmi 1f + tst.l (TASK_MM-4,%a2) + jmi 1f + tst.l (TASK_MM,%a2) + jpl 2f +1: printf ,"oops:%p,%p,%p\n",3,%a2@(TASK_MM-8),%a2@(TASK_MM-4),%a2@(TASK_MM) +2: clr.l %d0 + rts + + .globl fp_conv_long2ext, fp_conv_single2ext + .globl fp_conv_double2ext, fp_conv_ext2ext + .globl fp_normalize_ext, fp_normalize_double + .globl fp_normalize_single, fp_normalize_single_fast + .globl fp_conv_ext2double, fp_conv_ext2single + .globl fp_conv_ext2long, fp_conv_ext2short + .globl fp_conv_ext2byte + .globl fp_finalrounding_single, fp_finalrounding_single_fast + .globl fp_finalrounding_double + .globl fp_finalrounding, fp_finaltest, fp_final + +/* + * First several conversion functions from a source operand + * into the extended format. Note, that only fp_conv_ext2ext + * normalizes the number and is always called after the other + * conversion functions, which only move the information into + * fp_ext structure. + */ + + | fp_conv_long2ext: + | + | args: %d0 = source (32-bit long) + | %a0 = destination (ptr to struct fp_ext) + +fp_conv_long2ext: + printf PCONV,"l2e: %p -> %p(",2,%d0,%a0 + clr.l %d1 | sign defaults to zero + tst.l %d0 + jeq fp_l2e_zero | is source zero? + jpl 1f | positive? + moveq #1,%d1 + neg.l %d0 +1: swap %d1 + move.w #0x3fff+31,%d1 + move.l %d1,(%a0)+ | set sign / exp + move.l %d0,(%a0)+ | set mantissa + clr.l (%a0) + subq.l #8,%a0 | restore %a0 + printx PCONV,%a0@ + printf PCONV,")\n" + rts + | source is zero +fp_l2e_zero: + clr.l (%a0)+ + clr.l (%a0)+ + clr.l (%a0) + subq.l #8,%a0 + printx PCONV,%a0@ + printf PCONV,")\n" + rts + + | fp_conv_single2ext + | args: %d0 = source (single-precision fp value) + | %a0 = dest (struct fp_ext *) + +fp_conv_single2ext: + printf PCONV,"s2e: %p -> %p(",2,%d0,%a0 + move.l %d0,%d1 + lsl.l #8,%d0 | shift mantissa + lsr.l #8,%d1 | exponent / sign + lsr.l #7,%d1 + lsr.w #8,%d1 + jeq fp_s2e_small | zero / denormal? + cmp.w #0xff,%d1 | NaN / Inf? + jeq fp_s2e_large + bset #31,%d0 | set explizit bit + add.w #0x3fff-0x7f,%d1 | re-bias the exponent. +9: move.l %d1,(%a0)+ | fp_ext.sign, fp_ext.exp + move.l %d0,(%a0)+ | high lword of fp_ext.mant + clr.l (%a0) | low lword = 0 + subq.l #8,%a0 + printx PCONV,%a0@ + printf PCONV,")\n" + rts + | zeros and denormalized +fp_s2e_small: + | exponent is zero, so explizit bit is already zero too + tst.l %d0 + jeq 9b + move.w #0x4000-0x7f,%d1 + jra 9b + | infinities and NAN +fp_s2e_large: + bclr #31,%d0 | clear explizit bit + move.w #0x7fff,%d1 + jra 9b + +fp_conv_double2ext: +#ifdef FPU_EMU_DEBUG + getuser.l %a1@(0),%d0,fp_err_ua2,%a1 + getuser.l %a1@(4),%d1,fp_err_ua2,%a1 + printf PCONV,"d2e: %p%p -> %p(",3,%d0,%d1,%a0 +#endif + getuser.l (%a1)+,%d0,fp_err_ua2,%a1 + move.l %d0,%d1 + lsl.l #8,%d0 | shift high mantissa + lsl.l #3,%d0 + lsr.l #8,%d1 | exponent / sign + lsr.l #7,%d1 + lsr.w #5,%d1 + jeq fp_d2e_small | zero / denormal? + cmp.w #0x7ff,%d1 | NaN / Inf? + jeq fp_d2e_large + bset #31,%d0 | set explizit bit + add.w #0x3fff-0x3ff,%d1 | re-bias the exponent. +9: move.l %d1,(%a0)+ | fp_ext.sign, fp_ext.exp + move.l %d0,(%a0)+ + getuser.l (%a1)+,%d0,fp_err_ua2,%a1 + move.l %d0,%d1 + lsl.l #8,%d0 + lsl.l #3,%d0 + move.l %d0,(%a0) + moveq #21,%d0 + lsr.l %d0,%d1 + or.l %d1,-(%a0) + subq.l #4,%a0 + printx PCONV,%a0@ + printf PCONV,")\n" + rts + | zeros and denormalized +fp_d2e_small: + | exponent is zero, so explizit bit is already zero too + tst.l %d0 + jeq 9b + move.w #0x4000-0x3ff,%d1 + jra 9b + | infinities and NAN +fp_d2e_large: + bclr #31,%d0 | clear explizit bit + move.w #0x7fff,%d1 + jra 9b + + | fp_conv_ext2ext: + | originally used to get longdouble from userspace, now it's + | called before arithmetic operations to make sure the number + | is normalized [maybe rename it?]. + | args: %a0 = dest (struct fp_ext *) + | returns 0 in %d0 for a NaN, otherwise 1 + +fp_conv_ext2ext: + printf PCONV,"e2e: %p(",1,%a0 + printx PCONV,%a0@ + printf PCONV,"), " + move.l (%a0)+,%d0 + cmp.w #0x7fff,%d0 | Inf / NaN? + jeq fp_e2e_large + move.l (%a0),%d0 + jpl fp_e2e_small | zero / denorm? + | The high bit is set, so normalization is irrelevant. +fp_e2e_checkround: + subq.l #4,%a0 +#ifdef CONFIG_M68KFPU_EMU_EXTRAPREC + move.b (%a0),%d0 + jne fp_e2e_round +#endif + printf PCONV,"%p(",1,%a0 + printx PCONV,%a0@ + printf PCONV,")\n" + moveq #1,%d0 + rts +#ifdef CONFIG_M68KFPU_EMU_EXTRAPREC +fp_e2e_round: + fp_set_sr FPSR_EXC_INEX2 + clr.b (%a0) + move.w (FPD_RND,FPDATA),%d2 + jne fp_e2e_roundother | %d2 == 0, round to nearest + tst.b %d0 | test guard bit + jpl 9f | zero is closer + btst #0,(11,%a0) | test lsb bit + jne fp_e2e_doroundup | round to infinity + lsl.b #1,%d0 | check low bits + jeq 9f | round to zero +fp_e2e_doroundup: + addq.l #1,(8,%a0) + jcc 9f + addq.l #1,(4,%a0) + jcc 9f + move.w #0x8000,(4,%a0) + addq.w #1,(2,%a0) +9: printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts +fp_e2e_roundother: + subq.w #2,%d2 + jcs 9b | %d2 < 2, round to zero + jhi 1f | %d2 > 2, round to +infinity + tst.b (1,%a0) | to -inf + jne fp_e2e_doroundup | negative, round to infinity + jra 9b | positive, round to zero +1: tst.b (1,%a0) | to +inf + jeq fp_e2e_doroundup | positive, round to infinity + jra 9b | negative, round to zero +#endif + | zeros and subnormals: + | try to normalize these anyway. +fp_e2e_small: + jne fp_e2e_small1 | high lword zero? + move.l (4,%a0),%d0 + jne fp_e2e_small2 +#ifdef CONFIG_M68KFPU_EMU_EXTRAPREC + clr.l %d0 + move.b (-4,%a0),%d0 + jne fp_e2e_small3 +#endif + | Genuine zero. + clr.w -(%a0) + subq.l #2,%a0 + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + moveq #1,%d0 + rts + | definitely subnormal, need to shift all 64 bits +fp_e2e_small1: + bfffo %d0{#0,#32},%d1 + move.w -(%a0),%d2 + sub.w %d1,%d2 + jcc 1f + | Pathologically small, denormalize. + add.w %d2,%d1 + clr.w %d2 +1: move.w %d2,(%a0)+ + move.w %d1,%d2 + jeq fp_e2e_checkround + | fancy 64-bit double-shift begins here + lsl.l %d2,%d0 + move.l %d0,(%a0)+ + move.l (%a0),%d0 + move.l %d0,%d1 + lsl.l %d2,%d0 + move.l %d0,(%a0) + neg.w %d2 + and.w #0x1f,%d2 + lsr.l %d2,%d1 + or.l %d1,-(%a0) +#ifdef CONFIG_M68KFPU_EMU_EXTRAPREC +fp_e2e_extra1: + clr.l %d0 + move.b (-4,%a0),%d0 + neg.w %d2 + add.w #24,%d2 + jcc 1f + clr.b (-4,%a0) + lsl.l %d2,%d0 + or.l %d0,(4,%a0) + jra fp_e2e_checkround +1: addq.w #8,%d2 + lsl.l %d2,%d0 + move.b %d0,(-4,%a0) + lsr.l #8,%d0 + or.l %d0,(4,%a0) +#endif + jra fp_e2e_checkround + | pathologically small subnormal +fp_e2e_small2: + bfffo %d0{#0,#32},%d1 + add.w #32,%d1 + move.w -(%a0),%d2 + sub.w %d1,%d2 + jcc 1f + | Beyond pathologically small, denormalize. + add.w %d2,%d1 + clr.w %d2 +1: move.w %d2,(%a0)+ + ext.l %d1 + jeq fp_e2e_checkround + clr.l (4,%a0) + sub.w #32,%d2 + jcs 1f + lsl.l %d1,%d0 | lower lword needs only to be shifted + move.l %d0,(%a0) | into the higher lword +#ifdef CONFIG_M68KFPU_EMU_EXTRAPREC + clr.l %d0 + move.b (-4,%a0),%d0 + clr.b (-4,%a0) + neg.w %d1 + add.w #32,%d1 + bfins %d0,(%a0){%d1,#8} +#endif + jra fp_e2e_checkround +1: neg.w %d1 | lower lword is splitted between + bfins %d0,(%a0){%d1,#32} | higher and lower lword +#ifndef CONFIG_M68KFPU_EMU_EXTRAPREC + jra fp_e2e_checkround +#else + move.w %d1,%d2 + jra fp_e2e_extra1 + | These are extremely small numbers, that will mostly end up as zero + | anyway, so this is only important for correct rounding. +fp_e2e_small3: + bfffo %d0{#24,#8},%d1 + add.w #40,%d1 + move.w -(%a0),%d2 + sub.w %d1,%d2 + jcc 1f + | Pathologically small, denormalize. + add.w %d2,%d1 + clr.w %d2 +1: move.w %d2,(%a0)+ + ext.l %d1 + jeq fp_e2e_checkround + cmp.w #8,%d1 + jcs 2f +1: clr.b (-4,%a0) + sub.w #64,%d1 + jcs 1f + add.w #24,%d1 + lsl.l %d1,%d0 + move.l %d0,(%a0) + jra fp_e2e_checkround +1: neg.w %d1 + bfins %d0,(%a0){%d1,#8} + jra fp_e2e_checkround +2: lsl.l %d1,%d0 + move.b %d0,(-4,%a0) + lsr.l #8,%d0 + move.b %d0,(7,%a0) + jra fp_e2e_checkround +#endif +1: move.l %d0,%d1 | lower lword is splitted between + lsl.l %d2,%d0 | higher and lower lword + move.l %d0,(%a0) + move.l %d1,%d0 + neg.w %d2 + add.w #32,%d2 + lsr.l %d2,%d0 + move.l %d0,-(%a0) + jra fp_e2e_checkround + | Infinities and NaNs +fp_e2e_large: + move.l (%a0)+,%d0 + jne 3f +1: tst.l (%a0) + jne 4f + moveq #1,%d0 +2: subq.l #8,%a0 + printf PCONV,"%p(",1,%a0 + printx PCONV,%a0@ + printf PCONV,")\n" + rts + | we have maybe a NaN, shift off the highest bit +3: lsl.l #1,%d0 + jeq 1b + | we have a NaN, clear the return value +4: clrl %d0 + jra 2b + + +/* + * Normalization functions. Call these on the output of general + * FP operators, and before any conversion into the destination + * formats. fp_normalize_ext has always to be called first, the + * following conversion functions expect an already normalized + * number. + */ + + | fp_normalize_ext: + | normalize an extended in extended (unpacked) format, basically + | it does the same as fp_conv_ext2ext, additionally it also does + | the necessary postprocessing checks. + | args: %a0 (struct fp_ext *) + | NOTE: it does _not_ modify %a0/%a1 and the upper word of %d2 + +fp_normalize_ext: + printf PNORM,"ne: %p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,"), " + move.l (%a0)+,%d0 + cmp.w #0x7fff,%d0 | Inf / NaN? + jeq fp_ne_large + move.l (%a0),%d0 + jpl fp_ne_small | zero / denorm? + | The high bit is set, so normalization is irrelevant. +fp_ne_checkround: + subq.l #4,%a0 +#ifdef CONFIG_M68KFPU_EMU_EXTRAPREC + move.b (%a0),%d0 + jne fp_ne_round +#endif + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts +#ifdef CONFIG_M68KFPU_EMU_EXTRAPREC +fp_ne_round: + fp_set_sr FPSR_EXC_INEX2 + clr.b (%a0) + move.w (FPD_RND,FPDATA),%d2 + jne fp_ne_roundother | %d2 == 0, round to nearest + tst.b %d0 | test guard bit + jpl 9f | zero is closer + btst #0,(11,%a0) | test lsb bit + jne fp_ne_doroundup | round to infinity + lsl.b #1,%d0 | check low bits + jeq 9f | round to zero +fp_ne_doroundup: + addq.l #1,(8,%a0) + jcc 9f + addq.l #1,(4,%a0) + jcc 9f + addq.w #1,(2,%a0) + move.w #0x8000,(4,%a0) +9: printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts +fp_ne_roundother: + subq.w #2,%d2 + jcs 9b | %d2 < 2, round to zero + jhi 1f | %d2 > 2, round to +infinity + tst.b (1,%a0) | to -inf + jne fp_ne_doroundup | negative, round to infinity + jra 9b | positive, round to zero +1: tst.b (1,%a0) | to +inf + jeq fp_ne_doroundup | positive, round to infinity + jra 9b | negative, round to zero +#endif + | Zeros and subnormal numbers + | These are probably merely subnormal, rather than "denormalized" + | numbers, so we will try to make them normal again. +fp_ne_small: + jne fp_ne_small1 | high lword zero? + move.l (4,%a0),%d0 + jne fp_ne_small2 +#ifdef CONFIG_M68KFPU_EMU_EXTRAPREC + clr.l %d0 + move.b (-4,%a0),%d0 + jne fp_ne_small3 +#endif + | Genuine zero. + clr.w -(%a0) + subq.l #2,%a0 + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts + | Subnormal. +fp_ne_small1: + bfffo %d0{#0,#32},%d1 + move.w -(%a0),%d2 + sub.w %d1,%d2 + jcc 1f + | Pathologically small, denormalize. + add.w %d2,%d1 + clr.w %d2 + fp_set_sr FPSR_EXC_UNFL +1: move.w %d2,(%a0)+ + move.w %d1,%d2 + jeq fp_ne_checkround + | This is exactly the same 64-bit double shift as seen above. + lsl.l %d2,%d0 + move.l %d0,(%a0)+ + move.l (%a0),%d0 + move.l %d0,%d1 + lsl.l %d2,%d0 + move.l %d0,(%a0) + neg.w %d2 + and.w #0x1f,%d2 + lsr.l %d2,%d1 + or.l %d1,-(%a0) +#ifdef CONFIG_M68KFPU_EMU_EXTRAPREC +fp_ne_extra1: + clr.l %d0 + move.b (-4,%a0),%d0 + neg.w %d2 + add.w #24,%d2 + jcc 1f + clr.b (-4,%a0) + lsl.l %d2,%d0 + or.l %d0,(4,%a0) + jra fp_ne_checkround +1: addq.w #8,%d2 + lsl.l %d2,%d0 + move.b %d0,(-4,%a0) + lsr.l #8,%d0 + or.l %d0,(4,%a0) +#endif + jra fp_ne_checkround + | May or may not be subnormal, if so, only 32 bits to shift. +fp_ne_small2: + bfffo %d0{#0,#32},%d1 + add.w #32,%d1 + move.w -(%a0),%d2 + sub.w %d1,%d2 + jcc 1f + | Beyond pathologically small, denormalize. + add.w %d2,%d1 + clr.w %d2 + fp_set_sr FPSR_EXC_UNFL +1: move.w %d2,(%a0)+ + ext.l %d1 + jeq fp_ne_checkround + clr.l (4,%a0) + sub.w #32,%d1 + jcs 1f + lsl.l %d1,%d0 | lower lword needs only to be shifted + move.l %d0,(%a0) | into the higher lword +#ifdef CONFIG_M68KFPU_EMU_EXTRAPREC + clr.l %d0 + move.b (-4,%a0),%d0 + clr.b (-4,%a0) + neg.w %d1 + add.w #32,%d1 + bfins %d0,(%a0){%d1,#8} +#endif + jra fp_ne_checkround +1: neg.w %d1 | lower lword is splitted between + bfins %d0,(%a0){%d1,#32} | higher and lower lword +#ifndef CONFIG_M68KFPU_EMU_EXTRAPREC + jra fp_ne_checkround +#else + move.w %d1,%d2 + jra fp_ne_extra1 + | These are extremely small numbers, that will mostly end up as zero + | anyway, so this is only important for correct rounding. +fp_ne_small3: + bfffo %d0{#24,#8},%d1 + add.w #40,%d1 + move.w -(%a0),%d2 + sub.w %d1,%d2 + jcc 1f + | Pathologically small, denormalize. + add.w %d2,%d1 + clr.w %d2 +1: move.w %d2,(%a0)+ + ext.l %d1 + jeq fp_ne_checkround + cmp.w #8,%d1 + jcs 2f +1: clr.b (-4,%a0) + sub.w #64,%d1 + jcs 1f + add.w #24,%d1 + lsl.l %d1,%d0 + move.l %d0,(%a0) + jra fp_ne_checkround +1: neg.w %d1 + bfins %d0,(%a0){%d1,#8} + jra fp_ne_checkround +2: lsl.l %d1,%d0 + move.b %d0,(-4,%a0) + lsr.l #8,%d0 + move.b %d0,(7,%a0) + jra fp_ne_checkround +#endif + | Infinities and NaNs, again, same as above. +fp_ne_large: + move.l (%a0)+,%d0 + jne 3f +1: tst.l (%a0) + jne 4f +2: subq.l #8,%a0 + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts + | we have maybe a NaN, shift off the highest bit +3: move.l %d0,%d1 + lsl.l #1,%d1 + jne 4f + clr.l (-4,%a0) + jra 1b + | we have a NaN, test if it is signaling +4: bset #30,%d0 + jne 2b + fp_set_sr FPSR_EXC_SNAN + move.l %d0,(-4,%a0) + jra 2b + + | these next two do rounding as per the IEEE standard. + | values for the rounding modes appear to be: + | 0: Round to nearest + | 1: Round to zero + | 2: Round to -Infinity + | 3: Round to +Infinity + | both functions expect that fp_normalize was already + | called (and extended argument is already normalized + | as far as possible), these are used if there is different + | rounding precision is selected and before converting + | into single/double + + | fp_normalize_double: + | normalize an extended with double (52-bit) precision + | args: %a0 (struct fp_ext *) + +fp_normalize_double: + printf PNORM,"nd: %p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,"), " + move.l (%a0)+,%d2 + tst.w %d2 + jeq fp_nd_zero | zero / denormalized + cmp.w #0x7fff,%d2 + jeq fp_nd_huge | NaN / infinitive. + sub.w #0x4000-0x3ff,%d2 | will the exponent fit? + jcs fp_nd_small | too small. + cmp.w #0x7fe,%d2 + jcc fp_nd_large | too big. + addq.l #4,%a0 + move.l (%a0),%d0 | low lword of mantissa + | now, round off the low 11 bits. +fp_nd_round: + moveq #21,%d1 + lsl.l %d1,%d0 | keep 11 low bits. + jne fp_nd_checkround | Are they non-zero? + | nothing to do here +9: subq.l #8,%a0 + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts + | Be careful with the X bit! It contains the lsb + | from the shift above, it is needed for round to nearest. +fp_nd_checkround: + fp_set_sr FPSR_EXC_INEX2 | INEX2 bit + and.w #0xf800,(2,%a0) | clear bits 0-10 + move.w (FPD_RND,FPDATA),%d2 | rounding mode + jne 2f | %d2 == 0, round to nearest + tst.l %d0 | test guard bit + jpl 9b | zero is closer + | here we test the X bit by adding it to %d2 + clr.w %d2 | first set z bit, addx only clears it + addx.w %d2,%d2 | test lsb bit + | IEEE754-specified "round to even" behaviour. If the guard + | bit is set, then the number is odd, so rounding works like + | in grade-school arithmetic (i.e. 1.5 rounds to 2.0) + | Otherwise, an equal distance rounds towards zero, so as not + | to produce an odd number. This is strange, but it is what + | the standard says. + jne fp_nd_doroundup | round to infinity + lsl.l #1,%d0 | check low bits + jeq 9b | round to zero +fp_nd_doroundup: + | round (the mantissa, that is) towards infinity + add.l #0x800,(%a0) + jcc 9b | no overflow, good. + addq.l #1,-(%a0) | extend to high lword + jcc 1f | no overflow, good. + | Yow! we have managed to overflow the mantissa. Since this + | only happens when %d1 was 0xfffff800, it is now zero, so + | reset the high bit, and increment the exponent. + move.w #0x8000,(%a0) + addq.w #1,-(%a0) + cmp.w #0x43ff,(%a0)+ | exponent now overflown? + jeq fp_nd_large | yes, so make it infinity. +1: subq.l #4,%a0 + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts +2: subq.w #2,%d2 + jcs 9b | %d2 < 2, round to zero + jhi 3f | %d2 > 2, round to +infinity + | Round to +Inf or -Inf. High word of %d2 contains the + | sign of the number, by the way. + swap %d2 | to -inf + tst.b %d2 + jne fp_nd_doroundup | negative, round to infinity + jra 9b | positive, round to zero +3: swap %d2 | to +inf + tst.b %d2 + jeq fp_nd_doroundup | positive, round to infinity + jra 9b | negative, round to zero + | Exponent underflow. Try to make a denormal, and set it to + | the smallest possible fraction if this fails. +fp_nd_small: + fp_set_sr FPSR_EXC_UNFL | set UNFL bit + move.w #0x3c01,(-2,%a0) | 2**-1022 + neg.w %d2 | degree of underflow + cmp.w #32,%d2 | single or double shift? + jcc 1f + | Again, another 64-bit double shift. + move.l (%a0),%d0 + move.l %d0,%d1 + lsr.l %d2,%d0 + move.l %d0,(%a0)+ + move.l (%a0),%d0 + lsr.l %d2,%d0 + neg.w %d2 + add.w #32,%d2 + lsl.l %d2,%d1 + or.l %d1,%d0 + move.l (%a0),%d1 + move.l %d0,(%a0) + | Check to see if we shifted off any significant bits + lsl.l %d2,%d1 + jeq fp_nd_round | Nope, round. + bset #0,%d0 | Yes, so set the "sticky bit". + jra fp_nd_round | Now, round. + | Another 64-bit single shift and store +1: sub.w #32,%d2 + cmp.w #32,%d2 | Do we really need to shift? + jcc 2f | No, the number is too small. + move.l (%a0),%d0 + clr.l (%a0)+ + move.l %d0,%d1 + lsr.l %d2,%d0 + neg.w %d2 + add.w #32,%d2 + | Again, check to see if we shifted off any significant bits. + tst.l (%a0) + jeq 1f + bset #0,%d0 | Sticky bit. +1: move.l %d0,(%a0) + lsl.l %d2,%d1 + jeq fp_nd_round + bset #0,%d0 + jra fp_nd_round + | Sorry, the number is just too small. +2: clr.l (%a0)+ + clr.l (%a0) + moveq #1,%d0 | Smallest possible fraction, + jra fp_nd_round | round as desired. + | zero and denormalized +fp_nd_zero: + tst.l (%a0)+ + jne 1f + tst.l (%a0) + jne 1f + subq.l #8,%a0 + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts | zero. nothing to do. + | These are not merely subnormal numbers, but true denormals, + | i.e. pathologically small (exponent is 2**-16383) numbers. + | It is clearly impossible for even a normal extended number + | with that exponent to fit into double precision, so just + | write these ones off as "too darn small". +1: fp_set_sr FPSR_EXC_UNFL | Set UNFL bit + clr.l (%a0) + clr.l -(%a0) + move.w #0x3c01,-(%a0) | i.e. 2**-1022 + addq.l #6,%a0 + moveq #1,%d0 + jra fp_nd_round | round. + | Exponent overflow. Just call it infinity. +fp_nd_large: + move.w #0x7ff,%d0 + and.w (6,%a0),%d0 + jeq 1f + fp_set_sr FPSR_EXC_INEX2 +1: fp_set_sr FPSR_EXC_OVFL + move.w (FPD_RND,FPDATA),%d2 + jne 3f | %d2 = 0 round to nearest +1: move.w #0x7fff,(-2,%a0) + clr.l (%a0)+ + clr.l (%a0) +2: subq.l #8,%a0 + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts +3: subq.w #2,%d2 + jcs 5f | %d2 < 2, round to zero + jhi 4f | %d2 > 2, round to +infinity + tst.b (-3,%a0) | to -inf + jne 1b + jra 5f +4: tst.b (-3,%a0) | to +inf + jeq 1b +5: move.w #0x43fe,(-2,%a0) + moveq #-1,%d0 + move.l %d0,(%a0)+ + move.w #0xf800,%d0 + move.l %d0,(%a0) + jra 2b + | Infinities or NaNs +fp_nd_huge: + subq.l #4,%a0 + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts + + | fp_normalize_single: + | normalize an extended with single (23-bit) precision + | args: %a0 (struct fp_ext *) + +fp_normalize_single: + printf PNORM,"ns: %p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,") " + addq.l #2,%a0 + move.w (%a0)+,%d2 + jeq fp_ns_zero | zero / denormalized + cmp.w #0x7fff,%d2 + jeq fp_ns_huge | NaN / infinitive. + sub.w #0x4000-0x7f,%d2 | will the exponent fit? + jcs fp_ns_small | too small. + cmp.w #0xfe,%d2 + jcc fp_ns_large | too big. + move.l (%a0)+,%d0 | get high lword of mantissa +fp_ns_round: + tst.l (%a0) | check the low lword + jeq 1f + | Set a sticky bit if it is non-zero. This should only + | affect the rounding in what would otherwise be equal- + | distance situations, which is what we want it to do. + bset #0,%d0 +1: clr.l (%a0) | zap it from memory. + | now, round off the low 8 bits of the hi lword. + tst.b %d0 | 8 low bits. + jne fp_ns_checkround | Are they non-zero? + | nothing to do here + subq.l #8,%a0 + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts +fp_ns_checkround: + fp_set_sr FPSR_EXC_INEX2 | INEX2 bit + clr.b -(%a0) | clear low byte of high lword + subq.l #3,%a0 + move.w (FPD_RND,FPDATA),%d2 | rounding mode + jne 2f | %d2 == 0, round to nearest + tst.b %d0 | test guard bit + jpl 9f | zero is closer + btst #8,%d0 | test lsb bit + | round to even behaviour, see above. + jne fp_ns_doroundup | round to infinity + lsl.b #1,%d0 | check low bits + jeq 9f | round to zero +fp_ns_doroundup: + | round (the mantissa, that is) towards infinity + add.l #0x100,(%a0) + jcc 9f | no overflow, good. + | Overflow. This means that the %d1 was 0xffffff00, so it + | is now zero. We will set the mantissa to reflect this, and + | increment the exponent (checking for overflow there too) + move.w #0x8000,(%a0) + addq.w #1,-(%a0) + cmp.w #0x407f,(%a0)+ | exponent now overflown? + jeq fp_ns_large | yes, so make it infinity. +9: subq.l #4,%a0 + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts + | check nondefault rounding modes +2: subq.w #2,%d2 + jcs 9b | %d2 < 2, round to zero + jhi 3f | %d2 > 2, round to +infinity + tst.b (-3,%a0) | to -inf + jne fp_ns_doroundup | negative, round to infinity + jra 9b | positive, round to zero +3: tst.b (-3,%a0) | to +inf + jeq fp_ns_doroundup | positive, round to infinity + jra 9b | negative, round to zero + | Exponent underflow. Try to make a denormal, and set it to + | the smallest possible fraction if this fails. +fp_ns_small: + fp_set_sr FPSR_EXC_UNFL | set UNFL bit + move.w #0x3f81,(-2,%a0) | 2**-126 + neg.w %d2 | degree of underflow + cmp.w #32,%d2 | single or double shift? + jcc 2f + | a 32-bit shift. + move.l (%a0),%d0 + move.l %d0,%d1 + lsr.l %d2,%d0 + move.l %d0,(%a0)+ + | Check to see if we shifted off any significant bits. + neg.w %d2 + add.w #32,%d2 + lsl.l %d2,%d1 + jeq 1f + bset #0,%d0 | Sticky bit. + | Check the lower lword +1: tst.l (%a0) + jeq fp_ns_round + clr (%a0) + bset #0,%d0 | Sticky bit. + jra fp_ns_round + | Sorry, the number is just too small. +2: clr.l (%a0)+ + clr.l (%a0) + moveq #1,%d0 | Smallest possible fraction, + jra fp_ns_round | round as desired. + | Exponent overflow. Just call it infinity. +fp_ns_large: + tst.b (3,%a0) + jeq 1f + fp_set_sr FPSR_EXC_INEX2 +1: fp_set_sr FPSR_EXC_OVFL + move.w (FPD_RND,FPDATA),%d2 + jne 3f | %d2 = 0 round to nearest +1: move.w #0x7fff,(-2,%a0) + clr.l (%a0)+ + clr.l (%a0) +2: subq.l #8,%a0 + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts +3: subq.w #2,%d2 + jcs 5f | %d2 < 2, round to zero + jhi 4f | %d2 > 2, round to +infinity + tst.b (-3,%a0) | to -inf + jne 1b + jra 5f +4: tst.b (-3,%a0) | to +inf + jeq 1b +5: move.w #0x407e,(-2,%a0) + move.l #0xffffff00,(%a0)+ + clr.l (%a0) + jra 2b + | zero and denormalized +fp_ns_zero: + tst.l (%a0)+ + jne 1f + tst.l (%a0) + jne 1f + subq.l #8,%a0 + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts | zero. nothing to do. + | These are not merely subnormal numbers, but true denormals, + | i.e. pathologically small (exponent is 2**-16383) numbers. + | It is clearly impossible for even a normal extended number + | with that exponent to fit into single precision, so just + | write these ones off as "too darn small". +1: fp_set_sr FPSR_EXC_UNFL | Set UNFL bit + clr.l (%a0) + clr.l -(%a0) + move.w #0x3f81,-(%a0) | i.e. 2**-126 + addq.l #6,%a0 + moveq #1,%d0 + jra fp_ns_round | round. + | Infinities or NaNs +fp_ns_huge: + subq.l #4,%a0 + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts + + | fp_normalize_single_fast: + | normalize an extended with single (23-bit) precision + | this is only used by fsgldiv/fsgdlmul, where the + | operand is not completly normalized. + | args: %a0 (struct fp_ext *) + +fp_normalize_single_fast: + printf PNORM,"nsf: %p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,") " + addq.l #2,%a0 + move.w (%a0)+,%d2 + cmp.w #0x7fff,%d2 + jeq fp_nsf_huge | NaN / infinitive. + move.l (%a0)+,%d0 | get high lword of mantissa +fp_nsf_round: + tst.l (%a0) | check the low lword + jeq 1f + | Set a sticky bit if it is non-zero. This should only + | affect the rounding in what would otherwise be equal- + | distance situations, which is what we want it to do. + bset #0,%d0 +1: clr.l (%a0) | zap it from memory. + | now, round off the low 8 bits of the hi lword. + tst.b %d0 | 8 low bits. + jne fp_nsf_checkround | Are they non-zero? + | nothing to do here + subq.l #8,%a0 + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts +fp_nsf_checkround: + fp_set_sr FPSR_EXC_INEX2 | INEX2 bit + clr.b -(%a0) | clear low byte of high lword + subq.l #3,%a0 + move.w (FPD_RND,FPDATA),%d2 | rounding mode + jne 2f | %d2 == 0, round to nearest + tst.b %d0 | test guard bit + jpl 9f | zero is closer + btst #8,%d0 | test lsb bit + | round to even behaviour, see above. + jne fp_nsf_doroundup | round to infinity + lsl.b #1,%d0 | check low bits + jeq 9f | round to zero +fp_nsf_doroundup: + | round (the mantissa, that is) towards infinity + add.l #0x100,(%a0) + jcc 9f | no overflow, good. + | Overflow. This means that the %d1 was 0xffffff00, so it + | is now zero. We will set the mantissa to reflect this, and + | increment the exponent (checking for overflow there too) + move.w #0x8000,(%a0) + addq.w #1,-(%a0) + cmp.w #0x407f,(%a0)+ | exponent now overflown? + jeq fp_nsf_large | yes, so make it infinity. +9: subq.l #4,%a0 + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts + | check nondefault rounding modes +2: subq.w #2,%d2 + jcs 9b | %d2 < 2, round to zero + jhi 3f | %d2 > 2, round to +infinity + tst.b (-3,%a0) | to -inf + jne fp_nsf_doroundup | negative, round to infinity + jra 9b | positive, round to zero +3: tst.b (-3,%a0) | to +inf + jeq fp_nsf_doroundup | positive, round to infinity + jra 9b | negative, round to zero + | Exponent overflow. Just call it infinity. +fp_nsf_large: + tst.b (3,%a0) + jeq 1f + fp_set_sr FPSR_EXC_INEX2 +1: fp_set_sr FPSR_EXC_OVFL + move.w (FPD_RND,FPDATA),%d2 + jne 3f | %d2 = 0 round to nearest +1: move.w #0x7fff,(-2,%a0) + clr.l (%a0)+ + clr.l (%a0) +2: subq.l #8,%a0 + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts +3: subq.w #2,%d2 + jcs 5f | %d2 < 2, round to zero + jhi 4f | %d2 > 2, round to +infinity + tst.b (-3,%a0) | to -inf + jne 1b + jra 5f +4: tst.b (-3,%a0) | to +inf + jeq 1b +5: move.w #0x407e,(-2,%a0) + move.l #0xffffff00,(%a0)+ + clr.l (%a0) + jra 2b + | Infinities or NaNs +fp_nsf_huge: + subq.l #4,%a0 + printf PNORM,"%p(",1,%a0 + printx PNORM,%a0@ + printf PNORM,")\n" + rts + + | conv_ext2int (macro): + | Generates a subroutine that converts an extended value to an + | integer of a given size, again, with the appropriate type of + | rounding. + + | Macro arguments: + | s: size, as given in an assembly instruction. + | b: number of bits in that size. + + | Subroutine arguments: + | %a0: source (struct fp_ext *) + + | Returns the integer in %d0 (like it should) + +.macro conv_ext2int s,b + .set inf,(1<<(\b-1))-1 | i.e. MAXINT + printf PCONV,"e2i%d: %p(",2,#\b,%a0 + printx PCONV,%a0@ + printf PCONV,") " + addq.l #2,%a0 + move.w (%a0)+,%d2 | exponent + jeq fp_e2i_zero\b | zero / denorm (== 0, here) + cmp.w #0x7fff,%d2 + jeq fp_e2i_huge\b | Inf / NaN + sub.w #0x3ffe,%d2 + jcs fp_e2i_small\b + cmp.w #\b,%d2 + jhi fp_e2i_large\b + move.l (%a0),%d0 + move.l %d0,%d1 + lsl.l %d2,%d1 + jne fp_e2i_round\b + tst.l (4,%a0) + jne fp_e2i_round\b + neg.w %d2 + add.w #32,%d2 + lsr.l %d2,%d0 +9: tst.w (-4,%a0) + jne 1f + tst.\s %d0 + jmi fp_e2i_large\b + printf PCONV,"-> %p\n",1,%d0 + rts +1: neg.\s %d0 + jeq 1f + jpl fp_e2i_large\b +1: printf PCONV,"-> %p\n",1,%d0 + rts +fp_e2i_round\b: + fp_set_sr FPSR_EXC_INEX2 | INEX2 bit + neg.w %d2 + add.w #32,%d2 + .if \b>16 + jeq 5f + .endif + lsr.l %d2,%d0 + move.w (FPD_RND,FPDATA),%d2 | rounding mode + jne 2f | %d2 == 0, round to nearest + tst.l %d1 | test guard bit + jpl 9b | zero is closer + btst %d2,%d0 | test lsb bit (%d2 still 0) + jne fp_e2i_doroundup\b + lsl.l #1,%d1 | check low bits + jne fp_e2i_doroundup\b + tst.l (4,%a0) + jeq 9b +fp_e2i_doroundup\b: + addq.l #1,%d0 + jra 9b + | check nondefault rounding modes +2: subq.w #2,%d2 + jcs 9b | %d2 < 2, round to zero + jhi 3f | %d2 > 2, round to +infinity + tst.w (-4,%a0) | to -inf + jne fp_e2i_doroundup\b | negative, round to infinity + jra 9b | positive, round to zero +3: tst.w (-4,%a0) | to +inf + jeq fp_e2i_doroundup\b | positive, round to infinity + jra 9b | negative, round to zero + | we are only want -2**127 get correctly rounded here, + | since the guard bit is in the lower lword. + | everything else ends up anyway as overflow. + .if \b>16 +5: move.w (FPD_RND,FPDATA),%d2 | rounding mode + jne 2b | %d2 == 0, round to nearest + move.l (4,%a0),%d1 | test guard bit + jpl 9b | zero is closer + lsl.l #1,%d1 | check low bits + jne fp_e2i_doroundup\b + jra 9b + .endif +fp_e2i_zero\b: + clr.l %d0 + tst.l (%a0)+ + jne 1f + tst.l (%a0) + jeq 3f +1: subq.l #4,%a0 + fp_clr_sr FPSR_EXC_UNFL | fp_normalize_ext has set this bit +fp_e2i_small\b: + fp_set_sr FPSR_EXC_INEX2 + clr.l %d0 + move.w (FPD_RND,FPDATA),%d2 | rounding mode + subq.w #2,%d2 + jcs 3f | %d2 < 2, round to nearest/zero + jhi 2f | %d2 > 2, round to +infinity + tst.w (-4,%a0) | to -inf + jeq 3f + subq.\s #1,%d0 + jra 3f +2: tst.w (-4,%a0) | to +inf + jne 3f + addq.\s #1,%d0 +3: printf PCONV,"-> %p\n",1,%d0 + rts +fp_e2i_large\b: + fp_set_sr FPSR_EXC_OPERR + move.\s #inf,%d0 + tst.w (-4,%a0) + jeq 1f + addq.\s #1,%d0 +1: printf PCONV,"-> %p\n",1,%d0 + rts +fp_e2i_huge\b: + move.\s (%a0),%d0 + tst.l (%a0) + jne 1f + tst.l (%a0) + jeq fp_e2i_large\b + | fp_normalize_ext has set this bit already + | and made the number nonsignaling +1: fp_tst_sr FPSR_EXC_SNAN + jne 1f + fp_set_sr FPSR_EXC_OPERR +1: printf PCONV,"-> %p\n",1,%d0 + rts +.endm + +fp_conv_ext2long: + conv_ext2int l,32 + +fp_conv_ext2short: + conv_ext2int w,16 + +fp_conv_ext2byte: + conv_ext2int b,8 + +fp_conv_ext2double: + jsr fp_normalize_double + printf PCONV,"e2d: %p(",1,%a0 + printx PCONV,%a0@ + printf PCONV,"), " + move.l (%a0)+,%d2 + cmp.w #0x7fff,%d2 + jne 1f + move.w #0x7ff,%d2 + move.l (%a0)+,%d0 + jra 2f +1: sub.w #0x3fff-0x3ff,%d2 + move.l (%a0)+,%d0 + jmi 2f + clr.w %d2 +2: lsl.w #5,%d2 + lsl.l #7,%d2 + lsl.l #8,%d2 + move.l %d0,%d1 + lsl.l #1,%d0 + lsr.l #4,%d0 + lsr.l #8,%d0 + or.l %d2,%d0 + putuser.l %d0,(%a1)+,fp_err_ua2,%a1 + moveq #21,%d0 + lsl.l %d0,%d1 + move.l (%a0),%d0 + lsr.l #4,%d0 + lsr.l #7,%d0 + or.l %d1,%d0 + putuser.l %d0,(%a1),fp_err_ua2,%a1 +#ifdef FPU_EMU_DEBUG + getuser.l %a1@(-4),%d0,fp_err_ua2,%a1 + getuser.l %a1@(0),%d1,fp_err_ua2,%a1 + printf PCONV,"%p(%08x%08x)\n",3,%a1,%d0,%d1 +#endif + rts + +fp_conv_ext2single: + jsr fp_normalize_single + printf PCONV,"e2s: %p(",1,%a0 + printx PCONV,%a0@ + printf PCONV,"), " + move.l (%a0)+,%d1 + cmp.w #0x7fff,%d1 + jne 1f + move.w #0xff,%d1 + move.l (%a0)+,%d0 + jra 2f +1: sub.w #0x3fff-0x7f,%d1 + move.l (%a0)+,%d0 + jmi 2f + clr.w %d1 +2: lsl.w #8,%d1 + lsl.l #7,%d1 + lsl.l #8,%d1 + bclr #31,%d0 + lsr.l #8,%d0 + or.l %d1,%d0 + printf PCONV,"%08x\n",1,%d0 + rts + + | special return addresses for instr that + | encode the rounding precision in the opcode + | (e.g. fsmove,fdmove) + +fp_finalrounding_single: + addq.l #8,%sp + jsr fp_normalize_ext + jsr fp_normalize_single + jra fp_finaltest + +fp_finalrounding_single_fast: + addq.l #8,%sp + jsr fp_normalize_ext + jsr fp_normalize_single_fast + jra fp_finaltest + +fp_finalrounding_double: + addq.l #8,%sp + jsr fp_normalize_ext + jsr fp_normalize_double + jra fp_finaltest + + | fp_finaltest: + | set the emulated status register based on the outcome of an + | emulated instruction. + +fp_finalrounding: + addq.l #8,%sp +| printf ,"f: %p\n",1,%a0 + jsr fp_normalize_ext + move.w (FPD_PREC,FPDATA),%d0 + subq.w #1,%d0 + jcs fp_finaltest + jne 1f + jsr fp_normalize_single + jra 2f +1: jsr fp_normalize_double +2:| printf ,"f: %p\n",1,%a0 +fp_finaltest: + | First, we do some of the obvious tests for the exception + | status byte and condition code bytes of fp_sr here, so that + | they do not have to be handled individually by every + | emulated instruction. + clr.l %d0 + addq.l #1,%a0 + tst.b (%a0)+ | sign + jeq 1f + bset #FPSR_CC_NEG-24,%d0 | N bit +1: cmp.w #0x7fff,(%a0)+ | exponent + jeq 2f + | test for zero + moveq #FPSR_CC_Z-24,%d1 + tst.l (%a0)+ + jne 9f + tst.l (%a0) + jne 9f + jra 8f + | infinitiv and NAN +2: moveq #FPSR_CC_NAN-24,%d1 + move.l (%a0)+,%d2 + lsl.l #1,%d2 | ignore high bit + jne 8f + tst.l (%a0) + jne 8f + moveq #FPSR_CC_INF-24,%d1 +8: bset %d1,%d0 +9: move.b %d0,(FPD_FPSR+0,FPDATA) | set condition test result + | move instructions enter here + | Here, we test things in the exception status byte, and set + | other things in the accrued exception byte accordingly. + | Emulated instructions can set various things in the former, + | as defined in fp_emu.h. +fp_final: + move.l (FPD_FPSR,FPDATA),%d0 +#if 0 + btst #FPSR_EXC_SNAN,%d0 | EXC_SNAN + jne 1f + btst #FPSR_EXC_OPERR,%d0 | EXC_OPERR + jeq 2f +1: bset #FPSR_AEXC_IOP,%d0 | set IOP bit +2: btst #FPSR_EXC_OVFL,%d0 | EXC_OVFL + jeq 1f + bset #FPSR_AEXC_OVFL,%d0 | set OVFL bit +1: btst #FPSR_EXC_UNFL,%d0 | EXC_UNFL + jeq 1f + btst #FPSR_EXC_INEX2,%d0 | EXC_INEX2 + jeq 1f + bset #FPSR_AEXC_UNFL,%d0 | set UNFL bit +1: btst #FPSR_EXC_DZ,%d0 | EXC_INEX1 + jeq 1f + bset #FPSR_AEXC_DZ,%d0 | set DZ bit +1: btst #FPSR_EXC_OVFL,%d0 | EXC_OVFL + jne 1f + btst #FPSR_EXC_INEX2,%d0 | EXC_INEX2 + jne 1f + btst #FPSR_EXC_INEX1,%d0 | EXC_INEX1 + jeq 2f +1: bset #FPSR_AEXC_INEX,%d0 | set INEX bit +2: move.l %d0,(FPD_FPSR,FPDATA) +#else + | same as above, greatly optimized, but untested (yet) + move.l %d0,%d2 + lsr.l #5,%d0 + move.l %d0,%d1 + lsr.l #4,%d1 + or.l %d0,%d1 + and.b #0x08,%d1 + move.l %d2,%d0 + lsr.l #6,%d0 + or.l %d1,%d0 + move.l %d2,%d1 + lsr.l #4,%d1 + or.b #0xdf,%d1 + and.b %d1,%d0 + move.l %d2,%d1 + lsr.l #7,%d1 + and.b #0x80,%d1 + or.b %d1,%d0 + and.b #0xf8,%d0 + or.b %d0,%d2 + move.l %d2,(FPD_FPSR,FPDATA) +#endif + move.b (FPD_FPSR+2,FPDATA),%d0 + and.b (FPD_FPCR+2,FPDATA),%d0 + jeq 1f + printf ,"send signal!!!\n" +1: jra fp_end diff -u --recursive --new-file v2.3.13/linux/arch/m68k/math-emu/multi_arith.h linux/arch/m68k/math-emu/multi_arith.h --- v2.3.13/linux/arch/m68k/math-emu/multi_arith.h Wed Dec 31 16:00:00 1969 +++ linux/arch/m68k/math-emu/multi_arith.h Sun Aug 15 11:47:29 1999 @@ -0,0 +1,822 @@ +/* multi_arith.h: multi-precision integer arithmetic functions, needed + to do extended-precision floating point. + + (c) 1998 David Huggins-Daines. + + Somewhat based on arch/alpha/math-emu/ieee-math.c, which is (c) + David Mosberger-Tang. + + You may copy, modify, and redistribute this file under the terms of + the GNU General Public License, version 2, or any later version, at + your convenience. */ + +/* Note: + + These are not general multi-precision math routines. Rather, they + implement the subset of integer arithmetic that we need in order to + multiply, divide, and normalize 128-bit unsigned mantissae. */ + +#ifndef MULTI_ARITH_H +#define MULTI_ARITH_H + +#if 0 /* old code... */ + +/* Unsigned only, because we don't need signs to multiply and divide. */ +typedef unsigned int int128[4]; + +/* Word order */ +enum { + MSW128, + NMSW128, + NLSW128, + LSW128 +}; + +/* big-endian */ +#define LO_WORD(ll) (((unsigned int *) &ll)[1]) +#define HI_WORD(ll) (((unsigned int *) &ll)[0]) + +/* Convenience functions to stuff various integer values into int128s */ + +extern inline void zero128(int128 a) +{ + a[LSW128] = a[NLSW128] = a[NMSW128] = a[MSW128] = 0; +} + +/* Human-readable word order in the arguments */ +extern inline void set128(unsigned int i3, + unsigned int i2, + unsigned int i1, + unsigned int i0, + int128 a) +{ + a[LSW128] = i0; + a[NLSW128] = i1; + a[NMSW128] = i2; + a[MSW128] = i3; +} + +/* Convenience functions (for testing as well) */ +extern inline void int64_to_128(unsigned long long src, + int128 dest) +{ + dest[LSW128] = (unsigned int) src; + dest[NLSW128] = src >> 32; + dest[NMSW128] = dest[MSW128] = 0; +} + +extern inline void int128_to_64(const int128 src, + unsigned long long *dest) +{ + *dest = src[LSW128] | (long long) src[NLSW128] << 32; +} + +extern inline void put_i128(const int128 a) +{ + printk("%08x %08x %08x %08x\n", a[MSW128], a[NMSW128], + a[NLSW128], a[LSW128]); +} + +/* Internal shifters: + + Note that these are only good for 0 < count < 32. + */ + +extern inline void _lsl128(unsigned int count, int128 a) +{ + a[MSW128] = (a[MSW128] << count) | (a[NMSW128] >> (32 - count)); + a[NMSW128] = (a[NMSW128] << count) | (a[NLSW128] >> (32 - count)); + a[NLSW128] = (a[NLSW128] << count) | (a[LSW128] >> (32 - count)); + a[LSW128] <<= count; +} + +extern inline void _lsr128(unsigned int count, int128 a) +{ + a[LSW128] = (a[LSW128] >> count) | (a[NLSW128] << (32 - count)); + a[NLSW128] = (a[NLSW128] >> count) | (a[NMSW128] << (32 - count)); + a[NMSW128] = (a[NMSW128] >> count) | (a[MSW128] << (32 - count)); + a[MSW128] >>= count; +} + +/* Should be faster, one would hope */ + +extern inline void lslone128(int128 a) +{ + asm volatile ("lsl.l #1,%0\n" + "roxl.l #1,%1\n" + "roxl.l #1,%2\n" + "roxl.l #1,%3\n" + : + "=d" (a[LSW128]), + "=d"(a[NLSW128]), + "=d"(a[NMSW128]), + "=d"(a[MSW128]) + : + "0"(a[LSW128]), + "1"(a[NLSW128]), + "2"(a[NMSW128]), + "3"(a[MSW128])); +} + +extern inline void lsrone128(int128 a) +{ + asm volatile ("lsr.l #1,%0\n" + "roxr.l #1,%1\n" + "roxr.l #1,%2\n" + "roxr.l #1,%3\n" + : + "=d" (a[MSW128]), + "=d"(a[NMSW128]), + "=d"(a[NLSW128]), + "=d"(a[LSW128]) + : + "0"(a[MSW128]), + "1"(a[NMSW128]), + "2"(a[NLSW128]), + "3"(a[LSW128])); +} + +/* Generalized 128-bit shifters: + + These bit-shift to a multiple of 32, then move whole longwords. */ + +extern inline void lsl128(unsigned int count, int128 a) +{ + int wordcount, i; + + if (count % 32) + _lsl128(count % 32, a); + + if (0 == (wordcount = count / 32)) + return; + + /* argh, gak, endian-sensitive */ + for (i = 0; i < 4 - wordcount; i++) { + a[i] = a[i + wordcount]; + } + for (i = 3; i >= 4 - wordcount; --i) { + a[i] = 0; + } +} + +extern inline void lsr128(unsigned int count, int128 a) +{ + int wordcount, i; + + if (count % 32) + _lsr128(count % 32, a); + + if (0 == (wordcount = count / 32)) + return; + + for (i = 3; i >= wordcount; --i) { + a[i] = a[i - wordcount]; + } + for (i = 0; i < wordcount; i++) { + a[i] = 0; + } +} + +extern inline int orl128(int a, int128 b) +{ + b[LSW128] |= a; +} + +extern inline int btsthi128(const int128 a) +{ + return a[MSW128] & 0x80000000; +} + +/* test bits (numbered from 0 = LSB) up to and including "top" */ +extern inline int bftestlo128(int top, const int128 a) +{ + int r = 0; + + if (top > 31) + r |= a[LSW128]; + if (top > 63) + r |= a[NLSW128]; + if (top > 95) + r |= a[NMSW128]; + + r |= a[3 - (top / 32)] & ((1 << (top % 32 + 1)) - 1); + + return (r != 0); +} + +/* Aargh. We need these because GCC is broken */ +/* FIXME: do them in assembly, for goodness' sake! */ +extern inline void mask64(int pos, unsigned long long *mask) +{ + *mask = 0; + + if (pos < 32) { + LO_WORD(*mask) = (1 << pos) - 1; + return; + } + LO_WORD(*mask) = -1; + HI_WORD(*mask) = (1 << (pos - 32)) - 1; +} + +extern inline void bset64(int pos, unsigned long long *dest) +{ + /* This conditional will be optimized away. Thanks, GCC! */ + if (pos < 32) + asm volatile ("bset %1,%0":"=m" + (LO_WORD(*dest)):"id"(pos)); + else + asm volatile ("bset %1,%0":"=m" + (HI_WORD(*dest)):"id"(pos - 32)); +} + +extern inline int btst64(int pos, unsigned long long dest) +{ + if (pos < 32) + return (0 != (LO_WORD(dest) & (1 << pos))); + else + return (0 != (HI_WORD(dest) & (1 << (pos - 32)))); +} + +extern inline void lsl64(int count, unsigned long long *dest) +{ + if (count < 32) { + HI_WORD(*dest) = (HI_WORD(*dest) << count) + | (LO_WORD(*dest) >> count); + LO_WORD(*dest) <<= count; + return; + } + count -= 32; + HI_WORD(*dest) = LO_WORD(*dest) << count; + LO_WORD(*dest) = 0; +} + +extern inline void lsr64(int count, unsigned long long *dest) +{ + if (count < 32) { + LO_WORD(*dest) = (LO_WORD(*dest) >> count) + | (HI_WORD(*dest) << (32 - count)); + HI_WORD(*dest) >>= count; + return; + } + count -= 32; + LO_WORD(*dest) = HI_WORD(*dest) >> count; + HI_WORD(*dest) = 0; +} +#endif + +extern inline void fp_denormalize(struct fp_ext *reg, unsigned int cnt) +{ + reg->exp += cnt; + + switch (cnt) { + case 0 ... 8: + reg->lowmant = reg->mant.m32[1] << (8 - cnt); + reg->mant.m32[1] = (reg->mant.m32[1] >> cnt) | + (reg->mant.m32[0] << (32 - cnt)); + reg->mant.m32[0] = reg->mant.m32[0] >> cnt; + break; + case 9 ... 32: + reg->lowmant = reg->mant.m32[1] >> (cnt - 8); + if (reg->mant.m32[1] << (40 - cnt)) + reg->lowmant |= 1; + reg->mant.m32[1] = (reg->mant.m32[1] >> cnt) | + (reg->mant.m32[0] << (32 - cnt)); + reg->mant.m32[0] = reg->mant.m32[0] >> cnt; + break; + case 33 ... 39: + asm volatile ("bfextu %1{%2,#8},%0" : "=d" (reg->lowmant) + : "m" (reg->mant.m32[0]), "d" (64 - cnt)); + if (reg->mant.m32[1] << (40 - cnt)) + reg->lowmant |= 1; + reg->mant.m32[1] = reg->mant.m32[0] >> (cnt - 32); + reg->mant.m32[0] = 0; + break; + case 40 ... 71: + reg->lowmant = reg->mant.m32[0] >> (cnt - 40); + if ((reg->mant.m32[0] << (72 - cnt)) || reg->mant.m32[1]) + reg->lowmant |= 1; + reg->mant.m32[1] = reg->mant.m32[0] >> (cnt - 32); + reg->mant.m32[0] = 0; + break; + default: + reg->lowmant = reg->mant.m32[0] || reg->mant.m32[1]; + reg->mant.m32[0] = 0; + reg->mant.m32[1] = 0; + break; + } +} + +extern inline int fp_overnormalize(struct fp_ext *reg) +{ + int shift; + + if (reg->mant.m32[0]) { + asm ("bfffo %1{#0,#32},%0" : "=d" (shift) : "dm" (reg->mant.m32[0])); + reg->mant.m32[0] = (reg->mant.m32[0] << shift) | (reg->mant.m32[1] >> (32 - shift)); + reg->mant.m32[1] = (reg->mant.m32[1] << shift); + } else { + asm ("bfffo %1{#0,#32},%0" : "=d" (shift) : "dm" (reg->mant.m32[1])); + reg->mant.m32[0] = (reg->mant.m32[1] << shift); + reg->mant.m32[1] = 0; + shift += 32; + } + + return shift; +} + +extern inline int fp_addmant(struct fp_ext *dest, struct fp_ext *src) +{ + int carry; + + /* we assume here, gcc only insert move and a clr instr */ + asm volatile ("add.b %1,%0" : "=d,=g" (dest->lowmant) + : "g,d" (src->lowmant), "0,0" (dest->lowmant)); + asm volatile ("addx.l %1,%0" : "=d" (dest->mant.m32[1]) + : "d" (src->mant.m32[1]), "0" (dest->mant.m32[1])); + asm volatile ("addx.l %1,%0" : "=d" (dest->mant.m32[0]) + : "d" (src->mant.m32[0]), "0" (dest->mant.m32[0])); + asm volatile ("addx.l %0,%0" : "=d" (carry) : "0" (0)); + + return carry; +} + +extern inline int fp_addcarry(struct fp_ext *reg) +{ + if (++reg->exp == 0x7fff) { + if (reg->mant.m64) + fp_set_sr(FPSR_EXC_INEX2); + reg->mant.m64 = 0; + fp_set_sr(FPSR_EXC_OVFL); + return 0; + } + reg->lowmant = (reg->mant.m32[1] << 7) | (reg->lowmant ? 1 : 0); + reg->mant.m32[1] = (reg->mant.m32[1] >> 1) | + (reg->mant.m32[0] << 31); + reg->mant.m32[0] = (reg->mant.m32[0] >> 1) | 0x80000000; + + return 1; +} + +extern inline void fp_submant(struct fp_ext *dest, struct fp_ext *src1, struct fp_ext *src2) +{ + /* we assume here, gcc only insert move and a clr instr */ + asm volatile ("sub.b %1,%0" : "=d,=g" (dest->lowmant) + : "g,d" (src2->lowmant), "0,0" (src1->lowmant)); + asm volatile ("subx.l %1,%0" : "=d" (dest->mant.m32[1]) + : "d" (src2->mant.m32[1]), "0" (src1->mant.m32[1])); + asm volatile ("subx.l %1,%0" : "=d" (dest->mant.m32[0]) + : "d" (src2->mant.m32[0]), "0" (src1->mant.m32[0])); +} + +#define fp_mul64(desth, destl, src1, src2) ({ \ + asm ("mulu.l %2,%1:%0" : "=d" (destl), "=d" (desth) \ + : "g" (src1), "0" (src2)); \ +}) +#define fp_div64(quot, rem, srch, srcl, div) \ + asm ("divu.l %2,%1:%0" : "=d" (quot), "=d" (rem) \ + : "dm" (div), "1" (srch), "0" (srcl)) +#define fp_add64(dest1, dest2, src1, src2) ({ \ + asm ("add.l %1,%0" : "=d,=dm" (dest2) \ + : "dm,d" (src2), "0,0" (dest2)); \ + asm ("addx.l %1,%0" : "=d" (dest1) \ + : "d" (src1), "0" (dest1)); \ +}) +#define fp_addx96(dest, src) ({ \ + /* we assume here, gcc only insert move and a clr instr */ \ + asm volatile ("add.l %1,%0" : "=d,=g" (dest->m32[2]) \ + : "g,d" (temp.m32[1]), "0,0" (dest->m32[2])); \ + asm volatile ("addx.l %1,%0" : "=d" (dest->m32[1]) \ + : "d" (temp.m32[0]), "0" (dest->m32[1])); \ + asm volatile ("addx.l %1,%0" : "=d" (dest->m32[0]) \ + : "d" (0), "0" (dest->m32[0])); \ +}) +#define fp_sub64(dest, src) ({ \ + asm ("sub.l %1,%0" : "=d,=dm" (dest.m32[1]) \ + : "dm,d" (src.m32[1]), "0,0" (dest.m32[1])); \ + asm ("subx.l %1,%0" : "=d" (dest.m32[0]) \ + : "d" (src.m32[0]), "0" (dest.m32[0])); \ +}) +#define fp_sub96c(dest, srch, srcm, srcl) ({ \ + char carry; \ + asm ("sub.l %1,%0" : "=d,=dm" (dest.m32[2]) \ + : "dm,d" (srcl), "0,0" (dest.m32[2])); \ + asm ("subx.l %1,%0" : "=d" (dest.m32[1]) \ + : "d" (srcm), "0" (dest.m32[1])); \ + asm ("subx.l %2,%1; scs %0" : "=d" (carry), "=d" (dest.m32[0]) \ + : "d" (srch), "1" (dest.m32[0])); \ + carry; \ +}) + +extern inline void fp_multiplymant(union fp_mant128 *dest, struct fp_ext *src1, struct fp_ext *src2) +{ + union fp_mant64 temp; + + fp_mul64(dest->m32[0], dest->m32[1], src1->mant.m32[0], src2->mant.m32[0]); + fp_mul64(dest->m32[2], dest->m32[3], src1->mant.m32[1], src2->mant.m32[1]); + + fp_mul64(temp.m32[0], temp.m32[1], src1->mant.m32[0], src2->mant.m32[1]); + fp_addx96(dest, temp); + + fp_mul64(temp.m32[0], temp.m32[1], src1->mant.m32[1], src2->mant.m32[0]); + fp_addx96(dest, temp); +} + +extern inline void fp_dividemant(union fp_mant128 *dest, struct fp_ext *src, struct fp_ext *div) +{ + union fp_mant128 tmp; + union fp_mant64 tmp64; + unsigned long *mantp = dest->m32; + unsigned long fix, rem, first, dummy; + int i; + + /* the algorithm below requires dest to be smaller than div, + but both have the high bit set */ + if (src->mant.m64 >= div->mant.m64) { + fp_sub64(src->mant, div->mant); + *mantp = 1; + } else + *mantp = 0; + mantp++; + + /* basic idea behind this algorithm: we can't divide two 64bit numbers + (AB/CD) directly, but we can calculate AB/C0, but this means this + quotient is off by C0/CD, so we have to multiply the first result + to fix the result, after that we have nearly the correct result + and only a few corrections are needed. */ + + /* C0/CD can be precalculated, but it's an 64bit division again, but + we can make it a bit easier, by dividing first through C so we get + 10/1D and now only a single shift and the value fits into 32bit. */ + fix = 0x80000000; + dummy = div->mant.m32[1] / div->mant.m32[0] + 1; + dummy = (dummy >> 1) | fix; + fp_div64(fix, dummy, fix, 0, dummy); + fix--; + + for (i = 0; i < 3; i++, mantp++) { + if (src->mant.m32[0] == div->mant.m32[0]) { + fp_div64(first, rem, 0, src->mant.m32[1], div->mant.m32[0]); + + fp_mul64(*mantp, dummy, first, fix); + *mantp += fix; + } else { + fp_div64(first, rem, src->mant.m32[0], src->mant.m32[1], div->mant.m32[0]); + + fp_mul64(*mantp, dummy, first, fix); + } + + fp_mul64(tmp.m32[0], tmp.m32[1], div->mant.m32[0], first - *mantp); + fp_add64(tmp.m32[0], tmp.m32[1], 0, rem); + tmp.m32[2] = 0; + + fp_mul64(tmp64.m32[0], tmp64.m32[1], *mantp, div->mant.m32[1]); + fp_sub96c(tmp, 0, tmp64.m32[0], tmp64.m32[1]); + + src->mant.m32[0] = tmp.m32[1]; + src->mant.m32[1] = tmp.m32[2]; + + while (!fp_sub96c(tmp, 0, div->mant.m32[0], div->mant.m32[1])) { + src->mant.m32[0] = tmp.m32[1]; + src->mant.m32[1] = tmp.m32[2]; + *mantp += 1; + } + } +} + +#if 0 +extern inline unsigned int fp_fls128(union fp_mant128 *src) +{ + unsigned long data; + unsigned int res, off; + + if ((data = src->m32[0])) + off = 0; + else if ((data = src->m32[1])) + off = 32; + else if ((data = src->m32[2])) + off = 64; + else if ((data = src->m32[3])) + off = 96; + else + return 128; + + asm ("bfffo %1{#0,#32},%0" : "=d" (res) : "dm" (data)); + return res + off; +} + +extern inline void fp_shiftmant128(union fp_mant128 *src, int shift) +{ + unsigned long sticky; + + switch (shift) { + case 0: + return; + case 1: + asm volatile ("lsl.l #1,%0" + : "=d" (src->m32[3]) : "0" (src->m32[3])); + asm volatile ("roxl.l #1,%0" + : "=d" (src->m32[2]) : "0" (src->m32[2])); + asm volatile ("roxl.l #1,%0" + : "=d" (src->m32[1]) : "0" (src->m32[1])); + asm volatile ("roxl.l #1,%0" + : "=d" (src->m32[0]) : "0" (src->m32[0])); + return; + case 2 ... 31: + src->m32[0] = (src->m32[0] << shift) | (src->m32[1] >> (32 - shift)); + src->m32[1] = (src->m32[1] << shift) | (src->m32[2] >> (32 - shift)); + src->m32[2] = (src->m32[2] << shift) | (src->m32[3] >> (32 - shift)); + src->m32[3] = (src->m32[3] << shift); + return; + case 32 ... 63: + shift -= 32; + src->m32[0] = (src->m32[1] << shift) | (src->m32[2] >> (32 - shift)); + src->m32[1] = (src->m32[2] << shift) | (src->m32[3] >> (32 - shift)); + src->m32[2] = (src->m32[3] << shift); + src->m32[3] = 0; + return; + case 64 ... 95: + shift -= 64; + src->m32[0] = (src->m32[2] << shift) | (src->m32[3] >> (32 - shift)); + src->m32[1] = (src->m32[3] << shift); + src->m32[2] = src->m32[3] = 0; + return; + case 96 ... 127: + shift -= 96; + src->m32[0] = (src->m32[3] << shift); + src->m32[1] = src->m32[2] = src->m32[3] = 0; + return; + case -31 ... -1: + shift = -shift; + sticky = 0; + if (src->m32[3] << (32 - shift)) + sticky = 1; + src->m32[3] = (src->m32[3] >> shift) | (src->m32[2] << (32 - shift)) | sticky; + src->m32[2] = (src->m32[2] >> shift) | (src->m32[1] << (32 - shift)); + src->m32[1] = (src->m32[1] >> shift) | (src->m32[0] << (32 - shift)); + src->m32[0] = (src->m32[0] >> shift); + return; + case -63 ... -32: + shift = -shift - 32; + sticky = 0; + if ((src->m32[2] << (32 - shift)) || src->m32[3]) + sticky = 1; + src->m32[3] = (src->m32[2] >> shift) | (src->m32[1] << (32 - shift)) | sticky; + src->m32[2] = (src->m32[1] >> shift) | (src->m32[0] << (32 - shift)); + src->m32[1] = (src->m32[0] >> shift); + src->m32[0] = 0; + return; + case -95 ... -64: + shift = -shift - 64; + sticky = 0; + if ((src->m32[1] << (32 - shift)) || src->m32[2] || src->m32[3]) + sticky = 1; + src->m32[3] = (src->m32[1] >> shift) | (src->m32[0] << (32 - shift)) | sticky; + src->m32[2] = (src->m32[0] >> shift); + src->m32[1] = src->m32[0] = 0; + return; + case -127 ... -96: + shift = -shift - 96; + sticky = 0; + if ((src->m32[0] << (32 - shift)) || src->m32[1] || src->m32[2] || src->m32[3]) + sticky = 1; + src->m32[3] = (src->m32[0] >> shift) | sticky; + src->m32[2] = src->m32[1] = src->m32[0] = 0; + return; + } + + if (shift < 0 && (src->m32[0] || src->m32[1] || src->m32[2] || src->m32[3])) + src->m32[3] = 1; + else + src->m32[3] = 0; + src->m32[2] = 0; + src->m32[1] = 0; + src->m32[0] = 0; +} +#endif + +extern inline void fp_putmant128(struct fp_ext *dest, union fp_mant128 *src, int shift) +{ + unsigned long tmp; + + switch (shift) { + case 0: + dest->mant.m64 = src->m64[0]; + dest->lowmant = src->m32[2] >> 24; + if (src->m32[3] || (src->m32[2] << 8)) + dest->lowmant |= 1; + break; + case 1: + asm volatile ("lsl.l #1,%0" + : "=d" (tmp) : "0" (src->m32[2])); + asm volatile ("roxl.l #1,%0" + : "=d" (dest->mant.m32[1]) : "0" (src->m32[1])); + asm volatile ("roxl.l #1,%0" + : "=d" (dest->mant.m32[0]) : "0" (src->m32[0])); + dest->lowmant = tmp >> 24; + if (src->m32[3] || (tmp << 8)) + dest->lowmant |= 1; + break; + case 31: + asm volatile ("lsr.l #1,%1; roxr.l #1,%0" + : "=d" (dest->mant.m32[0]) + : "d" (src->m32[0]), "0" (src->m32[1])); + asm volatile ("roxr.l #1,%0" + : "=d" (dest->mant.m32[1]) : "0" (src->m32[2])); + asm volatile ("roxr.l #1,%0" + : "=d" (tmp) : "0" (src->m32[3])); + dest->lowmant = tmp >> 24; + if (src->m32[3] << 7) + dest->lowmant |= 1; + break; + case 32: + dest->mant.m32[0] = src->m32[1]; + dest->mant.m32[1] = src->m32[2]; + dest->lowmant = src->m32[3] >> 24; + if (src->m32[3] << 8) + dest->lowmant |= 1; + break; + } +} + +#if 0 /* old code... */ +extern inline int fls(unsigned int a) +{ + int r; + + asm volatile ("bfffo %1{#0,#32},%0" + : "=d" (r) : "md" (a)); + return r; +} + +/* fls = "find last set" (cf. ffs(3)) */ +extern inline int fls128(const int128 a) +{ + if (a[MSW128]) + return fls(a[MSW128]); + if (a[NMSW128]) + return fls(a[NMSW128]) + 32; + /* XXX: it probably never gets beyond this point in actual + use, but that's indicative of a more general problem in the + algorithm (i.e. as per the actual 68881 implementation, we + really only need at most 67 bits of precision [plus + overflow]) so I'm not going to fix it. */ + if (a[NLSW128]) + return fls(a[NLSW128]) + 64; + if (a[LSW128]) + return fls(a[LSW128]) + 96; + else + return -1; +} + +extern inline int zerop128(const int128 a) +{ + return !(a[LSW128] | a[NLSW128] | a[NMSW128] | a[MSW128]); +} + +extern inline int nonzerop128(const int128 a) +{ + return (a[LSW128] | a[NLSW128] | a[NMSW128] | a[MSW128]); +} + +/* Addition and subtraction */ +/* Do these in "pure" assembly, because "extended" asm is unmanageable + here */ +extern inline void add128(const int128 a, int128 b) +{ + /* rotating carry flags */ + unsigned int carry[2]; + + carry[0] = a[LSW128] > (0xffffffff - b[LSW128]); + b[LSW128] += a[LSW128]; + + carry[1] = a[NLSW128] > (0xffffffff - b[NLSW128] - carry[0]); + b[NLSW128] = a[NLSW128] + b[NLSW128] + carry[0]; + + carry[0] = a[NMSW128] > (0xffffffff - b[NMSW128] - carry[1]); + b[NMSW128] = a[NMSW128] + b[NMSW128] + carry[1]; + + b[MSW128] = a[MSW128] + b[MSW128] + carry[0]; +} + +/* Note: assembler semantics: "b -= a" */ +extern inline void sub128(const int128 a, int128 b) +{ + /* rotating borrow flags */ + unsigned int borrow[2]; + + borrow[0] = b[LSW128] < a[LSW128]; + b[LSW128] -= a[LSW128]; + + borrow[1] = b[NLSW128] < a[NLSW128] + borrow[0]; + b[NLSW128] = b[NLSW128] - a[NLSW128] - borrow[0]; + + borrow[0] = b[NMSW128] < a[NMSW128] + borrow[1]; + b[NMSW128] = b[NMSW128] - a[NMSW128] - borrow[1]; + + b[MSW128] = b[MSW128] - a[MSW128] - borrow[0]; +} + +/* Poor man's 64-bit expanding multiply */ +extern inline void mul64(unsigned long long a, + unsigned long long b, + int128 c) +{ + unsigned long long acc; + int128 acc128; + + zero128(acc128); + zero128(c); + + /* first the low words */ + if (LO_WORD(a) && LO_WORD(b)) { + acc = (long long) LO_WORD(a) * LO_WORD(b); + c[NLSW128] = HI_WORD(acc); + c[LSW128] = LO_WORD(acc); + } + /* Next the high words */ + if (HI_WORD(a) && HI_WORD(b)) { + acc = (long long) HI_WORD(a) * HI_WORD(b); + c[MSW128] = HI_WORD(acc); + c[NMSW128] = LO_WORD(acc); + } + /* The middle words */ + if (LO_WORD(a) && HI_WORD(b)) { + acc = (long long) LO_WORD(a) * HI_WORD(b); + acc128[NMSW128] = HI_WORD(acc); + acc128[NLSW128] = LO_WORD(acc); + add128(acc128, c); + } + /* The first and last words */ + if (HI_WORD(a) && LO_WORD(b)) { + acc = (long long) HI_WORD(a) * LO_WORD(b); + acc128[NMSW128] = HI_WORD(acc); + acc128[NLSW128] = LO_WORD(acc); + add128(acc128, c); + } +} + +/* Note: unsigned */ +extern inline int cmp128(int128 a, int128 b) +{ + if (a[MSW128] < b[MSW128]) + return -1; + if (a[MSW128] > b[MSW128]) + return 1; + if (a[NMSW128] < b[NMSW128]) + return -1; + if (a[NMSW128] > b[NMSW128]) + return 1; + if (a[NLSW128] < b[NLSW128]) + return -1; + if (a[NLSW128] > b[NLSW128]) + return 1; + + return (signed) a[LSW128] - b[LSW128]; +} + +inline void div128(int128 a, int128 b, int128 c) +{ + int128 mask; + + /* Algorithm: + + Shift the divisor until it's at least as big as the + dividend, keeping track of the position to which we've + shifted it, i.e. the power of 2 which we've multiplied it + by. + + Then, for this power of 2 (the mask), and every one smaller + than it, subtract the mask from the dividend and add it to + the quotient until the dividend is smaller than the raised + divisor. At this point, divide the dividend and the mask + by 2 (i.e. shift one place to the right). Lather, rinse, + and repeat, until there are no more powers of 2 left. */ + + /* FIXME: needless to say, there's room for improvement here too. */ + + /* Shift up */ + /* XXX: since it just has to be "at least as big", we can + probably eliminate this horribly wasteful loop. I will + have to prove this first, though */ + set128(0, 0, 0, 1, mask); + while (cmp128(b, a) < 0 && !btsthi128(b)) { + lslone128(b); + lslone128(mask); + } + + /* Shift down */ + zero128(c); + do { + if (cmp128(a, b) >= 0) { + sub128(b, a); + add128(mask, c); + } + lsrone128(mask); + lsrone128(b); + } while (nonzerop128(mask)); + + /* The remainder is in a... */ +} +#endif + +#endif /* MULTI_ARITH_H */ diff -u --recursive --new-file v2.3.13/linux/arch/m68k/q40/README linux/arch/m68k/q40/README --- v2.3.13/linux/arch/m68k/q40/README Tue May 11 09:57:14 1999 +++ linux/arch/m68k/q40/README Sun Aug 15 11:47:29 1999 @@ -7,7 +7,7 @@ and mirrors. Hints to documentation usually refer to the linux source tree in -/usr/src/linux unless URL given. +/usr/src/linux/Documentation unless URL given. It seems IRQ unmasking can't be safely done on a Q40. Autoprobing is not yet implemented - do not try it! (See below) @@ -18,8 +18,8 @@ The floppy imposes a very high interrupt load on the CPU, approx 30K/s. When something blocks interrupts (HD) it will loose some of them, so far this is not known to have caused any data loss. On hihgly loaded systems -it can make the floppy very slow. Other Q40 OS' simply poll the floppy -for this reason - something that can't be done in Linux. +it can make the floppy very slow or practicaly stop. Other Q40 OS' simply +poll the floppy for this reason - something that can't be done in Linux. Only possible cure is getting a 82072 contoler with fifo instead of the 8272A @@ -48,7 +48,7 @@ Upon startup the kernel will usually output "ABCQGHIJ" into the SRAM, preceded by the booter signature. This is a trace just in case something went wrong during earliest setup stages. -*Changed* to preserve SRAM contents by default, this is only done when +**Changed** to preserve SRAM contents by default, this is only done when requested - SRAM must start with '%LX$' signature to do this. '-d' option to 'lxx' loader enables this. @@ -92,12 +92,22 @@ ========== q40 master chip handles only level triggered interrupts :-(( -further limitation is no disabling etc. Unless someone finds -some ingenious clue this means autoprobing will never work. -Parallel port interrupts cause most trouble.. - -IRQ sharing is not yet implemented. - +further limitation is no disabling etc. There is NO WAY to remove +an ISA irq request other than serve the HW specific control register, +the ISA irq lines are connected straight to the CPU ipl1 pin.. + +IRQ sharing is not yet implemented but this should be only a minor +problem.. + +Linux has some requirements wrt interrupt architecture, these are +to my knowledge: + (a) interrupt handler must not be reentered even when sti() is called + (b) working enable/disable_irq + +Luckily these requirements are only important for drivers shared +with other architectures - ide,serial,parallel, ethernet.. +q40ints.c now contains a trivial hack for (a), however (b) could +be only solved by driver-specific code Keyboard ======== diff -u --recursive --new-file v2.3.13/linux/arch/m68k/q40/config.c linux/arch/m68k/q40/config.c --- v2.3.13/linux/arch/m68k/q40/config.c Mon Aug 9 14:59:19 1999 +++ linux/arch/m68k/q40/config.c Sun Aug 15 11:47:29 1999 @@ -1,12 +1,12 @@ /* * arch/m68k/q40/config.c * + * Copyright (C) 1999 Richard Zidlicky + * * originally based on: * * linux/bvme/config.c * - * Copyright (C) 1993 Hamish Macdonald - * * This file is subject to the terms and conditions of the GNU General Public * License. See the file README.legal in the main directory of this archive * for more details. @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -134,12 +135,11 @@ void q40_reset() { - printk ("\n\n*******************************************\n" - "Called q40_reset : press the RESET button!! \n"); - printk( "*******************************************\n"); - - while(1) - ; + printk ("\n\n*******************************************\n" + "Called q40_reset : press the RESET button!! \n" + "*******************************************\n"); + + while(1) ; } static void q40_get_model(char *model) @@ -232,6 +232,9 @@ } static void (*q40_timer_routine)(int, void *, struct pt_regs *); +static short rtc_oldsecs=0; +unsigned rtc_irq_flags=0; +unsigned rtc_irq_ctrl=0; static void q40_timer_int (int irq, void *dev_id, struct pt_regs *fp) { @@ -250,6 +253,14 @@ *DAC_LEFT=sval; *DAC_RIGHT=sval; } +#ifdef CONFIG_Q40RTC + if (rtc_irq_ctrl && (rtc_oldsecs != RTC_SECS)) + { + rtc_oldsecs = RTC_SECS; + rtc_irq_flags = RTC_UIE; + rtc_interrupt(); + } +#endif if (ql_ticks) return; #endif q40_timer_routine(irq, dev_id, fp); diff -u --recursive --new-file v2.3.13/linux/arch/m68k/q40/q40ints.c linux/arch/m68k/q40/q40ints.c --- v2.3.13/linux/arch/m68k/q40/q40ints.c Tue May 11 09:57:14 1999 +++ linux/arch/m68k/q40/q40ints.c Tue Aug 17 10:39:32 1999 @@ -29,7 +29,7 @@ * 3,4,5,6,7,10,11,14,15 : ISA dev IRQs * 16-31: reserved * 32 : keyboard int - * 33 : frame int (50 Hz periodic timer) + * 33 : frame int (50/200 Hz periodic timer) * 34 : sample int (10/20 KHz periodic timer) * */ @@ -45,20 +45,21 @@ static void q40_defhand (int irq, void *dev_id, struct pt_regs *fp); static void sys_default_handler(int lev, void *dev_id, struct pt_regs *regs); -/* - * This should ideally be 4 elements only, for speed. - */ #define DEVNAME_SIZE 24 -static struct { +static struct q40_irq_node { void (*handler)(int, void *, struct pt_regs *); unsigned long flags; void *dev_id; + /* struct q40_irq_node *next;*/ char devname[DEVNAME_SIZE]; unsigned count; + unsigned short state; } irq_tab[Q40_IRQ_MAX+1]; +short unsigned q40_ablecount[Q40_IRQ_MAX+1]; + /* * void q40_init_IRQ (void) * @@ -78,8 +79,11 @@ irq_tab[i].handler = q40_defhand; irq_tab[i].flags = IRQ_FLG_STD; irq_tab[i].dev_id = NULL; + /* irq_tab[i].next = NULL;*/ irq_tab[i].devname[0] = 0; irq_tab[i].count = 0; + irq_tab[i].state =0; + q40_ablecount[i]=0; /* all enabled */ } /* setup handler for ISA ints */ @@ -108,23 +112,20 @@ } /* test for ISA ints not implemented by HW */ - if (irq<15) + switch (irq) { - switch (irq){ - case 1: case 2: case 8: case 9: - case 12: case 13: - printk("%s: ISA IRQ %d from %s not implemented by HW\n", __FUNCTION__, irq, devname); - return -ENXIO; - default: - } + case 1: case 2: case 8: case 9: + case 12: case 13: + printk("%s: ISA IRQ %d from %s not implemented by HW\n", __FUNCTION__, irq, devname); + return -ENXIO; + case 11: + printk("warning IRQ 10 and 11 not distinguishable\n"); + irq=10; + default: } if (irqsr;*/ + fp->sr = (fp->sr & (~0x700))+0x200; + disabled=1; + return; + } + irq_tab[irq].state |= IRQ_INPROGRESS; irq_tab[irq].handler(irq,irq_tab[irq].dev_id,fp); + + /* naively enable everything, if that fails than */ + /* this function will be reentered immediately thus */ + /* getting another chance to disable the IRQ */ + + irq_tab[irq].state &= ~IRQ_INPROGRESS; + if ( disabled ) + { + /*printk("reenabling irq %d\n",irq); */ + fp->sr = (fp->sr & (~0x700)); /*saved_mask; */ + disabled=0; + } + else if ( fp->sr &0x200 ) + printk("exiting irq handler: fp->sr &0x200 !!\n"); + return; } } @@ -279,7 +312,17 @@ if (irq_tab[irq].handler == q40_defhand ) continue; /* ignore uninited INTs :-( */ + /* the INPROGRESS stuff should be completely useless*/ + /* for internal ints, nevertheless test it..*/ + if ( irq_tab[irq].state & IRQ_INPROGRESS ) + { + /*disable_irq(irq); + return;*/ + printk("rentering handler for IRQ %d !!\n",irq); + } irq_tab[irq].handler(irq,irq_tab[irq].dev_id,fp); + irq_tab[irq].state &= ~IRQ_INPROGRESS; + /*enable_irq(irq);*/ /* better not try luck !*/ return; } } @@ -327,19 +370,59 @@ sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler }; +int irq_disabled=0; void q40_enable_irq (unsigned int irq) { + /* enable ISA iqs */ + if ( irq>=0 && irq<=15 ) /* the moderately bad case */ + master_outb(1,EXT_ENABLE_REG); +#if 0 + unsigned long flags; + int i; + + if (irq>=10 && irq <= 15) + { + if ( !(--q40_ablecount[irq])) + for (i=10,irq_disabled=0; i<=15; i++) + { + irq_disabled |= (q40_ablecount[irq] !=0); + } + if ( !irq_disabled ) + { + save_flags(flags); + restore_flags(flags & (~0x700)); + } + } +#endif } void q40_disable_irq (unsigned int irq) { + /* disable ISA iqs : only do something if the driver has been + * verified to be Q40 "compatible" - right now only IDE + * Any driver should not attempt to sleep accross disable_irq !! + */ + + if ( irq>=10 && irq<=15 ) /* the moderately bad case */ + master_outb(0,EXT_ENABLE_REG); +#if 0 + unsigned long flags; + + if (irq>=10 && irq <= 15) + { + save_flags(flags); + restore_flags(flags | 0x200 ); + irq_disabled=1; + q40_ablecount[irq]++; + } +#endif } unsigned long q40_probe_irq_on (void) { - printk("sorry, irq probing not yet implemented - reconfigure the driver to avoid this\n"); - return 0; + printk("irq probing not working - reconfigure the driver to avoid this\n"); + return -1; } int q40_probe_irq_off (unsigned long irqs) { diff -u --recursive --new-file v2.3.13/linux/arch/ppc/8xx_io/enet.c linux/arch/ppc/8xx_io/enet.c --- v2.3.13/linux/arch/ppc/8xx_io/enet.c Fri Apr 16 08:20:23 1999 +++ linux/arch/ppc/8xx_io/enet.c Wed Aug 18 11:39:01 1999 @@ -152,13 +152,13 @@ unsigned long lock; }; -static int cpm_enet_open(struct device *dev); -static int cpm_enet_start_xmit(struct sk_buff *skb, struct device *dev); -static int cpm_enet_rx(struct device *dev); +static int cpm_enet_open(struct net_device *dev); +static int cpm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int cpm_enet_rx(struct net_device *dev); static void cpm_enet_interrupt(void *dev_id); -static int cpm_enet_close(struct device *dev); -static struct net_device_stats *cpm_enet_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static int cpm_enet_close(struct net_device *dev); +static struct net_device_stats *cpm_enet_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); /* Get this from various configuration locations (depends on board). */ @@ -181,7 +181,7 @@ #endif static int -cpm_enet_open(struct device *dev) +cpm_enet_open(struct net_device *dev) { /* I should reset the ring buffers here, but I don't yet know @@ -196,7 +196,7 @@ } static int -cpm_enet_start_xmit(struct sk_buff *skb, struct device *dev) +cpm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct cpm_enet_private *cep = (struct cpm_enet_private *)dev->priv; volatile cbd_t *bdp; @@ -326,7 +326,7 @@ static void cpm_enet_interrupt(void *dev_id) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; volatile struct cpm_enet_private *cep; volatile cbd_t *bdp; ushort int_events; @@ -503,7 +503,7 @@ * effectively tossing the packet. */ static int -cpm_enet_rx(struct device *dev) +cpm_enet_rx(struct net_device *dev) { struct cpm_enet_private *cep; volatile cbd_t *bdp; @@ -597,7 +597,7 @@ } static int -cpm_enet_close(struct device *dev) +cpm_enet_close(struct net_device *dev) { /* Don't know what to do yet. */ @@ -605,7 +605,7 @@ return 0; } -static struct net_device_stats *cpm_enet_get_stats(struct device *dev) +static struct net_device_stats *cpm_enet_get_stats(struct net_device *dev) { struct cpm_enet_private *cep = (struct cpm_enet_private *)dev->priv; @@ -622,7 +622,7 @@ * this kind of feature?). */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { struct cpm_enet_private *cep; struct dev_mc_list *dmi; @@ -701,7 +701,7 @@ int __init cpm_enet_init() { m8xx_enet_init(); } int __init m8xx_enet_init(void) { - struct device *dev; + struct net_device *dev; struct cpm_enet_private *cep; int i, j; unsigned char *eap; diff -u --recursive --new-file v2.3.13/linux/arch/ppc/8xx_io/fec.c linux/arch/ppc/8xx_io/fec.c --- v2.3.13/linux/arch/ppc/8xx_io/fec.c Wed Sep 30 10:14:16 1998 +++ linux/arch/ppc/8xx_io/fec.c Wed Aug 18 11:39:01 1999 @@ -106,14 +106,14 @@ unsigned long lock; }; -static int fec_enet_open(struct device *dev); -static int fec_enet_start_xmit(struct sk_buff *skb, struct device *dev); -static int fec_enet_rx(struct device *dev); -static void fec_enet_mii(struct device *dev); +static int fec_enet_open(struct net_device *dev); +static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int fec_enet_rx(struct net_device *dev); +static void fec_enet_mii(struct net_device *dev); static void fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs); -static int fec_enet_close(struct device *dev); -static struct net_device_stats *fec_enet_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static int fec_enet_close(struct net_device *dev); +static struct net_device_stats *fec_enet_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); static ushort my_enet_addr[] = { 0x0800, 0x3e26, 0x1559 }; @@ -142,7 +142,7 @@ (VAL & 0xffff)) static int -fec_enet_open(struct device *dev) +fec_enet_open(struct net_device *dev) { /* I should reset the ring buffers here, but I don't yet know @@ -157,7 +157,7 @@ } static int -fec_enet_start_xmit(struct sk_buff *skb, struct device *dev) +fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct fec_enet_private *fep = (struct fec_enet_private *)dev->priv; volatile cbd_t *bdp; @@ -282,7 +282,7 @@ static void fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct fec_enet_private *fep; volatile cbd_t *bdp; volatile fec_t *ep; @@ -393,7 +393,7 @@ * effectively tossing the packet. */ static int -fec_enet_rx(struct device *dev) +fec_enet_rx(struct net_device *dev) { struct fec_enet_private *fep; volatile cbd_t *bdp; @@ -506,7 +506,7 @@ } static void -fec_enet_mii(struct device *dev) +fec_enet_mii(struct net_device *dev) { struct fec_enet_private *fep; volatile fec_t *ep; @@ -676,7 +676,7 @@ static void mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct fec_enet_private *fep; volatile fec_t *ep; @@ -696,7 +696,7 @@ } static int -fec_enet_close(struct device *dev) +fec_enet_close(struct net_device *dev) { /* Don't know what to do yet. */ @@ -704,7 +704,7 @@ return 0; } -static struct net_device_stats *fec_enet_get_stats(struct device *dev) +static struct net_device_stats *fec_enet_get_stats(struct net_device *dev) { struct fec_enet_private *fep = (struct fec_enet_private *)dev->priv; @@ -721,7 +721,7 @@ * this kind of feature?). */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { struct fec_enet_private *fep; struct dev_mc_list *dmi; @@ -792,7 +792,7 @@ */ __initfunc(int m8xx_enet_init(void)) { - struct device *dev; + struct net_device *dev; struct fec_enet_private *fep; int i, j; unsigned char *eap; diff -u --recursive --new-file v2.3.13/linux/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c --- v2.3.13/linux/arch/ppc/kernel/smp.c Mon Aug 9 14:59:19 1999 +++ linux/arch/ppc/kernel/smp.c Thu Aug 12 11:50:14 1999 @@ -31,7 +31,6 @@ #include #include #include -#include #include #include diff -u --recursive --new-file v2.3.13/linux/arch/sparc64/kernel/ioctl32.c linux/arch/sparc64/kernel/ioctl32.c --- v2.3.13/linux/arch/sparc64/kernel/ioctl32.c Mon Aug 9 14:59:19 1999 +++ linux/arch/sparc64/kernel/ioctl32.c Wed Aug 18 11:39:01 1999 @@ -421,7 +421,7 @@ static int dev_ifname32(unsigned int fd, unsigned long arg) { - struct device *dev; + struct net_device *dev; struct ifreq32 ifr32; int err; diff -u --recursive --new-file v2.3.13/linux/arch/sparc64/solaris/ioctl.c linux/arch/sparc64/solaris/ioctl.c --- v2.3.13/linux/arch/sparc64/solaris/ioctl.c Mon Aug 9 14:59:19 1999 +++ linux/arch/sparc64/solaris/ioctl.c Wed Aug 18 11:39:02 1999 @@ -663,7 +663,7 @@ #endif case 87: /* SIOCGIFNUM */ { - struct device *d; + struct net_device *d; int i = 0; read_lock_bh(&dev_base_lock); diff -u --recursive --new-file v2.3.13/linux/drivers/Makefile linux/drivers/Makefile --- v2.3.13/linux/drivers/Makefile Wed Jul 28 14:47:42 1999 +++ linux/drivers/Makefile Mon Aug 9 16:11:33 1999 @@ -7,7 +7,7 @@ # # Note 2! The CFLAGS definitions are now in the main makefile. -SUB_DIRS := block char net parport sound +SUB_DIRS := block char net parport sound misc MOD_SUB_DIRS := $(SUB_DIRS) ALL_SUB_DIRS := $(SUB_DIRS) pci sgi scsi sbus cdrom isdn pnp i2o \ macintosh video dio zorro fc4 usb \ diff -u --recursive --new-file v2.3.13/linux/drivers/acorn/net/ether1.c linux/drivers/acorn/net/ether1.c --- v2.3.13/linux/drivers/acorn/net/ether1.c Thu Jun 17 01:11:35 1999 +++ linux/drivers/acorn/net/ether1.c Wed Aug 18 11:38:59 1999 @@ -85,7 +85,7 @@ #define ether1_outw(dev, val, addr, type, offset, svflgs) ether1_outw_p (dev, val, addr + (int)(&((type *)0)->offset), svflgs) static inline unsigned short -ether1_inw_p (struct device *dev, int addr, int svflgs) +ether1_inw_p (struct net_device *dev, int addr, int svflgs) { unsigned long flags; unsigned short ret; @@ -101,7 +101,7 @@ } static inline void -ether1_outw_p (struct device *dev, unsigned short val, int addr, int svflgs) +ether1_outw_p (struct net_device *dev, unsigned short val, int addr, int svflgs) { unsigned long flags; @@ -211,7 +211,7 @@ static void -ether1_writebuffer (struct device *dev, void *data, unsigned int start, unsigned int length) +ether1_writebuffer (struct net_device *dev, void *data, unsigned int start, unsigned int length) { unsigned int page, thislen, offset; @@ -233,7 +233,7 @@ } static void -ether1_readbuffer (struct device *dev, void *data, unsigned int start, unsigned int length) +ether1_readbuffer (struct net_device *dev, void *data, unsigned int start, unsigned int length) { unsigned int page, thislen, offset; @@ -255,7 +255,7 @@ } __initfunc(static int -ether1_ramtest (struct device *dev, unsigned char byte)) +ether1_ramtest (struct net_device *dev, unsigned char byte)) { unsigned char *buffer = kmalloc (BUFFER_SIZE, GFP_KERNEL); int i, ret = BUFFER_SIZE; @@ -302,14 +302,14 @@ } static int -ether1_reset (struct device *dev) +ether1_reset (struct net_device *dev) { outb (CTRL_RST|CTRL_ACK, REG_CONTROL); return BUS_16; } __initfunc(static int -ether1_init_2 (struct device *dev)) +ether1_init_2 (struct net_device *dev)) { int i; dev->mem_start = 0; @@ -447,7 +447,7 @@ #define TBD_SIZE (0x08) static int -ether1_init_for_open (struct device *dev) +ether1_init_for_open (struct net_device *dev) { struct ether1_priv *priv = (struct ether1_priv *)dev->priv; int i, status, addr, next, next2; @@ -613,7 +613,7 @@ } __initfunc(static int -ether1_probe1 (struct device *dev)) +ether1_probe1 (struct net_device *dev)) { static unsigned int version_printed = 0; struct ether1_priv *priv; @@ -665,7 +665,7 @@ /* ------------------------------------------------------------------------- */ __initfunc(static void -ether1_addr (struct device *dev)) +ether1_addr (struct net_device *dev)) { int i; @@ -674,7 +674,7 @@ } __initfunc(int -ether1_probe (struct device *dev)) +ether1_probe (struct net_device *dev)) { #ifndef MODULE struct expansion_card *ec; @@ -702,7 +702,7 @@ /* ------------------------------------------------------------------------- */ static int -ether1_txalloc (struct device *dev, int size) +ether1_txalloc (struct net_device *dev, int size) { struct ether1_priv *priv = (struct ether1_priv *)dev->priv; int start, tail; @@ -728,7 +728,7 @@ } static void -ether1_restart (struct device *dev, char *reason) +ether1_restart (struct net_device *dev, char *reason) { struct ether1_priv *priv = (struct ether1_priv *)dev->priv; priv->stats.tx_errors ++; @@ -750,7 +750,7 @@ } static int -ether1_open (struct device *dev) +ether1_open (struct net_device *dev) { struct ether1_priv *priv = (struct ether1_priv *)dev->priv; @@ -775,7 +775,7 @@ } static int -ether1_sendpacket (struct sk_buff *skb, struct device *dev) +ether1_sendpacket (struct sk_buff *skb, struct net_device *dev) { struct ether1_priv *priv = (struct ether1_priv *)dev->priv; @@ -860,7 +860,7 @@ } static void -ether1_xmit_done (struct device *dev) +ether1_xmit_done (struct net_device *dev) { struct ether1_priv *priv = (struct ether1_priv *)dev->priv; nop_t nop; @@ -963,7 +963,7 @@ } static void -ether1_recv_done (struct device *dev) +ether1_recv_done (struct net_device *dev) { struct ether1_priv *priv = (struct ether1_priv *)dev->priv; int status; @@ -1020,7 +1020,7 @@ static void ether1_interrupt (int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct ether1_priv *priv = (struct ether1_priv *)dev->priv; int status; @@ -1070,7 +1070,7 @@ } static int -ether1_close (struct device *dev) +ether1_close (struct net_device *dev) { ether1_reset (dev); @@ -1085,7 +1085,7 @@ } static struct enet_statistics * -ether1_getstats (struct device *dev) +ether1_getstats (struct net_device *dev) { struct ether1_priv *priv = (struct ether1_priv *)dev->priv; return &priv->stats; @@ -1099,7 +1099,7 @@ * best-effort filtering. */ static void -ether1_setmulticastlist (struct device *dev) +ether1_setmulticastlist (struct net_device *dev) { } @@ -1110,7 +1110,7 @@ static struct ether_dev { struct expansion_card *ec; char name[9]; - struct device dev; + struct net_device dev; } ether_devs[MAX_ECARDS]; int diff -u --recursive --new-file v2.3.13/linux/drivers/acorn/net/ether1.h linux/drivers/acorn/net/ether1.h --- v2.3.13/linux/drivers/acorn/net/ether1.h Mon Feb 16 15:49:47 1998 +++ linux/drivers/acorn/net/ether1.h Wed Aug 18 11:38:59 1999 @@ -43,12 +43,12 @@ unsigned char restart : 1; }; -static int ether1_open (struct device *dev); -static int ether1_sendpacket (struct sk_buff *skb, struct device *dev); +static int ether1_open (struct net_device *dev); +static int ether1_sendpacket (struct sk_buff *skb, struct net_device *dev); static void ether1_interrupt (int irq, void *dev_id, struct pt_regs *regs); -static int ether1_close (struct device *dev); -static struct enet_statistics *ether1_getstats (struct device *dev); -static void ether1_setmulticastlist (struct device *dev); +static int ether1_close (struct net_device *dev); +static struct enet_statistics *ether1_getstats (struct net_device *dev); +static void ether1_setmulticastlist (struct net_device *dev); #define I82586_NULL (-1) diff -u --recursive --new-file v2.3.13/linux/drivers/acorn/net/ether3.c linux/drivers/acorn/net/ether3.c --- v2.3.13/linux/drivers/acorn/net/ether3.c Mon Aug 9 14:59:19 1999 +++ linux/drivers/acorn/net/ether3.c Wed Aug 18 11:38:59 1999 @@ -74,9 +74,9 @@ { 0xffff, 0xffff } }; -static void ether3_setmulticastlist(struct device *dev); -static int ether3_rx(struct device *dev, struct dev_priv *priv, unsigned int maxcnt); -static void ether3_tx(struct device *dev, struct dev_priv *priv); +static void ether3_setmulticastlist(struct net_device *dev); +static int ether3_rx(struct net_device *dev, struct dev_priv *priv, unsigned int maxcnt); +static void ether3_tx(struct net_device *dev, struct dev_priv *priv); #define BUS_16 2 #define BUS_8 1 @@ -115,7 +115,7 @@ #define ether3_inw(r) ({ unsigned int __v = inw((r)); udelay(1); __v; }) static int -ether3_setbuffer(struct device *dev, buffer_rw_t read, int start) +ether3_setbuffer(struct net_device *dev, buffer_rw_t read, int start) { struct dev_priv *priv = (struct dev_priv *)dev->priv; int timeout = 1000; @@ -175,7 +175,7 @@ static void ether3_ledoff(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct dev_priv *priv = (struct dev_priv *)dev->priv; ether3_outw(priv->regs.config2 |= CFG2_CTRLO, REG_CONFIG2); } @@ -184,7 +184,7 @@ * switch LED on... */ static inline void -ether3_ledon(struct device *dev, struct dev_priv *priv) +ether3_ledon(struct net_device *dev, struct dev_priv *priv) { del_timer(&priv->timer); priv->timer.expires = jiffies + HZ / 50; /* leave on for 1/50th second */ @@ -225,7 +225,7 @@ /* --------------------------------------------------------------------------- */ __initfunc(static int -ether3_ramtest(struct device *dev, unsigned char byte)) +ether3_ramtest(struct net_device *dev, unsigned char byte)) { unsigned char *buffer = kmalloc(RX_END, GFP_KERNEL); int i,ret = 0; @@ -274,7 +274,7 @@ /* ------------------------------------------------------------------------------- */ __initfunc(static int -ether3_init_2(struct device *dev)) +ether3_init_2(struct net_device *dev)) { struct dev_priv *priv = (struct dev_priv *)dev->priv; int i; @@ -324,7 +324,7 @@ } static void -ether3_init_for_open(struct device *dev) +ether3_init_for_open(struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; int i; @@ -364,7 +364,7 @@ } static inline int -ether3_probe_bus_8(struct device *dev, int val) +ether3_probe_bus_8(struct net_device *dev, int val) { int write_low, write_high, read_low, read_high; @@ -385,7 +385,7 @@ } static inline int -ether3_probe_bus_16(struct device *dev, int val) +ether3_probe_bus_16(struct net_device *dev, int val) { int read_val; @@ -401,7 +401,7 @@ * This is the real probe routine. */ __initfunc(static int -ether3_probe1(struct device *dev)) +ether3_probe1(struct net_device *dev)) { static unsigned version_printed = 0; struct dev_priv *priv; @@ -479,7 +479,7 @@ } __initfunc(static void -ether3_get_dev(struct device *dev, struct expansion_card *ec)) +ether3_get_dev(struct net_device *dev, struct expansion_card *ec)) { ecard_claim(ec); @@ -499,7 +499,7 @@ #ifndef MODULE __initfunc(int -ether3_probe(struct device *dev)) +ether3_probe(struct net_device *dev)) { struct expansion_card *ec; @@ -526,7 +526,7 @@ * there is non-reboot way to recover if something goes wrong. */ static int -ether3_open(struct device *dev) +ether3_open(struct net_device *dev) { MOD_INC_USE_COUNT; @@ -548,7 +548,7 @@ * The inverse routine to ether3_open(). */ static int -ether3_close(struct device *dev) +ether3_close(struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; @@ -573,7 +573,7 @@ * Get the current statistics. This may be called with the card open or * closed. */ -static struct enet_statistics *ether3_getstats(struct device *dev) +static struct enet_statistics *ether3_getstats(struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; return &priv->stats; @@ -585,7 +585,7 @@ * We don't attempt any packet filtering. The card may have a SEEQ 8004 * in which does not have the other ethernet address registers present... */ -static void ether3_setmulticastlist(struct device *dev) +static void ether3_setmulticastlist(struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; @@ -606,7 +606,7 @@ * Transmit a packet */ static int -ether3_sendpacket(struct sk_buff *skb, struct device *dev) +ether3_sendpacket(struct sk_buff *skb, struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; retry: @@ -710,7 +710,7 @@ static void ether3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct dev_priv *priv; unsigned int status; @@ -747,7 +747,7 @@ * If we have a good packet(s), get it/them out of the buffers. */ static int -ether3_rx(struct device *dev, struct dev_priv *priv, unsigned int maxcnt) +ether3_rx(struct net_device *dev, struct dev_priv *priv, unsigned int maxcnt) { unsigned int next_ptr = priv->rx_head, received = 0; ether3_ledon(dev, priv); @@ -867,7 +867,7 @@ * Update stats for the transmitted packet(s) */ static void -ether3_tx(struct device *dev, struct dev_priv *priv) +ether3_tx(struct net_device *dev, struct dev_priv *priv) { unsigned int tx_tail = priv->tx_tail; int max_work = 14; @@ -914,7 +914,7 @@ static struct ether_dev { struct expansion_card *ec; char name[9]; - struct device dev; + struct net_device dev; } ether_devs[MAX_ECARDS]; int diff -u --recursive --new-file v2.3.13/linux/drivers/acorn/net/ether3.h linux/drivers/acorn/net/ether3.h --- v2.3.13/linux/drivers/acorn/net/ether3.h Thu Jun 17 01:11:35 1999 +++ linux/drivers/acorn/net/ether3.h Wed Aug 18 11:38:59 1999 @@ -159,13 +159,13 @@ int broken; /* 0 = ok, 1 = something went wrong */ }; -extern int ether3_probe (struct device *dev); -static int ether3_probe1 (struct device *dev); -static int ether3_open (struct device *dev); -static int ether3_sendpacket (struct sk_buff *skb, struct device *dev); +extern int ether3_probe (struct net_device *dev); +static int ether3_probe1 (struct net_device *dev); +static int ether3_open (struct net_device *dev); +static int ether3_sendpacket (struct sk_buff *skb, struct net_device *dev); static void ether3_interrupt (int irq, void *dev_id, struct pt_regs *regs); -static int ether3_close (struct device *dev); -static struct enet_statistics *ether3_getstats (struct device *dev); -static void ether3_setmulticastlist (struct device *dev); +static int ether3_close (struct net_device *dev); +static struct enet_statistics *ether3_getstats (struct net_device *dev); +static void ether3_setmulticastlist (struct net_device *dev); #endif diff -u --recursive --new-file v2.3.13/linux/drivers/acorn/net/etherh.c linux/drivers/acorn/net/etherh.c --- v2.3.13/linux/drivers/acorn/net/etherh.c Thu Jun 17 01:11:35 1999 +++ linux/drivers/acorn/net/etherh.c Wed Aug 18 11:38:59 1999 @@ -104,7 +104,7 @@ } static void -etherh_setif(struct device *dev) +etherh_setif(struct net_device *dev) { unsigned long addr; unsigned long flags; @@ -140,7 +140,7 @@ } static int -etherh_getifstat(struct device *dev) +etherh_getifstat(struct net_device *dev) { int stat; @@ -172,7 +172,7 @@ * Reset the 8390 (hard reset) */ static void -etherh_reset(struct device *dev) +etherh_reset(struct net_device *dev) { outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, dev->base_addr); @@ -183,7 +183,7 @@ * Write a block of data out to the 8390 */ static void -etherh_block_output (struct device *dev, int count, const unsigned char *buf, int start_page) +etherh_block_output (struct net_device *dev, int count, const unsigned char *buf, int start_page) { unsigned int addr, dma_addr; unsigned long dma_start; @@ -241,7 +241,7 @@ * Read a block of data from the 8390 */ static void -etherh_block_input (struct device *dev, int count, struct sk_buff *skb, int ring_offset) +etherh_block_input (struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned int addr, dma_addr; unsigned char *buf; @@ -281,7 +281,7 @@ * Read a header from the 8390 */ static void -etherh_get_header (struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +etherh_get_header (struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned int addr, dma_addr; @@ -322,7 +322,7 @@ * there is non-reboot way to recover if something goes wrong. */ static int -etherh_open(struct device *dev) +etherh_open(struct net_device *dev) { MOD_INC_USE_COUNT; @@ -340,7 +340,7 @@ * The inverse routine to etherh_open(). */ static int -etherh_close(struct device *dev) +etherh_close(struct net_device *dev) { ei_close (dev); free_irq (dev->irq, dev); @@ -353,7 +353,7 @@ * This is the real probe routine. */ __initfunc(static int -etherh_probe1(struct device *dev)) +etherh_probe1(struct net_device *dev)) { static int version_printed; unsigned int addr, i, reg0, tmp; @@ -464,7 +464,7 @@ }; __initfunc(static void -etherh_initdev(ecard_t *ec, struct device *dev)) +etherh_initdev(ecard_t *ec, struct net_device *dev)) { ecard_claim (ec); @@ -497,7 +497,7 @@ #ifndef MODULE __initfunc(int -etherh_probe(struct device *dev)) +etherh_probe(struct net_device *dev)) { if (!dev) return ENODEV; @@ -522,13 +522,13 @@ static int io[MAX_ETHERH_CARDS]; static int irq[MAX_ETHERH_CARDS]; static char ethernames[MAX_ETHERH_CARDS][9]; -static struct device *my_ethers[MAX_ETHERH_CARDS]; +static struct net_device *my_ethers[MAX_ETHERH_CARDS]; static struct expansion_card *ec[MAX_ETHERH_CARDS]; static int init_all_cards(void) { - struct device *dev = NULL; + struct net_device *dev = NULL; int i, found = 0; for (i = 0; i < MAX_ETHERH_CARDS; i++) { @@ -541,9 +541,9 @@ for (i = 0; i < MAX_ETHERH_CARDS; i++) { if (!dev) - dev = (struct device *)kmalloc (sizeof (struct device), GFP_KERNEL); + dev = (struct net_device *)kmalloc (sizeof (struct net_device), GFP_KERNEL); if (dev) - memset (dev, 0, sizeof (struct device)); + memset (dev, 0, sizeof (struct net_device)); if (!io[i]) { if ((ec[i] = ecard_find (0, etherh_cids)) == NULL) diff -u --recursive --new-file v2.3.13/linux/drivers/acorn/net/net-probe.c linux/drivers/acorn/net/net-probe.c --- v2.3.13/linux/drivers/acorn/net/net-probe.c Mon Feb 16 15:49:48 1998 +++ linux/drivers/acorn/net/net-probe.c Wed Aug 18 11:38:59 1999 @@ -8,11 +8,11 @@ #include #include -extern int ether1_probe (struct device *dev); -extern int ether3_probe (struct device *dev); -extern int etherh_probe (struct device *dev); +extern int ether1_probe (struct net_device *dev); +extern int ether3_probe (struct net_device *dev); +extern int etherh_probe (struct net_device *dev); -__initfunc(int acorn_ethif_probe(struct device *dev)) +__initfunc(int acorn_ethif_probe(struct net_device *dev)) { if (1 #ifdef CONFIG_ARM_ETHERH diff -u --recursive --new-file v2.3.13/linux/drivers/ap1000/apfddi.c linux/drivers/ap1000/apfddi.c --- v2.3.13/linux/drivers/ap1000/apfddi.c Wed Mar 10 16:51:35 1999 +++ linux/drivers/ap1000/apfddi.c Wed Aug 18 11:38:58 1999 @@ -124,7 +124,7 @@ /* XXX our hardware address, canonical bit order */ static u_char apfddi_saddr[6] = { 0x42, 0x9a, 0x08, 0x6e, 0x11, 0x41 }; -struct device *apfddi_device = NULL; +struct net_device *apfddi_device = NULL; struct net_device_stats *apfddi_stats = NULL; volatile struct apfddi_queue *apfddi_queue_top = NULL; @@ -249,11 +249,11 @@ } -int apfddi_init(struct device *dev); +int apfddi_init(struct net_device *dev); static void apfddi_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int apfddi_xmit(struct sk_buff *skb, struct device *dev); +static int apfddi_xmit(struct sk_buff *skb, struct net_device *dev); int apfddi_rx(struct mac_buf *mbuf); -static struct net_device_stats *apfddi_get_stats(struct device *dev); +static struct net_device_stats *apfddi_get_stats(struct net_device *dev); #if APFDDI_DEBUG void dump_packet(char *action, char *buf, int len, int seq); #endif @@ -264,7 +264,7 @@ * saddr=NULL means use device source address (always will anyway) * daddr=NULL means leave destination address (eg unresolved arp) */ -static int apfddi_hard_header(struct sk_buff *skb, struct device *dev, +static int apfddi_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { @@ -366,7 +366,7 @@ * other address resolution) has completed on this sk_buff. We now let * ARP fill in the other fields. */ -static int apfddi_rebuild_header(void *buff, struct device *dev, +static int apfddi_rebuild_header(void *buff, struct net_device *dev, unsigned long raddr, struct sk_buff *skb) { int i, status; @@ -399,7 +399,7 @@ return(status); } -static int apfddi_set_mac_address(struct device *dev, void *addr) +static int apfddi_set_mac_address(struct net_device *dev, void *addr) { #if APFDDI_DEBUG printk("In apfddi_set_mac_address\n"); @@ -407,14 +407,14 @@ return (0); } -static void apfddi_set_multicast_list(struct device *dev) +static void apfddi_set_multicast_list(struct net_device *dev) { #if APFDDI_DEBUG printk("In apfddi_set_multicast_list\n"); #endif } -static int apfddi_do_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int apfddi_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { #if APFDDI_DEBUG printk("In apfddi_do_ioctl\n"); @@ -422,7 +422,7 @@ return (0); } -static int apfddi_set_config(struct device *dev, struct ifmap *map) +static int apfddi_set_config(struct net_device *dev, struct ifmap *map) { #if APFDDI_DEBUG printk("In apfddi_set_config\n"); @@ -433,7 +433,7 @@ /* * Opening the fddi device through ifconfig. */ -int apfddi_open(struct device *dev) +int apfddi_open(struct net_device *dev) { static int already_run = 0; unsigned flags; @@ -473,7 +473,7 @@ /* * Stop the fddi device through ifconfig. */ -int apfddi_stop(struct device *dev) +int apfddi_stop(struct net_device *dev) { *csr0 &= ~CS0_INT_ENABLE; apfddi_sleep(); @@ -484,7 +484,7 @@ /* * Initialise fddi network interface. */ -int apfddi_init(struct device *dev) +int apfddi_init(struct net_device *dev) { int i; @@ -625,7 +625,7 @@ /* * Transmitting packet over FDDI. */ -static int apfddi_xmit(struct sk_buff *skb, struct device *dev) +static int apfddi_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned long flags; @@ -692,7 +692,7 @@ /* * Return statistics of fddi driver. */ -static struct net_device_stats *apfddi_get_stats(struct device *dev) +static struct net_device_stats *apfddi_get_stats(struct net_device *dev) { return((struct net_device_stats *)dev->priv); } diff -u --recursive --new-file v2.3.13/linux/drivers/ap1000/apfddi.h linux/drivers/ap1000/apfddi.h --- v2.3.13/linux/drivers/ap1000/apfddi.h Fri Feb 7 05:54:54 1997 +++ linux/drivers/ap1000/apfddi.h Wed Aug 18 11:38:58 1999 @@ -137,6 +137,6 @@ void rmt_event(int st); void set_cf_join(int on); -extern struct device *apfddi_device; +extern struct net_device *apfddi_device; extern struct net_device_stats *apfddi_stats; diff -u --recursive --new-file v2.3.13/linux/drivers/ap1000/bif.c linux/drivers/ap1000/bif.c --- v2.3.13/linux/drivers/ap1000/bif.c Thu Jul 8 15:42:19 1999 +++ linux/drivers/ap1000/bif.c Wed Aug 18 11:38:58 1999 @@ -44,17 +44,17 @@ #define BIF_MTU 10240 -static struct device *bif_device = 0; +static struct net_device *bif_device = 0; static struct net_device_stats *bif_stats = 0; -int bif_init(struct device *dev); -int bif_open(struct device *dev); -static int bif_xmit(struct sk_buff *skb, struct device *dev); +int bif_init(struct net_device *dev); +int bif_open(struct net_device *dev); +static int bif_xmit(struct sk_buff *skb, struct net_device *dev); int bif_rx(struct sk_buff *skb); -int bif_stop(struct device *dev); -static struct net_device_stats *bif_get_stats(struct device *dev); +int bif_stop(struct net_device *dev); +static struct net_device_stats *bif_get_stats(struct net_device *dev); -static int bif_hard_header(struct sk_buff *skb, struct device *dev, +static int bif_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { @@ -70,7 +70,7 @@ return (dev->hard_header_len); } -static int bif_rebuild_header(void *buff, struct device *dev, +static int bif_rebuild_header(void *buff, struct net_device *dev, unsigned long raddr, struct sk_buff *skb) { /* this would normally be used to fill in hardware addresses after @@ -82,24 +82,24 @@ return(0); } -static int bif_set_mac_address(struct device *dev, void *addr) +static int bif_set_mac_address(struct net_device *dev, void *addr) { printk("BIF: set_mac_address called\n"); return (0); } -static void bif_set_multicast_list(struct device *dev) +static void bif_set_multicast_list(struct net_device *dev) { return; } -static int bif_do_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int bif_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { printk("BIF: Called do_ioctl\n"); return (0); } -static int bif_set_config(struct device *dev, struct ifmap *map) +static int bif_set_config(struct net_device *dev, struct ifmap *map) { printk("BIF: Called bif_set_config\n"); return (0); @@ -108,7 +108,7 @@ /* * Initialise bif network interface. */ -int bif_init(struct device *dev) +int bif_init(struct net_device *dev) { int i; @@ -149,7 +149,7 @@ return(0); } -int bif_open(struct device *dev) +int bif_open(struct net_device *dev) { printk("In bif_open\n"); dev->tbusy = 0; @@ -189,7 +189,7 @@ #endif -static int bif_xmit(struct sk_buff *skb, struct device *dev) +static int bif_xmit(struct sk_buff *skb, struct net_device *dev) { extern int bif_send_ip(int cid,struct sk_buff *skb); extern int tnet_send_ip(int cid,struct sk_buff *skb); @@ -260,7 +260,7 @@ return 0; } -int bif_stop(struct device *dev) +int bif_stop(struct net_device *dev) { printk("in bif_close\n"); @@ -273,7 +273,7 @@ /* * Return statistics of bif driver. */ -static struct net_device_stats *bif_get_stats(struct device *dev) +static struct net_device_stats *bif_get_stats(struct net_device *dev) { return((struct net_device_stats *)dev->priv); } diff -u --recursive --new-file v2.3.13/linux/drivers/block/floppy.c linux/drivers/block/floppy.c --- v2.3.13/linux/drivers/block/floppy.c Mon Aug 9 14:59:19 1999 +++ linux/drivers/block/floppy.c Tue Aug 17 10:48:20 1999 @@ -106,6 +106,12 @@ * 1998/09/20 -- David Weinehall -- Added slow-down code for buggy PS/2-drives. */ +/* + * 1999/08/13 -- Paul Slootman -- floppy stopped working on Alpha after 24 + * days, 6 hours, 32 minutes and 32 seconds (i.e. MAXINT jiffies; ints were + * being used to store jiffies, which are unsigned longs). + */ + #define FLOPPY_SANITY_CHECK #undef FLOPPY_SILENT_DCL_CLEAR @@ -606,10 +612,10 @@ #define OLOGSIZE 20 static void (*lasthandler)(void) = NULL; -static int interruptjiffies=0; -static int resultjiffies=0; +static unsigned long interruptjiffies=0; +static unsigned long resultjiffies=0; static int resultsize=0; -static int lastredo=0; +static unsigned long lastredo=0; static struct output_log { unsigned char data; @@ -629,7 +635,7 @@ drive = current_drive; del_timer(&fd_timeout); if (drive < 0 || drive > N_DRIVE) { - fd_timeout.expires = jiffies + 20*HZ; + fd_timeout.expires = jiffies + 20UL*HZ; drive=0; } else fd_timeout.expires = jiffies + UDP->timeout; @@ -712,7 +718,7 @@ #ifdef DCL_DEBUG if (UDP->flags & FD_DEBUG){ DPRINT("checking disk change line for drive %d\n",drive); - DPRINT("jiffies=%ld\n", jiffies); + DPRINT("jiffies=%lu\n", jiffies); DPRINT("disk change line=%x\n",fd_inb(FD_DIR)&0x80); DPRINT("flags=%lx\n",UDRS->flags); } @@ -1006,7 +1012,7 @@ } /* waits for a delay (spinup or select) to pass */ -static int wait_for_completion(int delay, timeout_fn function) +static int wait_for_completion(unsigned long delay, timeout_fn function) { if (FDCS->reset){ reset_fdc(); /* do the reset during sleep to win time @@ -1277,7 +1283,7 @@ static void fdc_specify(void) { unsigned char spec1, spec2; - int srt, hlt, hut; + unsigned long srt, hlt, hut; unsigned long dtr = NOMINAL_DTR; unsigned long scale_dtr = NOMINAL_DTR; int hlt_max_code = 0x7f; @@ -1367,7 +1373,7 @@ * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies) */ FDCS->dtr = raw_cmd->rate & 3; - return(wait_for_completion(jiffies+2*HZ/100, + return(wait_for_completion(jiffies+2UL*HZ/100, (timeout_fn) floppy_ready)); } /* fdc_dtr */ @@ -1463,7 +1469,8 @@ */ static void setup_rw_floppy(void) { - int i,ready_date,r, flags,dflags; + int i,r, flags,dflags; + unsigned long ready_date; timeout_fn function; flags = raw_cmd->flags; @@ -1536,7 +1543,7 @@ #ifdef DCL_DEBUG if (DP->flags & FD_DEBUG){ DPRINT("clearing NEWCHANGE flag because of effective seek\n"); - DPRINT("jiffies=%ld\n", jiffies); + DPRINT("jiffies=%lu\n", jiffies); } #endif CLEARF(FD_DISK_NEWCHANGE); /* effective seek */ @@ -1826,20 +1833,20 @@ printk("\n"); printk("floppy driver state\n"); printk("-------------------\n"); - printk("now=%ld last interrupt=%d last called handler=%p\n", - jiffies, interruptjiffies, lasthandler); + printk("now=%lu last interrupt=%lu diff=%lu last called handler=%p\n", + jiffies, interruptjiffies, jiffies-interruptjiffies, lasthandler); #ifdef FLOPPY_SANITY_CHECK printk("timeout_message=%s\n", timeout_message); printk("last output bytes:\n"); for (i=0; i < OLOGSIZE; i++) - printk("%2x %2x %ld\n", + printk("%2x %2x %lu\n", output_log[(i+output_log_pos) % OLOGSIZE].data, output_log[(i+output_log_pos) % OLOGSIZE].status, output_log[(i+output_log_pos) % OLOGSIZE].jiffies); - printk("last result at %d\n", resultjiffies); - printk("last redo_fd_request at %d\n", lastredo); + printk("last result at %lu\n", resultjiffies); + printk("last redo_fd_request at %lu\n", lastredo); for (i=0; icheckfreq < jiffies - UDRS->last_checked){ + if (UDP->checkfreq < (int)(jiffies - UDRS->last_checked)) { lock_fdc(drive,0); poll_drive(0,0); process_fd_request(); @@ -4061,8 +4068,7 @@ { "no_unexpected_interrupts", 0, &print_unex, 0, 0 }, { "L40SX", 0, &print_unex, 0, 0 } }; -#define FLOPPY_SETUP -void __init floppy_setup(char *str) +static int __init floppy_setup(char *str) { int i; int param; @@ -4084,7 +4090,7 @@ DPRINT("%s=%d\n", str, param); *config_params[i].var = param; } - return; + return 1; } } } @@ -4098,6 +4104,7 @@ } else DPRINT("botched floppy option\n"); DPRINT("Read linux/drivers/block/README.fd\n"); + return 1; } static int have_no_fdc= -EIO; @@ -4365,7 +4372,6 @@ static void __init parse_floppy_cfg_string(char *cfg) { char *ptr; - int ints[11]; while(*cfg) { for(ptr = cfg;*cfg && *cfg != ' ' && *cfg != '\t'; cfg++); @@ -4457,6 +4463,9 @@ #endif #else + +__setup ("floppy=", floppy_setup); + /* eject the boot floppy (if we need the drive for a different root floppy) */ /* This should only be called at boot time when we're sure that there's no * resource contention. */ diff -u --recursive --new-file v2.3.13/linux/drivers/block/genhd.c linux/drivers/block/genhd.c --- v2.3.13/linux/drivers/block/genhd.c Mon Aug 9 14:59:19 1999 +++ linux/drivers/block/genhd.c Thu Aug 12 12:26:06 1999 @@ -4,1404 +4,27 @@ * * Copyright (C) 1991-1998 Linus Torvalds * - * - * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug - * in the early extended-partition checks and added DM partitions - * - * Support for DiskManager v6.0x added by Mark Lord, - * with information provided by OnTrack. This now works for linux fdisk - * and LILO, as well as loadlin and bootln. Note that disks other than - * /dev/hda *must* have a "DOS" type 0x51 partition in the first slot (hda1). - * - * More flexible handling of extended partitions - aeb, 950831 - * - * Check partition table on IDE disks for common CHS translations - * - * Added needed MAJORS for new pairs, {hdi,hdj}, {hdk,hdl} + * Moved partition checking code to fs/partitions* - Russell King + * (linux@arm.uk.linux.org) */ #include #include #include #include -#include -#include #include #include -#include -#include - -/* - * Many architectures don't like unaligned accesses, which is - * frequently the case with the nr_sects and start_sect partition - * table entries. - */ -#include - -#define SYS_IND(p) (get_unaligned(&p->sys_ind)) -#define NR_SECTS(p) ({ __typeof__(p->nr_sects) __a = \ - get_unaligned(&p->nr_sects); \ - le32_to_cpu(__a); \ - }) - -#define START_SECT(p) ({ __typeof__(p->start_sect) __a = \ - get_unaligned(&p->start_sect); \ - le32_to_cpu(__a); \ - }) - -struct gendisk *gendisk_head = NULL; - -static int current_minor = 0; -extern int *blk_size[]; -extern void rd_load(void); -extern void initrd_load(void); - +extern int parport_init(void); extern int chr_dev_init(void); extern int blk_dev_init(void); extern int scsi_dev_init(void); extern int net_dev_init(void); -extern int i2o_init(void); - -#ifdef CONFIG_PPC -extern void note_bootable_part(kdev_t dev, int part); -#endif - -/* - * disk_name() is used by genhd.c and blkpg.c. - * It formats the devicename of the indicated disk into - * the supplied buffer (of size at least 32), and returns - * a pointer to that same buffer (for convenience). - */ -char *disk_name (struct gendisk *hd, int minor, char *buf) -{ - unsigned int part; - const char *maj = hd->major_name; - int unit = (minor >> hd->minor_shift) + 'a'; - - /* - * IDE devices use multiple major numbers, but the drives - * are named as: {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}.. - * This requires special handling here. - */ - switch (hd->major) { - case IDE9_MAJOR: - unit += 2; - case IDE8_MAJOR: - unit += 2; - case IDE7_MAJOR: - unit += 2; - case IDE6_MAJOR: - unit += 2; - case IDE5_MAJOR: - unit += 2; - case IDE4_MAJOR: - unit += 2; - case IDE3_MAJOR: - unit += 2; - case IDE2_MAJOR: - unit += 2; - case IDE1_MAJOR: - unit += 2; - case IDE0_MAJOR: - maj = "hd"; - break; - } - part = minor & ((1 << hd->minor_shift) - 1); - if (hd->major >= SCSI_DISK1_MAJOR && hd->major <= SCSI_DISK7_MAJOR) { - unit = unit + (hd->major - SCSI_DISK1_MAJOR + 1) * 16; - if (unit > 'z') { - unit -= 'z' + 1; - sprintf(buf, "sd%c%c", 'a' + unit / 26, 'a' + unit % 26); - if (part) - sprintf(buf + 4, "%d", part); - return buf; - } - } - if (hd->major >= COMPAQ_SMART2_MAJOR && hd->major <= COMPAQ_SMART2_MAJOR+7) { - int ctlr = hd->major - COMPAQ_SMART2_MAJOR; - int disk = minor >> hd->minor_shift; - int part = minor & (( 1 << hd->minor_shift) - 1); - if (part == 0) - sprintf(buf, "%s/c%dd%d", maj, ctlr, disk); - else - sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, disk, part); - return buf; - } - if (part) - sprintf(buf, "%s%c%d", maj, unit, part); - else - sprintf(buf, "%s%c", maj, unit); - return buf; -} - -static void add_partition (struct gendisk *hd, int minor, int start, int size) -{ - char buf[40]; - hd->part[minor].start_sect = start; - hd->part[minor].nr_sects = size; - if (hd->major >= COMPAQ_SMART2_MAJOR+0 && hd->major <= COMPAQ_SMART2_MAJOR+7) - printk(" p%d", (minor & ((1 << hd->minor_shift) - 1))); - else - printk(" %s", disk_name(hd, minor, buf)); -} - -static inline int is_extended_partition(struct partition *p) -{ - return (SYS_IND(p) == DOS_EXTENDED_PARTITION || - SYS_IND(p) == WIN98_EXTENDED_PARTITION || - SYS_IND(p) == LINUX_EXTENDED_PARTITION); -} - -int get_hardsect_size(kdev_t dev) -{ - if (hardsect_size[MAJOR(dev)] != NULL) - return hardsect_size[MAJOR(dev)][MINOR(dev)]; - else - return 512; -} - -static unsigned int get_ptable_blocksize(kdev_t dev) -{ - int ret = 1024; - - /* - * See whether the low-level driver has given us a minumum blocksize. - * If so, check to see whether it is larger than the default of 1024. - */ - if (!blksize_size[MAJOR(dev)]) - { - return ret; - } - - /* - * Check for certain special power of two sizes that we allow. - * With anything larger than 1024, we must force the blocksize up to - * the natural blocksize for the device so that we don't have to try - * and read partial sectors. Anything smaller should be just fine. - */ - - switch( blksize_size[MAJOR(dev)][MINOR(dev)] ) - { - case 2048: - ret = 2048; - break; - case 4096: - ret = 4096; - break; - case 8192: - ret = 8192; - break; - case 1024: - case 512: - case 256: - case 0: - /* - * These are all OK. - */ - break; - default: - panic("Strange blocksize for partition table\n"); - } - - return ret; - -} - -#ifdef CONFIG_MSDOS_PARTITION -/* - * Create devices for each logical partition in an extended partition. - * The logical partitions form a linked list, with each entry being - * a partition table with two entries. The first entry - * is the real data partition (with a start relative to the partition - * table start). The second is a pointer to the next logical partition - * (with a start relative to the entire extended partition). - * We do not create a Linux partition for the partition tables, but - * only for the actual data partitions. - */ - -#define MSDOS_LABEL_MAGIC 0xAA55 - -static void extended_partition(struct gendisk *hd, kdev_t dev) -{ - struct buffer_head *bh; - struct partition *p; - unsigned long first_sector, first_size, this_sector, this_size; - int mask = (1 << hd->minor_shift) - 1; - int sector_size = get_hardsect_size(dev) / 512; - int i; - - first_sector = hd->part[MINOR(dev)].start_sect; - first_size = hd->part[MINOR(dev)].nr_sects; - this_sector = first_sector; - - while (1) { - if ((current_minor & mask) == 0) - return; - if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) - return; - - if ((*(__u16 *) (bh->b_data+510)) != cpu_to_le16(MSDOS_LABEL_MAGIC)) - goto done; - - p = (struct partition *) (0x1BE + bh->b_data); - - this_size = hd->part[MINOR(dev)].nr_sects; - - /* - * Usually, the first entry is the real data partition, - * the 2nd entry is the next extended partition, or empty, - * and the 3rd and 4th entries are unused. - * However, DRDOS sometimes has the extended partition as - * the first entry (when the data partition is empty), - * and OS/2 seems to use all four entries. - */ - - /* - * First process the data partition(s) - */ - for (i=0; i<4; i++, p++) { - if (!NR_SECTS(p) || is_extended_partition(p)) - continue; - - /* Check the 3rd and 4th entries - - these sometimes contain random garbage */ - if (i >= 2 - && START_SECT(p) + NR_SECTS(p) > this_size - && (this_sector + START_SECT(p) < first_sector || - this_sector + START_SECT(p) + NR_SECTS(p) > - first_sector + first_size)) - continue; - - add_partition(hd, current_minor, this_sector+START_SECT(p)*sector_size, NR_SECTS(p)*sector_size); - current_minor++; - if ((current_minor & mask) == 0) - goto done; - } - /* - * Next, process the (first) extended partition, if present. - * (So far, there seems to be no reason to make - * extended_partition() recursive and allow a tree - * of extended partitions.) - * It should be a link to the next logical partition. - * Create a minor for this just long enough to get the next - * partition table. The minor will be reused for the next - * data partition. - */ - p -= 4; - for (i=0; i<4; i++, p++) - if(NR_SECTS(p) && is_extended_partition(p)) - break; - if (i == 4) - goto done; /* nothing left to do */ - - hd->part[current_minor].nr_sects = NR_SECTS(p) * sector_size; /* JSt */ - hd->part[current_minor].start_sect = first_sector + START_SECT(p) * sector_size; - this_sector = first_sector + START_SECT(p) * sector_size; - dev = MKDEV(hd->major, current_minor); - - /* Use bforget(), as we have changed the disk geometry */ - bforget(bh); - } -done: - bforget(bh); -} - -#ifdef CONFIG_SOLARIS_X86_PARTITION -static void -solaris_x86_partition(struct gendisk *hd, kdev_t dev, long offset) { - - struct buffer_head *bh; - struct solaris_x86_vtoc *v; - struct solaris_x86_slice *s; - int i; - - if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) - return; - v = (struct solaris_x86_vtoc *)(bh->b_data + 512); - if(v->v_sanity != SOLARIS_X86_VTOC_SANE) { - brelse(bh); - return; - } - printk(" v_version != 1) { - printk(" cannot handle version %ld vtoc>", v->v_version); - brelse(bh); - return; - } - for(i=0; iv_slice[i]; - - if (s->s_size == 0) - continue; - printk(" [s%d]", i); - /* solaris partitions are relative to current MS-DOS - * one but add_partition starts relative to sector - * zero of the disk. Therefore, must add the offset - * of the current partition */ - add_partition(hd, current_minor, s->s_start+offset, s->s_size); - current_minor++; - } - brelse(bh); - printk(" >"); -} -#endif - -#ifdef CONFIG_BSD_DISKLABEL -static void check_and_add_bsd_partition(struct gendisk *hd, - struct bsd_partition *bsd_p, kdev_t dev) -{ - struct hd_struct *lin_p; - /* check relative position of partitions. */ - for (lin_p = hd->part + 1 + MINOR(dev); - lin_p - hd->part - MINOR(dev) < current_minor; lin_p++) { - /* no relationship -> try again */ - if (lin_p->start_sect + lin_p->nr_sects <= bsd_p->p_offset - || lin_p->start_sect >= bsd_p->p_offset + bsd_p->p_size) - continue; - /* equal -> no need to add */ - if (lin_p->start_sect == bsd_p->p_offset && - lin_p->nr_sects == bsd_p->p_size) - return; - /* bsd living within dos partition */ - if (lin_p->start_sect <= bsd_p->p_offset && lin_p->start_sect - + lin_p->nr_sects >= bsd_p->p_offset + bsd_p->p_size) { -#ifdef DEBUG_BSD_DISKLABEL - printk("w: %d %ld+%ld,%d+%d", - lin_p - hd->part, - lin_p->start_sect, lin_p->nr_sects, - bsd_p->p_offset, bsd_p->p_size); -#endif - break; - } - /* ouch: bsd and linux overlap. Don't even try for that partition */ -#ifdef DEBUG_BSD_DISKLABEL - printk("???: %d %ld+%ld,%d+%d", - lin_p - hd->part, lin_p->start_sect, lin_p->nr_sects, - bsd_p->p_offset, bsd_p->p_size); -#endif - printk("???"); - return; - } /* if the bsd partition is not currently known to linux, we end - * up here - */ - add_partition(hd, current_minor, bsd_p->p_offset, bsd_p->p_size); - current_minor++; -} -/* - * Create devices for BSD partitions listed in a disklabel, under a - * dos-like partition. See extended_partition() for more information. - */ -static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev, - int max_partitions) -{ - struct buffer_head *bh; - struct bsd_disklabel *l; - struct bsd_partition *p; - int mask = (1 << hd->minor_shift) - 1; - - if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) - return; - l = (struct bsd_disklabel *) (bh->b_data+512); - if (l->d_magic != BSD_DISKMAGIC) { - brelse(bh); - return; - } - - if (l->d_npartitions < max_partitions) - max_partitions = l->d_npartitions; - for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) { - if ((current_minor & mask) >= (4 + hd->max_p)) - break; - - if (p->p_fstype != BSD_FS_UNUSED) - check_and_add_bsd_partition(hd, p, dev); - } - - /* Use bforget(), as we have changed the disk setup */ - bforget(bh); - -} -#endif - -#ifdef CONFIG_UNIXWARE_DISKLABEL -/* - * Create devices for Unixware partitions listed in a disklabel, under a - * dos-like partition. See extended_partition() for more information. - */ -static void unixware_partition(struct gendisk *hd, kdev_t dev) -{ - struct buffer_head *bh; - struct unixware_disklabel *l; - struct unixware_slice *p; - int mask = (1 << hd->minor_shift) - 1; - - if (!(bh = bread(dev, 14, get_ptable_blocksize(dev)))) - return; - l = (struct unixware_disklabel *) (bh->b_data+512); - if (le32_to_cpu(l->d_magic) != UNIXWARE_DISKMAGIC || - le32_to_cpu(l->vtoc.v_magic) != UNIXWARE_DISKMAGIC2) { - brelse(bh); - return; - } - printk(" vtoc.v_slice[1]; - /* I omit the 0th slice as it is the same as whole disk. */ - while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) { - if ((current_minor & mask) == 0) - break; - - if (p->s_label != UNIXWARE_FS_UNUSED) { - add_partition(hd, current_minor, START_SECT(p), NR_SECTS(p)); - current_minor++; - } - p++; - } - /* Use bforget, as we have changed the disk setup */ - bforget(bh); - printk(" >"); -} -#endif - -static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector) -{ - int i, minor = current_minor; - struct buffer_head *bh; - struct partition *p; - unsigned char *data; - int mask = (1 << hd->minor_shift) - 1; - int sector_size = get_hardsect_size(dev) / 512; -#ifdef CONFIG_BSD_DISKLABEL - /* no bsd disklabel as a default */ - kdev_t bsd_kdev = 0; - int bsd_maxpart = BSD_MAXPARTITIONS; -#endif -#ifdef CONFIG_BLK_DEV_IDE - int tested_for_xlate = 0; - -read_mbr: -#endif - if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) { - printk(" unable to read partition table\n"); - return -1; - } - data = bh->b_data; -#ifdef CONFIG_BLK_DEV_IDE -check_table: -#endif - /* Use bforget(), because we have potentially changed the disk geometry */ - if (*(unsigned short *) (0x1fe + data) != cpu_to_le16(MSDOS_LABEL_MAGIC)) { - bforget(bh); - return 0; - } - p = (struct partition *) (0x1be + data); - -#ifdef CONFIG_BLK_DEV_IDE - if (!tested_for_xlate++) { /* Do this only once per disk */ - /* - * Look for various forms of IDE disk geometry translation - */ - extern int ide_xlate_1024(kdev_t, int, const char *); - unsigned int sig = le16_to_cpu(*(unsigned short *)(data + 2)); - if (SYS_IND(p) == EZD_PARTITION) { - /* - * The remainder of the disk must be accessed using - * a translated geometry that reduces the number of - * apparent cylinders to less than 1024 if possible. - * - * ide_xlate_1024() will take care of the necessary - * adjustments to fool fdisk/LILO and partition check. - */ - if (ide_xlate_1024(dev, -1, " [EZD]")) { - data += 512; - goto check_table; - } - } else if (SYS_IND(p) == DM6_PARTITION) { - - /* - * Everything on the disk is offset by 63 sectors, - * including a "new" MBR with its own partition table, - * and the remainder of the disk must be accessed using - * a translated geometry that reduces the number of - * apparent cylinders to less than 1024 if possible. - * - * ide_xlate_1024() will take care of the necessary - * adjustments to fool fdisk/LILO and partition check. - */ - if (ide_xlate_1024(dev, 1, " [DM6:DDO]")) { - bforget(bh); - goto read_mbr; /* start over with new MBR */ - } - } else if (sig <= 0x1ae && - *(unsigned short *)(data + sig) == cpu_to_le16(0x55AA) && - (1 & *(unsigned char *)(data + sig + 2))) { - /* DM6 signature in MBR, courtesy of OnTrack */ - (void) ide_xlate_1024 (dev, 0, " [DM6:MBR]"); - } else if (SYS_IND(p) == DM6_AUX1PARTITION || SYS_IND(p) == DM6_AUX3PARTITION) { - /* - * DM6 on other than the first (boot) drive - */ - (void) ide_xlate_1024(dev, 0, " [DM6:AUX]"); - } else { - /* - * Examine the partition table for common translations. - * This is useful for drives in situations where the - * translated geometry is unavailable from the BIOS. - */ - for (i = 0; i < 4; i++) { - struct partition *q = &p[i]; - if (NR_SECTS(q) - && (q->sector & 63) == 1 - && (q->end_sector & 63) == 63) { - unsigned int heads = q->end_head + 1; - if (heads == 32 || heads == 64 || - heads == 128 || heads == 240 || - heads == 255) { - (void) ide_xlate_1024(dev, heads, " [PTBL]"); - break; - } - } - } - } - } -#endif /* CONFIG_BLK_DEV_IDE */ - - current_minor += 4; /* first "extra" minor (for extended partitions) */ - for (i=1 ; i<=4 ; minor++,i++,p++) { - if (!NR_SECTS(p)) - continue; - add_partition(hd, minor, first_sector+START_SECT(p)*sector_size, NR_SECTS(p)*sector_size); - if (is_extended_partition(p)) { - printk(" <"); - /* - * If we are rereading the partition table, we need - * to set the size of the partition so that we will - * be able to bread the block containing the extended - * partition info. - */ - hd->sizes[minor] = hd->part[minor].nr_sects - >> (BLOCK_SIZE_BITS - 9); - extended_partition(hd, MKDEV(hd->major, minor)); - printk(" >"); - /* prevent someone doing mkfs or mkswap on an - extended partition, but leave room for LILO */ - if (hd->part[minor].nr_sects > 2) - hd->part[minor].nr_sects = 2; - } -#ifdef CONFIG_BSD_DISKLABEL - /* tag first disklabel for late recognition */ - if (SYS_IND(p) == BSD_PARTITION || SYS_IND(p) == NETBSD_PARTITION) { - printk("!"); - if (!bsd_kdev) - bsd_kdev = MKDEV(hd->major, minor); - } else if (SYS_IND(p) == OPENBSD_PARTITION) { - printk("!"); - if (!bsd_kdev) { - bsd_kdev = MKDEV(hd->major, minor); - bsd_maxpart = OPENBSD_MAXPARTITIONS; - } - } -#endif -#ifdef CONFIG_UNIXWARE_DISKLABEL - if (SYS_IND(p) == UNIXWARE_PARTITION) - unixware_partition(hd, MKDEV(hd->major, minor)); -#endif -#ifdef CONFIG_SOLARIS_X86_PARTITION - - /* james@bpgc.com: Solaris has a nasty indicator: 0x82 - * which also means linux swap. For that reason, all - * of the prints are done inside the - * solaris_x86_partition routine */ - - if(SYS_IND(p) == SOLARIS_X86_PARTITION) { - solaris_x86_partition(hd, MKDEV(hd->major, minor), - first_sector+START_SECT(p)); - } -#endif - } -#ifdef CONFIG_BSD_DISKLABEL - if (bsd_kdev) { - printk(" <"); - bsd_disklabel_partition(hd, bsd_kdev, bsd_maxpart); - printk(" >"); - } -#endif - /* - * Check for old-style Disk Manager partition table - */ - if (*(unsigned short *) (data+0xfc) == cpu_to_le16(MSDOS_LABEL_MAGIC)) { - p = (struct partition *) (0x1be + data); - for (i = 4 ; i < 16 ; i++, current_minor++) { - p--; - if ((current_minor & mask) == 0) - break; - if (!(START_SECT(p) && NR_SECTS(p))) - continue; - add_partition(hd, current_minor, START_SECT(p), NR_SECTS(p)); - } - } - printk("\n"); - bforget(bh); - return 1; -} - -#endif /* CONFIG_MSDOS_PARTITION */ - -#ifdef CONFIG_OSF_PARTITION - -static int osf_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector) -{ - int i; - int mask = (1 << hd->minor_shift) - 1; - struct buffer_head *bh; - struct disklabel { - u32 d_magic; - u16 d_type,d_subtype; - u8 d_typename[16]; - u8 d_packname[16]; - u32 d_secsize; - u32 d_nsectors; - u32 d_ntracks; - u32 d_ncylinders; - u32 d_secpercyl; - u32 d_secprtunit; - u16 d_sparespertrack; - u16 d_sparespercyl; - u32 d_acylinders; - u16 d_rpm, d_interleave, d_trackskew, d_cylskew; - u32 d_headswitch, d_trkseek, d_flags; - u32 d_drivedata[5]; - u32 d_spare[5]; - u32 d_magic2; - u16 d_checksum; - u16 d_npartitions; - u32 d_bbsize, d_sbsize; - struct d_partition { - u32 p_size; - u32 p_offset; - u32 p_fsize; - u8 p_fstype; - u8 p_frag; - u16 p_cpg; - } d_partitions[8]; - } * label; - struct d_partition * partition; -#define DISKLABELMAGIC (0x82564557UL) - - if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) { - printk("unable to read partition table\n"); - return -1; - } - label = (struct disklabel *) (bh->b_data+64); - partition = label->d_partitions; - if (label->d_magic != DISKLABELMAGIC) { - brelse(bh); - return 0; - } - if (label->d_magic2 != DISKLABELMAGIC) { - brelse(bh); - return 0; - } - for (i = 0 ; i < label->d_npartitions; i++, partition++) { - if ((current_minor & mask) == 0) - break; - if (partition->p_size) - add_partition(hd, current_minor, - first_sector+partition->p_offset, - partition->p_size); - current_minor++; - } - printk("\n"); - brelse(bh); - return 1; -} - -#endif /* CONFIG_OSF_PARTITION */ - -#ifdef CONFIG_SUN_PARTITION - -static int sun_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector) -{ - int i, csum; - unsigned short *ush; - struct buffer_head *bh; - struct sun_disklabel { - unsigned char info[128]; /* Informative text string */ - unsigned char spare[292]; /* Boot information etc. */ - unsigned short rspeed; /* Disk rotational speed */ - unsigned short pcylcount; /* Physical cylinder count */ - unsigned short sparecyl; /* extra sects per cylinder */ - unsigned char spare2[4]; /* More magic... */ - unsigned short ilfact; /* Interleave factor */ - unsigned short ncyl; /* Data cylinder count */ - unsigned short nacyl; /* Alt. cylinder count */ - unsigned short ntrks; /* Tracks per cylinder */ - unsigned short nsect; /* Sectors per track */ - unsigned char spare3[4]; /* Even more magic... */ - struct sun_partition { - __u32 start_cylinder; - __u32 num_sectors; - } partitions[8]; - unsigned short magic; /* Magic number */ - unsigned short csum; /* Label xor'd checksum */ - } * label; - struct sun_partition *p; - unsigned long spc; -#define SUN_LABEL_MAGIC 0xDABE - - if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) { - printk("Dev %s: unable to read partition table\n", - kdevname(dev)); - return -1; - } - label = (struct sun_disklabel *) bh->b_data; - p = label->partitions; - if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) { - printk("Dev %s Sun disklabel: bad magic %04x\n", - kdevname(dev), be16_to_cpu(label->magic)); - brelse(bh); - return 0; - } - /* Look at the checksum */ - ush = ((unsigned short *) (label+1)) - 1; - for(csum = 0; ush >= ((unsigned short *) label);) - csum ^= *ush--; - if(csum) { - printk("Dev %s Sun disklabel: Csum bad, label corrupted\n", - kdevname(dev)); - brelse(bh); - return 0; - } - /* All Sun disks have 8 partition entries */ - spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect); - for(i=0; i < 8; i++, p++) { - unsigned long st_sector; - int num_sectors; - - st_sector = first_sector + be32_to_cpu(p->start_cylinder) * spc; - num_sectors = be32_to_cpu(p->num_sectors); - if (num_sectors) - add_partition(hd, current_minor, st_sector, num_sectors); - current_minor++; - } - printk("\n"); - brelse(bh); - return 1; -} - -#endif /* CONFIG_SUN_PARTITION */ - -#ifdef CONFIG_SGI_PARTITION +extern void console_map_init(void); +extern int soc_probe(void); -static int sgi_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector) +void __init device_init(void) { - int i, csum, magic; - unsigned int *ui, start, blocks, cs; - struct buffer_head *bh; - struct sgi_disklabel { - int magic_mushroom; /* Big fat spliff... */ - short root_part_num; /* Root partition number */ - short swap_part_num; /* Swap partition number */ - char boot_file[16]; /* Name of boot file for ARCS */ - unsigned char _unused0[48]; /* Device parameter useless crapola.. */ - struct sgi_volume { - char name[8]; /* Name of volume */ - int block_num; /* Logical block number */ - int num_bytes; /* How big, in bytes */ - } volume[15]; - struct sgi_partition { - int num_blocks; /* Size in logical blocks */ - int first_block; /* First logical block */ - int type; /* Type of this partition */ - } partitions[16]; - int csum; /* Disk label checksum */ - int _unused1; /* Padding */ - } *label; - struct sgi_partition *p; -#define SGI_LABEL_MAGIC 0x0be5a941 - - if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) { - printk("Dev %s: unable to read partition table\n", kdevname(dev)); - return -1; - } - label = (struct sgi_disklabel *) bh->b_data; - p = &label->partitions[0]; - magic = label->magic_mushroom; - if(be32_to_cpu(magic) != SGI_LABEL_MAGIC) { - printk("Dev %s SGI disklabel: bad magic %08x\n", - kdevname(dev), magic); - brelse(bh); - return 0; - } - ui = ((unsigned int *) (label + 1)) - 1; - for(csum = 0; ui >= ((unsigned int *) label);) { - cs = *ui--; - csum += be32_to_cpu(cs); - } - if(csum) { - printk("Dev %s SGI disklabel: csum bad, label corrupted\n", - kdevname(dev)); - brelse(bh); - return 0; - } - /* All SGI disk labels have 16 partitions, disks under Linux only - * have 15 minor's. Luckily there are always a few zero length - * partitions which we don't care about so we never overflow the - * current_minor. - */ - for(i = 0; i < 16; i++, p++) { - blocks = be32_to_cpu(p->num_blocks); - start = be32_to_cpu(p->first_block); - if(!blocks) - continue; - add_partition(hd, current_minor, start, blocks); - current_minor++; - } - printk("\n"); - brelse(bh); - return 1; -} - -#endif - -#ifdef CONFIG_AMIGA_PARTITION -#include - -static __inline__ u32 -checksum_block(u32 *m, int size) -{ - u32 sum = 0; - - while (size--) - sum += htonl(*m++); - return sum; -} - -static int -amiga_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector) -{ - struct buffer_head *bh; - struct RigidDiskBlock *rdb; - struct PartitionBlock *pb; - int start_sect; - int nr_sects; - int blk; - int part, res; - int old_blocksize; - int blocksize; - - old_blocksize = get_ptable_blocksize(dev); - blocksize = get_hardsect_size(dev); - - set_blocksize(dev,blocksize); - res = 0; - - for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) { - if(!(bh = bread(dev,blk,blocksize))) { - printk("Dev %s: unable to read RDB block %d\n", - kdevname(dev),blk); - goto rdb_done; - } - if (*(u32 *)bh->b_data == htonl(IDNAME_RIGIDDISK)) { - rdb = (struct RigidDiskBlock *)bh->b_data; - if (checksum_block((u32 *)bh->b_data,htonl(rdb->rdb_SummedLongs) & 0x7F)) { - /* Try again with 0xdc..0xdf zeroed, Windows might have - * trashed it. - */ - *(u32 *)(&bh->b_data[0xdc]) = 0; - if (checksum_block((u32 *)bh->b_data, - htonl(rdb->rdb_SummedLongs) & 0x7F)) { - brelse(bh); - printk("Dev %s: RDB in block %d has bad checksum\n", - kdevname(dev),blk); - continue; - } - printk("Warning: Trashed word at 0xd0 in block %d " - "ignored in checksum calculation\n",blk); - } - printk(" RDSK"); - blk = htonl(rdb->rdb_PartitionList); - brelse(bh); - for (part = 1; blk > 0 && part <= 16; part++) { - if (!(bh = bread(dev,blk,blocksize))) { - printk("Dev %s: unable to read partition block %d\n", - kdevname(dev),blk); - goto rdb_done; - } - pb = (struct PartitionBlock *)bh->b_data; - blk = htonl(pb->pb_Next); - if (pb->pb_ID == htonl(IDNAME_PARTITION) && checksum_block( - (u32 *)pb,htonl(pb->pb_SummedLongs) & 0x7F) == 0 ) { - - /* Tell Kernel about it */ - - if (!(nr_sects = (htonl(pb->pb_Environment[10]) + 1 - - htonl(pb->pb_Environment[9])) * - htonl(pb->pb_Environment[3]) * - htonl(pb->pb_Environment[5]))) { - brelse(bh); - continue; - } - start_sect = htonl(pb->pb_Environment[9]) * - htonl(pb->pb_Environment[3]) * - htonl(pb->pb_Environment[5]); - add_partition(hd,current_minor,start_sect,nr_sects); - current_minor++; - res = 1; - } - brelse(bh); - } - printk("\n"); - } - else - brelse(bh); - } - -rdb_done: - set_blocksize(dev,old_blocksize); - return res; -} -#endif /* CONFIG_AMIGA_PARTITION */ - -#ifdef CONFIG_MAC_PARTITION -#include - -/* - * Code to understand MacOS partition tables. - */ - -#define MAC_PARTITION_MAGIC 0x504d - -/* type field value for A/UX or other Unix partitions */ -#define APPLE_AUX_TYPE "Apple_UNIX_SVR2" - -struct mac_partition { - __u16 signature; /* expected to be MAC_PARTITION_MAGIC */ - __u16 res1; - __u32 map_count; /* # blocks in partition map */ - __u32 start_block; /* absolute starting block # of partition */ - __u32 block_count; /* number of blocks in partition */ - char name[32]; /* partition name */ - char type[32]; /* string type description */ - __u32 data_start; /* rel block # of first data block */ - __u32 data_count; /* number of data blocks */ - __u32 status; /* partition status bits */ - __u32 boot_start; - __u32 boot_size; - __u32 boot_load; - __u32 boot_load2; - __u32 boot_entry; - __u32 boot_entry2; - __u32 boot_cksum; - char processor[16]; /* identifies ISA of boot */ - /* there is more stuff after this that we don't need */ -}; - -#define MAC_STATUS_BOOTABLE 8 /* partition is bootable */ - -#define MAC_DRIVER_MAGIC 0x4552 - -/* Driver descriptor structure, in block 0 */ -struct mac_driver_desc { - __u16 signature; /* expected to be MAC_DRIVER_MAGIC */ - __u16 block_size; - __u32 block_count; - /* ... more stuff */ -}; - -static int mac_partition(struct gendisk *hd, kdev_t dev, unsigned long fsec) -{ - struct buffer_head *bh; - int blk, blocks_in_map; - int dev_bsize, dev_pos, pos; - unsigned secsize; -#ifdef CONFIG_PPC - int first_bootable = 1; -#endif - struct mac_partition *part; - struct mac_driver_desc *md; - - dev_bsize = get_ptable_blocksize(dev); - dev_pos = 0; - /* Get 0th block and look at the first partition map entry. */ - if ((bh = bread(dev, 0, dev_bsize)) == 0) { - printk("%s: error reading partition table\n", - kdevname(dev)); - return -1; - } - md = (struct mac_driver_desc *) bh->b_data; - if (be16_to_cpu(md->signature) != MAC_DRIVER_MAGIC) { - brelse(bh); - return 0; - } - secsize = be16_to_cpu(md->block_size); - if (secsize >= dev_bsize) { - brelse(bh); - dev_pos = secsize; - if ((bh = bread(dev, secsize/dev_bsize, dev_bsize)) == 0) { - printk("%s: error reading partition table\n", - kdevname(dev)); - return -1; - } - } - part = (struct mac_partition *) (bh->b_data + secsize - dev_pos); - if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) { - brelse(bh); - return 0; /* not a MacOS disk */ - } - blocks_in_map = be32_to_cpu(part->map_count); - for (blk = 1; blk <= blocks_in_map; ++blk) { - pos = blk * secsize; - if (pos >= dev_pos + dev_bsize) { - brelse(bh); - dev_pos = pos; - if ((bh = bread(dev, pos/dev_bsize, dev_bsize)) == 0) { - printk("%s: error reading partition table\n", - kdevname(dev)); - return -1; - } - } - part = (struct mac_partition *) (bh->b_data + pos - dev_pos); - if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) - break; - blocks_in_map = be32_to_cpu(part->map_count); - add_partition(hd, current_minor, - fsec + be32_to_cpu(part->start_block) * (secsize/512), - be32_to_cpu(part->block_count) * (secsize/512)); - -#ifdef CONFIG_PPC - /* - * If this is the first bootable partition, tell the - * setup code, in case it wants to make this the root. - */ - if ( (_machine == _MACH_Pmac) && first_bootable - && (be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE) - && strcasecmp(part->processor, "powerpc") == 0) { - note_bootable_part(dev, blk); - first_bootable = 0; - } -#endif /* CONFIG_PPC */ - - ++current_minor; - } - brelse(bh); - printk("\n"); - return 1; -} - -#endif /* CONFIG_MAC_PARTITION */ - -#ifdef CONFIG_ATARI_PARTITION -#include - -/* ++guenther: this should be settable by the user ("make config")?. - */ -#define ICD_PARTS - -static int atari_partition (struct gendisk *hd, kdev_t dev, - unsigned long first_sector) -{ - int minor = current_minor, m_lim = current_minor + hd->max_p; - struct buffer_head *bh; - struct rootsector *rs; - struct partition_info *pi; - ulong extensect; - unsigned int psum; - int i; -#ifdef ICD_PARTS - int part_fmt = 0; /* 0:unknown, 1:AHDI, 2:ICD/Supra */ -#endif - - bh = bread (dev, 0, get_ptable_blocksize(dev)); - if (!bh) { - printk (" unable to read block 0 (partition table)\n"); - return -1; - } - - /* Verify this is an Atari rootsector: */ - psum=0; - for (i=0;i<256;i++) { - psum+=ntohs(((__u16 *) (bh->b_data))[i]); - } - if ((psum & 0xFFFF) != 0x1234) { - brelse(bh); - return 0; - } - - rs = (struct rootsector *) bh->b_data; - pi = &rs->part[0]; - printk (" AHDI"); - for (; pi < &rs->part[4] && minor < m_lim; minor++, pi++) - { - if (pi->flg & 1) - /* active partition */ - { - if (memcmp (pi->id, "XGM", 3) == 0) - /* extension partition */ - { - struct rootsector *xrs; - struct buffer_head *xbh; - ulong partsect; - -#ifdef ICD_PARTS - part_fmt = 1; -#endif - printk(" XGM<"); - partsect = extensect = ntohl(pi->st); - while (1) - { - xbh = bread (dev, partsect / 2, get_ptable_blocksize(dev)); - if (!xbh) - { - printk (" block %ld read failed\n", partsect); - brelse(bh); - return 0; - } - if (partsect & 1) - xrs = (struct rootsector *) &xbh->b_data[512]; - else - xrs = (struct rootsector *) &xbh->b_data[0]; - - /* ++roman: sanity check: bit 0 of flg field must be set */ - if (!(xrs->part[0].flg & 1)) { - printk( "\nFirst sub-partition in extended partition is not valid!\n" ); - break; - } - - add_partition(hd, minor, partsect + ntohl(xrs->part[0].st), - ntohl(xrs->part[0].siz)); - - if (!(xrs->part[1].flg & 1)) { - /* end of linked partition list */ - brelse( xbh ); - break; - } - if (memcmp( xrs->part[1].id, "XGM", 3 ) != 0) { - printk( "\nID of extended partition is not XGM!\n" ); - brelse( xbh ); - break; - } - - partsect = ntohl(xrs->part[1].st) + extensect; - brelse (xbh); - minor++; - if (minor >= m_lim) { - printk( "\nMaximum number of partitions reached!\n" ); - break; - } - } - printk(" >"); - } - else - { - /* we don't care about other id's */ - add_partition (hd, minor, ntohl(pi->st), ntohl(pi->siz)); - } - } - } -#ifdef ICD_PARTS - if ( part_fmt!=1 ) /* no extended partitions -> test ICD-format */ - { - pi = &rs->icdpart[0]; - /* sanity check: no ICD format if first partition invalid */ - if (memcmp (pi->id, "GEM", 3) == 0 || - memcmp (pi->id, "BGM", 3) == 0 || - memcmp (pi->id, "LNX", 3) == 0 || - memcmp (pi->id, "SWP", 3) == 0 || - memcmp (pi->id, "RAW", 3) == 0 ) - { - printk(" ICD<"); - for (; pi < &rs->icdpart[8] && minor < m_lim; minor++, pi++) - { - /* accept only GEM,BGM,RAW,LNX,SWP partitions */ - if (pi->flg & 1 && - (memcmp (pi->id, "GEM", 3) == 0 || - memcmp (pi->id, "BGM", 3) == 0 || - memcmp (pi->id, "LNX", 3) == 0 || - memcmp (pi->id, "SWP", 3) == 0 || - memcmp (pi->id, "RAW", 3) == 0) ) - { - part_fmt = 2; - add_partition (hd, minor, ntohl(pi->st), ntohl(pi->siz)); - } - } - printk(" >"); - } - } -#endif - brelse (bh); - - printk ("\n"); - - return 1; -} -#endif /* CONFIG_ATARI_PARTITION */ - -#ifdef CONFIG_ULTRIX_PARTITION - -static int ultrix_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector) -{ - int i, minor = current_minor; - struct buffer_head *bh; - struct ultrix_disklabel { - s32 pt_magic; /* magic no. indicating part. info exits */ - s32 pt_valid; /* set by driver if pt is current */ - struct pt_info { - s32 pi_nblocks; /* no. of sectors */ - u32 pi_blkoff; /* block offset for start */ - } pt_part[8]; - } *label; - -#define PT_MAGIC 0x032957 /* Partition magic number */ -#define PT_VALID 1 /* Indicates if struct is valid */ - -#define SBLOCK ((unsigned long)((16384 - sizeof(struct ultrix_disklabel)) \ - /get_ptable_blocksize(dev))) - - bh = bread (dev, SBLOCK, get_ptable_blocksize(dev)); - if (!bh) { - printk (" unable to read block 0x%lx\n", SBLOCK); - return -1; - } - - label = (struct ultrix_disklabel *)(bh->b_data - + get_ptable_blocksize(dev) - - sizeof(struct ultrix_disklabel)); - - if (label->pt_magic == PT_MAGIC && label->pt_valid == PT_VALID) { - for (i=0; i<8; i++, minor++) - if (label->pt_part[i].pi_nblocks) - add_partition(hd, minor, - label->pt_part[i].pi_blkoff, - label->pt_part[i].pi_nblocks); - brelse(bh); - printk ("\n"); - return 1; - } else { - brelse(bh); - return 0; - } -} - -#endif /* CONFIG_ULTRIX_PARTITION */ - -static void check_partition(struct gendisk *hd, kdev_t dev) -{ - static int first_time = 1; - unsigned long first_sector; - char buf[40]; - - if (first_time) - printk(KERN_INFO "Partition check:\n"); - first_time = 0; - first_sector = hd->part[MINOR(dev)].start_sect; - - /* - * This is a kludge to allow the partition check to be - * skipped for specific drives (e.g. IDE CD-ROM drives) - */ - if ((int)first_sector == -1) { - hd->part[MINOR(dev)].start_sect = 0; - return; - } - - printk(KERN_INFO " %s:", disk_name(hd, MINOR(dev), buf)); -#ifdef CONFIG_MSDOS_PARTITION - if (msdos_partition(hd, dev, first_sector)) - return; -#endif -#ifdef CONFIG_OSF_PARTITION - if (osf_partition(hd, dev, first_sector)) - return; -#endif -#ifdef CONFIG_SUN_PARTITION - if(sun_partition(hd, dev, first_sector)) - return; -#endif -#ifdef CONFIG_AMIGA_PARTITION - if(amiga_partition(hd, dev, first_sector)) - return; -#endif -#ifdef CONFIG_ATARI_PARTITION - if(atari_partition(hd, dev, first_sector)) - return; -#endif -#ifdef CONFIG_MAC_PARTITION - if (mac_partition(hd, dev, first_sector)) - return; -#endif -#ifdef CONFIG_SGI_PARTITION - if(sgi_partition(hd, dev, first_sector)) - return; -#endif -#ifdef CONFIG_ULTRIX_PARTITION - if(ultrix_partition(hd, dev, first_sector)) - return; -#endif - printk(" unknown partition table\n"); -} - -/* This function is used to re-read partition tables for removable disks. - Much of the cleanup from the old partition tables should have already been - done */ - -/* This function will re-read the partition tables for a given device, -and set things back up again. There are some important caveats, -however. You must ensure that no one is using the device, and no one -can start using the device while this function is being executed. */ - -void resetup_one_dev(struct gendisk *dev, int drive) -{ - int i; - int first_minor = drive << dev->minor_shift; - int end_minor = first_minor + dev->max_p; - - blk_size[dev->major] = NULL; - current_minor = 1 + first_minor; - check_partition(dev, MKDEV(dev->major, first_minor)); - - /* - * We need to set the sizes array before we will be able to access - * any of the partitions on this device. - */ - if (dev->sizes != NULL) { /* optional safeguard in ll_rw_blk.c */ - for (i = first_minor; i < end_minor; i++) - dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9); - blk_size[dev->major] = dev->sizes; - } -} - -static inline void setup_dev(struct gendisk *dev) -{ - int i, drive; - int end_minor = dev->max_nr * dev->max_p; - - blk_size[dev->major] = NULL; - for (i = 0; i < end_minor; i++) { - dev->part[i].start_sect = 0; - dev->part[i].nr_sects = 0; - dev->sizes[i] = 0; - } - dev->init(dev); - for (drive = 0; drive < dev->nr_real; drive++) - resetup_one_dev(dev, drive); -} - -static int __init device_setup(void) -{ - extern void console_map_init(void); - extern void cpqarray_init(void); -#ifdef CONFIG_PARPORT - extern int parport_init(void) __init; -#endif -#ifdef CONFIG_MD_BOOT - extern void md_setup_drive(void) __init; -#endif -#ifdef CONFIG_FC4_SOC - extern int soc_probe(void); -#endif - struct gendisk *p; - #ifdef CONFIG_PARPORT parport_init(); #endif @@ -1431,43 +54,4 @@ #ifdef CONFIG_VT console_map_init(); #endif - - for (p = gendisk_head ; p ; p=p->next) - setup_dev(p); - -#ifdef CONFIG_BLK_DEV_RAM -#ifdef CONFIG_BLK_DEV_INITRD - if (initrd_start && mount_initrd) initrd_load(); - else -#endif - rd_load(); -#endif -#ifdef CONFIG_MD_BOOT - md_setup_drive(); -#endif - return 0; } - -__initcall(device_setup); - -#ifdef CONFIG_PROC_FS -int get_partition_list(char * page) -{ - struct gendisk *p; - char buf[40]; - int n, len; - - len = sprintf(page, "major minor #blocks name\n\n"); - for (p = gendisk_head; p; p = p->next) { - for (n=0; n < (p->nr_real << p->minor_shift); n++) { - if (p->part[n].nr_sects && len < PAGE_SIZE - 80) { - len += sprintf(page+len, - "%4d %4d %10d %s\n", - p->major, n, p->sizes[n], - disk_name(p, n, buf)); - } - } - } - return len; -} -#endif diff -u --recursive --new-file v2.3.13/linux/drivers/block/hd.c linux/drivers/block/hd.c --- v2.3.13/linux/drivers/block/hd.c Mon Aug 9 14:59:19 1999 +++ linux/drivers/block/hd.c Thu Aug 12 11:50:14 1999 @@ -27,7 +27,6 @@ /* Uncomment the following if you want verbose error reports. */ /* #define VERBOSE_ERRORS */ -#include #include #include #include @@ -52,7 +51,9 @@ #ifdef __arm__ #undef HD_IRQ +#endif #include +#ifdef __arm__ #define HD_IRQ IRQ_HARDDISK #endif diff -u --recursive --new-file v2.3.13/linux/drivers/block/ide.c linux/drivers/block/ide.c --- v2.3.13/linux/drivers/block/ide.c Mon Aug 9 14:59:19 1999 +++ linux/drivers/block/ide.c Wed Aug 18 16:14:46 1999 @@ -39,7 +39,7 @@ * October, 1994 -- Complete line-by-line overhaul for linux 1.1.x, by: * * Mark Lord (mlord@pobox.com) (IDE Perf.Pkg) - * Delman Lee (delman@mipg.upenn.edu) ("Mr. atdisk2") + * Delman Lee (delman@ieee.org) ("Mr. atdisk2") * Scott Snyder (snyder@fnald0.fnal.gov) (ATAPI IDE cd-rom) * * This was a rewrite of just about everything from hd.c, though some original @@ -434,8 +434,8 @@ void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) { ++bytecount; -#ifdef CONFIG_ATARI - if (MACH_IS_ATARI) { +#if defined(CONFIG_ATARI) || defined(CONFIG_Q40) + if (MACH_IS_ATARI || MACH_IS_Q40) { /* Atari has a byte-swapped IDE interface */ insw_swapw(IDE_DATA_REG, buffer, bytecount / 2); return; @@ -449,8 +449,8 @@ void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount) { ++bytecount; -#ifdef CONFIG_ATARI - if (MACH_IS_ATARI) { +#if defined(CONFIG_ATARI) || defined(CONFIG_Q40) + if (MACH_IS_ATARI || MACH_IS_Q40) { /* Atari has a byte-swapped IDE interface */ outsw_swapw(IDE_DATA_REG, buffer, bytecount / 2); return; diff -u --recursive --new-file v2.3.13/linux/drivers/block/md.c linux/drivers/block/md.c --- v2.3.13/linux/drivers/block/md.c Mon Aug 9 14:59:19 1999 +++ linux/drivers/block/md.c Thu Aug 12 10:16:28 1999 @@ -740,7 +740,7 @@ if (buffer_locked(bh)) return 0; set_bit(BH_Lock, &bh->b_state); - if (rw == WRITE || rw == WRITEA) { + if (rw == WRITE) { if (!buffer_dirty(bh)) { bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state)); return 0; diff -u --recursive --new-file v2.3.13/linux/drivers/block/raid1.c linux/drivers/block/raid1.c --- v2.3.13/linux/drivers/block/raid1.c Wed Jun 30 13:38:19 1999 +++ linux/drivers/block/raid1.c Thu Aug 12 10:16:28 1999 @@ -159,7 +159,7 @@ } /* - * WRITE or WRITEA. + * WRITE. */ PRINTK(("raid1_end_request(), write branch.\n")); @@ -215,15 +215,14 @@ memset (r1_bh, 0, sizeof (struct raid1_bh)); /* - * make_request() can abort the operation when READA or WRITEA are being + * make_request() can abort the operation when READA is being * used and no empty request is available. * * Currently, just replace the command with READ/WRITE. */ if (rw == READA) rw = READ; - if (rw == WRITEA) rw = WRITE; - if (rw == WRITE || rw == WRITEA) + if (rw == WRITE) mark_buffer_clean(bh); /* Too early ? */ /* @@ -269,7 +268,7 @@ } /* - * WRITE or WRITEA. + * WRITE. */ PRINTK(("raid1_make_request(n=%d), write branch.\n",n)); diff -u --recursive --new-file v2.3.13/linux/drivers/block/raid5.c linux/drivers/block/raid5.c --- v2.3.13/linux/drivers/block/raid5.c Wed Jun 30 13:38:19 1999 +++ linux/drivers/block/raid5.c Thu Aug 12 10:16:28 1999 @@ -1206,7 +1206,6 @@ struct stripe_head *sh; if (rw == READA) rw = READ; - if (rw == WRITEA) rw = WRITE; new_sector = raid5_compute_sector(bh->b_rsector, raid_disks, data_disks, &dd_idx, &pd_idx, raid_conf); diff -u --recursive --new-file v2.3.13/linux/drivers/block/z2ram.c linux/drivers/block/z2ram.c --- v2.3.13/linux/drivers/block/z2ram.c Mon Aug 9 14:59:19 1999 +++ linux/drivers/block/z2ram.c Thu Aug 12 11:50:14 1999 @@ -27,7 +27,6 @@ #define MAJOR_NR Z2RAM_MAJOR -#include #include #include #include diff -u --recursive --new-file v2.3.13/linux/drivers/char/adbmouse.c linux/drivers/char/adbmouse.c --- v2.3.13/linux/drivers/char/adbmouse.c Mon Aug 9 14:59:19 1999 +++ linux/drivers/char/adbmouse.c Thu Aug 12 11:50:14 1999 @@ -40,7 +40,7 @@ #ifdef __powerpc__ #include #endif -#ifdef __mc68000__ +#if defined(__mc68000__) || defined(MODULE) #include #endif @@ -186,8 +186,6 @@ } #ifdef MODULE -#include - int init_module(void) { return adb_mouse_init(); diff -u --recursive --new-file v2.3.13/linux/drivers/char/busmouse.c linux/drivers/char/busmouse.c --- v2.3.13/linux/drivers/char/busmouse.c Mon Aug 9 14:59:19 1999 +++ linux/drivers/char/busmouse.c Sun Aug 15 11:48:40 1999 @@ -380,7 +380,7 @@ if (busmouse_data[msedev]) return -EBUSY; - mse = kmalloc(GFP_KERNEL, sizeof(*mse)); + mse = kmalloc(sizeof(*mse), GFP_KERNEL); if (!mse) return -ENOMEM; @@ -465,6 +465,7 @@ return 0; } +EXPORT_SYMBOL(busmouse_add_movementbuttons); EXPORT_SYMBOL(busmouse_add_movement); EXPORT_SYMBOL(busmouse_add_buttons); EXPORT_SYMBOL(register_busmouse); diff -u --recursive --new-file v2.3.13/linux/drivers/char/console.c linux/drivers/char/console.c --- v2.3.13/linux/drivers/char/console.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/char/console.c Fri Aug 13 12:19:25 1999 @@ -1984,7 +1984,7 @@ static unsigned long printing = 0; const ushort *start; ushort cnt = 0; - ushort myx = x; + ushort myx; /* console busy or not yet initialized */ if (!printable || test_and_set_bit(0, &printing)) @@ -1992,6 +1992,10 @@ if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1)) currcons = kmsg_redirect - 1; + + /* read `x' only after setting currecons properly (otherwise + the `x' macro will read the x of the foreground console). */ + myx = x; if (!vc_cons_allocated(currcons)) { /* impossible */ diff -u --recursive --new-file v2.3.13/linux/drivers/char/defkeymap.c linux/drivers/char/defkeymap.c --- v2.3.13/linux/drivers/char/defkeymap.c Fri Feb 24 11:38:27 1995 +++ linux/drivers/char/defkeymap.c Thu Aug 12 10:17:17 1999 @@ -233,6 +233,7 @@ {'A', 'A', '\305'}, {'a', 'a', '\345'}, {'A', 'E', '\306'}, {'a', 'e', '\346'}, {',', 'C', '\307'}, {',', 'c', '\347'}, + {'\'', 'C', '\307'}, {'\'', 'c', '\347'}, {'`', 'E', '\310'}, {'`', 'e', '\350'}, {'\'', 'E', '\311'}, {'\'', 'e', '\351'}, {'^', 'E', '\312'}, {'^', 'e', '\352'}, @@ -259,4 +260,4 @@ {'s', 'z', '\337'}, {'i', 'j', '\377'}, }; -unsigned int accent_table_size = 68; +unsigned int accent_table_size = 70; diff -u --recursive --new-file v2.3.13/linux/drivers/char/ftape/lowlevel/ftape-setup.c linux/drivers/char/ftape/lowlevel/ftape-setup.c --- v2.3.13/linux/drivers/char/ftape/lowlevel/ftape-setup.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/char/ftape/lowlevel/ftape-setup.c Thu Aug 12 11:53:22 1999 @@ -60,12 +60,15 @@ { "mach2", &ft_mach2, CONFIG_FT_MACH2, 0, 1} }; -void __init ftape_setup(char *str, int *ints) +static int __init ftape_setup(char *str) { int i; int param; + int ints[2]; + TRACE_FUN(ft_t_flow); + str = get_options(str, ARRAY_SIZE(ints), ints); if (str) { for (i=0; i < NR_ITEMS(config_params); i++) { if (strcmp(str,config_params[i].name) == 0){ @@ -81,13 +84,13 @@ config_params[i].name, config_params[i].min, config_params[i].max); - TRACE_EXIT; + goto out; } if(config_params[i].var) { TRACE(ft_t_info, "%s=%d", str, param); *config_params[i].var = param; } - TRACE_EXIT; + goto out; } } } @@ -101,5 +104,8 @@ } else { TRACE(ft_t_err, "botched ftape option"); } - TRACE_EXIT; + out: + TRACE_EXIT 1; } + +__setup("ftape=", ftape_setup); diff -u --recursive --new-file v2.3.13/linux/drivers/char/lp_intern.c linux/drivers/char/lp_intern.c --- v2.3.13/linux/drivers/char/lp_intern.c Mon Aug 9 14:59:20 1999 +++ linux/drivers/char/lp_intern.c Wed Dec 31 16:00:00 1969 @@ -1,364 +0,0 @@ - -/* - * split into mid and low-level for better support of different hardware - * by Joerg Dorchain (dorchain@mpi-sb.mpg.de) - * - * Amiga printer device by Michael Rausch (linux@uni-koblenz.de); - * Atari support added by Andreas Schwab (schwab@ls5.informatik.uni-dortmund.de); - * based upon work from - * - * Copyright (C) 1992 by Jim Weigand and Linus Torvalds - * Copyright (C) 1992,1993 by Michael K. Johnson - * - Thanks much to Gunter Windau for pointing out to me where the error - * checking ought to be. - * Copyright (C) 1993 by Nigel Gamble (added interrupt code) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_AMIGA -#include -#include -#endif -#ifdef CONFIG_ATARI -#include -#include -#include -#endif -#ifdef CONFIG_MVME16x -#include -#endif -#ifdef CONFIG_BVME6000 -#include -#endif -#include - -static int minor = -1; -MODULE_PARM(minor,"i"); - -static void lp_int_out(int, int); -static int lp_int_busy(int); -static int lp_int_pout(int); -static int lp_int_online(int); - - -static void -lp_int_out (int c, int dev) -{ - switch (m68k_machtype) - { -#ifdef CONFIG_AMIGA - case MACH_AMIGA: - { - int wait = 0; - while (wait != lp_table[dev]->wait) wait++; - ciaa.prb = c; - } - break; -#endif -#ifdef CONFIG_ATARI - case MACH_ATARI: - { - int wait = 0; - sound_ym.rd_data_reg_sel = 15; - sound_ym.wd_data = c; - sound_ym.rd_data_reg_sel = 14; - while (wait != lp_table[dev]->wait) wait++; - sound_ym.wd_data = sound_ym.rd_data_reg_sel & ~(1 << 5); - while (wait) wait--; - sound_ym.wd_data = sound_ym.rd_data_reg_sel | (1 << 5); - break; - } -#endif -#ifdef CONFIG_MVME16x - case MACH_MVME16x: - { - int wait = 0; - while (wait != lp_table[dev]->wait) wait++; - mvmelp.data = c; - break; - } -#endif -#ifdef CONFIG_BVME6000 - case MACH_BVME6000: - { - int wait = 0; - while (wait != lp_table[dev]->wait) wait++; - bvmepit.padr = c; - bvmepit.pacr |= 0x02; - break; - } -#endif - } -} - -static int -lp_int_busy (int dev) -{ - switch (m68k_machtype) - { -#ifdef CONFIG_AMIGA - case MACH_AMIGA: - return ciab.pra & 1; -#endif -#ifdef CONFIG_ATARI - case MACH_ATARI: - return mfp.par_dt_reg & 1; -#endif -#ifdef CONFIG_MVME16x - case MACH_MVME16x: - return mvmelp.isr & 1; -#endif -#ifdef CONFIG_BVME6000 - case MACH_BVME6000: - return 0 /* !(bvmepit.psr & 0x40) */ ; -#endif - default: - return 0; - } -} - -static int -lp_int_pout (int dev) -{ - switch (m68k_machtype) - { -#ifdef CONFIG_AMIGA - case MACH_AMIGA: - return ciab.pra & 2; -#endif -#ifdef CONFIG_ATARI - case MACH_ATARI: - return 0; -#endif -#ifdef CONFIG_MVME16x - case MACH_MVME16x: - return mvmelp.isr & 2; -#endif -#ifdef CONFIG_BVME6000 - case MACH_BVME6000: - return 0; -#endif - default: - return 0; - } -} - -static int -lp_int_online (int dev) -{ - switch (m68k_machtype) - { -#ifdef CONFIG_AMIGA - case MACH_AMIGA: - return ciab.pra & 4; -#endif -#ifdef CONFIG_ATARI - case MACH_ATARI: - return !(mfp.par_dt_reg & 1); -#endif -#ifdef CONFIG_MVME16x - case MACH_MVME16x: - return mvmelp.isr & 4; -#endif -#ifdef CONFIG_BVME6000 - case MACH_BVME6000: - return 1; -#endif - default: - return 0; - } -} - -static void lp_int_interrupt(int irq, void *data, struct pt_regs *fp) -{ -#ifdef CONFIG_MVME16x - if (MACH_IS_MVME16x) - mvmelp.ack_icr |= 0x08; -#endif -#ifdef CONFIG_BVME6000 - if (MACH_IS_BVME6000) - bvmepit.pacr &= ~0x02; -#endif - lp_interrupt(minor); -} - -static int lp_int_open(int dev) -{ - MOD_INC_USE_COUNT; - return 0; -} - -static void lp_int_release(int dev) -{ - MOD_DEC_USE_COUNT; -} - -static struct lp_struct tab = { - "Builtin parallel port", /* name */ - 0, /* irq */ - lp_int_out, - lp_int_busy, - lp_int_pout, - lp_int_online, - 0, - NULL, /* ioctl */ - lp_int_open, - lp_int_release, - LP_EXIST, - LP_INIT_CHAR, - LP_INIT_TIME, - LP_INIT_WAIT, - NULL, - NULL, -}; - -int __init lp_internal_init(void) -{ -#ifdef CONFIG_AMIGA - if (MACH_IS_AMIGA && AMIGAHW_PRESENT(AMI_PARALLEL)) - { - ciaa.ddrb = 0xff; - ciab.ddra &= 0xf8; - if (lp_irq) - tab.irq = request_irq(IRQ_AMIGA_CIAA_FLG, lp_int_interrupt, - 0, "builtin printer port", lp_int_interrupt); - tab.base = (void *) &ciaa.prb; /* dummy, not used */ - tab.type = LP_AMIGA; - } -#endif -#ifdef CONFIG_ATARI - if (MACH_IS_ATARI) - { - unsigned long flags; - - save_flags(flags); - cli(); - sound_ym.rd_data_reg_sel = 7; - sound_ym.wd_data = (sound_ym.rd_data_reg_sel & 0x3f) | 0xc0; - restore_flags(flags); - if (lp_irq) - tab.irq = request_irq(IRQ_MFP_BUSY, lp_int_interrupt, - IRQ_TYPE_SLOW, "builtin printer port", lp_int_interrupt); - tab.base = (void *) &sound_ym.wd_data; /* dummy, not used */ - tab.type = LP_ATARI; - } -#endif -#ifdef CONFIG_MAC - if (MACH_IS_MAC) - return -ENODEV; -#endif -#ifdef CONFIG_MVME16x - if (MACH_IS_MVME16x) - { - unsigned long flags; - - if (!(mvme16x_config & MVME16x_CONFIG_GOT_LP)) - return -ENODEV; - - save_flags(flags); - cli(); - mvmelp.ack_icr = 0x08; - mvmelp.flt_icr = 0x08; - mvmelp.sel_icr = 0x08; - mvmelp.pe_icr = 0x08; - mvmelp.bsy_icr = 0x08; - mvmelp.cr = 0x10; - mvmelp.ack_icr = 0xd9; /* Int on trailing edge of ACK */ - restore_flags(flags); - - if (lp_irq) - tab.irq = request_irq(MVME167_IRQ_PRN, lp_int_interrupt, - 0, "builtin printer port", lp_int_interrupt); - tab.base = (void *)&mvmelp; /* dummy, not used */ - tab.type = LP_MVME167; - } -#endif -#ifdef CONFIG_BVME6000 - if (MACH_IS_BVME6000) - { - unsigned long flags; - - save_flags(flags); - cli(); - bvmepit.pgcr = 0x0f; - bvmepit.psrr = 0x18; - bvmepit.paddr = 0xff; - bvmepit.pcdr = (bvmepit.pcdr & 0xfc) | 0x02; - bvmepit.pcddr |= 0x03; - bvmepit.pacr = 0x78; - bvmepit.pbcr = 0x00; - bvmepit.pivr = BVME_IRQ_PRN; - bvmepit.pgcr = 0x1f; - restore_flags(flags); - - if (lp_irq) - tab.irq = request_irq(BVME_IRQ_PRN, lp_int_interrupt, - 0, "builtin printer port", lp_int_interrupt); - tab.base = (void *)&bvmepit; /* dummy, not used */ - tab.type = LP_BVME6000; - } -#endif - - - if ((minor = register_parallel(&tab, minor)) < 0) { - printk("builtin lp init: cant get a minor\n"); - if (lp_irq) { -#ifdef CONFIG_AMIGA - if (MACH_IS_AMIGA) - free_irq(IRQ_AMIGA_CIAA_FLG, lp_int_interrupt); -#endif -#ifdef CONFIG_ATARI - if (MACH_IS_ATARI) - free_irq(IRQ_MFP_BUSY, lp_int_interrupt); -#endif -#ifdef CONFIG_MVME16x - if (MACH_IS_MVME16x) - free_irq(MVME167_IRQ_PRN, lp_int_interrupt); -#endif -#ifdef CONFIG_BVME6000 - if (MACH_IS_BVME6000) - free_irq(BVME_IRQ_PRN, lp_int_interrupt); -#endif - } - return -ENODEV; - } - - return 0; -} - -#ifdef MODULE -int init_module(void) -{ -return lp_internal_init(); -} - -void cleanup_module(void) -{ -if (lp_irq) { -#ifdef CONFIG_AMIGA - if (MACH_IS_AMIGA) - free_irq(IRQ_AMIGA_CIAA_FLG, lp_int_interrupt); -#endif -#ifdef CONFIG_ATARI - if (MACH_IS_ATARI) - free_irq(IRQ_MFP_BUSY, lp_int_interrupt); -#endif -#ifdef CONFIG_MVME16x - if (MACH_IS_MVME16x) - free_irq(MVME167_IRQ_PRN, lp_int_interrupt); -#endif -#ifdef CONFIG_BVME6000 - if (MACH_IS_BVME6000) - free_irq(BVME_IRQ_PRN, lp_int_interrupt); -#endif -} -unregister_parallel(minor); -} -#endif diff -u --recursive --new-file v2.3.13/linux/drivers/char/lp_m68k.c linux/drivers/char/lp_m68k.c --- v2.3.13/linux/drivers/char/lp_m68k.c Mon Aug 9 14:59:20 1999 +++ linux/drivers/char/lp_m68k.c Wed Dec 31 16:00:00 1969 @@ -1,556 +0,0 @@ -/* - * split in two parts for better support of different hardware - * by Joerg Dorchain (dorchain@mpi-sb.mpg.de) - * - * Amiga printer device by Michael Rausch (linux@uni-koblenz.de); - * Atari support added by Andreas Schwab (schwab@ls5.informatik.uni-dortmund.de); - * based upon work from - * - * Copyright (C) 1992 by Jim Weigand and Linus Torvalds - * Copyright (C) 1992,1993 by Michael K. Johnson - * - Thanks much to Gunter Windau for pointing out to me where the error - * checking ought to be. - * Copyright (C) 1993 by Nigel Gamble (added interrupt code) - */ - -/* 01/17/95: Matthias Welwarsky (dg8y@rs11.hrz.th-darmstadt.de) - * lp_write(): rewritten from scratch - * lp_interrupt(): fixed cli()/sti()-bug - * - * 95/05/28: Andreas Schwab (schwab@issan.informatik.uni-dortmund.de) - * lp_write() fixed to make it work again. - * 95/08/18: Andreas Schwab - * lp_write_interrupt: fix race condition - * - * * CAUTION, please do check! * - * - * on 68000-based machines sti() must NEVER appear in interrupt driven - * code. The 68k-CPU has a priority-based interrupt scheme. while an interrupt - * with a certain priority is executed, all requests with lower or same - * priority get locked out. executing the sti()-macro allows ANY interrupt - * to be served. this really causes BIG trouble! - * to protect an interrupt driven routine against being interrupted - * (if absolutely needed!) one should use save_flags();cli()/restore_flags()! - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_AMIGA -#ifdef CONFIG_MULTIFACE_III_LP -#include -#endif -#endif - -#include -#include -#include -#include - -#include -#include -#include - - -/* - * why bother around with the pio driver when the interrupt works; - * so, for "security" reasons only, it's configurable here. - * saves some bytes, at least ... - */ -#define FORCE_POLLING 0 -#define FORCE_INTERRUPT 1 -/* - * PREFER_INTERRUPT doesn't make much sense on m68k. - * it is preserved here in case of joining with the i386 driver - * -#define PREFER_INTERRUPT 2 - */ - -#define WHICH_DRIVER FORCE_INTERRUPT - -struct lp_struct *lp_table[MAX_LP] = {NULL,}; - -static int max_lp; /* the real number of devices */ - -/* - * All my debugging code assumes that you debug with only one printer at - * a time. RWWH - */ - -#define LP_DEBUG -#undef LP_DEBUG - - -#if WHICH_DRIVER != FORCE_INTERRUPT -#ifdef LP_DEBUG -static int lp_max_count = 1; -#endif - -static int lp_char_polled(char lpchar, int dev) -{ - unsigned long count = 0; - - do { - count ++; - if (current->need_resched) - schedule(); - } while (lp_table[dev]->lp_is_busy(dev) && count < lp_table[dev]->chars); - - if (count == lp_table[dev]->chars) { - return 0; - /* we timed out, and the character was /not/ printed */ - } -#ifdef LP_DEBUG - if (count > lp_max_count) { - printk("lp success after %d counts.\n",count); - lp_max_count = count; - } -#endif - lp_table[dev]->lp_out(lpchar, dev); - return 1; -} -#endif - - -#ifdef LP_DEBUG -unsigned int lp_total_chars = 0; -unsigned int lp_last_call = 0; -#endif - - -#if WHICH_DRIVER != FORCE_POLLING -static __inline__ int lp_char_interrupt(char lpchar, int dev) -{ - if (!lp_table[dev]->lp_is_busy(dev)) { - lp_table[dev]->lp_out(lpchar,dev); - return 1; - } - return 0; -} - -static int lp_error; - -void lp_interrupt(int dev) -{ - if (dev >= 0 && dev < MAX_LP && lp_table[dev]->do_print) - { - if (lp_table[dev]->copy_size) - { - unsigned long flags; - save_flags(flags); - cli(); - if (lp_char_interrupt(lp_table[dev]->lp_buffer[lp_table[dev]->bytes_written], dev)) { - --lp_table[dev]->copy_size; - ++lp_table[dev]->bytes_written; - restore_flags(flags); - } - else - { - lp_table[dev]->do_print = 0; - restore_flags(flags); - lp_error = 1; - wake_up_interruptible(&lp_table[dev]->lp_wait_q); - } - } - else - { - lp_table[dev]->do_print = 0; - lp_error = 0; - wake_up_interruptible(&lp_table[dev]->lp_wait_q); - } - - } -} - -#if WHICH_DRIVER == FORCE_INTERRUPT -static ssize_t lp_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -#else -static ssize_t lp_write_interrupt(struct file *file, const char *buf, - size_t count, loff_t *ppos) -#endif -{ - struct inode *inode = file->f_dentry->d_inode; - unsigned long total_bytes_written = 0; - unsigned int flags; - long timeout; - int rc; - int dev = MINOR(inode->i_rdev); - - do { - lp_table[dev]->do_print = 0; /* disable lp_interrupt() */ - lp_table[dev]->bytes_written = 0; /* init buffer read-pointer */ - lp_error = 0; - lp_table[dev]->copy_size = (count <= LP_BUFFER_SIZE ? count : LP_BUFFER_SIZE); - if (copy_from_user(lp_table[dev]->lp_buffer, buf, - lp_table[dev]->copy_size)) - return -EFAULT; - while (lp_table[dev]->copy_size) { - save_flags(flags); - cli(); /* no interrupts now */ - lp_table[dev]->do_print = 1; /* enable lp_interrupt() */ - if (lp_char_interrupt(lp_table[dev]->lp_buffer[lp_table[dev]->bytes_written], dev)) { - ++lp_table[dev]->bytes_written; - --lp_table[dev]->copy_size; - lp_error = 0; - } else { /* something went wrong */ - lp_table[dev]->do_print = 0; /* disable lp_interrupt() */ - lp_error = 1; /* printer caused error */ - } - if (lp_error) { - - /* something blocked printing, so we don't want to sleep too long, - in case we have to rekick the interrupt */ - - timeout = LP_TIMEOUT_POLLED; - } else { - timeout = LP_TIMEOUT_INTERRUPT; - } - - interruptible_sleep_on_timeout(&lp_table[dev]->lp_wait_q, timeout); - restore_flags(flags); - - /* we're up again and running. we first disable lp_interrupt(), then - check what happened meanwhile */ - - lp_table[dev]->do_print = 0; - rc = total_bytes_written + lp_table[dev]->bytes_written; - - if (signal_pending(current)) { - if (rc == 0) - rc = -EINTR; - return rc; - } - if (lp_error) { - - /* an error has occurred, maybe in lp_interrupt(). - figure out the type of error, exit on request or if nothing has - been printed at all. */ - - if (lp_table[dev]->lp_has_pout(dev)) { - printk(KERN_NOTICE "lp%d: paper-out\n",dev); - if (!rc) rc = -ENOSPC; - } else if (!lp_table[dev]->lp_is_online(dev)) { - printk(KERN_NOTICE "lp%d: off-line\n",dev); - if (!rc) rc = -EIO; - } else if (lp_table[dev]->lp_is_busy(dev)) { - printk(KERN_NOTICE "lp%d: on fire\n",dev); - if (!rc) rc = -EIO; - } - if (lp_table[dev]->flags & LP_ABORT) - return rc; - } - /* check if our buffer was completely printed, if not, most likely - an unsolved error blocks the printer. As we can`t do anything - against, we start all over again. Else we set the read-pointer - of the buffer and count the printed characters */ - - if (!lp_table[dev]->copy_size) { - total_bytes_written += lp_table[dev]->bytes_written; - buf += lp_table[dev]->bytes_written; - count -= lp_table[dev]->bytes_written; - } - } - } while (count > 0); - return total_bytes_written; -} -#else -void (*lp_interrupt)() = NULL; -#endif - -#if WHICH_DRIVER != FORCE_INTERRUPT -#if WHICH_DRIVER == FORCE_POLLING -static ssize_t lp_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -#else -static ssize_t lp_write_polled(struct file *file, const char *buf, - size_t count, loff_t *ppos) -#endif -{ - struct inode *inode = file->f_dentry->d_inode; - char *temp = buf; - int dev = MINOR(inode->i_rdev); - -#ifdef LP_DEBUG - if (time_after(jiffies, lp_last_call + lp_table[dev]->time)) { - lp_total_chars = 0; - lp_max_count = 1; - } - lp_last_call = jiffies; -#endif - - temp = buf; - while (count > 0) { - int c; - if (get_user(c, temp)) - return -EFAULT; - if (lp_char_polled(c, dev)) { - /* only update counting vars if character was printed */ - count--; temp++; -#ifdef LP_DEBUG - lp_total_chars++; -#endif - } else { /* if printer timed out */ - unsigned long timeout = LP_TIMEOUT_POLLED; - int error = 0; - if (lp_table[dev]->lp_has_pout(dev)) { - printk(KERN_NOTICE "lp%d: out of paper\n",dev); - if (lp_table[dev]->flags & LP_ABORT) - error = -ENOSPC; - } else if (!lp_table[dev]->lp_is_online(dev)) { - printk(KERN_NOTICE "lp%d: off-line\n",dev); - if (lp_table[dev]->flags & LP_ABORT) - error = -EIO; - } else - /* not offline or out of paper. on fire? */ - if (lp_table[dev]->lp_is_busy(dev)) { - printk(KERN_NOTICE "lp%d: on fire\n",dev); - if (lp_table[dev]->flags & LP_ABORT) - error = -EIO; - } - else - timeout = lp_table[dev]->time; - - /* check for signals before going to sleep */ - if (error == 0 && signal_pending(current)) - error = -EINTR; - if (error) { - if (temp != buf) - return temp-buf; - else - return error; - } - -#ifdef LP_DEBUG - printk("lp sleeping at %d characters for %d jiffies\n", - lp_total_chars, timeout); - lp_total_chars = 0; -#endif - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(timeout); - } - } - return temp - buf; -} -#endif - -unsigned int lp_irq = 0; - -#if WHICH_DRIVER == PREFER_INTERRUPT -static ssize_t lp_write(struct file *file, const char *buf, size_t count, - loff_t *ppos) -{ - if (lp_irq) - return lp_write_interrupt(file, buf, count, ppos); - else - return lp_write_polled(file, buf, count, ppos); -} -#endif - -static long long lp_lseek(struct file * file, long long offset, int origin) -{ - return -ESPIPE; -} - -static int lp_open(struct inode *inode, struct file *file) -{ - int dev = MINOR(inode->i_rdev); - int ret; - - MOD_INC_USE_COUNT; - - ret = -ENODEV; - if (dev >= MAX_LP) - goto out_err; - - if (!lp_table[dev]) { - char modname[30]; - - sprintf(modname, "char-major-%d-%d", LP_MAJOR, dev); - request_module(modname); - } - if (!lp_table[dev]) - goto out_err; - if (!(lp_table[dev]->flags & LP_EXIST)) - goto out_err; - ret = -EBUSY; - if (lp_table[dev]->flags & LP_BUSY) - goto out_err; - - lp_table[dev]->flags |= LP_BUSY; - - ret = lp_table[dev]->lp_open(dev); - if (ret != 0) { - lp_table[dev]->flags &= ~LP_BUSY; - goto out_err; - } - return ret; - -out_err: - MOD_DEC_USE_COUNT; - return ret; -} - -static int lp_release(struct inode *inode, struct file *file) -{ - int dev =MINOR(inode->i_rdev); - - lp_table[dev]->flags &= ~LP_BUSY; - lp_table[dev]->lp_release(dev); - MOD_DEC_USE_COUNT; - return 0; -} - - -static int lp_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - unsigned int minor = MINOR(inode->i_rdev); - int retval = -ENODEV; - -#ifdef LP_DEBUG - printk("lp%d ioctl, cmd: 0x%x, arg: 0x%x\n", minor, cmd, arg); -#endif - if (minor >= max_lp) - goto out; - if (!(lp_table[minor]->flags & LP_EXIST)) - goto out; - retval = 0; - switch (cmd) { - case LPTIME: - lp_table[minor]->time = arg; - break; - case LPCHAR: - lp_table[minor]->chars = arg; - break; - case LPABORT: - if (arg) - lp_table[minor]->flags |= LP_ABORT; - else - lp_table[minor]->flags &= ~LP_ABORT; - break; - case LPWAIT: - lp_table[minor]->wait = arg; - break; - case LPSETIRQ: - case LPGETIRQ: - retval = lp_irq; - break; - default: - retval = -EINVAL; - if (lp_table[minor]->lp_ioctl) - retval = lp_table[minor]->lp_ioctl(minor, cmd, arg); - } -out: - return retval; -} - - -static struct file_operations lp_fops = { - lp_lseek, - NULL, /* lp_read */ - lp_write, - NULL, /* lp_readdir */ - NULL, /* lp_poll */ - lp_ioctl, - NULL, /* lp_mmap */ - lp_open, - NULL, /* flush */ - lp_release -}; - -EXPORT_SYMBOL(lp_table); -EXPORT_SYMBOL(lp_irq); -EXPORT_SYMBOL(lp_interrupt); -EXPORT_SYMBOL(register_parallel); -EXPORT_SYMBOL(unregister_parallel); - -int __init lp_m68k_init(void) -{ - extern char m68k_debug_device[]; - - if (!strcmp( m68k_debug_device, "par" )) - return -EBUSY; - - if (register_chrdev(LP_MAJOR,"lp", &lp_fops)) { - printk(KERN_ERR "unable to get major %d for line printer\n", LP_MAJOR); - return -ENXIO; - } - -#if WHICH_DRIVER == FORCE_POLLING - lp_irq = 0; - printk(KERN_INFO "lp_init: lp using polling driver\n"); -#else - - lp_irq = 1; - printk(KERN_INFO "lp_init: lp using interrupt driver\n"); -#endif - -#ifndef MODULE - lp_internal_init(); -#ifdef CONFIG_MULTIFACE_III_LP - lp_mfc_init(); -#endif -#endif - return 0; -} - -/* - * Currently we do not accept any lp-parameters, but that may change. - */ -void __init lp_setup(char *str, int *ints) -{ -} - -#ifdef MODULE -int init_module(void) -{ - return lp_m68k_init(); -} - -void cleanup_module(void) -{ - unregister_chrdev(LP_MAJOR, "lp"); -} -#endif - -/* - * (un-)register for hardware drivers - * tab is an inititalised lp_struct, dev the desired minor - * if dev < 0, let the driver choose the first free minor - * if successful return the minor, else -1 - */ -int register_parallel(struct lp_struct *tab, int dev) -{ -if (dev < 0) { - dev = 0; - while ((dev < MAX_LP) && (lp_table[dev] != NULL)) - dev++; -} -if (dev > MAX_LP) - return -1; -if (lp_table[dev] != NULL) - return -1; -lp_table[dev] = tab; -printk(KERN_INFO "lp%d: %s at 0x%08lx\n", dev, tab->name, (long)tab->base); -return dev; -} - -#ifdef CONFIG_MODULES -void unregister_parallel(int dev) -{ -if ((dev < 0) || (dev > MAX_LP) || (lp_table[dev] == NULL)) - printk(KERN_ERR "WARNING: unregister_parallel for non-existant device ignored!\n"); -else - lp_table[dev] = NULL; -} -#endif diff -u --recursive --new-file v2.3.13/linux/drivers/char/mem.c linux/drivers/char/mem.c --- v2.3.13/linux/drivers/char/mem.c Mon Aug 9 14:59:20 1999 +++ linux/drivers/char/mem.c Thu Aug 12 10:41:30 1999 @@ -465,17 +465,12 @@ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; } -static int open_mem(struct inode * inode, struct file * filp) -{ - return (capable(CAP_SYS_RAWIO) - || !(filp->f_mode & FMODE_WRITE)) ? 0 : -EPERM; -} - #define mmap_kmem mmap_mem #define zero_lseek null_lseek #define full_lseek null_lseek #define write_zero write_null #define read_full read_zero +#define open_mem open_port #define open_kmem open_mem static struct file_operations mem_fops = { diff -u --recursive --new-file v2.3.13/linux/drivers/char/q40_keyb.c linux/drivers/char/q40_keyb.c --- v2.3.13/linux/drivers/char/q40_keyb.c Mon Aug 9 14:59:20 1999 +++ linux/drivers/char/q40_keyb.c Sun Aug 15 11:48:32 1999 @@ -240,32 +240,15 @@ -int q40kbd_pretranslate(unsigned char scancode, char raw_mode) -{ - if (scancode == 0xff) { - /* in scancode mode 1, my ESC key generates 0xff */ - /* the calculator keys on a FOCUS 9000 generate 0xff */ -#ifndef KBD_IS_FOCUS_9000 -#ifdef KBD_REPORT_ERR - if (!raw_mode) - printk(KERN_DEBUG "Keyboard error\n"); -#endif -#endif - prev_scancode = 0; - return 0; - } - if (scancode == 0xe0 || scancode == 0xe1) { +int q40kbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode) +{ + if (scancode == 0xe0 || scancode == 0xe1) { prev_scancode = scancode; return 0; } - return 1; -} -int q40kbd_translate(unsigned char scancode, unsigned char *keycode, - char raw_mode) -{ - /*printk("translate ...\n");*/ if (prev_scancode) { /* * usually it will be 0xe0, but a Pause key generates @@ -376,7 +359,7 @@ if (qcode == 0xe0) { qprev=0xe0; - handle_scancode(qprev); + handle_scancode(qprev , 1); goto exit; } @@ -394,7 +377,7 @@ if (scancode==0xff) /* SySrq */ scancode=SYSRQ_KEY; - handle_scancode(scancode | (keyup ? 0200 : 0)); + handle_scancode(scancode, ! keyup ); keyup=0; mark_bh(KEYBOARD_BH); diff -u --recursive --new-file v2.3.13/linux/drivers/i2o/i2o_lan.c linux/drivers/i2o/i2o_lan.c --- v2.3.13/linux/drivers/i2o/i2o_lan.c Mon Aug 9 14:59:20 1999 +++ linux/drivers/i2o/i2o_lan.c Wed Aug 18 11:38:59 1999 @@ -54,7 +54,7 @@ #endif #define MAX_LAN_CARDS 4 -static struct device *i2o_landevs[MAX_LAN_CARDS+1]; +static struct net_device *i2o_landevs[MAX_LAN_CARDS+1]; static int unit = -1; /* device unit number */ struct i2o_lan_local { @@ -63,7 +63,7 @@ int reply_flag; /* needed by scalar/table queries */ u32 packet_tresh; /* treshold for incoming skb's */ struct fddi_statistics stats; /* see also struct net_device_stats */ - unsigned short (*type_trans)(struct sk_buff *, struct device *); + unsigned short (*type_trans)(struct sk_buff *, struct net_device *); /* * Due to way that interrupts can pile up, we need to keep track * of buckets ourselves. Otherwise we'll end up flooding @@ -73,8 +73,8 @@ }; /* function prototypes */ -static int i2o_lan_receive_post(struct device *dev); -static int i2o_lan_receive_post_reply(struct device *dev, struct i2o_message *m); +static int i2o_lan_receive_post(struct net_device *dev); +static int i2o_lan_receive_post_reply(struct net_device *dev, struct i2o_message *m); static void i2o_lan_release_buckets(u32 *msg, struct i2o_lan_local *priv); /* @@ -89,7 +89,7 @@ { u32 *msg = (u32 *)m; u8 unit = (u8)(msg[2]>>16); // InitiatorContext - struct device *dev = i2o_landevs[unit]; + struct net_device *dev = i2o_landevs[unit]; struct i2o_lan_local *priv; if(dev) @@ -202,7 +202,7 @@ static int lan_context; -static int i2o_lan_receive_post_reply(struct device *dev, struct i2o_message *m) +static int i2o_lan_receive_post_reply(struct net_device *dev, struct i2o_message *m) { u32 *msg = (u32 *)m; struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; @@ -284,7 +284,7 @@ /* * i2o_lan_receive_post(): Post buckets to receive packets. */ -static int i2o_lan_receive_post(struct device *dev) +static int i2o_lan_receive_post(struct net_device *dev) { struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; struct i2o_device *i2o_dev = priv->i2o_dev; @@ -343,7 +343,7 @@ * i2o_lan_reset(): Reset the LAN adapter into the operational state and * restore it to full operation. */ -static int i2o_lan_reset(struct device *dev) +static int i2o_lan_reset(struct net_device *dev) { struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; struct i2o_device *i2o_dev = priv->i2o_dev; @@ -367,7 +367,7 @@ * Reply to any LAN class message with status error_no_data_transfer * / suspended. */ -static int i2o_lan_suspend(struct device *dev) +static int i2o_lan_suspend(struct net_device *dev) { struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; struct i2o_device *i2o_dev = priv->i2o_dev; @@ -390,7 +390,7 @@ /* * Set DDM into batch mode. */ -static void i2o_set_batch_mode(struct device *dev) +static void i2o_set_batch_mode(struct net_device *dev) { /* @@ -436,7 +436,7 @@ * i2o_lan_open(): Open the device to send/receive packets via * the network device. */ -static int i2o_lan_open(struct device *dev) +static int i2o_lan_open(struct net_device *dev) { struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; struct i2o_device *i2o_dev = priv->i2o_dev; @@ -470,7 +470,7 @@ /* * i2o_lan_close(): End the transfering. */ -static int i2o_lan_close(struct device *dev) +static int i2o_lan_close(struct net_device *dev) { struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; struct i2o_device *i2o_dev = priv->i2o_dev; @@ -503,7 +503,7 @@ * Must be supported by Fibre Channel, optional for Ethernet/802.3, * Token Ring, FDDI */ -static int i2o_lan_sdu_send(struct sk_buff *skb, struct device *dev) +static int i2o_lan_sdu_send(struct sk_buff *skb, struct net_device *dev) { #if 0 /* not yet tested */ @@ -550,7 +550,7 @@ * Must be supported by Ethernet/802.3, Token Ring, FDDI, optional for * Fibre Channel */ -static int i2o_lan_packet_send(struct sk_buff *skb, struct device *dev) +static int i2o_lan_packet_send(struct sk_buff *skb, struct net_device *dev) { struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; struct i2o_device *i2o_dev = priv->i2o_dev; @@ -583,7 +583,7 @@ return 0; } -static struct net_device_stats *i2o_lan_get_stats(struct device *dev) +static struct net_device_stats *i2o_lan_get_stats(struct net_device *dev) { struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; struct i2o_device *i2o_dev = priv->i2o_dev; @@ -709,7 +709,7 @@ * i2o_lan_set_multicast_list(): Enable a network device to receive packets * not send to the protocol address. */ -static void i2o_lan_set_multicast_list(struct device *dev) +static void i2o_lan_set_multicast_list(struct net_device *dev) { struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; struct i2o_device *i2o_dev = priv->i2o_dev; @@ -805,13 +805,13 @@ return; } -struct device *i2o_lan_register_device(struct i2o_device *i2o_dev) +struct net_device *i2o_lan_register_device(struct i2o_device *i2o_dev) { - struct device *dev = NULL; + struct net_device *dev = NULL; struct i2o_lan_local *priv = NULL; u8 hw_addr[8]; - unsigned short (*type_trans)(struct sk_buff *, struct device *); - void (*unregister_dev)(struct device *dev); + unsigned short (*type_trans)(struct sk_buff *, struct net_device *); + void (*unregister_dev)(struct net_device *dev); switch (i2o_dev->subclass) { @@ -844,10 +844,10 @@ #ifdef CONFIG_FDDI case I2O_LAN_FDDI: { - int size = sizeof(struct device) + sizeof(struct i2o_lan_local) + int size = sizeof(struct net_device) + sizeof(struct i2o_lan_local) + sizeof("fddi%d "); - dev = (struct device *) kmalloc(size, GFP_KERNEL); + dev = (struct net_device *) kmalloc(size, GFP_KERNEL); memset((char *)dev, 0, size); dev->priv = (void *)(dev + 1); dev->name = (char *)(dev + 1) + sizeof(struct i2o_lan_local); @@ -922,7 +922,7 @@ __init int i2o_lan_init(void) { - struct device *dev; + struct net_device *dev; int i; bucketpost = bucketpost - bucketthresh; @@ -987,7 +987,7 @@ for (i = 0; i <= unit; i++) { - struct device *dev = i2o_landevs[i]; + struct net_device *dev = i2o_landevs[i]; struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; struct i2o_device *i2o_dev = priv->i2o_dev; diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/Config.in linux/drivers/isdn/Config.in --- v2.3.13/linux/drivers/isdn/Config.in Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/Config.in Thu Aug 12 09:42:33 1999 @@ -9,6 +9,10 @@ fi fi bool 'Support audio via ISDN' CONFIG_ISDN_AUDIO +if [ "$CONFIG_ISDN_AUDIO" != "n" ]; then + bool 'Support AT-Fax Class 2 commands' CONFIG_ISDN_TTY_FAX +fi +bool 'Support isdn diversion services' CONFIG_ISDN_DIVERSION if [ "$CONFIG_X25" != "n" ]; then bool 'X.25 PLP on top of ISDN (EXPERIMENTAL)' CONFIG_ISDN_X25 fi @@ -26,7 +30,6 @@ bool 'HiSax Support for german 1TR6' CONFIG_HISAX_1TR6 bool 'HiSax Support for Teles 16.0/8.0' CONFIG_HISAX_16_0 bool 'HiSax Support for Teles 16.3 or PNP or PCMCIA' CONFIG_HISAX_16_3 - bool 'HiSax Support for Teles 16.3c' CONFIG_HISAX_TELES3C bool 'HiSax Support for Teles PCI' CONFIG_HISAX_TELESPCI bool 'HiSax Support for Teles S0Box' CONFIG_HISAX_S0BOX bool 'HiSax Support for AVM A1 (Fritz)' CONFIG_HISAX_AVM_A1 @@ -37,24 +40,39 @@ bool 'HiSax Support for Eicon.Diehl Diva cards' CONFIG_HISAX_DIEHLDIVA bool 'HiSax Support for ASUSCOM cards' CONFIG_HISAX_ASUSCOM bool 'HiSax Support for TELEINT cards' CONFIG_HISAX_TELEINT - bool 'HiSax Support for Sedlbauer speed card/win/star/fax' CONFIG_HISAX_SEDLBAUER + bool 'HiSax Support for HFC-S based cards' CONFIG_HISAX_HFCS + bool 'HiSax Support for Sedlbauer cards' CONFIG_HISAX_SEDLBAUER bool 'HiSax Support for USR Sportster internal TA' CONFIG_HISAX_SPORTSTER bool 'HiSax Support for MIC card' CONFIG_HISAX_MIC bool 'HiSax Support for NETjet card' CONFIG_HISAX_NETJET bool 'HiSax Support for Niccy PnP/PCI card' CONFIG_HISAX_NICCY + bool 'HiSax Support for Siemens I-Surf card' CONFIG_HISAX_ISURF + bool 'HiSax Support for HST Saphir card' CONFIG_HISAX_HSTSAPHIR + bool 'HiSax Support for Telekom A4T card' CONFIG_HISAX_BKM_A4T + bool 'HiSax Support for Scitel Quadro card' CONFIG_HISAX_SCT_QUADRO + bool 'HiSax Support for Gazel cards' CONFIG_HISAX_GAZEL if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then - if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then - bool 'HiSax Support for Am7930' CONFIG_HISAX_AMD7930 - fi + bool 'HiSax Support for HFC PCI-Bus cards (EXPERIMENTAL)' CONFIG_HISAX_HFC_PCI +# bool 'HiSax Support for TESTEMULATOR (EXPERIMENTAL)' CONFIG_HISAX_TESTEMU + if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then + bool 'HiSax Support for Am7930' CONFIG_HISAX_AMD7930 + fi fi fi if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then dep_tristate 'Spellcaster support (EXPERIMENTAL)' CONFIG_ISDN_DRV_SC $CONFIG_ISDN dep_tristate 'IBM Active 2000 support (EXPERIMENTAL)' CONFIG_ISDN_DRV_ACT2000 $CONFIG_ISDN - dep_tristate 'Eicon.Diehl active card support (EXPERIMENTAL)' CONFIG_ISDN_DRV_EICON $CONFIG_ISDN fi -dep_tristate 'AVM-B1 with CAPI2.0 support' CONFIG_ISDN_DRV_AVMB1 $CONFIG_ISDN +dep_tristate 'Eicon.Diehl active card support' CONFIG_ISDN_DRV_EICON $CONFIG_ISDN +if [ "$CONFIG_ISDN_DRV_EICON" != "n" ]; then + bool 'Eicon S,SX,SCOM,Quadro,S2M support' CONFIG_ISDN_DRV_EICON_ISA +fi +dep_tristate 'AVM CAPI2.0 support' CONFIG_ISDN_DRV_AVMB1 $CONFIG_ISDN if [ "$CONFIG_ISDN_DRV_AVMB1" != "n" ]; then + bool 'AVM B1 ISA support' CONFIG_ISDN_DRV_AVMB1_B1ISA + bool 'AVM B1 PCI support' CONFIG_ISDN_DRV_AVMB1_B1PCI + bool 'AVM T1/T1B ISA support' CONFIG_ISDN_DRV_AVMB1_T1ISA + bool 'AVM B1/M1/M2 PCMCIA support' CONFIG_ISDN_DRV_AVMB1_B1PCMCIA bool 'Verbose reason code reporting (kernel size +=7K)' CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON fi diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/Makefile linux/drivers/isdn/Makefile --- v2.3.13/linux/drivers/isdn/Makefile Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/Makefile Thu Aug 12 09:42:33 1999 @@ -1,6 +1,6 @@ SUB_DIRS := MOD_SUB_DIRS := -ALL_SUB_DIRS := icn pcbit hisax avmb1 act2000 eicon +ALL_SUB_DIRS := icn pcbit hisax avmb1 act2000 eicon divert L_OBJS := LX_OBJS := @@ -24,6 +24,9 @@ endif ifdef CONFIG_ISDN_AUDIO L_OBJS += isdn_audio.o + ifdef CONFIG_ISDN_TTY_FAX + L_OBJS += isdn_ttyfax.o + endif endif else ifeq ($(CONFIG_ISDN),m) @@ -41,8 +44,17 @@ endif ifdef CONFIG_ISDN_AUDIO O_OBJS += isdn_audio.o + ifdef CONFIG_ISDN_TTY_FAX + O_OBJS += isdn_ttyfax.o + endif endif endif +endif + +ifeq ($(CONFIG_ISDN_DIVERSION),y) + ifeq ($(CONFIG_MODULES),y) + MOD_SUB_DIRS += divert + endif endif ifeq ($(CONFIG_ISDN_DRV_HISAX),y) diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/avmb1/Makefile linux/drivers/isdn/avmb1/Makefile --- v2.3.13/linux/drivers/isdn/avmb1/Makefile Thu May 29 21:53:05 1997 +++ linux/drivers/isdn/avmb1/Makefile Thu Aug 12 09:42:33 1999 @@ -1,5 +1,5 @@ # -# $Id: Makefile,v 1.4 1997/03/30 17:10:40 calle Exp $ +# $Id: Makefile,v 1.6 1999/07/20 06:41:44 calle Exp $ # # Makefile for the CAPI and AVM-B1 device drivers. # @@ -11,6 +11,26 @@ # parent makes.. # # $Log: Makefile,v $ +# Revision 1.6 1999/07/20 06:41:44 calle +# Bugfix: After the redesign of the AVM B1 driver, the driver didn't even +# compile, if not selected as modules. +# +# Revision 1.5 1999/07/01 15:26:20 calle +# complete new version (I love it): +# + new hardware independed "capi_driver" interface that will make it easy to: +# - support other controllers with CAPI-2.0 (i.e. USB Controller) +# - write a CAPI-2.0 for the passive cards +# - support serial link CAPI-2.0 boxes. +# + wrote "capi_driver" for all supported cards. +# + "capi_driver" (supported cards) now have to be configured with +# make menuconfig, in the past all supported cards where included +# at once. +# + new and better informations in /proc/capi/ +# + new ioctl to switch trace of capi messages per controller +# using "avmcapictrl trace [contr] on|off|...." +# + complete testcircle with all supported cards and also the +# PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done. +# # Revision 1.4 1997/03/30 17:10:40 calle # added support for AVM-B1-PCI card. # @@ -56,20 +76,38 @@ ifeq ($(CONFIG_ISDN_DRV_AVMB1),y) O_TARGET += avmb1.o - O_OBJS += capi.o b1lli.o - OX_OBJS += capiutil.o b1capi.o capidrv.o - ifdef CONFIG_PCI - OX_OBJS += b1pci.o + OX_OBJS += kcapi.o + O_OBJS += capi.o + ifdef CONFIG_ISDN_DRV_AVMB1_B1ISA + O_OBJS += b1isa.o + endif + ifdef CONFIG_ISDN_DRV_AVMB1_B1PCI + O_OBJS += b1pci.o + endif + ifdef CONFIG_ISDN_DRV_AVMB1_T1ISA + O_OBJS += t1isa.o + endif + ifdef CONFIG_ISDN_DRV_AVMB1_B1PCMCIA + OX_OBJS += b1pcmcia.o endif + OX_OBJS += capiutil.o capidrv.o b1.o else ifeq ($(CONFIG_ISDN_DRV_AVMB1),m) O_TARGET += kernelcapi.o - O_OBJS += b1lli.o - OX_OBJS += b1capi.o + OX_OBJS += kcapi.o M_OBJS += capi.o kernelcapi.o - MX_OBJS += capiutil.o capidrv.o - ifdef CONFIG_PCI - MX_OBJS += b1pci.o + ifdef CONFIG_ISDN_DRV_AVMB1_B1ISA + M_OBJS += b1isa.o + endif + ifdef CONFIG_ISDN_DRV_AVMB1_B1PCI + M_OBJS += b1pci.o + endif + ifdef CONFIG_ISDN_DRV_AVMB1_T1ISA + M_OBJS += t1isa.o + endif + MX_OBJS += capiutil.o capidrv.o b1.o + ifdef CONFIG_ISDN_DRV_AVMB1_B1PCMCIA + MX_OBJS += b1pcmcia.o endif endif endif diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/avmb1/avmcard.h linux/drivers/isdn/avmb1/avmcard.h --- v2.3.13/linux/drivers/isdn/avmb1/avmcard.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/avmb1/avmcard.h Thu Aug 12 09:42:33 1999 @@ -0,0 +1,559 @@ +/* + * $Id: avmcard.h,v 1.4 1999/08/04 10:10:08 calle Exp $ + * + * Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * + * $Log: avmcard.h,v $ + * Revision 1.4 1999/08/04 10:10:08 calle + * Bugfix: corrected /proc functions, added structure for new AVM cards. + * + * Revision 1.3 1999/07/23 08:41:47 calle + * prepared for new AVM cards. + * + * Revision 1.2 1999/07/05 15:09:45 calle + * - renamed "appl_release" to "appl_released". + * - version und profile data now cleared on controller reset + * - extended /proc interface, to allow driver and controller specific + * informations to include by driver hackers. + * + * Revision 1.1 1999/07/01 15:26:22 calle + * complete new version (I love it): + * + new hardware independed "capi_driver" interface that will make it easy to: + * - support other controllers with CAPI-2.0 (i.e. USB Controller) + * - write a CAPI-2.0 for the passive cards + * - support serial link CAPI-2.0 boxes. + * + wrote "capi_driver" for all supported cards. + * + "capi_driver" (supported cards) now have to be configured with + * make menuconfig, in the past all supported cards where included + * at once. + * + new and better informations in /proc/capi/ + * + new ioctl to switch trace of capi messages per controller + * using "avmcapictrl trace [contr] on|off|...." + * + complete testcircle with all supported cards and also the + * PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done. + * + */ + +#ifndef _AVMCARD_H_ +#define _AVMCARD_H_ + +#define AVMB1_PORTLEN 0x1f +#define AVM_MAXVERSION 8 +#define AVM_NAPPS 30 +#define AVM_NCCI_PER_CHANNEL 4 + +/* + * Versions + */ + +#define VER_DRIVER 0 +#define VER_CARDTYPE 1 +#define VER_HWID 2 +#define VER_SERIAL 3 +#define VER_OPTION 4 +#define VER_PROTO 5 +#define VER_PROFILE 6 +#define VER_CAPI 7 + +enum avmcardtype { + avm_b1isa, + avm_b1pci, + avm_b1pcmcia, + avm_m1, + avm_m2, + avm_t1isa, + avm_t1pci, + avm_c4 +}; + +typedef struct avmcard_dmainfo { + __u32 recvlen; + __u8 recvbuf[128+2048]; + struct sk_buff_head send_queue; + __u8 sendbuf[128+2048]; +} avmcard_dmainfo; + +typedef struct avmcard { + char name[32]; + unsigned int port; + unsigned irq; + unsigned long membase; + enum avmcardtype cardtype; + int cardnr; /* for t1isa */ + + int versionlen; + char versionbuf[1024]; + char *version[AVM_MAXVERSION]; + + char cardname[32]; + + char infobuf[128]; /* for function procinfo */ + char msgbuf[128]; /* capimsg msg part */ + char databuf[2048]; /* capimsg data part */ + + int interrupt; + + void *mbase; + __u32 csr; + avmcard_dmainfo *dma; + + struct capi_ctr *ctrl; +} avmcard; + +extern int b1_irq_table[16]; + +/* + * LLI Messages to the ISDN-ControllerISDN Controller + */ + +#define SEND_POLL 0x72 /* + * after load <- RECEIVE_POLL + */ +#define SEND_INIT 0x11 /* + * first message <- RECEIVE_INIT + * int32 NumApplications int32 + * NumNCCIs int32 BoardNumber + */ +#define SEND_REGISTER 0x12 /* + * register an application int32 + * ApplIDId int32 NumMessages + * int32 NumB3Connections int32 + * NumB3Blocks int32 B3Size + * + * AnzB3Connection != 0 && + * AnzB3Blocks >= 1 && B3Size >= 1 + */ +#define SEND_RELEASE 0x14 /* + * deregister an application int32 + * ApplID + */ +#define SEND_MESSAGE 0x15 /* + * send capi-message int32 length + * capi-data ... + */ +#define SEND_DATA_B3_REQ 0x13 /* + * send capi-data-message int32 + * MsgLength capi-data ... int32 + * B3Length data .... + */ + +#define SEND_CONFIG 0x21 /* + */ + +#define SEND_POLLACK 0x73 /* T1 Watchdog */ + +/* + * LLI Messages from the ISDN-ControllerISDN Controller + */ + +#define RECEIVE_POLL 0x32 /* + * <- after SEND_POLL + */ +#define RECEIVE_INIT 0x27 /* + * <- after SEND_INIT int32 length + * byte total length b1struct board + * driver revision b1struct card + * type b1struct reserved b1struct + * serial number b1struct driver + * capability b1struct d-channel + * protocol b1struct CAPI-2.0 + * profile b1struct capi version + */ +#define RECEIVE_MESSAGE 0x21 /* + * <- after SEND_MESSAGE int32 + * AppllID int32 Length capi-data + * .... + */ +#define RECEIVE_DATA_B3_IND 0x22 /* + * received data int32 AppllID + * int32 Length capi-data ... + * int32 B3Length data ... + */ +#define RECEIVE_START 0x23 /* + * Handshake + */ +#define RECEIVE_STOP 0x24 /* + * Handshake + */ +#define RECEIVE_NEW_NCCI 0x25 /* + * int32 AppllID int32 NCCI int32 + * WindowSize + */ +#define RECEIVE_FREE_NCCI 0x26 /* + * int32 AppllID int32 NCCI + */ +#define RECEIVE_RELEASE 0x26 /* + * int32 AppllID int32 0xffffffff + */ +#define RECEIVE_TASK_READY 0x31 /* + * int32 tasknr + * int32 Length Taskname ... + */ +#define RECEIVE_DEBUGMSG 0x71 /* + * int32 Length message + * + */ +#define RECEIVE_POLLDWORD 0x75 /* t1pci in dword mode */ + +#define WRITE_REGISTER 0x00 +#define READ_REGISTER 0x01 + +/* + * port offsets + */ + +#define B1_READ 0x00 +#define B1_WRITE 0x01 +#define B1_INSTAT 0x02 +#define B1_OUTSTAT 0x03 +#define B1_RESET 0x10 +#define B1_ANALYSE 0x04 + + +#define B1_STAT0(cardtype) ((cardtype) == avm_m1 ? 0x81200000l : 0x80A00000l) +#define B1_STAT1(cardtype) (0x80E00000l) + +/* ---------------------------------------------------------------- */ + +static inline unsigned char b1outp(unsigned int base, + unsigned short offset, + unsigned char value) +{ + outb(value, base + offset); + return inb(base + B1_ANALYSE); +} + + +static inline int b1_rx_full(unsigned int base) +{ + return inb(base + B1_INSTAT) & 0x1; +} + +static inline unsigned char b1_get_byte(unsigned int base) +{ + unsigned long stop = jiffies + 1 * HZ; /* maximum wait time 1 sec */ + while (!b1_rx_full(base) && time_before(jiffies, stop)); + if (b1_rx_full(base)) + return inb(base + B1_READ); + printk(KERN_CRIT "b1lli(0x%x): rx not full after 1 second\n", base); + return 0; +} + +static inline unsigned int b1_get_word(unsigned int base) +{ + unsigned int val = 0; + val |= b1_get_byte(base); + val |= (b1_get_byte(base) << 8); + val |= (b1_get_byte(base) << 16); + val |= (b1_get_byte(base) << 24); + return val; +} + +static inline int b1_tx_empty(unsigned int base) +{ + return inb(base + B1_OUTSTAT) & 0x1; +} + +static inline void b1_put_byte(unsigned int base, unsigned char val) +{ + while (!b1_tx_empty(base)); + b1outp(base, B1_WRITE, val); +} + +static inline int b1_save_put_byte(unsigned int base, unsigned char val) +{ + unsigned long stop = jiffies + 2 * HZ; + while (!b1_tx_empty(base) && time_before(jiffies,stop)); + if (!b1_tx_empty(base)) return -1; + b1outp(base, B1_WRITE, val); + return 0; +} + +static inline void b1_put_word(unsigned int base, unsigned int val) +{ + b1_put_byte(base, val & 0xff); + b1_put_byte(base, (val >> 8) & 0xff); + b1_put_byte(base, (val >> 16) & 0xff); + b1_put_byte(base, (val >> 24) & 0xff); +} + +static inline unsigned int b1_get_slice(unsigned int base, + unsigned char *dp) +{ + unsigned int len, i; + + len = i = b1_get_word(base); + while (i-- > 0) *dp++ = b1_get_byte(base); + return len; +} + +static inline void b1_put_slice(unsigned int base, + unsigned char *dp, unsigned int len) +{ + unsigned i = len; + b1_put_word(base, i); + while (i-- > 0) + b1_put_byte(base, *dp++); +} + +static void b1_wr_reg(unsigned int base, + unsigned int reg, + unsigned int value) +{ + b1_put_byte(base, WRITE_REGISTER); + b1_put_word(base, reg); + b1_put_word(base, value); +} + +static inline unsigned int b1_rd_reg(unsigned int base, + unsigned int reg) +{ + b1_put_byte(base, READ_REGISTER); + b1_put_word(base, reg); + return b1_get_word(base); + +} + +static inline void b1_reset(unsigned int base) +{ + b1outp(base, B1_RESET, 0); + udelay(55 * 2 * 1000); /* 2 TIC's */ + + b1outp(base, B1_RESET, 1); + udelay(55 * 2 * 1000); /* 2 TIC's */ + + b1outp(base, B1_RESET, 0); + udelay(55 * 2 * 1000); /* 2 TIC's */ +} + +static inline unsigned char b1_disable_irq(unsigned int base) +{ + return b1outp(base, B1_INSTAT, 0x00); +} + +/* ---------------------------------------------------------------- */ + +static inline void b1_set_test_bit(unsigned int base, + enum avmcardtype cardtype, + int onoff) +{ + b1_wr_reg(base, B1_STAT0(cardtype), onoff ? 0x21 : 0x20); +} + +static inline int b1_get_test_bit(unsigned int base, + enum avmcardtype cardtype) +{ + return (b1_rd_reg(base, B1_STAT0(cardtype)) & 0x01) != 0; +} + +/* ---------------------------------------------------------------- */ + +#define T1_FASTLINK 0x00 +#define T1_SLOWLINK 0x08 + +#define T1_READ B1_READ +#define T1_WRITE B1_WRITE +#define T1_INSTAT B1_INSTAT +#define T1_OUTSTAT B1_OUTSTAT +#define T1_IRQENABLE 0x05 +#define T1_FIFOSTAT 0x06 +#define T1_RESETLINK 0x10 +#define T1_ANALYSE 0x11 +#define T1_IRQMASTER 0x12 +#define T1_IDENT 0x17 +#define T1_RESETBOARD 0x1f + +#define T1F_IREADY 0x01 +#define T1F_IHALF 0x02 +#define T1F_IFULL 0x04 +#define T1F_IEMPTY 0x08 +#define T1F_IFLAGS 0xF0 + +#define T1F_OREADY 0x10 +#define T1F_OHALF 0x20 +#define T1F_OEMPTY 0x40 +#define T1F_OFULL 0x80 +#define T1F_OFLAGS 0xF0 + +/* there are HEMA cards with 1k and 4k FIFO out */ +#define FIFO_OUTBSIZE 256 +#define FIFO_INPBSIZE 512 + +#define HEMA_VERSION_ID 0 +#define HEMA_PAL_ID 0 + +static inline void t1outp(unsigned int base, + unsigned short offset, + unsigned char value) +{ + outb(value, base + offset); +} + +static inline unsigned char t1inp(unsigned int base, + unsigned short offset) +{ + return inb(base + offset); +} + +static inline int t1_isfastlink(unsigned int base) +{ + return (inb(base + T1_IDENT) & ~0x82) == 1; +} + +static inline unsigned char t1_fifostatus(unsigned int base) +{ + return inb(base + T1_FIFOSTAT); +} + +static inline unsigned int t1_get_slice(unsigned int base, + unsigned char *dp) +{ + unsigned int len, i; +#ifdef FASTLINK_DEBUG + unsigned wcnt = 0, bcnt = 0; +#endif + + len = i = b1_get_word(base); + if (t1_isfastlink(base)) { + int status; + while (i > 0) { + status = t1_fifostatus(base) & (T1F_IREADY|T1F_IHALF); + if (i >= FIFO_INPBSIZE) status |= T1F_IFULL; + + switch (status) { + case T1F_IREADY|T1F_IHALF|T1F_IFULL: + insb(base+B1_READ, dp, FIFO_INPBSIZE); + dp += FIFO_INPBSIZE; + i -= FIFO_INPBSIZE; +#ifdef FASTLINK_DEBUG + wcnt += FIFO_INPBSIZE; +#endif + break; + case T1F_IREADY|T1F_IHALF: + insb(base+B1_READ,dp, i); +#ifdef FASTLINK_DEBUG + wcnt += i; +#endif + dp += i; + i = 0; + if (i == 0) + break; + /* fall through */ + default: + *dp++ = b1_get_byte(base); + i--; +#ifdef FASTLINK_DEBUG + bcnt++; +#endif + break; + } + } +#ifdef FASTLINK_DEBUG + if (wcnt) + printk(KERN_DEBUG "b1lli(0x%x): get_slice l=%d w=%d b=%d\n", + base, len, wcnt, bcnt); +#endif + } else { + while (i-- > 0) + *dp++ = b1_get_byte(base); + } + return len; +} + +static inline void t1_put_slice(unsigned int base, + unsigned char *dp, unsigned int len) +{ + unsigned i = len; + b1_put_word(base, i); + if (t1_isfastlink(base)) { + int status; + while (i > 0) { + status = t1_fifostatus(base) & (T1F_OREADY|T1F_OHALF); + if (i >= FIFO_OUTBSIZE) status |= T1F_OEMPTY; + switch (status) { + case T1F_OREADY|T1F_OHALF|T1F_OEMPTY: + outsb(base+B1_WRITE, dp, FIFO_OUTBSIZE); + dp += FIFO_OUTBSIZE; + i -= FIFO_OUTBSIZE; + break; + case T1F_OREADY|T1F_OHALF: + outsb(base+B1_WRITE, dp, i); + dp += i; + i = 0; + break; + default: + b1_put_byte(base, *dp++); + i--; + break; + } + } + } else { + while (i-- > 0) + b1_put_byte(base, *dp++); + } +} + +static inline void t1_disable_irq(unsigned int base) +{ + t1outp(base, T1_IRQMASTER, 0x00); +} + +static inline void t1_reset(unsigned int base) +{ + /* reset T1 Controller */ + b1_reset(base); + /* disable irq on HEMA */ + t1outp(base, B1_INSTAT, 0x00); + t1outp(base, B1_OUTSTAT, 0x00); + t1outp(base, T1_IRQMASTER, 0x00); + /* reset HEMA board configuration */ + t1outp(base, T1_RESETBOARD, 0xf); +} + +static inline void b1_setinterrupt(unsigned int base, unsigned irq, + enum avmcardtype cardtype) +{ + switch (cardtype) { + case avm_t1isa: + t1outp(base, B1_INSTAT, 0x00); + t1outp(base, B1_INSTAT, 0x02); + t1outp(base, T1_IRQMASTER, 0x08); + break; + case avm_b1isa: + b1outp(base, B1_INSTAT, 0x00); + b1outp(base, B1_RESET, b1_irq_table[irq]); + b1outp(base, B1_INSTAT, 0x02); + break; + default: + case avm_m1: + case avm_m2: + case avm_b1pci: + b1outp(base, B1_INSTAT, 0x00); + b1outp(base, B1_RESET, 0xf0); + b1outp(base, B1_INSTAT, 0x02); + break; + case avm_c4: + case avm_t1pci: + b1outp(base, B1_RESET, 0xf0); + break; + } +} + +int b1_detect(unsigned int base, enum avmcardtype cardtype); +int b1_load_t4file(unsigned int base, capiloaddatapart * t4file); +int b1_load_config(unsigned int base, capiloaddatapart * config); +int b1_loaded(unsigned int base); +int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data); +void b1_reset_ctr(struct capi_ctr *ctrl); +void b1_register_appl(struct capi_ctr *ctrl, __u16 appl, + capi_register_params *rp); +void b1_release_appl(struct capi_ctr *ctrl, __u16 appl); +void b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); +void b1_parse_version(avmcard *card); +void b1_handle_interrupt(avmcard * card); + +int b1ctl_read_proc(char *page, char **start, off_t off, + int count, int *eof, struct capi_ctr *ctrl); + + +#endif /* _AVMCARD_H_ */ diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/avmb1/b1.c linux/drivers/isdn/avmb1/b1.c --- v2.3.13/linux/drivers/isdn/avmb1/b1.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/avmb1/b1.c Sun Aug 15 11:49:08 1999 @@ -0,0 +1,687 @@ +/* + * $Id: b1.c,v 1.7 1999/08/04 10:10:09 calle Exp $ + * + * Common module for AVM B1 cards. + * + * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * + * $Log: b1.c,v $ + * Revision 1.7 1999/08/04 10:10:09 calle + * Bugfix: corrected /proc functions, added structure for new AVM cards. + * + * Revision 1.6 1999/07/23 08:51:04 calle + * small fix and typo in checkin before. + * + * Revision 1.5 1999/07/23 08:41:48 calle + * prepared for new AVM cards. + * + * Revision 1.4 1999/07/09 15:05:38 keil + * compat.h is now isdn_compat.h + * + * Revision 1.3 1999/07/06 07:41:59 calle + * - changes in /proc interface + * - check and changed calls to [dev_]kfree_skb and [dev_]alloc_skb. + * + * Revision 1.2 1999/07/05 15:09:47 calle + * - renamed "appl_release" to "appl_released". + * - version und profile data now cleared on controller reset + * - extended /proc interface, to allow driver and controller specific + * informations to include by driver hackers. + * + * Revision 1.1 1999/07/01 15:26:23 calle + * complete new version (I love it): + * + new hardware independed "capi_driver" interface that will make it easy to: + * - support other controllers with CAPI-2.0 (i.e. USB Controller) + * - write a CAPI-2.0 for the passive cards + * - support serial link CAPI-2.0 boxes. + * + wrote "capi_driver" for all supported cards. + * + "capi_driver" (supported cards) now have to be configured with + * make menuconfig, in the past all supported cards where included + * at once. + * + new and better informations in /proc/capi/ + * + new ioctl to switch trace of capi messages per controller + * using "avmcapictrl trace [contr] on|off|...." + * + complete testcircle with all supported cards and also the + * PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done. + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "capilli.h" +#include "avmcard.h" +#include "capicmd.h" +#include "capiutil.h" + +static char *revision = "$Revision: 1.7 $"; + +/* ------------------------------------------------------------- */ + +MODULE_AUTHOR("Carsten Paeth "); + +/* ------------------------------------------------------------- */ + +int b1_irq_table[16] = +{0, + 0, + 0, + 192, /* irq 3 */ + 32, /* irq 4 */ + 160, /* irq 5 */ + 96, /* irq 6 */ + 224, /* irq 7 */ + 0, + 64, /* irq 9 */ + 80, /* irq 10 */ + 208, /* irq 11 */ + 48, /* irq 12 */ + 0, + 0, + 112, /* irq 15 */ +}; + +/* ------------------------------------------------------------- */ + +int b1_detect(unsigned int base, enum avmcardtype cardtype) +{ + int onoff, i; + + /* + * Statusregister 0000 00xx + */ + if ((inb(base + B1_INSTAT) & 0xfc) + || (inb(base + B1_OUTSTAT) & 0xfc)) + return 1; + /* + * Statusregister 0000 001x + */ + b1outp(base, B1_INSTAT, 0x2); /* enable irq */ + /* b1outp(base, B1_OUTSTAT, 0x2); */ + if ((inb(base + B1_INSTAT) & 0xfe) != 0x2 + /* || (inb(base + B1_OUTSTAT) & 0xfe) != 0x2 */) + return 2; + /* + * Statusregister 0000 000x + */ + b1outp(base, B1_INSTAT, 0x0); /* disable irq */ + b1outp(base, B1_OUTSTAT, 0x0); + if ((inb(base + B1_INSTAT) & 0xfe) + || (inb(base + B1_OUTSTAT) & 0xfe)) + return 3; + + for (onoff = !0, i= 0; i < 10 ; i++) { + b1_set_test_bit(base, cardtype, onoff); + if (b1_get_test_bit(base, cardtype) != onoff) + return 4; + onoff = !onoff; + } + + if (cardtype == avm_m1) + return 0; + + if ((b1_rd_reg(base, B1_STAT1(cardtype)) & 0x0f) != 0x01) + return 5; + + return 0; +} + +int b1_load_t4file(unsigned int base, capiloaddatapart * t4file) +{ + unsigned char buf[256]; + unsigned char *dp; + int i, left, retval; + + dp = t4file->data; + left = t4file->len; + while (left > sizeof(buf)) { + if (t4file->user) { + retval = copy_from_user(buf, dp, sizeof(buf)); + if (retval) + return -EFAULT; + } else { + memcpy(buf, dp, sizeof(buf)); + } + for (i = 0; i < sizeof(buf); i++) + if (b1_save_put_byte(base, buf[i]) < 0) { + printk(KERN_ERR "b1_load_t4file: corrupted t4 file ?\n"); + return -EIO; + } + left -= sizeof(buf); + dp += sizeof(buf); + } + if (left) { + if (t4file->user) { + retval = copy_from_user(buf, dp, left); + if (retval) + return -EFAULT; + } else { + memcpy(buf, dp, left); + } + for (i = 0; i < left; i++) + if (b1_save_put_byte(base, buf[i]) < 0) { + printk(KERN_ERR "b1_load_t4file: corrupted t4 file ?\n"); + return -EIO; + } + } + return 0; +} + +int b1_load_config(unsigned int base, capiloaddatapart * config) +{ + unsigned char buf[256]; + unsigned char *dp; + int i, j, left, retval; + + dp = config->data; + left = config->len; + if (left) { + b1_put_byte(base, SEND_CONFIG); + b1_put_word(base, 1); + b1_put_byte(base, SEND_CONFIG); + b1_put_word(base, left); + } + while (left > sizeof(buf)) { + if (config->user) { + retval = copy_from_user(buf, dp, sizeof(buf)); + if (retval) + return -EFAULT; + } else { + memcpy(buf, dp, sizeof(buf)); + } + for (i = 0; i < sizeof(buf); ) { + b1_put_byte(base, SEND_CONFIG); + for (j=0; j < 4; j++) { + b1_put_byte(base, buf[i++]); + } + } + left -= sizeof(buf); + dp += sizeof(buf); + } + if (left) { + if (config->user) { + retval = copy_from_user(buf, dp, left); + if (retval) + return -EFAULT; + } else { + memcpy(buf, dp, left); + } + for (i = 0; i < left; ) { + b1_put_byte(base, SEND_CONFIG); + for (j=0; j < 4; j++) { + if (i < left) + b1_put_byte(base, buf[i++]); + else + b1_put_byte(base, 0); + } + } + } + return 0; +} + +int b1_loaded(unsigned int base) +{ + unsigned long stop; + unsigned char ans; + unsigned long tout = 2; + + for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) { + if (b1_tx_empty(base)) + break; + } + if (!b1_tx_empty(base)) { + printk(KERN_ERR "b1_loaded: tx err, corrupted t4 file ?\n"); + return 0; + } + b1_put_byte(base, SEND_POLL); + for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) { + if (b1_rx_full(base)) { + if ((ans = b1_get_byte(base)) == RECEIVE_POLL) { + return 1; + } + printk(KERN_ERR "b1_loaded: got 0x%x, firmware not running\n", ans); + return 0; + } + } + printk(KERN_ERR "b1_loaded: firmware not running\n"); + return 0; +} + +/* ------------------------------------------------------------- */ + +int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) +{ + avmcard *card = (avmcard *)(ctrl->driverdata); + unsigned int port = card->port; + unsigned long flags; + int retval; + + b1_reset(port); + + if ((retval = b1_load_t4file(port, &data->firmware))) { + b1_reset(port); + printk(KERN_ERR "%s: failed to load t4file!!\n", + card->name); + return retval; + } + + b1_disable_irq(port); + + if (data->configuration.len > 0 && data->configuration.data) { + if ((retval = b1_load_config(port, &data->configuration))) { + b1_reset(port); + printk(KERN_ERR "%s: failed to load config!!\n", + card->name); + return retval; + } + } + + if (!b1_loaded(port)) { + printk(KERN_ERR "%s: failed to load t4file.\n", card->name); + return -EIO; + } + + save_flags(flags); + cli(); + b1_setinterrupt(port, card->irq, card->cardtype); + b1_put_byte(port, SEND_INIT); + b1_put_word(port, AVM_NAPPS); + b1_put_word(port, AVM_NCCI_PER_CHANNEL*2); + b1_put_word(port, ctrl->cnr - 1); + restore_flags(flags); + + return 0; +} + +void b1_reset_ctr(struct capi_ctr *ctrl) +{ + avmcard *card = (avmcard *)(ctrl->driverdata); + unsigned int port = card->port; + + b1_reset(port); + b1_reset(port); + + memset(card->version, 0, sizeof(card->version)); + ctrl->reseted(ctrl); +} + +void b1_register_appl(struct capi_ctr *ctrl, + __u16 appl, + capi_register_params *rp) +{ + avmcard *card = (avmcard *)(ctrl->driverdata); + unsigned int port = card->port; + unsigned long flags; + int nconn, want = rp->level3cnt; + + if (want > 0) nconn = want; + else nconn = ctrl->profile.nbchannel * -want; + if (nconn == 0) nconn = ctrl->profile.nbchannel; + + save_flags(flags); + cli(); + b1_put_byte(port, SEND_REGISTER); + b1_put_word(port, appl); + b1_put_word(port, 1024 * (nconn+1)); + b1_put_word(port, nconn); + b1_put_word(port, rp->datablkcnt); + b1_put_word(port, rp->datablklen); + restore_flags(flags); + + ctrl->appl_registered(ctrl, appl); +} + +void b1_release_appl(struct capi_ctr *ctrl, __u16 appl) +{ + avmcard *card = (avmcard *)(ctrl->driverdata); + unsigned int port = card->port; + unsigned long flags; + + save_flags(flags); + cli(); + b1_put_byte(port, SEND_RELEASE); + b1_put_word(port, appl); + restore_flags(flags); +} + +void b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) +{ + avmcard *card = (avmcard *)(ctrl->driverdata); + unsigned int port = card->port; + unsigned long flags; + __u16 len = CAPIMSG_LEN(skb->data); + __u8 cmd = CAPIMSG_COMMAND(skb->data); + __u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data); + + save_flags(flags); + cli(); + if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { + __u16 dlen = CAPIMSG_DATALEN(skb->data); + b1_put_byte(port, SEND_DATA_B3_REQ); + b1_put_slice(port, skb->data, len); + b1_put_slice(port, skb->data + len, dlen); + } else { + b1_put_byte(port, SEND_MESSAGE); + b1_put_slice(port, skb->data, len); + } + restore_flags(flags); + dev_kfree_skb(skb); +} + +/* ------------------------------------------------------------- */ + +void b1_parse_version(avmcard *card) +{ + struct capi_ctr *ctrl = card->ctrl; + capi_profile *profp; + __u8 *dversion; + __u8 flag; + int i, j; + + for (j = 0; j < AVM_MAXVERSION; j++) + card->version[j] = "\0\0" + 1; + for (i = 0, j = 0; + j < AVM_MAXVERSION && i < card->versionlen; + j++, i += card->versionbuf[i] + 1) + card->version[j] = &card->versionbuf[i + 1]; + + strncpy(ctrl->serial, card->version[VER_SERIAL], CAPI_SERIAL_LEN); + memcpy(&ctrl->profile, card->version[VER_PROFILE],sizeof(capi_profile)); + strncpy(ctrl->manu, "AVM GmbH", CAPI_MANUFACTURER_LEN); + dversion = card->version[VER_DRIVER]; + ctrl->version.majorversion = 2; + ctrl->version.minorversion = 0; + ctrl->version.majormanuversion = (((dversion[0] - '0') & 0xf) << 4); + ctrl->version.majormanuversion |= ((dversion[2] - '0') & 0xf); + ctrl->version.minormanuversion = (dversion[3] - '0') << 4; + ctrl->version.minormanuversion |= + (dversion[5] - '0') * 10 + ((dversion[6] - '0') & 0xf); + + profp = &ctrl->profile; + + flag = ((__u8 *)(profp->manu))[1]; + switch (flag) { + case 0: if (card->version[VER_CARDTYPE]) + strcpy(card->cardname, card->version[VER_CARDTYPE]); + else strcpy(card->cardname, "B1"); + break; + case 3: strcpy(card->cardname,"PCMCIA B"); break; + case 4: strcpy(card->cardname,"PCMCIA M1"); break; + case 5: strcpy(card->cardname,"PCMCIA M2"); break; + case 6: strcpy(card->cardname,"B1 V3.0"); break; + case 7: strcpy(card->cardname,"B1 PCI"); break; + default: sprintf(card->cardname, "AVM?%u", (unsigned int)flag); break; + } + printk(KERN_NOTICE "%s: card %d \"%s\" ready.\n", + card->name, ctrl->cnr, card->cardname); + + flag = ((__u8 *)(profp->manu))[3]; + if (flag) + printk(KERN_NOTICE "b1capi: card %d Protocol:%s%s%s%s%s%s%s\n", + ctrl->cnr, + (flag & 0x01) ? " DSS1" : "", + (flag & 0x02) ? " CT1" : "", + (flag & 0x04) ? " VN3" : "", + (flag & 0x08) ? " NI1" : "", + (flag & 0x10) ? " AUSTEL" : "", + (flag & 0x20) ? " ESS" : "", + (flag & 0x40) ? " 1TR6" : "" + ); + + flag = ((__u8 *)(profp->manu))[5]; + if (flag) + printk(KERN_NOTICE "%s: card %d Linetype:%s%s%s%s\n", + card->name, + ctrl->cnr, + (flag & 0x01) ? " point to point" : "", + (flag & 0x02) ? " point to multipoint" : "", + (flag & 0x08) ? " leased line without D-channel" : "", + (flag & 0x04) ? " leased line with D-channel" : "" + ); +} + +/* ------------------------------------------------------------- */ + +void b1_handle_interrupt(avmcard * card) +{ + struct capi_ctr *ctrl = card->ctrl; + unsigned char b1cmd; + struct sk_buff *skb; + + unsigned ApplId; + unsigned MsgLen; + unsigned DataB3Len; + unsigned NCCI; + unsigned WindowSize; + + if (!b1_rx_full(card->port)) + return; + + b1cmd = b1_get_byte(card->port); + + switch (b1cmd) { + + case RECEIVE_DATA_B3_IND: + + ApplId = (unsigned) b1_get_word(card->port); + MsgLen = b1_get_slice(card->port, card->msgbuf); + DataB3Len = b1_get_slice(card->port, card->databuf); + + if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) { + printk(KERN_ERR "%s: incoming packet dropped\n", + card->name); + } else { + memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); + memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len); + CAPIMSG_SETDATA(skb->data, skb->data + MsgLen); + ctrl->handle_capimsg(ctrl, ApplId, skb); + } + break; + + case RECEIVE_MESSAGE: + + ApplId = (unsigned) b1_get_word(card->port); + MsgLen = b1_get_slice(card->port, card->msgbuf); + if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) { + printk(KERN_ERR "%s: incoming packet dropped\n", + card->name); + } else { + memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); + ctrl->handle_capimsg(ctrl, ApplId, skb); + } + break; + + case RECEIVE_NEW_NCCI: + + ApplId = b1_get_word(card->port); + NCCI = b1_get_word(card->port); + WindowSize = b1_get_word(card->port); + + ctrl->new_ncci(ctrl, ApplId, NCCI, WindowSize); + + break; + + case RECEIVE_FREE_NCCI: + + ApplId = b1_get_word(card->port); + NCCI = b1_get_word(card->port); + + if (NCCI != 0xffffffff) + ctrl->free_ncci(ctrl, ApplId, NCCI); + else ctrl->appl_released(ctrl, ApplId); + break; + + case RECEIVE_START: + /* b1_put_byte(card->port, SEND_POLLACK); */ + ctrl->resume_output(ctrl); + break; + + case RECEIVE_STOP: + ctrl->suspend_output(ctrl); + break; + + case RECEIVE_INIT: + + card->versionlen = b1_get_slice(card->port, card->versionbuf); + b1_parse_version(card); + printk(KERN_INFO "%s: %s-card (%s) now active\n", + card->name, + card->version[VER_CARDTYPE], + card->version[VER_DRIVER]); + ctrl->ready(ctrl); + break; + + case RECEIVE_TASK_READY: + ApplId = (unsigned) b1_get_word(card->port); + MsgLen = b1_get_slice(card->port, card->msgbuf); + card->msgbuf[MsgLen--] = 0; + while ( MsgLen >= 0 + && ( card->msgbuf[MsgLen] == '\n' + || card->msgbuf[MsgLen] == '\r')) + card->msgbuf[MsgLen--] = 0; + printk(KERN_INFO "%s: task %d \"%s\" ready.\n", + card->name, ApplId, card->msgbuf); + break; + + case RECEIVE_DEBUGMSG: + MsgLen = b1_get_slice(card->port, card->msgbuf); + card->msgbuf[MsgLen--] = 0; + while ( MsgLen >= 0 + && ( card->msgbuf[MsgLen] == '\n' + || card->msgbuf[MsgLen] == '\r')) + card->msgbuf[MsgLen--] = 0; + printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf); + break; + + case 0xff: + printk(KERN_ERR "%s: card removed ?\n", card->name); + return; + default: + printk(KERN_ERR "%s: b1_interrupt: 0x%x ???\n", + card->name, b1cmd); + return; + } +} + +/* ------------------------------------------------------------- */ +int b1ctl_read_proc(char *page, char **start, off_t off, + int count, int *eof, struct capi_ctr *ctrl) +{ + avmcard *card = (avmcard *)(ctrl->driverdata); + __u8 flag; + int len = 0; + char *s; + + len += sprintf(page+len, "%-16s %s\n", "name", card->name); + len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port); + len += sprintf(page+len, "%-16s %d\n", "irq", card->irq); + switch (card->cardtype) { + case avm_b1isa: s = "B1 ISA"; break; + case avm_b1pci: s = "B1 PCI"; break; + case avm_b1pcmcia: s = "B1 PCMCIA"; break; + case avm_m1: s = "M1"; break; + case avm_m2: s = "M2"; break; + case avm_t1isa: s = "T1 ISA (HEMA)"; break; + case avm_t1pci: s = "T1 PCI"; break; + case avm_c4: s = "C4"; break; + default: s = "???"; break; + } + len += sprintf(page+len, "%-16s %s\n", "type", s); + if (card->cardtype == avm_t1isa) + len += sprintf(page+len, "%-16s %d\n", "cardnr", card->cardnr); + if ((s = card->version[VER_DRIVER]) != 0) + len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); + if ((s = card->version[VER_CARDTYPE]) != 0) + len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); + if ((s = card->version[VER_SERIAL]) != 0) + len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); + + if (card->cardtype != avm_m1) { + flag = ((__u8 *)(ctrl->profile.manu))[3]; + if (flag) + len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n", + "protocol", + (flag & 0x01) ? " DSS1" : "", + (flag & 0x02) ? " CT1" : "", + (flag & 0x04) ? " VN3" : "", + (flag & 0x08) ? " NI1" : "", + (flag & 0x10) ? " AUSTEL" : "", + (flag & 0x20) ? " ESS" : "", + (flag & 0x40) ? " 1TR6" : "" + ); + } + if (card->cardtype != avm_m1) { + flag = ((__u8 *)(ctrl->profile.manu))[5]; + if (flag) + len += sprintf(page+len, "%-16s%s%s%s%s\n", + "linetype", + (flag & 0x01) ? " point to point" : "", + (flag & 0x02) ? " point to multipoint" : "", + (flag & 0x08) ? " leased line without D-channel" : "", + (flag & 0x04) ? " leased line with D-channel" : "" + ); + } + len += sprintf(page+len, "%-16s %s\n", "cardname", card->cardname); + + if (off+count >= len) + *eof = 1; + if (len < off) + return 0; + *start = page + off; + return ((count < len-off) ? count : len-off); +} + +/* ------------------------------------------------------------- */ + +EXPORT_SYMBOL(b1_irq_table); + +EXPORT_SYMBOL(b1_detect); +EXPORT_SYMBOL(b1_load_t4file); +EXPORT_SYMBOL(b1_load_config); +EXPORT_SYMBOL(b1_loaded); +EXPORT_SYMBOL(b1_load_firmware); +EXPORT_SYMBOL(b1_reset_ctr); +EXPORT_SYMBOL(b1_register_appl); +EXPORT_SYMBOL(b1_release_appl); +EXPORT_SYMBOL(b1_send_message); + +EXPORT_SYMBOL(b1_parse_version); +EXPORT_SYMBOL(b1_handle_interrupt); + +EXPORT_SYMBOL(b1ctl_read_proc); + +#ifdef MODULE +#define b1_init init_module +void cleanup_module(void); +#endif + +int b1_init(void) +{ + char *p; + char rev[10]; + + if ((p = strchr(revision, ':'))) { + strncpy(rev, p + 1, sizeof(rev)); + p = strchr(rev, '$'); + *p = 0; + } else + strcpy(rev, "1.0"); + + printk(KERN_INFO "b1: revision %s\n", rev); + + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ +} +#endif diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/avmb1/b1isa.c linux/drivers/isdn/avmb1/b1isa.c --- v2.3.13/linux/drivers/isdn/avmb1/b1isa.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/avmb1/b1isa.c Sun Aug 15 11:49:08 1999 @@ -0,0 +1,237 @@ +/* + * $Id: b1isa.c,v 1.3 1999/07/09 15:05:40 keil Exp $ + * + * Module for AVM B1 ISA-card. + * + * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * + * $Log: b1isa.c,v $ + * Revision 1.3 1999/07/09 15:05:40 keil + * compat.h is now isdn_compat.h + * + * Revision 1.2 1999/07/05 15:09:49 calle + * - renamed "appl_release" to "appl_released". + * - version und profile data now cleared on controller reset + * - extended /proc interface, to allow driver and controller specific + * informations to include by driver hackers. + * + * Revision 1.1 1999/07/01 15:26:27 calle + * complete new version (I love it): + * + new hardware independed "capi_driver" interface that will make it easy to: + * - support other controllers with CAPI-2.0 (i.e. USB Controller) + * - write a CAPI-2.0 for the passive cards + * - support serial link CAPI-2.0 boxes. + * + wrote "capi_driver" for all supported cards. + * + "capi_driver" (supported cards) now have to be configured with + * make menuconfig, in the past all supported cards where included + * at once. + * + new and better informations in /proc/capi/ + * + new ioctl to switch trace of capi messages per controller + * using "avmcapictrl trace [contr] on|off|...." + * + complete testcircle with all supported cards and also the + * PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done. + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "capicmd.h" +#include "capiutil.h" +#include "capilli.h" +#include "avmcard.h" + +static char *revision = "$Revision: 1.3 $"; + +/* ------------------------------------------------------------- */ + +MODULE_AUTHOR("Carsten Paeth "); + +/* ------------------------------------------------------------- */ + +static struct capi_driver_interface *di; + +/* ------------------------------------------------------------- */ + +static void b1isa_interrupt(int interrupt, void *devptr, struct pt_regs *regs) +{ + avmcard *card; + + card = (avmcard *) devptr; + + if (!card) { + printk(KERN_WARNING "b1_interrupt: wrong device\n"); + return; + } + if (card->interrupt) { + printk(KERN_ERR "b1_interrupt: reentering interrupt hander (%s)\n", card->name); + return; + } + + card->interrupt = 1; + + b1_handle_interrupt(card); + + card->interrupt = 0; +} +/* ------------------------------------------------------------- */ + +static void b1isa_remove_ctr(struct capi_ctr *ctrl) +{ + avmcard *card = (avmcard *)(ctrl->driverdata); + unsigned int port = card->port; + + b1_reset(port); + b1_reset(port); + + di->detach_ctr(ctrl); + free_irq(card->irq, card); + release_region(card->port, AVMB1_PORTLEN); + kfree(card); + + MOD_DEC_USE_COUNT; +} + +/* ------------------------------------------------------------- */ + +static int b1isa_add_card(struct capi_driver *driver, struct capicardparams *p) +{ + avmcard *card; + int retval; + + card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC); + + if (!card) { + printk(KERN_WARNING "b1isa: no memory.\n"); + return -ENOMEM; + } + memset(card, 0, sizeof(avmcard)); + sprintf(card->name, "b1isa-%x", p->port); + card->port = p->port; + card->irq = p->irq; + card->cardtype = avm_b1isa; + + if (check_region(card->port, AVMB1_PORTLEN)) { + printk(KERN_WARNING + "b1isa: ports 0x%03x-0x%03x in use.\n", + card->port, card->port + AVMB1_PORTLEN); + kfree(card); + return -EBUSY; + } + if (b1_irq_table[card->irq & 0xf] == 0) { + printk(KERN_WARNING "b1isa: irq %d not valid.\n", card->irq); + kfree(card); + return -EINVAL; + } + if ( card->port != 0x150 && card->port != 0x250 + && card->port != 0x300 && card->port != 0x340) { + printk(KERN_WARNING "b1isa: illegal port 0x%x.\n", card->port); + kfree(card); + return -EINVAL; + } + b1_reset(card->port); + if ((retval = b1_detect(card->port, card->cardtype)) != 0) { + printk(KERN_NOTICE "b1isa: NO card at 0x%x (%d)\n", + card->port, retval); + kfree(card); + return -EIO; + } + b1_reset(card->port); + + request_region(p->port, AVMB1_PORTLEN, card->name); + + retval = request_irq(card->irq, b1isa_interrupt, 0, card->name, card); + if (retval) { + printk(KERN_ERR "b1isa: unable to get IRQ %d.\n", card->irq); + release_region(card->port, AVMB1_PORTLEN); + kfree(card); + return -EBUSY; + } + + card->ctrl = di->attach_ctr(driver, card->name, card); + if (!card->ctrl) { + printk(KERN_ERR "b1isa: attach controller failed.\n"); + free_irq(card->irq, card); + release_region(card->port, AVMB1_PORTLEN); + kfree(card); + return -EBUSY; + } + + MOD_INC_USE_COUNT; + return 0; +} + +static char *b1isa_procinfo(struct capi_ctr *ctrl) +{ + avmcard *card = (avmcard *)(ctrl->driverdata); + if (!card) + return ""; + sprintf(card->infobuf, "%s %s 0x%x %d", + card->cardname[0] ? card->cardname : "-", + card->version[VER_DRIVER] ? card->version[VER_DRIVER] : "-", + card->port, card->irq + ); + return card->infobuf; +} + +/* ------------------------------------------------------------- */ + +static struct capi_driver b1isa_driver = { + "b1isa", + "0.0", + b1_load_firmware, + b1_reset_ctr, + b1isa_remove_ctr, + b1_register_appl, + b1_release_appl, + b1_send_message, + + b1isa_procinfo, + b1ctl_read_proc, + 0, /* use standard driver_read_proc */ + + b1isa_add_card, +}; + +#ifdef MODULE +#define b1isa_init init_module +void cleanup_module(void); +#endif + +int b1isa_init(void) +{ + struct capi_driver *driver = &b1isa_driver; + char *p; + + if ((p = strchr(revision, ':'))) { + strncpy(driver->revision, p + 1, sizeof(driver->revision)); + p = strchr(driver->revision, '$'); + *p = 0; + } + + printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision); + + di = attach_capi_driver(driver); + + if (!di) { + printk(KERN_ERR "%s: failed to attach capi_driver\n", + driver->name); + return -EIO; + } + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ + detach_capi_driver(&b1isa_driver); +} +#endif diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/avmb1/b1pci.c linux/drivers/isdn/avmb1/b1pci.c --- v2.3.13/linux/drivers/isdn/avmb1/b1pci.c Tue Jun 1 23:25:48 1999 +++ linux/drivers/isdn/avmb1/b1pci.c Thu Aug 12 09:42:33 1999 @@ -1,59 +1,65 @@ /* - * $Id: b1pci.c,v 1.9 1999/04/15 19:49:32 calle Exp $ + * $Id: b1pci.c,v 1.16 1999/08/11 21:01:07 keil Exp $ * * Module for AVM B1 PCI-card. * - * (c) Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de) + * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: b1pci.c,v $ - * Revision 1.9 1999/04/15 19:49:32 calle - * fix fuer die B1-PCI. Jetzt geht z.B. auch IRQ 17 ... + * Revision 1.16 1999/08/11 21:01:07 keil + * new PCI codefix * - * Revision 1.8 1998/06/17 19:51:16 he - * merged with 2.1.10[34] (cosmetics and udelay() -> mdelay()) - * brute force fix to avoid Ugh's in isdn_tty_write() - * cleaned up some dead code - * - * Revision 1.7 1998/03/29 16:06:02 calle - * changes from 2.0 tree merged. - * - * Revision 1.2.2.2 1998/01/23 16:49:30 calle - * added functions for pcmcia cards, - * avmb1_addcard returns now the controller number. - * - * Revision 1.6 1998/02/25 09:15:36 fritz - * apply Martin's pci driver patch to isdn drivers (vgerCVS) - * - * Revision 1.5 1998/01/31 11:14:43 calle - * merged changes to 2.0 tree, prepare 2.1.82 to work. - * - * Revision 1.4 1997/12/10 20:00:50 calle - * get changes from 2.0 version - * - * Revision 1.3 1997/10/01 09:21:14 fritz - * Removed old compatibility stuff for 2.0.X kernels. - * From now on, this code is for 2.1.X ONLY! - * Old stuff is still in the separate branch. - * - * Revision 1.2 1997/05/18 09:24:13 calle - * added verbose disconnect reason reporting to avmb1. - * some fixes in capi20 interface. - * changed info messages for B1-PCI + * Revision 1.15 1999/08/10 16:02:27 calle + * struct pci_dev changed in 2.3.13. Made the necessary changes. + * + * Revision 1.14 1999/07/09 15:05:41 keil + * compat.h is now isdn_compat.h + * + * Revision 1.13 1999/07/05 15:09:50 calle + * - renamed "appl_release" to "appl_released". + * - version und profile data now cleared on controller reset + * - extended /proc interface, to allow driver and controller specific + * informations to include by driver hackers. + * + * Revision 1.12 1999/07/01 15:26:29 calle + * complete new version (I love it): + * + new hardware independed "capi_driver" interface that will make it easy to: + * - support other controllers with CAPI-2.0 (i.e. USB Controller) + * - write a CAPI-2.0 for the passive cards + * - support serial link CAPI-2.0 boxes. + * + wrote "capi_driver" for all supported cards. + * + "capi_driver" (supported cards) now have to be configured with + * make menuconfig, in the past all supported cards where included + * at once. + * + new and better informations in /proc/capi/ + * + new ioctl to switch trace of capi messages per controller + * using "avmcapictrl trace [contr] on|off|...." + * + complete testcircle with all supported cards and also the + * PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done. * - * Revision 1.1 1997/03/30 17:10:42 calle - * added support for AVM-B1-PCI card. * */ #include -#include #include #include -#include #include -#include "compat.h" +#include +#include +#include +#include +#include #include -#include +#include +#include +#include "capicmd.h" +#include "capiutil.h" +#include "capilli.h" +#include "avmcard.h" + +static char *revision = "$Revision: 1.16 $"; + +/* ------------------------------------------------------------- */ #ifndef PCI_VENDOR_ID_AVM #define PCI_VENDOR_ID_AVM 0x1244 @@ -63,65 +69,213 @@ #define PCI_DEVICE_ID_AVM_B1 0x700 #endif -static char *revision = "$Revision: 1.9 $"; - /* ------------------------------------------------------------- */ MODULE_AUTHOR("Carsten Paeth "); /* ------------------------------------------------------------- */ +static struct capi_driver_interface *di; + +/* ------------------------------------------------------------- */ + +static void b1pci_interrupt(int interrupt, void *devptr, struct pt_regs *regs) +{ + avmcard *card; + + card = (avmcard *) devptr; + + if (!card) { + printk(KERN_WARNING "b1_interrupt: wrong device\n"); + return; + } + if (card->interrupt) { + printk(KERN_ERR "b1_interrupt: reentering interrupt hander (%s)\n", card->name); + return; + } + + card->interrupt = 1; + + b1_handle_interrupt(card); + + card->interrupt = 0; +} +/* ------------------------------------------------------------- */ + +static void b1pci_remove_ctr(struct capi_ctr *ctrl) +{ + avmcard *card = (avmcard *)(ctrl->driverdata); + unsigned int port = card->port; + + b1_reset(port); + b1_reset(port); + + di->detach_ctr(ctrl); + free_irq(card->irq, card); + release_region(card->port, AVMB1_PORTLEN); + ctrl->driverdata = 0; + kfree(card); + + MOD_DEC_USE_COUNT; +} + /* ------------------------------------------------------------- */ -/* -------- Init & Cleanup ------------------------------------- */ + +static char *b1pci_procinfo(struct capi_ctr *ctrl) +{ + avmcard *card = (avmcard *)(ctrl->driverdata); + if (!card) + return ""; + sprintf(card->infobuf, "%s %s 0x%x %d", + card->cardname[0] ? card->cardname : "-", + card->version[VER_DRIVER] ? card->version[VER_DRIVER] : "-", + card->port, card->irq + ); + return card->infobuf; +} + /* ------------------------------------------------------------- */ -/* - * init / exit functions - */ +static int b1pci_add_card(struct capi_driver *driver, struct capicardparams *p) +{ + avmcard *card; + int retval; + + card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC); + + if (!card) { + printk(KERN_WARNING "b1pci: no memory.\n"); + return -ENOMEM; + } + memset(card, 0, sizeof(avmcard)); + sprintf(card->name, "b1pci-%x", p->port); + card->port = p->port; + card->irq = p->irq; + card->cardtype = avm_b1pci; + + if (check_region(card->port, AVMB1_PORTLEN)) { + printk(KERN_WARNING + "b1pci: ports 0x%03x-0x%03x in use.\n", + card->port, card->port + AVMB1_PORTLEN); + kfree(card); + return -EBUSY; + } + b1_reset(card->port); + if ((retval = b1_detect(card->port, card->cardtype)) != 0) { + printk(KERN_NOTICE "b1pci: NO card at 0x%x (%d)\n", + card->port, retval); + kfree(card); + return -EIO; + } + b1_reset(card->port); + + request_region(p->port, AVMB1_PORTLEN, card->name); + + retval = request_irq(card->irq, b1pci_interrupt, 0, card->name, card); + if (retval) { + printk(KERN_ERR "b1pci: unable to get IRQ %d.\n", card->irq); + release_region(card->port, AVMB1_PORTLEN); + kfree(card); + return -EBUSY; + } + + card->ctrl = di->attach_ctr(driver, card->name, card); + if (!card->ctrl) { + printk(KERN_ERR "b1pci: attach controller failed.\n"); + free_irq(card->irq, card); + release_region(card->port, AVMB1_PORTLEN); + kfree(card); + return -EBUSY; + } + + MOD_INC_USE_COUNT; + + return 0; +} + +/* ------------------------------------------------------------- */ + +static struct capi_driver b1pci_driver = { + "b1pci", + "0.0", + b1_load_firmware, + b1_reset_ctr, + b1pci_remove_ctr, + b1_register_appl, + b1_release_appl, + b1_send_message, + + b1pci_procinfo, + b1ctl_read_proc, + 0, /* use standard driver_read_proc */ + + 0, /* no add_card function */ +}; #ifdef MODULE #define b1pci_init init_module +void cleanup_module(void); #endif +static int ncards = 0; + int b1pci_init(void) { - char *p; - char rev[10]; - int rc; + struct capi_driver *driver = &b1pci_driver; struct pci_dev *dev = NULL; + char *p; + int retval; if ((p = strchr(revision, ':'))) { - strcpy(rev, p + 1); - p = strchr(rev, '$'); + strncpy(driver->revision, p + 1, sizeof(driver->revision)); + p = strchr(driver->revision, '$'); *p = 0; - } else - strcpy(rev, " ??? "); + } + printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision); + + di = attach_capi_driver(driver); + + if (!di) { + printk(KERN_ERR "%s: failed to attach capi_driver\n", + driver->name); + return -EIO; + } #ifdef CONFIG_PCI if (!pci_present()) { - printk(KERN_ERR "b1pci: no PCI bus present\n"); + printk(KERN_ERR "%s: no PCI bus present\n", driver->name); + detach_capi_driver(driver); return -EIO; } - printk(KERN_INFO "b1pci: revision %s\n", rev); - while ((dev = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_B1, dev))) { - unsigned int ioaddr = dev->base_address[1] & PCI_BASE_ADDRESS_IO_MASK; - unsigned int irq = dev->irq; + struct capicardparams param; + + param.port = get_pcibase(dev, 1) & PCI_BASE_ADDRESS_IO_MASK; + param.irq = dev->irq; printk(KERN_INFO - "b1pci: PCI BIOS reports AVM-B1 at i/o %#x, irq %d\n", - ioaddr, irq); - if ((rc = avmb1_probecard(ioaddr, irq, AVM_CARDTYPE_B1PCI)) != 0) { + "%s: PCI BIOS reports AVM-B1 at i/o %#x, irq %d\n", + driver->name, param.port, param.irq); + retval = b1pci_add_card(driver, ¶m); + if (retval != 0) { printk(KERN_ERR - "b1pci: no AVM-B1 at i/o %#x, irq %d detected\n", - ioaddr, irq); - return rc; + "%s: no AVM-B1 at i/o %#x, irq %d detected\n", + driver->name, param.port, param.irq); +#ifdef MODULE + cleanup_module(); +#endif + return retval; } - if ((rc = avmb1_addcard(ioaddr, irq, AVM_CARDTYPE_B1PCI)) < 0) - return rc; + ncards++; } - return 0; + if (ncards) { + printk(KERN_INFO "%s: %d B1-PCI card(s) detected\n", + driver->name, ncards); + return 0; + } + printk(KERN_ERR "%s: NO B1-PCI card detected\n", driver->name); + return -ESRCH; #else printk(KERN_ERR "b1pci: kernel not compiled with PCI.\n"); return -EIO; @@ -131,5 +285,6 @@ #ifdef MODULE void cleanup_module(void) { + detach_capi_driver(&b1pci_driver); } #endif diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/avmb1/b1pcmcia.c linux/drivers/isdn/avmb1/b1pcmcia.c --- v2.3.13/linux/drivers/isdn/avmb1/b1pcmcia.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/avmb1/b1pcmcia.c Sun Aug 15 11:49:08 1999 @@ -0,0 +1,266 @@ +/* + * $Id: b1pcmcia.c,v 1.3 1999/07/09 15:05:41 keil Exp $ + * + * Module for AVM B1/M1/M2 PCMCIA-card. + * + * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * + * $Log: b1pcmcia.c,v $ + * Revision 1.3 1999/07/09 15:05:41 keil + * compat.h is now isdn_compat.h + * + * Revision 1.2 1999/07/05 15:09:51 calle + * - renamed "appl_release" to "appl_released". + * - version und profile data now cleared on controller reset + * - extended /proc interface, to allow driver and controller specific + * informations to include by driver hackers. + * + * Revision 1.1 1999/07/01 15:26:30 calle + * complete new version (I love it): + * + new hardware independed "capi_driver" interface that will make it easy to: + * - support other controllers with CAPI-2.0 (i.e. USB Controller) + * - write a CAPI-2.0 for the passive cards + * - support serial link CAPI-2.0 boxes. + * + wrote "capi_driver" for all supported cards. + * + "capi_driver" (supported cards) now have to be configured with + * make menuconfig, in the past all supported cards where included + * at once. + * + new and better informations in /proc/capi/ + * + new ioctl to switch trace of capi messages per controller + * using "avmcapictrl trace [contr] on|off|...." + * + complete testcircle with all supported cards and also the + * PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done. + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "capicmd.h" +#include "capiutil.h" +#include "capilli.h" +#include "avmcard.h" + +static char *revision = "$Revision: 1.3 $"; + +/* ------------------------------------------------------------- */ + +MODULE_AUTHOR("Carsten Paeth "); + +/* ------------------------------------------------------------- */ + +static struct capi_driver_interface *di; + +/* ------------------------------------------------------------- */ + +static void b1pcmcia_interrupt(int interrupt, void *devptr, struct pt_regs *regs) +{ + avmcard *card; + + card = (avmcard *) devptr; + + if (!card) { + printk(KERN_WARNING "b1_interrupt: wrong device\n"); + return; + } + if (card->interrupt) { + printk(KERN_ERR "b1_interrupt: reentering interrupt hander (%s)\n", card->name); + return; + } + + card->interrupt = 1; + + b1_handle_interrupt(card); + + card->interrupt = 0; +} +/* ------------------------------------------------------------- */ + +static void b1pcmcia_remove_ctr(struct capi_ctr *ctrl) +{ + avmcard *card = (avmcard *)(ctrl->driverdata); + unsigned int port = card->port; + + b1_reset(port); + b1_reset(port); + + di->detach_ctr(ctrl); + free_irq(card->irq, card); + /* io addrsses managent by CardServices + * release_region(card->port, AVMB1_PORTLEN); + */ + kfree(card); + + MOD_DEC_USE_COUNT; +} + +/* ------------------------------------------------------------- */ + +static int b1pcmcia_add_card(struct capi_driver *driver, + unsigned int port, + unsigned irq, + enum avmcardtype cardtype) +{ + avmcard *card; + int retval; + + card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC); + + if (!card) { + printk(KERN_WARNING "b1pcmcia: no memory.\n"); + return -ENOMEM; + } + memset(card, 0, sizeof(avmcard)); + switch (cardtype) { + case avm_m1: sprintf(card->name, "m1-%x", port); break; + case avm_m2: sprintf(card->name, "m2-%x", port); break; + default: sprintf(card->name, "b1pcmcia-%x", port); break; + } + card->port = port; + card->irq = irq; + card->cardtype = cardtype; + + b1_reset(card->port); + if ((retval = b1_detect(card->port, card->cardtype)) != 0) { + printk(KERN_NOTICE "b1pcmcia: NO card at 0x%x (%d)\n", + card->port, retval); + kfree(card); + return -EIO; + } + b1_reset(card->port); + + retval = request_irq(card->irq, b1pcmcia_interrupt, 0, card->name, card); + if (retval) { + printk(KERN_ERR "b1pcmcia: unable to get IRQ %d.\n", card->irq); + kfree(card); + return -EBUSY; + } + + card->ctrl = di->attach_ctr(driver, card->name, card); + if (!card->ctrl) { + printk(KERN_ERR "b1pcmcia: attach controller failed.\n"); + free_irq(card->irq, card); + kfree(card); + return -EBUSY; + } + + MOD_INC_USE_COUNT; + return card->ctrl->cnr; +} + +/* ------------------------------------------------------------- */ + +static char *b1pcmcia_procinfo(struct capi_ctr *ctrl) +{ + avmcard *card = (avmcard *)(ctrl->driverdata); + if (!card) + return ""; + sprintf(card->infobuf, "%s %s 0x%x %d", + card->cardname[0] ? card->cardname : "-", + card->version[VER_DRIVER] ? card->version[VER_DRIVER] : "-", + card->port, card->irq + ); + return card->infobuf; +} + +/* ------------------------------------------------------------- */ + +static struct capi_driver b1pcmcia_driver = { + "b1pcmcia", + "0.0", + b1_load_firmware, + b1_reset_ctr, + b1pcmcia_remove_ctr, + b1_register_appl, + b1_release_appl, + b1_send_message, + + b1pcmcia_procinfo, + b1ctl_read_proc, + 0, /* use standard driver_read_proc */ + + 0, +}; + +/* ------------------------------------------------------------- */ + +int b1pcmcia_addcard_b1(unsigned int port, unsigned irq) +{ + return b1pcmcia_add_card(&b1pcmcia_driver, port, irq, avm_b1pcmcia); +} + +int b1pcmcia_addcard_m1(unsigned int port, unsigned irq) +{ + return b1pcmcia_add_card(&b1pcmcia_driver, port, irq, avm_m1); +} + +int b1pcmcia_addcard_m2(unsigned int port, unsigned irq) +{ + return b1pcmcia_add_card(&b1pcmcia_driver, port, irq, avm_m2); +} + +int b1pcmcia_delcard(unsigned int port, unsigned irq) +{ + struct capi_ctr *ctrl; + avmcard *card; + + for (ctrl = b1pcmcia_driver.controller; ctrl; ctrl = ctrl->next) { + card = (avmcard *)(ctrl->driverdata); + if (card->port == port && card->irq == irq) { + b1pcmcia_remove_ctr(ctrl); + return 0; + } + } + return -ESRCH; +} + +EXPORT_SYMBOL(b1pcmcia_addcard_b1); +EXPORT_SYMBOL(b1pcmcia_addcard_m1); +EXPORT_SYMBOL(b1pcmcia_addcard_m2); +EXPORT_SYMBOL(b1pcmcia_delcard); + +/* ------------------------------------------------------------- */ + +#ifdef MODULE +#define b1pcmcia_init init_module +void cleanup_module(void); +#endif + +int b1pcmcia_init(void) +{ + struct capi_driver *driver = &b1pcmcia_driver; + char *p; + + if ((p = strchr(revision, ':'))) { + strncpy(driver->revision, p + 1, sizeof(driver->revision)); + p = strchr(driver->revision, '$'); + *p = 0; + } + + printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision); + + di = attach_capi_driver(driver); + + if (!di) { + printk(KERN_ERR "%s: failed to attach capi_driver\n", + driver->name); + return -EIO; + } + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ + detach_capi_driver(&b1pcmcia_driver); +} +#endif diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/avmb1/capi.c linux/drivers/isdn/avmb1/capi.c --- v2.3.13/linux/drivers/isdn/avmb1/capi.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/avmb1/capi.c Thu Aug 12 09:42:33 1999 @@ -1,11 +1,43 @@ /* - * $Id: capi.c,v 1.13 1998/08/28 04:32:25 calle Exp $ + * $Id: capi.c,v 1.19 1999/07/09 15:05:42 keil Exp $ * * CAPI 2.0 Interface for Linux * * Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: capi.c,v $ + * Revision 1.19 1999/07/09 15:05:42 keil + * compat.h is now isdn_compat.h + * + * Revision 1.18 1999/07/06 07:42:01 calle + * - changes in /proc interface + * - check and changed calls to [dev_]kfree_skb and [dev_]alloc_skb. + * + * Revision 1.17 1999/07/01 15:26:30 calle + * complete new version (I love it): + * + new hardware independed "capi_driver" interface that will make it easy to: + * - support other controllers with CAPI-2.0 (i.e. USB Controller) + * - write a CAPI-2.0 for the passive cards + * - support serial link CAPI-2.0 boxes. + * + wrote "capi_driver" for all supported cards. + * + "capi_driver" (supported cards) now have to be configured with + * make menuconfig, in the past all supported cards where included + * at once. + * + new and better informations in /proc/capi/ + * + new ioctl to switch trace of capi messages per controller + * using "avmcapictrl trace [contr] on|off|...." + * + complete testcircle with all supported cards and also the + * PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done. + * + * Revision 1.16 1999/07/01 08:22:57 keil + * compatibility macros now in + * + * Revision 1.15 1999/06/21 15:24:11 calle + * extend information in /proc. + * + * Revision 1.14 1999/06/10 16:51:03 calle + * Bugfix: open/release of control device was not handled correct. + * * Revision 1.13 1998/08/28 04:32:25 calle * Added patch send by Michael.Mueller4@post.rwth-aachen.de, to get AVM B1 * driver running with 2.1.118. @@ -80,11 +112,12 @@ #include #include #include +#include #include #include #include -#include "compat.h" +#include #include "capiutil.h" #include "capicmd.h" #include "capidev.h" @@ -178,7 +211,10 @@ } copied = skb->len; - + if (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3 + && CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) + cdev->nrecvdatapkt++; + else cdev->nrecvctlpkt++; kfree_skb(skb); return copied; @@ -207,7 +243,7 @@ skb = alloc_skb(count, GFP_USER); if ((retval = copy_from_user(skb_put(skb, count), buf, count))) { - dev_kfree_skb(skb); + kfree_skb(skb); return retval; } cmd = CAPIMSG_COMMAND(skb->data); @@ -216,11 +252,11 @@ if (cmd == CAPI_DATA_B3 && subcmd == CAPI_REQ) { __u16 dlen = CAPIMSG_DATALEN(skb->data); if (mlen + dlen != count) { - dev_kfree_skb(skb); + kfree_skb(skb); return -EINVAL; } } else if (mlen != count) { - dev_kfree_skb(skb); + kfree_skb(skb); return -EINVAL; } CAPIMSG_SETAPPID(skb->data, cdev->applid); @@ -228,9 +264,12 @@ cdev->errcode = (*capifuncs->capi_put_message) (cdev->applid, skb); if (cdev->errcode) { - dev_kfree_skb(skb); + kfree_skb(skb); return -EIO; } + if (cmd == CAPI_DATA_B3 && subcmd == CAPI_REQ) + cdev->nsentdatapkt++; + else cdev->nsentctlpkt++; return count; } @@ -426,16 +465,13 @@ capidevs[minor].is_open = 1; skb_queue_head_init(&capidevs[minor].recv_queue); MOD_INC_USE_COUNT; + capidevs[minor].nopen++; } else { - - if (!capidevs[minor].is_open) { - capidevs[minor].is_open = 1; - MOD_INC_USE_COUNT; - } + capidevs[minor].is_open++; + MOD_INC_USE_COUNT; } - return 0; } @@ -460,10 +496,13 @@ cdev->is_registered = 0; cdev->applid = 0; - while ((skb = skb_dequeue(&cdev->recv_queue)) != 0) + while ((skb = skb_dequeue(&cdev->recv_queue)) != 0) { kfree_skb(skb); + } + cdev->is_open = 0; + } else { + cdev->is_open--; } - cdev->is_open = 0; MOD_DEC_USE_COUNT; return 0; @@ -487,7 +526,82 @@ NULL, /* capi_fasync */ }; +/* -------- /proc functions ----------------------------------- */ +/* + * /proc/capi/capi20: + * minor opencount nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt + */ +static int proc_capidev_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct capidev *cp; + int i; + int len = 0; + off_t begin = 0; + + for (i=0; i < CAPI_MAXMINOR; i++) { + cp = &capidevs[i+1]; + if (cp->nopen == 0) continue; + len += sprintf(page+len, "%d %lu %lu %lu %lu %lu\n", + i+1, + cp->nopen, + cp->nrecvctlpkt, + cp->nrecvdatapkt, + cp->nsentctlpkt, + cp->nsentdatapkt); + if (len+begin > off+count) + goto endloop; + if (len+begin < off) { + begin += len; + len = 0; + } + } +endloop: + if (i >= CAPI_MAXMINOR) + *eof = 1; + if (off >= len+begin) + return 0; + *start = page + (begin-off); + return ((count < begin+len-off) ? count : begin+len-off); +} + +static struct procfsentries { + char *name; + mode_t mode; + int (*read_proc)(char *page, char **start, off_t off, + int count, int *eof, void *data); + struct proc_dir_entry *procent; +} procfsentries[] = { + /* { "capi", S_IFDIR, 0 }, */ + { "capi/capi20", 0 , proc_capidev_read_proc }, +}; + +static void proc_init(void) +{ + int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]); + int i; + + for (i=0; i < nelem; i++) { + struct procfsentries *p = procfsentries + i; + p->procent = create_proc_entry(p->name, p->mode, 0); + if (p->procent) p->procent->read_proc = p->read_proc; + } +} + +static void proc_exit(void) +{ + int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]); + int i; + + for (i=nelem-1; i >= 0; i--) { + struct procfsentries *p = procfsentries + i; + if (p->procent) { + remove_proc_entry(p->name, 0); + p->procent = 0; + } + } +} /* -------- init function and module interface ---------------------- */ #ifdef MODULE @@ -501,12 +615,12 @@ int capi_init(void) { -#if LINUX_VERSION_CODE >= 131841 +#ifdef COMPAT_HAS_NEW_WAITQ int j; #endif memset(capidevs, 0, sizeof(capidevs)); -#if LINUX_VERSION_CODE >= 131841 +#ifdef COMPAT_HAS_NEW_WAITQ for ( j = 0; j < CAPI_MAXMINOR+1; j++ ) { init_waitqueue_head(&capidevs[j].recv_wait); } @@ -522,13 +636,14 @@ unregister_chrdev(capi_major, "capi20"); return -EIO; } - + (void)proc_init(); return 0; } #ifdef MODULE void cleanup_module(void) { + (void)proc_exit(); unregister_chrdev(capi_major, "capi20"); (void) detach_capi_interface(&cuser); } diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/avmb1/capidev.h linux/drivers/isdn/avmb1/capidev.h --- v2.3.13/linux/drivers/isdn/avmb1/capidev.h Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/avmb1/capidev.h Thu Aug 12 09:42:33 1999 @@ -1,11 +1,33 @@ /* - * $Id: capidev.h,v 1.1 1997/03/04 21:50:30 calle Exp $ + * $Id: capidev.h,v 1.4 1999/07/01 15:26:32 calle Exp $ * * CAPI 2.0 Interface for Linux * * (c) Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: capidev.h,v $ + * Revision 1.4 1999/07/01 15:26:32 calle + * complete new version (I love it): + * + new hardware independed "capi_driver" interface that will make it easy to: + * - support other controllers with CAPI-2.0 (i.e. USB Controller) + * - write a CAPI-2.0 for the passive cards + * - support serial link CAPI-2.0 boxes. + * + wrote "capi_driver" for all supported cards. + * + "capi_driver" (supported cards) now have to be configured with + * make menuconfig, in the past all supported cards where included + * at once. + * + new and better informations in /proc/capi/ + * + new ioctl to switch trace of capi messages per controller + * using "avmcapictrl trace [contr] on|off|...." + * + complete testcircle with all supported cards and also the + * PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done. + * + * Revision 1.3 1999/07/01 08:22:58 keil + * compatibility macros now in + * + * Revision 1.2 1999/06/21 15:24:13 calle + * extend information in /proc. + * * Revision 1.1 1997/03/04 21:50:30 calle * Frirst version in isdn4linux * @@ -22,12 +44,18 @@ int is_registered; __u16 applid; struct sk_buff_head recv_queue; -#if LINUX_VERSION_CODE < 131841 - struct wait_queue *recv_wait; -#else +#ifdef COMPAT_HAS_NEW_WAITQ wait_queue_head_t recv_wait; +#else + struct wait_queue *recv_wait; #endif __u16 errcode; + /* Statistic */ + unsigned long nopen; + unsigned long nrecvctlpkt; + unsigned long nrecvdatapkt; + unsigned long nsentctlpkt; + unsigned long nsentdatapkt; }; #define CAPI_MAXMINOR CAPI_MAXAPPL diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/avmb1/capidrv.c linux/drivers/isdn/avmb1/capidrv.c --- v2.3.13/linux/drivers/isdn/avmb1/capidrv.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/isdn/avmb1/capidrv.c Thu Aug 12 09:42:33 1999 @@ -1,11 +1,67 @@ /* - * $Id: capidrv.c,v 1.13 1998/06/26 15:12:55 fritz Exp $ + * $Id: capidrv.c,v 1.26 1999/08/06 07:41:16 calle Exp $ * * ISDN4Linux Driver, using capi20 interface (kernelcapi) * * Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: capidrv.c,v $ + * Revision 1.26 1999/08/06 07:41:16 calle + * Added the "vbox patch". if (si1 == 1) si2 = 0; + * + * Revision 1.25 1999/08/04 10:10:11 calle + * Bugfix: corrected /proc functions, added structure for new AVM cards. + * + * Revision 1.24 1999/07/20 06:48:02 calle + * Bugfix: firmware version check for D2 trace was too restrictiv. + * + * Revision 1.23 1999/07/09 15:05:44 keil + * compat.h is now isdn_compat.h + * + * Revision 1.22 1999/07/06 07:24:14 calle + * Bugfix: call to kfree_skb in capidrv_signal was too early, + * thanks to Lars Heete . + * + * Revision 1.21 1999/07/01 15:26:34 calle + * complete new version (I love it): + * + new hardware independed "capi_driver" interface that will make it easy to: + * - support other controllers with CAPI-2.0 (i.e. USB Controller) + * - write a CAPI-2.0 for the passive cards + * - support serial link CAPI-2.0 boxes. + * + wrote "capi_driver" for all supported cards. + * + "capi_driver" (supported cards) now have to be configured with + * make menuconfig, in the past all supported cards where included + * at once. + * + new and better informations in /proc/capi/ + * + new ioctl to switch trace of capi messages per controller + * using "avmcapictrl trace [contr] on|off|...." + * + complete testcircle with all supported cards and also the + * PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done. + * + * Revision 1.20 1999/07/01 08:22:59 keil + * compatibility macros now in + * + * Revision 1.19 1999/06/29 16:16:54 calle + * Let ISDN_CMD_UNLOAD work with open isdn devices without crash again. + * Also right unlocking (ISDN_CMD_UNLOCK) is done now. + * isdnlog should check returncode of read(2) calls. + * + * Revision 1.18 1999/06/21 15:24:15 calle + * extend information in /proc. + * + * Revision 1.17 1999/06/10 16:53:55 calle + * Removing of module b1pci will now remove card from lower level. + * + * Revision 1.16 1999/05/31 11:50:33 calle + * Bugfix: In if_sendbuf, skb_push'ed DATA_B3 header was not skb_pull'ed + * on failure, result in data block with DATA_B3 header transmitted + * + * Revision 1.15 1999/05/25 21:26:16 calle + * Include CAPI-Channelallocation (leased lines) from the 2.0 tree. + * + * Revision 1.14 1999/05/22 07:55:06 calle + * Added *V110* to AVM B1 driver. + * * Revision 1.13 1998/06/26 15:12:55 fritz * Added handling of STAT_ICALL with incomplete CPN. * Added AT&L for ttyI emulator. @@ -96,15 +152,18 @@ #include #include #include +#include #include #include +#include +#include -#include "compat.h" +#include #include "capiutil.h" #include "capicmd.h" #include "capidrv.h" -static char *revision = "$Revision: 1.13 $"; +static char *revision = "$Revision: 1.26 $"; int debugmode = 0; MODULE_AUTHOR("Carsten Paeth "); @@ -160,6 +219,7 @@ __u16 msgid; /* to identfy CONNECT_CONF */ int chan; int state; + int leasedline; struct capidrv_ncci { struct capidrv_ncci *next; struct capidrv_plci *plcip; @@ -194,6 +254,12 @@ __u16 appid; int ncontr; struct capidrv_contr *contr_list; + + /* statistic */ + unsigned long nrecvctlpkt; + unsigned long nrecvdatapkt; + unsigned long nsentctlpkt; + unsigned long nsentdatapkt; }; typedef struct capidrv_plci capidrv_plci; @@ -224,6 +290,12 @@ return 0; case ISDN_PROTO_L2_TRANS: return 1; + case ISDN_PROTO_L2_V11096: + case ISDN_PROTO_L2_V11019: + case ISDN_PROTO_L2_V11038: + return 2; + case ISDN_PROTO_L2_FAX: + return 4; } } @@ -237,7 +309,12 @@ return 0; case ISDN_PROTO_L2_HDLC: case ISDN_PROTO_L2_TRANS: + case ISDN_PROTO_L2_V11096: + case ISDN_PROTO_L2_V11019: + case ISDN_PROTO_L2_V11038: return 1; + case ISDN_PROTO_L2_FAX: + return 4; } } @@ -249,8 +326,45 @@ case ISDN_PROTO_L2_X75BUI: case ISDN_PROTO_L2_HDLC: case ISDN_PROTO_L2_TRANS: + case ISDN_PROTO_L2_V11096: + case ISDN_PROTO_L2_V11019: + case ISDN_PROTO_L2_V11038: default: return 0; + case ISDN_PROTO_L2_FAX: + return 4; + } +} + +static _cstruct b1config_sync_v110(__u16 rate) +{ + /* CAPI-Spec "B1 Configuration" */ + static unsigned char buf[9]; + buf[0] = 8; /* len */ + /* maximum bitrate */ + buf[1] = rate & 0xff; buf[2] = (rate >> 8) & 0xff; + buf[3] = buf[4] = 0; /* reserved, bits per character */ + buf[5] = buf[6] = 0; /* reserved, parity */ + buf[7] = buf[9] = 0; /* reserved, stop bits */ + return buf; +} + +static _cstruct b1config(int l2, int l3) +{ + switch (l2) { + case ISDN_PROTO_L2_X75I: + case ISDN_PROTO_L2_X75UI: + case ISDN_PROTO_L2_X75BUI: + case ISDN_PROTO_L2_HDLC: + case ISDN_PROTO_L2_TRANS: + default: + return 0; + case ISDN_PROTO_L2_V11096: + return b1config_sync_v110(9600); + case ISDN_PROTO_L2_V11019: + return b1config_sync_v110(19200); + case ISDN_PROTO_L2_V11038: + return b1config_sync_v110(38400); } } @@ -522,9 +636,10 @@ size_t len; capi_cmsg2message(cmsg, cmsg->buf); len = CAPIMSG_LEN(cmsg->buf); - skb = dev_alloc_skb(len); + skb = alloc_skb(len, GFP_ATOMIC); memcpy(skb_put(skb, len), cmsg->buf, len); (*capifuncs->capi_put_message) (global.appid, skb); + global.nsentctlpkt++; } /* -------- state machine -------------------------------------------- */ @@ -917,6 +1032,13 @@ cmd.parm.setup.si2, cmd.parm.setup.eazmsn); + if (cmd.parm.setup.si1 == 1 && cmd.parm.setup.si2 != 0) { + printk(KERN_INFO "capidrv-%d: patching si2=%d to 0 for VBOX\n", + card->contrnr, + cmd.parm.setup.si2); + cmd.parm.setup.si2 = 0; + } + switch (card->interface.statcallb(&cmd)) { case 0: case 3: @@ -1353,6 +1475,7 @@ printk(KERN_ERR "capidrv: %s from unknown controller 0x%x\n", capi_cmd2str(cmsg->Command, cmsg->Subcommand), cmsg->adr.adrController & 0x7f); + kfree_skb(skb); return; } if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI))) { @@ -1377,13 +1500,14 @@ while ((*capifuncs->capi_get_message) (global.appid, &skb) == CAPI_NOERROR) { capi_message2cmsg(&s_cmsg, skb->data); - if (debugmode > 1) + if (debugmode > 2) printk(KERN_DEBUG "capidrv_signal: applid=%d %s\n", applid, capi_cmsg2str(&s_cmsg)); if (s_cmsg.Command == CAPI_DATA_B3 && s_cmsg.Subcommand == CAPI_IND) { handle_data(&s_cmsg, skb); + global.nrecvdatapkt++; continue; } if ((s_cmsg.adr.adrController & 0xffffff00) == 0) @@ -1392,8 +1516,13 @@ handle_plci(&s_cmsg); else handle_ncci(&s_cmsg); - + /* + * data of skb used in s_cmsg, + * free data when s_cmsg is not used again + * thanks to Lars Heete + */ kfree_skb(skb); + global.nrecvctlpkt++; } } @@ -1459,6 +1588,11 @@ static int capidrv_ioctl(isdn_ctrl * c, capidrv_contr * card) { switch (c->arg) { + case 1: + debugmode = (int)(*((unsigned int *)c->parm.num)); + printk(KERN_DEBUG "capidrv-%d: debugmode=%d\n", + card->contrnr, debugmode); + return 0; default: printk(KERN_DEBUG "capidrv-%d: capidrv_ioctl(%ld) called ??\n", card->contrnr, c->arg); @@ -1467,11 +1601,103 @@ return -EINVAL; } +/* + * Handle leased lines (CAPI-Bundling) + */ + +struct internal_bchannelinfo { + unsigned short channelalloc; + unsigned short operation; + unsigned char cmask[31]; +}; + +static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep) +{ + unsigned long bmask = 0; + int active = !0; + char *s; + int i; + + if (strncmp(teln, "FV:", 3) != 0) + return 1; + s = teln + 3; + while (*s && *s == ' ') s++; + if (!*s) return -2; + if (*s == 'p' || *s == 'P') { + active = 0; + s++; + } + if (*s == 'a' || *s == 'A') { + active = !0; + s++; + } + while (*s) { + int digit1 = 0; + int digit2 = 0; + if (!isdigit(*s)) return -3; + while (isdigit(*s)) { digit1 = digit1*10 + (*s - '0'); s++; } + if (digit1 <= 0 && digit1 > 30) return -4; + if (*s == 0 || *s == ',' || *s == ' ') { + bmask |= (1 << digit1); + digit1 = 0; + if (*s) s++; + continue; + } + if (*s != '-') return -5; + s++; + if (!isdigit(*s)) return -3; + while (isdigit(*s)) { digit2 = digit2*10 + (*s - '0'); s++; } + if (digit2 <= 0 && digit2 > 30) return -4; + if (*s == 0 || *s == ',' || *s == ' ') { + if (digit1 > digit2) + for (i = digit2; i <= digit1 ; i++) + bmask |= (1 << i); + else + for (i = digit1; i <= digit2 ; i++) + bmask |= (1 << i); + digit1 = digit2 = 0; + if (*s) s++; + continue; + } + return -6; + } + if (activep) *activep = active; + if (bmaskp) *bmaskp = bmask; + return 0; +} + +static int FVteln2capi20(char *teln, __u8 AdditionalInfo[1+2+2+31]) +{ + unsigned long bmask; + int active; + int rc, i; + + rc = decodeFVteln(teln, &bmask, &active); + if (rc) return rc; + /* Length */ + AdditionalInfo[0] = 2+2+31; + /* Channel: 3 => use channel allocation */ + AdditionalInfo[1] = 3; AdditionalInfo[2] = 0; + /* Operation: 0 => DTE mode, 1 => DCE mode */ + if (active) { + AdditionalInfo[3] = 0; AdditionalInfo[4] = 0; + } else { + AdditionalInfo[3] = 1; AdditionalInfo[4] = 0; + } + /* Channel mask array */ + AdditionalInfo[5] = 0; /* no D-Channel */ + for (i=1; i <= 30; i++) + AdditionalInfo[5+i] = (bmask & (1 << i)) ? 0xff : 0; + return 0; +} + static int capidrv_command(isdn_ctrl * c, capidrv_contr * card) { isdn_ctrl cmd; struct capidrv_bchan *bchan; struct capidrv_plci *plcip; + __u8 AdditionalInfo[1+2+2+31]; + int rc, isleasedline = 0; if (c->command == ISDN_CMD_IOCTL) return capidrv_ioctl(c, card); @@ -1508,15 +1734,25 @@ strncpy(bchan->num, c->parm.setup.phone, sizeof(bchan->num)); strncpy(bchan->mynum, c->parm.setup.eazmsn, sizeof(bchan->mynum)); - - calling[0] = strlen(bchan->mynum) + 2; - calling[1] = 0; - calling[2] = 0x80; - strncpy(calling + 3, bchan->mynum, ISDN_MSNLEN); - - called[0] = strlen(bchan->num) + 1; - called[1] = 0x80; - strncpy(called + 2, bchan->num, ISDN_MSNLEN); + rc = FVteln2capi20(bchan->num, AdditionalInfo); + isleasedline = (rc == 0); + if (rc < 0) + printk(KERN_ERR "capidrv-%d: WARNING: illegal leased linedefinition \"%s\"\n", card->contrnr, bchan->num); + + if (isleasedline) { + calling[0] = 0; + called[0] = 0; + if (debugmode) + printk(KERN_DEBUG "capidrv-%d: connecting leased line\n", card->contrnr); + } else { + calling[0] = strlen(bchan->mynum) + 2; + calling[1] = 0; + calling[2] = 0x80; + strncpy(calling + 3, bchan->mynum, ISDN_MSNLEN); + called[0] = strlen(bchan->num) + 1; + called[1] = 0x80; + strncpy(called + 2, bchan->num, ISDN_MSNLEN); + } capi_fill_CONNECT_REQ(&cmdcmsg, global.appid, @@ -1530,13 +1766,14 @@ b1prot(bchan->l2, bchan->l3), /* B1protocol */ b2prot(bchan->l2, bchan->l3), /* B2protocol */ b3prot(bchan->l2, bchan->l3), /* B3protocol */ - 0, /* B1configuration */ + b1config(bchan->l2, bchan->l3), /* B1configuration */ 0, /* B2configuration */ 0, /* B3configuration */ 0, /* BC */ 0, /* LLC */ 0, /* HLC */ - 0, /* BChannelinformation */ + /* BChannelinformation */ + isleasedline ? AdditionalInfo : 0, 0, /* Keypadfacility */ 0, /* Useruserdata */ 0 /* Facilitydataarray */ @@ -1549,6 +1786,7 @@ return -1; } plcip->msgid = cmdcmsg.Messagenumber; + plcip->leasedline = isleasedline; plci_change_state(card, plcip, EV_PLCI_CONNECT_REQ); send_message(card, &cmdcmsg); return 0; @@ -1570,7 +1808,7 @@ b1prot(bchan->l2, bchan->l3), /* B1protocol */ b2prot(bchan->l2, bchan->l3), /* B2protocol */ b3prot(bchan->l2, bchan->l3), /* B3protocol */ - 0, /* B1configuration */ + b1config(bchan->l2, bchan->l3), /* B1configuration */ 0, /* B2configuration */ 0, /* B3configuration */ 0, /* ConnectedNumber */ @@ -1752,6 +1990,9 @@ card->contrnr, id); return 0; } + if (debugmode > 1) + printk(KERN_DEBUG "capidrv-%d: sendbuf len=%d skb=%p doack=%d\n", + card->contrnr, len, skb, doack); bchan = &card->bchans[channel % card->nbchan]; nccip = bchan->nccip; if (!nccip || nccip->state != ST_NCCI_ACTIVE) { @@ -1774,23 +2015,23 @@ capi_cmsg2message(&sendcmsg, sendcmsg.buf); msglen = CAPIMSG_LEN(sendcmsg.buf); if (skb_headroom(skb) < msglen) { - struct sk_buff *nskb = dev_alloc_skb(msglen + skb->len); + struct sk_buff *nskb = skb_realloc_headroom(skb, msglen); if (!nskb) { printk(KERN_ERR "capidrv-%d: if_sendbuf: no memory\n", card->contrnr); (void)capidrv_del_ack(nccip, datahandle); return 0; } -#if 0 - printk(KERN_DEBUG "capidrv-%d: only %d bytes headroom\n", - card->contrnr, skb_headroom(skb)); +#if 1 + printk(KERN_DEBUG "capidrv-%d: only %d bytes headroom, need %d\n", + card->contrnr, skb_headroom(skb), msglen); #endif - memcpy(skb_put(nskb, msglen), sendcmsg.buf, msglen); - memcpy(skb_put(nskb, skb->len), skb->data, skb->len); + memcpy(skb_push(nskb, msglen), sendcmsg.buf, msglen); errcode = (*capifuncs->capi_put_message) (global.appid, nskb); if (errcode == CAPI_NOERROR) { dev_kfree_skb(skb); nccip->datahandle++; + global.nsentdatapkt++; return len; } (void)capidrv_del_ack(nccip, datahandle); @@ -1801,8 +2042,10 @@ errcode = (*capifuncs->capi_put_message) (global.appid, skb); if (errcode == CAPI_NOERROR) { nccip->datahandle++; + global.nsentdatapkt++; return len; } + skb_pull(skb, msglen); (void)capidrv_del_ack(nccip, datahandle); return errcode == CAPI_SENDQUEUEFULL ? 0 : -1; } @@ -1847,8 +2090,8 @@ return; } if (strstr(manufacturer, "AVM") == 0) { - printk(KERN_ERR "%s: not from AVM, no d-channel trace possible\n", - card->name); + printk(KERN_ERR "%s: not from AVM, no d-channel trace possible (%s)\n", + card->name, manufacturer); return; } errcode = (*capifuncs->capi_get_version)(contr, &version); @@ -1862,7 +2105,7 @@ avmversion[1] |= (version.minormanuversion >> 4) & 0x0f; avmversion[2] |= version.minormanuversion & 0x0f; - if (avmversion[0] > 3 || (avmversion[0] == 3 && avmversion[1] > 6)) { + if (avmversion[0] > 3 || (avmversion[0] == 3 && avmversion[1] > 5)) { printk(KERN_INFO "%s: D2 trace enabled\n", card->name); capi_fill_MANUFACTURER_REQ(&cmdcmsg, global.appid, card->msgid++, @@ -1884,6 +2127,51 @@ send_message(card, &cmdcmsg); } +static void disable_dchannel_trace(capidrv_contr *card) +{ + __u8 manufacturer[CAPI_MANUFACTURER_LEN]; + capi_version version; + __u16 contr = card->contrnr; + __u16 errcode; + __u16 avmversion[3]; + + errcode = (*capifuncs->capi_get_manufacturer)(contr, manufacturer); + if (errcode != CAPI_NOERROR) { + printk(KERN_ERR "%s: can't get manufacturer (0x%x)\n", + card->name, errcode); + return; + } + if (strstr(manufacturer, "AVM") == 0) { + printk(KERN_ERR "%s: not from AVM, no d-channel trace possible (%s)\n", + card->name, manufacturer); + return; + } + errcode = (*capifuncs->capi_get_version)(contr, &version); + if (errcode != CAPI_NOERROR) { + printk(KERN_ERR "%s: can't get version (0x%x)\n", + card->name, errcode); + return; + } + avmversion[0] = (version.majormanuversion >> 4) & 0x0f; + avmversion[1] = (version.majormanuversion << 4) & 0xf0; + avmversion[1] |= (version.minormanuversion >> 4) & 0x0f; + avmversion[2] |= version.minormanuversion & 0x0f; + + if (avmversion[0] > 3 || (avmversion[0] == 3 && avmversion[1] > 5)) { + printk(KERN_INFO "%s: D2 trace disabled\n", card->name); + } else { + printk(KERN_INFO "%s: D3 trace disabled\n", card->name); + } + capi_fill_MANUFACTURER_REQ(&cmdcmsg, global.appid, + card->msgid++, + contr, + 0x214D5641, /* ManuID */ + 0, /* Class */ + 1, /* Function */ + (_cstruct)"\004\000\000\000\000"); + send_message(card, &cmdcmsg); +} + static int capidrv_addcontr(__u16 contr, struct capi_profile *profp) { capidrv_contr *card; @@ -1920,6 +2208,13 @@ ISDN_FEATURE_L2_HDLC | ISDN_FEATURE_L2_TRANS | ISDN_FEATURE_L3_TRANS | + ISDN_FEATURE_L2_V11096 | + ISDN_FEATURE_L2_V11019 | + ISDN_FEATURE_L2_V11038 | +#if 0 + ISDN_FEATURE_L2_FAX | + ISDN_FEATURE_L3_FAX | +#endif ISDN_FEATURE_P_UNKNOWN; card->interface.hl_hdrlen = 22; /* len of DATA_B3_REQ */ strncpy(card->interface.id, id, sizeof(card->interface.id) - 1); @@ -1964,8 +2259,7 @@ printk(KERN_INFO "%s: now up (%d B channels)\n", card->name, card->nbchan); - if (card->nbchan == 2) /* no T1 */ - enable_dchannel_trace(card); + enable_dchannel_trace(card); return 0; } @@ -1985,6 +2279,15 @@ return -1; } card = *pp; + + if (debugmode) + printk(KERN_DEBUG "capidrv-%d: id=%d unloading\n", + card->contrnr, card->myid); + + cmd.command = ISDN_STAT_UNLOAD; + cmd.driver = card->myid; + card->interface.statcallb(&cmd); + *pp = (*pp)->next; global.ncontr--; @@ -1998,10 +2301,6 @@ } kfree(card->bchans); - cmd.command = ISDN_STAT_UNLOAD; - cmd.driver = card->myid; - card->interface.statcallb(&cmd); - printk(KERN_INFO "%s: now down.\n", card->name); kfree(card); @@ -2012,16 +2311,78 @@ static void lower_callback(unsigned int cmd, __u16 contr, void *data) { + switch (cmd) { case KCI_CONTRUP: + printk(KERN_INFO "capidrv: controller %hu up\n", contr); (void) capidrv_addcontr(contr, (capi_profile *) data); break; case KCI_CONTRDOWN: + printk(KERN_INFO "capidrv: controller %hu down\n", contr); (void) capidrv_delcontr(contr); break; } } +/* + * /proc/capi/capidrv: + * nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt + */ +static int proc_capidrv_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = 0; + + len += sprintf(page+len, "%lu %lu %lu %lu\n", + global.nrecvctlpkt, + global.nrecvdatapkt, + global.nsentctlpkt, + global.nsentdatapkt); + if (off+count >= len) + *eof = 1; + if (len < off) + return 0; + *start = page + off; + return ((count < len-off) ? count : len-off); +} + +static struct procfsentries { + char *name; + mode_t mode; + int (*read_proc)(char *page, char **start, off_t off, + int count, int *eof, void *data); + struct proc_dir_entry *procent; +} procfsentries[] = { + /* { "capi", S_IFDIR, 0 }, */ + { "capi/capidrv", 0 , proc_capidrv_read_proc }, +}; + +static void proc_init(void) +{ + int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]); + int i; + + for (i=0; i < nelem; i++) { + struct procfsentries *p = procfsentries + i; + p->procent = create_proc_entry(p->name, p->mode, 0); + if (p->procent) p->procent->read_proc = p->read_proc; + } +} + +static void proc_exit(void) +{ + int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]); + int i; + + for (i=nelem-1; i >= 0; i--) { + struct procfsentries *p = procfsentries + i; + if (p->procent) { + remove_proc_entry(p->name, 0); + p->procent = 0; + } + } +} + static struct capi_interface_user cuser = { "capidrv", lower_callback @@ -2077,6 +2438,7 @@ continue; (void) capidrv_addcontr(contr, &profile); } + proc_init(); return 0; } @@ -2098,11 +2460,13 @@ for (card = global.contr_list; card; card = next) { next = card->next; + disable_dchannel_trace(card); capidrv_delcontr(card->contrnr); } (void) (*capifuncs->capi_release) (global.appid); detach_capi_interface(&cuser); + proc_exit(); printk(KERN_NOTICE "capidrv: Rev%s: unloaded\n", rev); } diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/avmb1/capilli.h linux/drivers/isdn/avmb1/capilli.h --- v2.3.13/linux/drivers/isdn/avmb1/capilli.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/avmb1/capilli.h Thu Aug 12 09:42:33 1999 @@ -0,0 +1,110 @@ +/* + * $Id: capilli.h,v 1.4 1999/07/23 08:51:05 calle Exp $ + * + * Kernel CAPI 2.0 Driver Interface for Linux + * + * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * + */ +#ifndef __CAPILLI_H__ +#define __CAPILLI_H__ + +typedef struct capiloaddatapart { + int user; /* data in userspace ? */ + int len; + unsigned char *data; +} capiloaddatapart; + +typedef struct capiloaddata { + capiloaddatapart firmware; + capiloaddatapart configuration; +} capiloaddata; + +typedef struct capicardparams { + unsigned int port; + unsigned irq; + int cardtype; + int cardnr; + unsigned int membase; +} capicardparams; + +struct capi_driver; + +struct capi_ctr { + struct capi_ctr *next; /* next ctr of same driver */ + struct capi_driver *driver; + int cnr; /* controller number */ + char name[32]; /* name of controller */ + volatile unsigned short cardstate; /* controller state */ + volatile int blocked; /* output blocked */ + int traceflag; /* capi trace */ + + void *driverdata; /* driver specific */ + + /* filled before calling ready callback */ + __u8 manu[CAPI_MANUFACTURER_LEN]; /* CAPI_GET_MANUFACTURER */ + capi_version version; /* CAPI_GET_VERSION */ + capi_profile profile; /* CAPI_GET_PROFILE */ + __u8 serial[CAPI_SERIAL_LEN]; /* CAPI_GET_SERIAL */ + + /* functions */ + void (*ready)(struct capi_ctr * card); + void (*reseted)(struct capi_ctr * card); + void (*suspend_output)(struct capi_ctr * card); + void (*resume_output)(struct capi_ctr * card); + void (*handle_capimsg)(struct capi_ctr * card, + __u16 appl, struct sk_buff *skb); + void (*appl_registered)(struct capi_ctr * card, __u16 appl); + void (*appl_released)(struct capi_ctr * card, __u16 appl); + + void (*new_ncci)(struct capi_ctr * card, + __u16 appl, __u32 ncci, __u32 winsize); + void (*free_ncci)(struct capi_ctr * card, __u16 appl, __u32 ncci); + + /* management information for kcapi */ + + unsigned long nrecvctlpkt; + unsigned long nrecvdatapkt; + unsigned long nsentctlpkt; + unsigned long nsentdatapkt; + + struct proc_dir_entry *procent; + char procfn[128]; +}; + +struct capi_driver_interface { + struct capi_ctr *(*attach_ctr)(struct capi_driver *driver, char *name, void *data); + int (*detach_ctr)(struct capi_ctr *); +}; + +struct capi_driver { + char name[32]; /* driver name */ + char revision[32]; + int (*load_firmware)(struct capi_ctr *, capiloaddata *); + void (*reset_ctr)(struct capi_ctr *); + void (*remove_ctr)(struct capi_ctr *); + void (*register_appl)(struct capi_ctr *, __u16 appl, + capi_register_params *); + void (*release_appl)(struct capi_ctr *, __u16 appl); + void (*send_message)(struct capi_ctr *, struct sk_buff *skb); + + char *(*procinfo)(struct capi_ctr *); + int (*ctr_read_proc)(char *page, char **start, off_t off, + int count, int *eof, struct capi_ctr *card); + int (*driver_read_proc)(char *page, char **start, off_t off, + int count, int *eof, struct capi_driver *driver); + + int (*add_card)(struct capi_driver *driver, capicardparams *data); + + /* intitialized by kcapi */ + struct capi_ctr *controller; /* list of controllers */ + struct capi_driver *next; + int ncontroller; + struct proc_dir_entry *procent; + char procfn[128]; +}; + +struct capi_driver_interface *attach_capi_driver(struct capi_driver *driver); +void detach_capi_driver(struct capi_driver *driver); + +#endif /* __CAPILLI_H__ */ diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/avmb1/capiutil.c linux/drivers/isdn/avmb1/capiutil.c --- v2.3.13/linux/drivers/isdn/avmb1/capiutil.c Wed Apr 1 16:20:57 1998 +++ linux/drivers/isdn/avmb1/capiutil.c Thu Aug 12 09:42:33 1999 @@ -1,5 +1,5 @@ /* - * $Id: capiutil.c,v 1.6 1997/11/04 06:12:12 calle Exp $ + * $Id: capiutil.c,v 1.9 1999/07/09 15:05:46 keil Exp $ * * CAPI 2.0 convert capi message to capi message struct * @@ -7,6 +7,28 @@ * Rewritten for Linux 1996 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: capiutil.c,v $ + * Revision 1.9 1999/07/09 15:05:46 keil + * compat.h is now isdn_compat.h + * + * Revision 1.8 1999/07/01 15:26:37 calle + * complete new version (I love it): + * + new hardware independed "capi_driver" interface that will make it easy to: + * - support other controllers with CAPI-2.0 (i.e. USB Controller) + * - write a CAPI-2.0 for the passive cards + * - support serial link CAPI-2.0 boxes. + * + wrote "capi_driver" for all supported cards. + * + "capi_driver" (supported cards) now have to be configured with + * make menuconfig, in the past all supported cards where included + * at once. + * + new and better informations in /proc/capi/ + * + new ioctl to switch trace of capi messages per controller + * using "avmcapictrl trace [contr] on|off|...." + * + complete testcircle with all supported cards and also the + * PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done. + * + * Revision 1.7 1999/07/01 08:23:01 keil + * compatibility macros now in + * * Revision 1.6 1997/11/04 06:12:12 calle * capi.c: new read/write in file_ops since 2.1.60 * capidrv.c: prepared isdnlog interface for d2-trace in newer firmware. @@ -48,7 +70,7 @@ #include #include -#include "compat.h" +#include #include "capiutil.h" /* from CAPI2.0 DDK AVM Berlin GmbH */ diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/avmb1/kcapi.c linux/drivers/isdn/avmb1/kcapi.c --- v2.3.13/linux/drivers/isdn/avmb1/kcapi.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/avmb1/kcapi.c Thu Aug 12 09:42:33 1999 @@ -0,0 +1,1553 @@ +/* + * $Id: kcapi.c,v 1.6 1999/07/20 06:41:49 calle Exp $ + * + * Kernel CAPI 2.0 Module + * + * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * + * $Log: kcapi.c,v $ + * Revision 1.6 1999/07/20 06:41:49 calle + * Bugfix: After the redesign of the AVM B1 driver, the driver didn't even + * compile, if not selected as modules. + * + * Revision 1.5 1999/07/09 15:05:48 keil + * compat.h is now isdn_compat.h + * + * Revision 1.4 1999/07/08 14:15:17 calle + * Forgot to count down ncards in drivercb_detach_ctr. + * + * Revision 1.3 1999/07/06 07:42:02 calle + * - changes in /proc interface + * - check and changed calls to [dev_]kfree_skb and [dev_]alloc_skb. + * + * Revision 1.2 1999/07/05 15:09:52 calle + * - renamed "appl_release" to "appl_released". + * - version und profile data now cleared on controller reset + * - extended /proc interface, to allow driver and controller specific + * informations to include by driver hackers. + * + * Revision 1.1 1999/07/01 15:26:42 calle + * complete new version (I love it): + * + new hardware independed "capi_driver" interface that will make it easy to: + * - support other controllers with CAPI-2.0 (i.e. USB Controller) + * - write a CAPI-2.0 for the passive cards + * - support serial link CAPI-2.0 boxes. + * + wrote "capi_driver" for all supported cards. + * + "capi_driver" (supported cards) now have to be configured with + * make menuconfig, in the past all supported cards where included + * at once. + * + new and better informations in /proc/capi/ + * + new ioctl to switch trace of capi messages per controller + * using "avmcapictrl trace [contr] on|off|...." + * + complete testcircle with all supported cards and also the + * PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done. + * + */ +#define CONFIG_AVMB1_COMPAT + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "capicmd.h" +#include "capiutil.h" +#include "capilli.h" +#ifdef CONFIG_AVMB1_COMPAT +#include +#endif + +static char *revision = "$Revision: 1.6 $"; + +/* ------------------------------------------------------------- */ + +#define CARD_FREE 0 +#define CARD_DETECTED 1 +#define CARD_LOADING 2 +#define CARD_RUNNING 3 + +/* ------------------------------------------------------------- */ + +int showcapimsgs = 0; + +MODULE_AUTHOR("Carsten Paeth "); +MODULE_PARM(showcapimsgs, "0-4i"); + +/* ------------------------------------------------------------- */ + +struct msgidqueue { + struct msgidqueue *next; + __u16 msgid; +}; + +struct capi_ncci { + struct capi_ncci *next; + __u16 applid; + __u32 ncci; + __u32 winsize; + int nmsg; + struct msgidqueue *msgidqueue; + struct msgidqueue *msgidlast; + struct msgidqueue *msgidfree; + struct msgidqueue msgidpool[CAPI_MAXDATAWINDOW]; +}; + +struct capi_appl { + __u16 applid; + capi_register_params rparam; + int releasing; + __u32 param; + void (*signal) (__u16 applid, __u32 param); + struct sk_buff_head recv_queue; + int nncci; + struct capi_ncci *nccilist; + + unsigned long nrecvctlpkt; + unsigned long nrecvdatapkt; + unsigned long nsentctlpkt; + unsigned long nsentdatapkt; +}; + +/* ------------------------------------------------------------- */ + +static struct capi_version driver_version = {2, 0, 1, 1<<4}; +static char driver_serial[CAPI_SERIAL_LEN] = "4711"; +static char capi_manufakturer[64] = "AVM Berlin"; + +#define APPL(a) (&applications[(a)-1]) +#define VALID_APPLID(a) ((a) && (a) <= CAPI_MAXAPPL && APPL(a)->applid == a) +#define APPL_IS_FREE(a) (APPL(a)->applid == 0) +#define APPL_MARK_FREE(a) do{ APPL(a)->applid=0; MOD_DEC_USE_COUNT; }while(0); +#define APPL_MARK_USED(a) do{ APPL(a)->applid=(a); MOD_INC_USE_COUNT; }while(0); + +#define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f) + +#define VALID_CARD(c) ((c) > 0 && (c) <= CAPI_MAXCONTR) +#define CARD(c) (&cards[(c)-1]) +#define CARDNR(cp) (((cp)-cards)+1) + +static struct capi_appl applications[CAPI_MAXAPPL]; +static struct capi_ctr cards[CAPI_MAXCONTR]; +static int ncards = 0; +static struct sk_buff_head recv_queue; +static struct capi_interface_user *capi_users = 0; +static struct capi_driver *drivers; +#ifdef CONFIG_AVMB1_COMPAT +static struct capi_driver *b1isa_driver; +static struct capi_driver *t1isa_driver; +#endif +static long notify_up_set = 0; +static long notify_down_set = 0; + +static struct tq_struct tq_state_notify; +static struct tq_struct tq_recv_notify; + +/* -------- util functions ------------------------------------ */ + +static char *cardstate2str(unsigned short cardstate) +{ + switch (cardstate) { + default: + case CARD_FREE: return "free"; + case CARD_DETECTED: return "detected"; + case CARD_LOADING: return "loading"; + case CARD_RUNNING: return "running"; + } +} + +static inline int capi_cmd_valid(__u8 cmd) +{ + switch (cmd) { + case CAPI_ALERT: + case CAPI_CONNECT: + case CAPI_CONNECT_ACTIVE: + case CAPI_CONNECT_B3_ACTIVE: + case CAPI_CONNECT_B3: + case CAPI_CONNECT_B3_T90_ACTIVE: + case CAPI_DATA_B3: + case CAPI_DISCONNECT_B3: + case CAPI_DISCONNECT: + case CAPI_FACILITY: + case CAPI_INFO: + case CAPI_LISTEN: + case CAPI_MANUFACTURER: + case CAPI_RESET_B3: + case CAPI_SELECT_B_PROTOCOL: + return 1; + } + return 0; +} + +static inline int capi_subcmd_valid(__u8 subcmd) +{ + switch (subcmd) { + case CAPI_REQ: + case CAPI_CONF: + case CAPI_IND: + case CAPI_RESP: + return 1; + } + return 0; +} + +/* -------- /proc functions ----------------------------------- */ +/* + * /proc/capi/applications: + * applid l3cnt dblkcnt dblklen #ncci recvqueuelen + */ +static int proc_applications_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct capi_appl *ap; + int i; + int len = 0; + off_t begin = 0; + + for (i=0; i < CAPI_MAXAPPL; i++) { + ap = &applications[i]; + if (ap->applid == 0) continue; + len += sprintf(page+len, "%u %d %d %d %d %d\n", + ap->applid, + ap->rparam.level3cnt, + ap->rparam.datablkcnt, + ap->rparam.datablklen, + ap->nncci, + skb_queue_len(&ap->recv_queue)); + if (len+begin > off+count) + goto endloop; + if (len+begin < off) { + begin += len; + len = 0; + } + } +endloop: + if (i >= CAPI_MAXAPPL) + *eof = 1; + if (off >= len+begin) + return 0; + *start = page + (begin-off); + return ((count < begin+len-off) ? count : begin+len-off); +} + +/* + * /proc/capi/ncci: + * applid ncci winsize nblk + */ +static int proc_ncci_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct capi_appl *ap; + struct capi_ncci *np; + int i; + int len = 0; + off_t begin = 0; + + for (i=0; i < CAPI_MAXAPPL; i++) { + ap = &applications[i]; + if (ap->applid == 0) continue; + for (np = ap->nccilist; np; np = np->next) { + len += sprintf(page+len, "%d 0x%x %d %d\n", + np->applid, + np->ncci, + np->winsize, + np->nmsg); + if (len+begin > off+count) + goto endloop; + if (len+begin < off) { + begin += len; + len = 0; + } + } + } +endloop: + if (i >= CAPI_MAXAPPL) + *eof = 1; + if (off >= len+begin) + return 0; + *start = page + (begin-off); + return ((count < begin+len-off) ? count : begin+len-off); +} + +/* + * /proc/capi/driver: + * driver ncontroller + */ +static int proc_driver_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct capi_driver *driver; + int len = 0; + off_t begin = 0; + + for (driver = drivers; driver; driver = driver->next) { + len += sprintf(page+len, "%-32s %d %s\n", + driver->name, + driver->ncontroller, + driver->revision); + if (len+begin > off+count) + goto endloop; + if (len+begin < off) { + begin += len; + len = 0; + } + } +endloop: + if (!driver) + *eof = 1; + if (off >= len+begin) + return 0; + *start = page + (begin-off); + return ((count < begin+len-off) ? count : begin+len-off); +} + +/* + * /proc/capi/users: + * name + */ +static int proc_users_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct capi_interface_user *cp; + int len = 0; + off_t begin = 0; + + for (cp = capi_users; cp ; cp = cp->next) { + len += sprintf(page+len, "%s\n", cp->name); + if (len+begin > off+count) + goto endloop; + if (len+begin < off) { + begin += len; + len = 0; + } + } +endloop: + if (cp == 0) + *eof = 1; + if (off >= len+begin) + return 0; + *start = page + (begin-off); + return ((count < begin+len-off) ? count : begin+len-off); +} + +/* + * /proc/capi/controller: + * cnr driver cardstate name driverinfo + */ +static int proc_controller_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct capi_ctr *cp; + int i; + int len = 0; + off_t begin = 0; + + for (i=0; i < CAPI_MAXCONTR; i++) { + cp = &cards[i]; + if (cp->cardstate == CARD_FREE) continue; + len += sprintf(page+len, "%d %-10s %-8s %-16s %s\n", + cp->cnr, cp->driver->name, + cardstate2str(cp->cardstate), + cp->name, + cp->driver->procinfo ? cp->driver->procinfo(cp) : "" + ); + if (len+begin > off+count) + goto endloop; + if (len+begin < off) { + begin += len; + len = 0; + } + } +endloop: + if (i >= CAPI_MAXCONTR) + *eof = 1; + if (off >= len+begin) + return 0; + *start = page + (begin-off); + return ((count < begin+len-off) ? count : begin+len-off); +} + +/* + * /proc/capi/applstats: + * applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt + */ +static int proc_applstats_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct capi_appl *ap; + int i; + int len = 0; + off_t begin = 0; + + for (i=0; i < CAPI_MAXAPPL; i++) { + ap = &applications[i]; + if (ap->applid == 0) continue; + len += sprintf(page+len, "%u %lu %lu %lu %lu\n", + ap->applid, + ap->nrecvctlpkt, + ap->nrecvdatapkt, + ap->nsentctlpkt, + ap->nsentdatapkt); + if (len+begin > off+count) + goto endloop; + if (len+begin < off) { + begin += len; + len = 0; + } + } +endloop: + if (i >= CAPI_MAXAPPL) + *eof = 1; + if (off >= len+begin) + return 0; + *start = page + (begin-off); + return ((count < begin+len-off) ? count : begin+len-off); +} + +/* + * /proc/capi/contrstats: + * cnr nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt + */ +static int proc_contrstats_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct capi_ctr *cp; + int i; + int len = 0; + off_t begin = 0; + + for (i=0; i < CAPI_MAXCONTR; i++) { + cp = &cards[i]; + if (cp->cardstate == CARD_FREE) continue; + len += sprintf(page+len, "%d %lu %lu %lu %lu\n", + cp->cnr, + cp->nrecvctlpkt, + cp->nrecvdatapkt, + cp->nsentctlpkt, + cp->nsentdatapkt); + if (len+begin > off+count) + goto endloop; + if (len+begin < off) { + begin += len; + len = 0; + } + } +endloop: + if (i >= CAPI_MAXCONTR) + *eof = 1; + if (off >= len+begin) + return 0; + *start = page + (begin-off); + return ((count < begin+len-off) ? count : begin+len-off); +} + +static struct procfsentries { + char *name; + mode_t mode; + int (*read_proc)(char *page, char **start, off_t off, + int count, int *eof, void *data); + struct proc_dir_entry *procent; +} procfsentries[] = { + { "capi", S_IFDIR, 0 }, + { "capi/applications", 0 , proc_applications_read_proc }, + { "capi/ncci", 0 , proc_ncci_read_proc }, + { "capi/driver", 0 , proc_driver_read_proc }, + { "capi/users", 0 , proc_users_read_proc }, + { "capi/controller", 0 , proc_controller_read_proc }, + { "capi/applstats", 0 , proc_applstats_read_proc }, + { "capi/contrstats", 0 , proc_contrstats_read_proc }, + { "capi/drivers", S_IFDIR, 0 }, + { "capi/controllers", S_IFDIR, 0 }, +}; + +static void proc_capi_init(void) +{ + int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]); + int i; + + for (i=0; i < nelem; i++) { + struct procfsentries *p = procfsentries + i; + p->procent = create_proc_entry(p->name, p->mode, 0); + if (p->procent) p->procent->read_proc = p->read_proc; + } +} + +static void proc_capi_exit(void) +{ + int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]); + int i; + + for (i=nelem-1; i >= 0; i--) { + struct procfsentries *p = procfsentries + i; + if (p->procent) { + remove_proc_entry(p->name, 0); + p->procent = 0; + } + } +} + +/* -------- NCCI Handling ------------------------------------- */ + +static inline void mq_init(struct capi_ncci * np) +{ + int i; + np->msgidqueue = 0; + np->msgidlast = 0; + np->nmsg = 0; + memset(np->msgidpool, 0, sizeof(np->msgidpool)); + np->msgidfree = &np->msgidpool[0]; + for (i = 1; i < np->winsize; i++) { + np->msgidpool[i].next = np->msgidfree; + np->msgidfree = &np->msgidpool[i]; + } +} + +static inline int mq_enqueue(struct capi_ncci * np, __u16 msgid) +{ + struct msgidqueue *mq; + if ((mq = np->msgidfree) == 0) + return 0; + np->msgidfree = mq->next; + mq->msgid = msgid; + mq->next = 0; + if (np->msgidlast) + np->msgidlast->next = mq; + np->msgidlast = mq; + if (!np->msgidqueue) + np->msgidqueue = mq; + np->nmsg++; + return 1; +} + +static inline int mq_dequeue(struct capi_ncci * np, __u16 msgid) +{ + struct msgidqueue **pp; + for (pp = &np->msgidqueue; *pp; pp = &(*pp)->next) { + if ((*pp)->msgid == msgid) { + struct msgidqueue *mq = *pp; + *pp = mq->next; + if (mq == np->msgidlast) + np->msgidlast = 0; + mq->next = np->msgidfree; + np->msgidfree = mq; + np->nmsg--; + return 1; + } + } + return 0; +} + +static void controllercb_appl_registered(struct capi_ctr * card, __u16 appl) +{ +} + +static void controllercb_appl_released(struct capi_ctr * card, __u16 appl) +{ + struct capi_ncci **pp, **nextpp; + for (pp = &APPL(appl)->nccilist; *pp; pp = nextpp) { + if (NCCI2CTRL((*pp)->ncci) == card->cnr) { + struct capi_ncci *np = *pp; + *pp = np->next; + printk(KERN_INFO "kcapi: appl %d ncci 0x%x down!\n", appl, np->ncci); + kfree(np); + APPL(appl)->nncci--; + nextpp = pp; + } else { + nextpp = &(*pp)->next; + } + } + APPL(appl)->releasing--; + if (APPL(appl)->releasing <= 0) { + APPL(appl)->signal = 0; + APPL_MARK_FREE(appl); + printk(KERN_INFO "kcapi: appl %d down\n", appl); + } +} +/* + * ncci managment + */ + +static void controllercb_new_ncci(struct capi_ctr * card, + __u16 appl, __u32 ncci, __u32 winsize) +{ + struct capi_ncci *np; + if (!VALID_APPLID(appl)) { + printk(KERN_ERR "avmb1_handle_new_ncci: illegal appl %d\n", appl); + return; + } + if ((np = (struct capi_ncci *) kmalloc(sizeof(struct capi_ncci), GFP_ATOMIC)) == 0) { + printk(KERN_ERR "capi_new_ncci: alloc failed ncci 0x%x\n", ncci); + return; + } + if (winsize > CAPI_MAXDATAWINDOW) { + printk(KERN_ERR "capi_new_ncci: winsize %d too big, set to %d\n", + winsize, CAPI_MAXDATAWINDOW); + winsize = CAPI_MAXDATAWINDOW; + } + np->applid = appl; + np->ncci = ncci; + np->winsize = winsize; + mq_init(np); + np->next = APPL(appl)->nccilist; + APPL(appl)->nccilist = np; + APPL(appl)->nncci++; + printk(KERN_INFO "kcapi: appl %d ncci 0x%x up\n", appl, ncci); + +} + +static void controllercb_free_ncci(struct capi_ctr * card, + __u16 appl, __u32 ncci) +{ + struct capi_ncci **pp; + if (!VALID_APPLID(appl)) { + printk(KERN_ERR "free_ncci: illegal appl %d\n", appl); + return; + } + for (pp = &APPL(appl)->nccilist; *pp; pp = &(*pp)->next) { + if ((*pp)->ncci == ncci) { + struct capi_ncci *np = *pp; + *pp = np->next; + kfree(np); + APPL(appl)->nncci--; + printk(KERN_INFO "kcapi: appl %d ncci 0x%x down\n", appl, ncci); + return; + } + } + printk(KERN_ERR "free_ncci: ncci 0x%x not found\n", ncci); +} + + +static struct capi_ncci *find_ncci(struct capi_appl * app, __u32 ncci) +{ + struct capi_ncci *np; + for (np = app->nccilist; np; np = np->next) { + if (np->ncci == ncci) + return np; + } + return 0; +} + +/* -------- Receiver ------------------------------------------ */ + +static void recv_handler(void *dummy) +{ + struct sk_buff *skb; + + while ((skb = skb_dequeue(&recv_queue)) != 0) { + __u16 appl = CAPIMSG_APPID(skb->data); + struct capi_ncci *np; + if (!VALID_APPLID(appl)) { + printk(KERN_ERR "kcapi: recv_handler: applid %d ? (%s)\n", + appl, capi_message2str(skb->data)); + kfree_skb(skb); + continue; + } + if (APPL(appl)->signal == 0) { + printk(KERN_ERR "kcapi: recv_handler: applid %d has no signal function\n", + appl); + kfree_skb(skb); + continue; + } + if ( CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3 + && CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF + && (np = find_ncci(APPL(appl), CAPIMSG_NCCI(skb->data))) != 0 + && mq_dequeue(np, CAPIMSG_MSGID(skb->data)) == 0) { + printk(KERN_ERR "kcapi: msgid %hu ncci 0x%x not on queue\n", + CAPIMSG_MSGID(skb->data), np->ncci); + } + if ( CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3 + && CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) { + APPL(appl)->nrecvdatapkt++; + } else { + APPL(appl)->nrecvctlpkt++; + } + skb_queue_tail(&APPL(appl)->recv_queue, skb); + (APPL(appl)->signal) (APPL(appl)->applid, APPL(appl)->param); + } +} + +static void controllercb_handle_capimsg(struct capi_ctr * card, + __u16 appl, struct sk_buff *skb) +{ + int showctl = 0; + __u8 cmd, subcmd; + + if (card->cardstate != CARD_RUNNING) { + printk(KERN_INFO "kcapi: controller %d not active, got: %s", + card->cnr, capi_message2str(skb->data)); + goto error; + } + cmd = CAPIMSG_COMMAND(skb->data); + subcmd = CAPIMSG_SUBCOMMAND(skb->data); + if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) { + card->nrecvdatapkt++; + if (card->traceflag > 2) showctl |= 2; + if (card->traceflag) showctl |= 2; + } else { + card->nrecvctlpkt++; + } + showctl |= (card->traceflag & 1); + if (showctl & 2) { + if (showctl & 1) { + printk(KERN_DEBUG "kcapi: got [0x%lx] id#%d %s len=%u\n", + (unsigned long) card->cnr, + CAPIMSG_APPID(skb->data), + capi_cmd2str(cmd, subcmd), + CAPIMSG_LEN(skb->data)); + } else { + printk(KERN_DEBUG "kcapi: got [0x%lx] %s\n", + (unsigned long) card->cnr, + capi_message2str(skb->data)); + } + + } + skb_queue_tail(&recv_queue, skb); + queue_task(&tq_recv_notify, &tq_immediate); + mark_bh(IMMEDIATE_BH); + return; + +error: + kfree_skb(skb); +} + +/* -------- Notifier ------------------------------------------ */ + +static void notify_up(__u16 contr) +{ + struct capi_interface_user *p; + + printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr); + for (p = capi_users; p; p = p->next) { + if (!p->callback) continue; + (*p->callback) (KCI_CONTRUP, contr, &CARD(contr)->profile); + } +} + +static void notify_down(__u16 contr) +{ + struct capi_interface_user *p; + printk(KERN_NOTICE "kcapi: notify down contr %d\n", contr); + for (p = capi_users; p; p = p->next) { + if (!p->callback) continue; + (*p->callback) (KCI_CONTRDOWN, contr, 0); + } +} + +static void notify_handler(void *dummy) +{ + __u16 contr; + + for (contr=1; VALID_CARD(contr); contr++) + if (test_and_clear_bit(contr, ¬ify_up_set)) + notify_up(contr); + for (contr=1; VALID_CARD(contr); contr++) + if (test_and_clear_bit(contr, ¬ify_down_set)) + notify_down(contr); +} + + +static void controllercb_ready(struct capi_ctr * card) +{ + __u16 appl; + + card->cardstate = CARD_RUNNING; + + for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { + if (!VALID_APPLID(appl)) continue; + if (APPL(appl)->releasing) continue; + card->driver->register_appl(card, appl, &APPL(appl)->rparam); + } + + set_bit(CARDNR(card), ¬ify_up_set); + queue_task(&tq_state_notify, &tq_scheduler); + + printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n", + CARDNR(card), card->name); +} + +static void controllercb_reseted(struct capi_ctr * card) +{ + __u16 appl; + + if (card->cardstate == CARD_FREE) + return; + if (card->cardstate == CARD_DETECTED) + return; + + card->cardstate = CARD_DETECTED; + + memset(card->manu, 0, sizeof(card->manu)); + memset(&card->version, 0, sizeof(card->version)); + memset(&card->profile, 0, sizeof(card->profile)); + memset(card->serial, 0, sizeof(card->serial)); + + for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { + struct capi_ncci **pp, **nextpp; + for (pp = &APPL(appl)->nccilist; *pp; pp = nextpp) { + if (NCCI2CTRL((*pp)->ncci) == card->cnr) { + struct capi_ncci *np = *pp; + *pp = np->next; + printk(KERN_INFO "kcapi: appl %d ncci 0x%x forced down!\n", appl, np->ncci); + kfree(np); + nextpp = pp; + } else { + nextpp = &(*pp)->next; + } + } + } + set_bit(CARDNR(card), ¬ify_down_set); + queue_task(&tq_state_notify, &tq_scheduler); + printk(KERN_NOTICE "kcapi: card %d down.\n", CARDNR(card)); +} + +static void controllercb_suspend_output(struct capi_ctr *card) +{ + if (!card->blocked) { + printk(KERN_DEBUG "kcapi: card %d suspend\n", CARDNR(card)); + card->blocked = 1; + } +} + +static void controllercb_resume_output(struct capi_ctr *card) +{ + if (card->blocked) { + printk(KERN_DEBUG "kcapi: card %d resume\n", CARDNR(card)); + card->blocked = 0; + } +} + +/* ------------------------------------------------------------- */ + + +struct capi_ctr * +drivercb_attach_ctr(struct capi_driver *driver, char *name, void *driverdata) +{ + struct capi_ctr *card, **pp; + int i; + + for (i=0; i < CAPI_MAXCONTR && cards[i].cardstate != CARD_FREE; i++) ; + + if (i == CAPI_MAXCONTR) { + printk(KERN_ERR "kcapi: out of controller slots\n"); + return 0; + } + card = &cards[i]; + memset(card, 0, sizeof(struct capi_ctr)); + card->driver = driver; + card->cnr = CARDNR(card); + strncpy(card->name, name, sizeof(card->name)); + card->cardstate = CARD_DETECTED; + card->blocked = 0; + card->driverdata = driverdata; + card->traceflag = showcapimsgs; + + card->ready = controllercb_ready; + card->reseted = controllercb_reseted; + card->suspend_output = controllercb_suspend_output; + card->resume_output = controllercb_resume_output; + card->handle_capimsg = controllercb_handle_capimsg; + card->appl_registered = controllercb_appl_registered; + card->appl_released = controllercb_appl_released; + card->new_ncci = controllercb_new_ncci; + card->free_ncci = controllercb_free_ncci; + + for (pp = &driver->controller; *pp; pp = &(*pp)->next) ; + card->next = 0; + *pp = card; + driver->ncontroller++; + sprintf(card->procfn, "capi/controllers/%d", card->cnr); + card->procent = create_proc_entry(card->procfn, 0, 0); + if (card->procent) { + card->procent->read_proc = + (int (*)(char *,char **,off_t,int,int *,void *)) + driver->ctr_read_proc; + card->procent->data = card; + } + + ncards++; + printk(KERN_NOTICE "kcapi: Controller %d: %s attached\n", + card->cnr, card->name); + return card; +} + +static int drivercb_detach_ctr(struct capi_ctr *card) +{ + struct capi_driver *driver = card->driver; + struct capi_ctr **pp; + + if (card->cardstate == CARD_FREE) + return 0; + if (card->cardstate != CARD_DETECTED) + controllercb_reseted(card); + for (pp = &driver->controller; *pp ; pp = &(*pp)->next) { + if (*pp == card) { + *pp = card->next; + driver->ncontroller--; + ncards--; + break; + } + } + if (card->procent) { + remove_proc_entry(card->procfn, 0); + card->procent = 0; + } + card->cardstate = CARD_FREE; + printk(KERN_NOTICE "kcapi: Controller %d: %s unregistered\n", + card->cnr, card->name); + return 0; +} + +/* ------------------------------------------------------------- */ + +/* fallback if no driver read_proc function defined by driver */ + +static int driver_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct capi_driver *driver = (struct capi_driver *)data; + int len = 0; + + len += sprintf(page+len, "%-16s %s\n", "name", driver->name); + len += sprintf(page+len, "%-16s %s\n", "revision", driver->revision); + + if (len < off) + return 0; + *eof = 1; + *start = page - off; + return ((count < len-off) ? count : len-off); +} + +/* ------------------------------------------------------------- */ + +static struct capi_driver_interface di = { + drivercb_attach_ctr, + drivercb_detach_ctr, +}; + +struct capi_driver_interface *attach_capi_driver(struct capi_driver *driver) +{ + struct capi_driver **pp; + + for (pp = &drivers; *pp; pp = &(*pp)->next) ; + driver->next = 0; + *pp = driver; + printk(KERN_NOTICE "kcapi: driver %s attached\n", driver->name); +#ifdef CONFIG_AVMB1_COMPAT + if (strcmp(driver->name, "b1isa") == 0 && driver->add_card) + b1isa_driver = driver; + if (strcmp(driver->name, "t1isa") == 0 && driver->add_card) + t1isa_driver = driver; +#endif + sprintf(driver->procfn, "capi/drivers/%s", driver->name); + driver->procent = create_proc_entry(driver->procfn, 0, 0); + if (driver->procent) { + if (driver->driver_read_proc) { + driver->procent->read_proc = + (int (*)(char *,char **,off_t,int,int *,void *)) + driver->driver_read_proc; + } else { + driver->procent->read_proc = driver_read_proc; + } + driver->procent->data = driver; + } + return &di; +} + +void detach_capi_driver(struct capi_driver *driver) +{ + struct capi_driver **pp; + for (pp = &drivers; *pp && *pp != driver; pp = &(*pp)->next) ; + if (*pp) { + *pp = (*pp)->next; +#ifdef CONFIG_AVMB1_COMPAT + if (driver == b1isa_driver) b1isa_driver = 0; + if (driver == t1isa_driver) t1isa_driver = 0; +#endif + printk(KERN_NOTICE "kcapi: driver %s detached\n", driver->name); + } else { + printk(KERN_ERR "kcapi: driver %s double detach ?\n", driver->name); + } + if (driver->procent) { + remove_proc_entry(driver->procfn, 0); + driver->procent = 0; + } +} + +/* ------------------------------------------------------------- */ +/* -------- CAPI2.0 Interface ---------------------------------- */ +/* ------------------------------------------------------------- */ + +static int capi_installed(void) +{ + int i; + for (i = 0; i < CAPI_MAXCONTR; i++) { + if (cards[i].cardstate == CARD_RUNNING) + return 1; + } + return 0; +} + +static __u16 capi_register(capi_register_params * rparam, __u16 * applidp) +{ + int appl; + int i; + + if (rparam->datablklen < 128) + return CAPI_LOGBLKSIZETOSMALL; + + for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { + if (APPL_IS_FREE(appl)) + break; + } + if (appl > CAPI_MAXAPPL) + return CAPI_TOOMANYAPPLS; + + APPL_MARK_USED(appl); + skb_queue_head_init(&APPL(appl)->recv_queue); + APPL(appl)->nncci = 0; + + memcpy(&APPL(appl)->rparam, rparam, sizeof(capi_register_params)); + + for (i = 0; i < CAPI_MAXCONTR; i++) { + if (cards[i].cardstate != CARD_RUNNING) + continue; + cards[i].driver->register_appl(&cards[i], appl, + &APPL(appl)->rparam); + } + *applidp = appl; + printk(KERN_INFO "kcapi: appl %d up\n", appl); + + return CAPI_NOERROR; +} + +static __u16 capi_release(__u16 applid) +{ + struct sk_buff *skb; + int i; + + if (!VALID_APPLID(applid) || APPL(applid)->releasing) + return CAPI_ILLAPPNR; + while ((skb = skb_dequeue(&APPL(applid)->recv_queue)) != 0) + kfree_skb(skb); + for (i = 0; i < CAPI_MAXCONTR; i++) { + if (cards[i].cardstate != CARD_RUNNING) + continue; + APPL(applid)->releasing++; + cards[i].driver->release_appl(&cards[i], applid); + } + if (APPL(applid)->releasing <= 0) { + APPL(applid)->signal = 0; + APPL_MARK_FREE(applid); + printk(KERN_INFO "kcapi: appl %d down\n", applid); + } + return CAPI_NOERROR; +} + +static __u16 capi_put_message(__u16 applid, struct sk_buff *skb) +{ + struct capi_ncci *np; + int contr; + int showctl = 0; + __u8 cmd, subcmd; + + if (ncards == 0) + return CAPI_REGNOTINSTALLED; + if (!VALID_APPLID(applid)) + return CAPI_ILLAPPNR; + if (skb->len < 12 + || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data)) + || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data))) + return CAPI_ILLCMDORSUBCMDORMSGTOSMALL; + contr = CAPIMSG_CONTROLLER(skb->data); + if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) { + contr = 1; + if (CARD(contr)->cardstate != CARD_RUNNING) + return CAPI_REGNOTINSTALLED; + } + if (CARD(contr)->blocked) + return CAPI_SENDQUEUEFULL; + + cmd = CAPIMSG_COMMAND(skb->data); + subcmd = CAPIMSG_SUBCOMMAND(skb->data); + + if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) { + if ((np = find_ncci(APPL(applid), CAPIMSG_NCCI(skb->data))) != 0 + && mq_enqueue(np, CAPIMSG_MSGID(skb->data)) == 0) + return CAPI_SENDQUEUEFULL; + CARD(contr)->nsentdatapkt++; + APPL(applid)->nsentdatapkt++; + if (CARD(contr)->traceflag > 2) showctl |= 2; + } else { + CARD(contr)->nsentctlpkt++; + APPL(applid)->nsentctlpkt++; + if (CARD(contr)->traceflag) showctl |= 2; + } + showctl |= (CARD(contr)->traceflag & 1); + if (showctl & 2) { + if (showctl & 1) { + printk(KERN_DEBUG "kcapi: put [0x%lx] id#%d %s len=%u\n", + (unsigned long) contr, + CAPIMSG_APPID(skb->data), + capi_cmd2str(cmd, subcmd), + CAPIMSG_LEN(skb->data)); + } else { + printk(KERN_DEBUG "kcapi: put [0x%lx] %s\n", + (unsigned long) contr, + capi_message2str(skb->data)); + } + + } + CARD(contr)->driver->send_message(CARD(contr), skb); + return CAPI_NOERROR; +} + +static __u16 capi_get_message(__u16 applid, struct sk_buff **msgp) +{ + struct sk_buff *skb; + + if (!VALID_APPLID(applid)) + return CAPI_ILLAPPNR; + if ((skb = skb_dequeue(&APPL(applid)->recv_queue)) == 0) + return CAPI_RECEIVEQUEUEEMPTY; + *msgp = skb; + return CAPI_NOERROR; +} + +static __u16 capi_set_signal(__u16 applid, + void (*signal) (__u16 applid, __u32 param), + __u32 param) +{ + if (!VALID_APPLID(applid)) + return CAPI_ILLAPPNR; + APPL(applid)->signal = signal; + APPL(applid)->param = param; + return CAPI_NOERROR; +} + +static __u16 capi_get_manufacturer(__u16 contr, __u8 buf[CAPI_MANUFACTURER_LEN]) +{ + if (contr == 0) { + strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); + return CAPI_NOERROR; + } + if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) + return 0x2002; + + strncpy(buf, CARD(contr)->manu, CAPI_MANUFACTURER_LEN); + return CAPI_NOERROR; +} + +static __u16 capi_get_version(__u16 contr, struct capi_version *verp) +{ + if (contr == 0) { + *verp = driver_version; + return CAPI_NOERROR; + } + if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) + return 0x2002; + + memcpy((void *) verp, &CARD(contr)->version, sizeof(capi_version)); + return CAPI_NOERROR; +} + +static __u16 capi_get_serial(__u16 contr, __u8 serial[CAPI_SERIAL_LEN]) +{ + if (contr == 0) { + strncpy(serial, driver_serial, CAPI_SERIAL_LEN); + return CAPI_NOERROR; + } + if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) + return 0x2002; + + strncpy((void *) serial, CARD(contr)->serial, CAPI_SERIAL_LEN); + return CAPI_NOERROR; +} + +static __u16 capi_get_profile(__u16 contr, struct capi_profile *profp) +{ + if (contr == 0) { + profp->ncontroller = ncards; + return CAPI_NOERROR; + } + if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) + return 0x2002; + + memcpy((void *) profp, &CARD(contr)->profile, + sizeof(struct capi_profile)); + return CAPI_NOERROR; +} + +#ifdef CONFIG_AVMB1_COMPAT +static int old_capi_manufacturer(unsigned int cmd, void *data) +{ + avmb1_loadandconfigdef ldef; + avmb1_extcarddef cdef; + avmb1_resetdef rdef; + avmb1_getdef gdef; + struct capi_driver *driver; + struct capi_ctr *card; + capicardparams cparams; + capiloaddata ldata; + int retval; + + switch (cmd) { + case AVMB1_ADDCARD: + case AVMB1_ADDCARD_WITH_TYPE: + if (cmd == AVMB1_ADDCARD) { + if ((retval = copy_from_user((void *) &cdef, data, + sizeof(avmb1_carddef)))) + return retval; + cdef.cardtype = AVM_CARDTYPE_B1; + } else { + if ((retval = copy_from_user((void *) &cdef, data, + sizeof(avmb1_extcarddef)))) + return retval; + } + cparams.port = cdef.port; + cparams.irq = cdef.irq; + cparams.cardnr = cdef.cardnr; + + switch (cdef.cardtype) { + case AVM_CARDTYPE_B1: driver = b1isa_driver; break; + case AVM_CARDTYPE_T1: driver = t1isa_driver; break; + default: driver = 0; + } + if (!driver || !driver->add_card) { + return -EIO; + } + + return driver->add_card(driver, &cparams); + + case AVMB1_LOAD: + case AVMB1_LOAD_AND_CONFIG: + + if (cmd == AVMB1_LOAD) { + if ((retval = copy_from_user((void *) &ldef, data, + sizeof(avmb1_loaddef)))) + return retval; + ldef.t4config.len = 0; + ldef.t4config.data = 0; + } else { + if ((retval = copy_from_user((void *) &ldef, data, + sizeof(avmb1_loadandconfigdef)))) + return retval; + } + if (!VALID_CARD(ldef.contr)) + return -ESRCH; + + card = CARD(ldef.contr); + if (card->cardstate == CARD_FREE) + return -ESRCH; + + if (ldef.t4file.len <= 0) { + printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len); + return -EINVAL; + } + if (ldef.t4file.data == 0) { + printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n"); + return -EINVAL; + } + + ldata.firmware.user = 1; + ldata.firmware.data = ldef.t4file.data; + ldata.firmware.len = ldef.t4file.len; + ldata.configuration.user = 1; + ldata.configuration.data = ldef.t4config.data; + ldata.configuration.len = ldef.t4config.len; + + if (card->cardstate != CARD_DETECTED) { + printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr); + return -EBUSY; + } + card->cardstate = CARD_LOADING; + + retval = card->driver->load_firmware(card, &ldata); + + if (retval) { + card->cardstate = CARD_DETECTED; + return retval; + } + + while (card->cardstate != CARD_RUNNING) { + + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(HZ/10); /* 0.1 sec */ + + if (signal_pending(current)) + return -EINTR; + } + return 0; + + case AVMB1_RESETCARD: + if ((retval = copy_from_user((void *) &rdef, data, + sizeof(avmb1_resetdef)))) + return retval; + if (!VALID_CARD(rdef.contr)) + return -ESRCH; + card = CARD(rdef.contr); + + if (card->cardstate == CARD_FREE) + return -ESRCH; + if (card->cardstate == CARD_DETECTED) + return 0; + + card->driver->reset_ctr(card); + + while (card->cardstate > CARD_DETECTED) { + + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(HZ/10); /* 0.1 sec */ + + if (signal_pending(current)) + return -EINTR; + } + return 0; + + case AVMB1_GET_CARDINFO: + if ((retval = copy_from_user((void *) &gdef, data, + sizeof(avmb1_getdef)))) + return retval; + + if (!VALID_CARD(gdef.contr)) + return -ESRCH; + + card = CARD(gdef.contr); + + if (card->cardstate == CARD_FREE) + return -ESRCH; + + gdef.cardstate = card->cardstate; + if (card->driver == b1isa_driver) + gdef.cardtype = AVM_CARDTYPE_B1; + else if (card->driver == t1isa_driver) + gdef.cardtype = AVM_CARDTYPE_T1; + else gdef.cardtype = AVM_CARDTYPE_B1; + + if ((retval = copy_to_user(data, (void *) &gdef, + sizeof(avmb1_getdef)))) + return retval; + + return 0; + + case AVMB1_REMOVECARD: + if ((retval = copy_from_user((void *) &rdef, data, + sizeof(avmb1_resetdef)))) + return retval; + + if (!VALID_CARD(rdef.contr)) + return -ESRCH; + card = CARD(rdef.contr); + + if (card->cardstate == CARD_FREE) + return -ESRCH; + + if (card->cardstate != CARD_DETECTED) + return -EBUSY; + + card->driver->remove_ctr(card); + + while (card->cardstate != CARD_FREE) { + + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(HZ/10); /* 0.1 sec */ + + if (signal_pending(current)) + return -EINTR; + } + return 0; + } + return -EINVAL; +} +#endif + +static int capi_manufacturer(unsigned int cmd, void *data) +{ + struct capi_ctr *card; + kcapi_flagdef fdef; + int retval; + + switch (cmd) { +#ifdef CONFIG_AVMB1_COMPAT + case AVMB1_ADDCARD: + case AVMB1_ADDCARD_WITH_TYPE: + case AVMB1_LOAD: + case AVMB1_LOAD_AND_CONFIG: + case AVMB1_RESETCARD: + case AVMB1_GET_CARDINFO: + case AVMB1_REMOVECARD: + return old_capi_manufacturer(cmd, data); +#endif + case KCAPI_CMD_TRACE: + if ((retval = copy_from_user((void *) &fdef, data, + sizeof(kcapi_flagdef)))) + return retval; + + if (!VALID_CARD(fdef.contr)) + return -ESRCH; + card = CARD(fdef.contr); + if (card->cardstate == CARD_FREE) + return -ESRCH; + card->traceflag = fdef.flag; + printk(KERN_INFO "kcapi: contr %d set trace=%d\n", + card->cnr, card->traceflag); + return 0; + } + return -EINVAL; +} + +struct capi_interface avmb1_interface = +{ + capi_installed, + capi_register, + capi_release, + capi_put_message, + capi_get_message, + capi_set_signal, + capi_get_manufacturer, + capi_get_version, + capi_get_serial, + capi_get_profile, + capi_manufacturer +}; + +/* ------------------------------------------------------------- */ +/* -------- Exported Functions --------------------------------- */ +/* ------------------------------------------------------------- */ + +struct capi_interface *attach_capi_interface(struct capi_interface_user *userp) +{ + struct capi_interface_user *p; + + for (p = capi_users; p; p = p->next) { + if (p == userp) { + printk(KERN_ERR "kcapi: double attach from %s\n", + userp->name); + return 0; + } + } + userp->next = capi_users; + capi_users = userp; + MOD_INC_USE_COUNT; + printk(KERN_NOTICE "kcapi: %s attached\n", userp->name); + + return &avmb1_interface; +} + +int detach_capi_interface(struct capi_interface_user *userp) +{ + struct capi_interface_user **pp; + + for (pp = &capi_users; *pp; pp = &(*pp)->next) { + if (*pp == userp) { + *pp = userp->next; + userp->next = 0; + MOD_DEC_USE_COUNT; + printk(KERN_NOTICE "kcapi: %s detached\n", userp->name); + return 0; + } + } + printk(KERN_ERR "kcapi: double detach from %s\n", userp->name); + return -1; +} + +/* ------------------------------------------------------------- */ +/* -------- Init & Cleanup ------------------------------------- */ +/* ------------------------------------------------------------- */ + +EXPORT_SYMBOL(attach_capi_interface); +EXPORT_SYMBOL(detach_capi_interface); +EXPORT_SYMBOL(attach_capi_driver); +EXPORT_SYMBOL(detach_capi_driver); + +#ifndef MODULE +#ifdef CONFIG_ISDN_DRV_AVMB1_B1ISA +extern int b1isa_init(void); +#endif +#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCI +extern int b1pci_init(void); +#endif +#ifdef CONFIG_ISDN_DRV_AVMB1_T1ISA +extern int t1isa_init(void); +#endif +#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCMCIA +extern int b1pcmcia_init(void); +#endif +#endif + +/* + * init / exit functions + */ + +#ifdef MODULE +#define kcapi_init init_module +#endif + +int kcapi_init(void) +{ + char *p; + char rev[10]; + + skb_queue_head_init(&recv_queue); + /* init_bh(CAPI_BH, do_capi_bh); */ + + tq_state_notify.routine = notify_handler; + tq_state_notify.data = 0; + + tq_recv_notify.routine = recv_handler; + tq_recv_notify.data = 0; + + proc_capi_init(); + + if ((p = strchr(revision, ':'))) { + strcpy(rev, p + 1); + p = strchr(rev, '$'); + *p = 0; + } else + strcpy(rev, "1.0"); + +#ifdef MODULE + printk(KERN_NOTICE "CAPI-driver Rev%s: loaded\n", rev); +#else + printk(KERN_NOTICE "CAPI-driver Rev%s: started\n", rev); +#ifdef CONFIG_ISDN_DRV_AVMB1_B1ISA + (void)b1isa_init(); +#endif +#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCI + (void)b1pci_init(); +#endif +#ifdef CONFIG_ISDN_DRV_AVMB1_T1ISA + (void)t1isa_init(); +#endif +#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCMCIA + (void)b1pcmcia_init(); +#endif +#endif + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ + char rev[10]; + char *p; + + if ((p = strchr(revision, ':'))) { + strcpy(rev, p + 1); + p = strchr(rev, '$'); + *p = 0; + } else { + strcpy(rev, "1.0"); + } + + schedule(); /* execute queued tasks .... */ + proc_capi_exit(); + printk(KERN_NOTICE "CAPI-driver Rev%s: unloaded\n", rev); +} +#endif diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/avmb1/t1isa.c linux/drivers/isdn/avmb1/t1isa.c --- v2.3.13/linux/drivers/isdn/avmb1/t1isa.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/avmb1/t1isa.c Sun Aug 15 11:49:08 1999 @@ -0,0 +1,544 @@ +/* + * $Id: t1isa.c,v 1.4 1999/07/09 15:05:50 keil Exp $ + * + * Module for AVM T1 HEMA-card. + * + * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * + * $Log: t1isa.c,v $ + * Revision 1.4 1999/07/09 15:05:50 keil + * compat.h is now isdn_compat.h + * + * Revision 1.3 1999/07/06 07:42:04 calle + * - changes in /proc interface + * - check and changed calls to [dev_]kfree_skb and [dev_]alloc_skb. + * + * Revision 1.2 1999/07/05 15:09:54 calle + * - renamed "appl_release" to "appl_released". + * - version und profile data now cleared on controller reset + * - extended /proc interface, to allow driver and controller specific + * informations to include by driver hackers. + * + * Revision 1.1 1999/07/01 15:26:44 calle + * complete new version (I love it): + * + new hardware independed "capi_driver" interface that will make it easy to: + * - support other controllers with CAPI-2.0 (i.e. USB Controller) + * - write a CAPI-2.0 for the passive cards + * - support serial link CAPI-2.0 boxes. + * + wrote "capi_driver" for all supported cards. + * + "capi_driver" (supported cards) now have to be configured with + * make menuconfig, in the past all supported cards where included + * at once. + * + new and better informations in /proc/capi/ + * + new ioctl to switch trace of capi messages per controller + * using "avmcapictrl trace [contr] on|off|...." + * + complete testcircle with all supported cards and also the + * PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done. + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "capicmd.h" +#include "capiutil.h" +#include "capilli.h" +#include "avmcard.h" + +static char *revision = "$Revision: 1.4 $"; + +/* ------------------------------------------------------------- */ + +MODULE_AUTHOR("Carsten Paeth "); + +/* ------------------------------------------------------------- */ + +static struct capi_driver_interface *di; + +/* ------------------------------------------------------------- */ + +static int hema_irq_table[16] = +{0, + 0, + 0, + 0x80, /* irq 3 */ + 0, + 0x90, /* irq 5 */ + 0, + 0xA0, /* irq 7 */ + 0, + 0xB0, /* irq 9 */ + 0xC0, /* irq 10 */ + 0xD0, /* irq 11 */ + 0xE0, /* irq 12 */ + 0, + 0, + 0xF0, /* irq 15 */ +}; + +static int t1_detectandinit(unsigned int base, unsigned irq, int cardnr) +{ + unsigned char cregs[8]; + unsigned char reverse_cardnr; + unsigned long flags; + unsigned char dummy; + int i; + + reverse_cardnr = ((cardnr & 0x01) << 3) | ((cardnr & 0x02) << 1) + | ((cardnr & 0x04) >> 1) | ((cardnr & 0x08) >> 3); + cregs[0] = (HEMA_VERSION_ID << 4) | (reverse_cardnr & 0xf); + cregs[1] = 0x00; /* fast & slow link connected to CON1 */ + cregs[2] = 0x05; /* fast link 20MBit, slow link 20 MBit */ + cregs[3] = 0; + cregs[4] = 0x11; /* zero wait state */ + cregs[5] = hema_irq_table[irq & 0xf]; + cregs[6] = 0; + cregs[7] = 0; + + save_flags(flags); + cli(); + /* board reset */ + t1outp(base, T1_RESETBOARD, 0xf); + udelay(100 * 1000); + dummy = t1inp(base, T1_FASTLINK+T1_OUTSTAT); /* first read */ + + /* write config */ + dummy = (base >> 4) & 0xff; + for (i=1;i<=0xf;i++) t1outp(base, i, dummy); + t1outp(base, HEMA_PAL_ID & 0xf, dummy); + t1outp(base, HEMA_PAL_ID >> 4, cregs[0]); + for(i=1;i<7;i++) t1outp(base, 0, cregs[i]); + t1outp(base, ((base >> 4)) & 0x3, cregs[7]); + restore_flags(flags); + + udelay(100 * 1000); + t1outp(base, T1_FASTLINK+T1_RESETLINK, 0); + t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0); + udelay(10 * 1000); + t1outp(base, T1_FASTLINK+T1_RESETLINK, 1); + t1outp(base, T1_SLOWLINK+T1_RESETLINK, 1); + udelay(100 * 1000); + t1outp(base, T1_FASTLINK+T1_RESETLINK, 0); + t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0); + udelay(10 * 1000); + t1outp(base, T1_FASTLINK+T1_ANALYSE, 0); + udelay(5 * 1000); + t1outp(base, T1_SLOWLINK+T1_ANALYSE, 0); + + if (t1inp(base, T1_FASTLINK+T1_OUTSTAT) != 0x1) /* tx empty */ + return 1; + if (t1inp(base, T1_FASTLINK+T1_INSTAT) != 0x0) /* rx empty */ + return 2; + if (t1inp(base, T1_FASTLINK+T1_IRQENABLE) != 0x0) + return 3; + if ((t1inp(base, T1_FASTLINK+T1_FIFOSTAT) & 0xf0) != 0x70) + return 4; + if ((t1inp(base, T1_FASTLINK+T1_IRQMASTER) & 0x0e) != 0) + return 5; + if ((t1inp(base, T1_FASTLINK+T1_IDENT) & 0x7d) != 1) + return 6; + if (t1inp(base, T1_SLOWLINK+T1_OUTSTAT) != 0x1) /* tx empty */ + return 7; + if ((t1inp(base, T1_SLOWLINK+T1_IRQMASTER) & 0x0e) != 0) + return 8; + if ((t1inp(base, T1_SLOWLINK+T1_IDENT) & 0x7d) != 0) + return 9; + return 0; +} + +static void t1_handle_interrupt(avmcard * card) +{ + struct capi_ctr *ctrl = card->ctrl; + unsigned char b1cmd; + struct sk_buff *skb; + + unsigned ApplId; + unsigned MsgLen; + unsigned DataB3Len; + unsigned NCCI; + unsigned WindowSize; + + while (b1_rx_full(card->port)) { + + b1cmd = b1_get_byte(card->port); + + switch (b1cmd) { + + case RECEIVE_DATA_B3_IND: + + ApplId = (unsigned) b1_get_word(card->port); + MsgLen = t1_get_slice(card->port, card->msgbuf); + DataB3Len = t1_get_slice(card->port, card->databuf); + + if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) { + printk(KERN_ERR "t1isa: incoming packet dropped\n"); + } else { + memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); + memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len); + CAPIMSG_SETDATA(skb->data, skb->data + MsgLen); + ctrl->handle_capimsg(ctrl, ApplId, skb); + } + break; + + case RECEIVE_MESSAGE: + + ApplId = (unsigned) b1_get_word(card->port); + MsgLen = t1_get_slice(card->port, card->msgbuf); + if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) { + printk(KERN_ERR "t1isa: incoming packet dropped\n"); + } else { + memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); + ctrl->handle_capimsg(ctrl, ApplId, skb); + } + break; + + case RECEIVE_NEW_NCCI: + + ApplId = b1_get_word(card->port); + NCCI = b1_get_word(card->port); + WindowSize = b1_get_word(card->port); + + ctrl->new_ncci(ctrl, ApplId, NCCI, WindowSize); + + break; + + case RECEIVE_FREE_NCCI: + + ApplId = b1_get_word(card->port); + NCCI = b1_get_word(card->port); + + if (NCCI != 0xffffffff) + ctrl->free_ncci(ctrl, ApplId, NCCI); + else ctrl->appl_released(ctrl, ApplId); + break; + + case RECEIVE_START: + b1_put_byte(card->port, SEND_POLLACK); + ctrl->resume_output(ctrl); + break; + + case RECEIVE_STOP: + ctrl->suspend_output(ctrl); + break; + + case RECEIVE_INIT: + + card->versionlen = t1_get_slice(card->port, card->versionbuf); + b1_parse_version(card); + printk(KERN_INFO "%s: %s-card (%s) now active\n", + card->name, + card->version[VER_CARDTYPE], + card->version[VER_DRIVER]); + ctrl->ready(ctrl); + break; + + case RECEIVE_TASK_READY: + ApplId = (unsigned) b1_get_word(card->port); + MsgLen = t1_get_slice(card->port, card->msgbuf); + card->msgbuf[MsgLen--] = 0; + while ( MsgLen >= 0 + && ( card->msgbuf[MsgLen] == '\n' + || card->msgbuf[MsgLen] == '\r')) + card->msgbuf[MsgLen--] = 0; + printk(KERN_INFO "%s: task %d \"%s\" ready.\n", + card->name, ApplId, card->msgbuf); + break; + + case RECEIVE_DEBUGMSG: + MsgLen = t1_get_slice(card->port, card->msgbuf); + card->msgbuf[MsgLen--] = 0; + while ( MsgLen >= 0 + && ( card->msgbuf[MsgLen] == '\n' + || card->msgbuf[MsgLen] == '\r')) + card->msgbuf[MsgLen--] = 0; + printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf); + break; + + case 0xff: + printk(KERN_ERR "%s: card reseted ?\n", card->name); + return; + default: + printk(KERN_ERR "%s: b1_interrupt: 0x%x ???\n", + card->name, b1cmd); + return; + } + } +} + +/* ------------------------------------------------------------- */ + +static void t1isa_interrupt(int interrupt, void *devptr, struct pt_regs *regs) +{ + avmcard *card; + + card = (avmcard *) devptr; + + if (!card) { + printk(KERN_WARNING "t1_interrupt: wrong device\n"); + return; + } + if (card->interrupt) { + printk(KERN_ERR "t1_interrupt: reentering interrupt hander (%s)\n", card->name); + return; + } + + card->interrupt = 1; + + t1_handle_interrupt(card); + + card->interrupt = 0; +} +/* ------------------------------------------------------------- */ + +static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) +{ + avmcard *card = (avmcard *)(ctrl->driverdata); + unsigned int port = card->port; + unsigned long flags; + int retval; + + t1_disable_irq(port); + b1_reset(port); + + if ((retval = b1_load_t4file(port, &data->firmware))) { + b1_reset(port); + printk(KERN_ERR "%s: failed to load t4file!!\n", + card->name); + return retval; + } + + if (data->configuration.len > 0 && data->configuration.data) { + if ((retval = b1_load_config(port, &data->configuration))) { + b1_reset(port); + printk(KERN_ERR "%s: failed to load config!!\n", + card->name); + return retval; + } + } + + if (!b1_loaded(port)) { + printk(KERN_ERR "%s: failed to load t4file.\n", card->name); + return -EIO; + } + + save_flags(flags); + cli(); + b1_setinterrupt(port, card->irq, card->cardtype); + b1_put_byte(port, SEND_INIT); + b1_put_word(port, AVM_NAPPS); + b1_put_word(port, AVM_NCCI_PER_CHANNEL*30); + b1_put_word(port, ctrl->cnr - 1); + restore_flags(flags); + + return 0; +} + +void t1isa_reset_ctr(struct capi_ctr *ctrl) +{ + avmcard *card = (avmcard *)(ctrl->driverdata); + unsigned int port = card->port; + + t1_disable_irq(port); + b1_reset(port); + b1_reset(port); + + memset(card->version, 0, sizeof(card->version)); + ctrl->reseted(ctrl); +} + +static void t1isa_remove_ctr(struct capi_ctr *ctrl) +{ + avmcard *card = (avmcard *)(ctrl->driverdata); + unsigned int port = card->port; + + t1_disable_irq(port); + b1_reset(port); + b1_reset(port); + t1_reset(port); + + di->detach_ctr(ctrl); + free_irq(card->irq, card); + release_region(card->port, AVMB1_PORTLEN); + kfree(card); + + MOD_DEC_USE_COUNT; +} + +/* ------------------------------------------------------------- */ + +static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p) +{ + struct capi_ctr *ctrl; + avmcard *card; + int retval; + + card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC); + + if (!card) { + printk(KERN_WARNING "t1isa: no memory.\n"); + return -ENOMEM; + } + memset(card, 0, sizeof(avmcard)); + sprintf(card->name, "t1isa-%x", p->port); + card->port = p->port; + card->irq = p->irq; + card->cardtype = avm_t1isa; + card->cardnr = p->cardnr; + + if (!(((card->port & 0x7) == 0) && ((card->port & 0x30) != 0x30))) { + printk(KERN_WARNING "t1isa: illegal port 0x%x.\n", card->port); + kfree(card); + return -EINVAL; + } + + if (check_region(card->port, AVMB1_PORTLEN)) { + printk(KERN_WARNING + "t1isa: ports 0x%03x-0x%03x in use.\n", + card->port, card->port + AVMB1_PORTLEN); + kfree(card); + return -EBUSY; + } + if (hema_irq_table[card->irq & 0xf] == 0) { + printk(KERN_WARNING "t1isa: irq %d not valid.\n", card->irq); + kfree(card); + return -EINVAL; + } + for (ctrl = driver->controller; ctrl; ctrl = ctrl->next) { + if (((avmcard *)(ctrl->driverdata))->cardnr == card->cardnr) { + printk(KERN_WARNING "t1isa: card with number %d already installed.\n", card->cardnr); + kfree(card); + return -EBUSY; + } + } + if ((retval = t1_detectandinit(card->port, card->irq, card->cardnr)) != 0) { + printk(KERN_NOTICE "t1isa: NO card at 0x%x (%d)\n", + card->port, retval); + kfree(card); + return -EIO; + } + t1_disable_irq(card->port); + b1_reset(card->port); + + request_region(p->port, AVMB1_PORTLEN, card->name); + + retval = request_irq(card->irq, t1isa_interrupt, 0, card->name, card); + if (retval) { + printk(KERN_ERR "t1isa: unable to get IRQ %d.\n", card->irq); + release_region(card->port, AVMB1_PORTLEN); + kfree(card); + return -EBUSY; + } + + card->ctrl = di->attach_ctr(driver, card->name, card); + if (!card->ctrl) { + printk(KERN_ERR "t1isa: attach controller failed.\n"); + free_irq(card->irq, card); + release_region(card->port, AVMB1_PORTLEN); + kfree(card); + return -EBUSY; + } + + MOD_INC_USE_COUNT; + return 0; +} + +static void t1isa_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) +{ + avmcard *card = (avmcard *)(ctrl->driverdata); + unsigned int port = card->port; + unsigned long flags; + __u16 len = CAPIMSG_LEN(skb->data); + __u8 cmd = CAPIMSG_COMMAND(skb->data); + __u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data); + + save_flags(flags); + cli(); + if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { + __u16 dlen = CAPIMSG_DATALEN(skb->data); + b1_put_byte(port, SEND_DATA_B3_REQ); + t1_put_slice(port, skb->data, len); + t1_put_slice(port, skb->data + len, dlen); + } else { + b1_put_byte(port, SEND_MESSAGE); + t1_put_slice(port, skb->data, len); + } + restore_flags(flags); + dev_kfree_skb(skb); +} +/* ------------------------------------------------------------- */ + +static char *t1isa_procinfo(struct capi_ctr *ctrl) +{ + avmcard *card = (avmcard *)(ctrl->driverdata); + if (!card) + return ""; + sprintf(card->infobuf, "%s %s 0x%x %d %d", + card->cardname[0] ? card->cardname : "-", + card->version[VER_DRIVER] ? card->version[VER_DRIVER] : "-", + card->port, card->irq, card->cardnr + ); + return card->infobuf; +} + + +/* ------------------------------------------------------------- */ + +static struct capi_driver t1isa_driver = { + "t1isa", + "0.0", + t1isa_load_firmware, + t1isa_reset_ctr, + t1isa_remove_ctr, + b1_register_appl, + b1_release_appl, + t1isa_send_message, + + t1isa_procinfo, + b1ctl_read_proc, + 0, /* use standard driver_read_proc */ + + t1isa_add_card, +}; + +#ifdef MODULE +#define t1isa_init init_module +void cleanup_module(void); +#endif + +int t1isa_init(void) +{ + struct capi_driver *driver = &t1isa_driver; + char *p; + + if ((p = strchr(revision, ':'))) { + strncpy(driver->revision, p + 1, sizeof(driver->revision)); + p = strchr(driver->revision, '$'); + *p = 0; + } + + printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision); + + di = attach_capi_driver(driver); + + if (!di) { + printk(KERN_ERR "%s: failed to attach capi_driver\n", + driver->name); + return -EIO; + } + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ + detach_capi_driver(&t1isa_driver); +} +#endif diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/divert/Makefile linux/drivers/isdn/divert/Makefile --- v2.3.13/linux/drivers/isdn/divert/Makefile Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/divert/Makefile Thu Aug 12 09:42:33 1999 @@ -0,0 +1,21 @@ +L_OBJS := +LX_OBJS := +M_OBJS := +MX_OBJS := +O_OBJS := +OX_OBJS := +L_TARGET := +O_TARGET := + +O_OBJS += isdn_divert.o divert_procfs.o +O_TARGET := dss1_divert.o +M_OBJS += dss1_divert.o +OX_OBJS += divert_init.o + +include $(TOPDIR)/Rules.make + + + + + + diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/divert/divert_init.c linux/drivers/isdn/divert/divert_init.c --- v2.3.13/linux/drivers/isdn/divert/divert_init.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/divert/divert_init.c Sun Aug 15 11:49:08 1999 @@ -0,0 +1,104 @@ +/* + * $Id: divert_init.c,v 1.3 1999/07/05 20:21:39 werner Exp $ + * + * Module init for DSS1 diversion services for i4l. + * + * Copyright 1999 by Werner Cornelius (werner@isdn4linux.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Log: divert_init.c,v $ + * Revision 1.3 1999/07/05 20:21:39 werner + * changes to use diversion sources for all kernel versions. + * removed static device, only proc filesystem used + * + * Revision 1.2 1999/07/04 21:37:30 werner + * Ported from kernel version 2.0 + * + * + * + */ + +#include +#include +#include "isdn_divert.h" + +/********************/ +/* needed externals */ +/********************/ +extern int printk(const char *fmt,...); + +/****************************************/ +/* structure containing interface to hl */ +/****************************************/ +isdn_divert_if divert_if = + { DIVERT_IF_MAGIC, /* magic value */ + DIVERT_CMD_REG, /* register cmd */ + ll_callback, /* callback routine from ll */ + NULL, /* command still not specified */ + NULL, /* drv_to_name */ + NULL, /* name_to_drv */ + }; + +/*************************/ +/* Module interface code */ +/* no cmd line parms */ +/*************************/ +int init_module(void) +{ int i; + + if (divert_dev_init()) + { printk(KERN_WARNING "dss1_divert: cannot install device, not loaded\n"); + return(-EIO); + } + if ((i = DIVERT_REG_NAME(&divert_if)) != DIVERT_NO_ERR) + { divert_dev_deinit(); + printk(KERN_WARNING "dss1_divert: error %d registering module, not loaded\n",i); + return(-EIO); + } +#if (LINUX_VERSION_CODE < 0x020111) + register_symtab(0); +#endif + printk(KERN_INFO "dss1_divert module successfully installed\n"); + return(0); +} /* init_module */ + +/**********************/ +/* Module deinit code */ +/**********************/ +void cleanup_module(void) +{ int flags; + int i; + + save_flags(flags); + cli(); + divert_if.cmd = DIVERT_CMD_REL; /* release */ + if ((i = DIVERT_REG_NAME(&divert_if)) != DIVERT_NO_ERR) + { printk(KERN_WARNING "dss1_divert: error %d releasing module\n",i); + restore_flags(flags); + return; + } + if (divert_dev_deinit()) + { printk(KERN_WARNING "dss1_divert: device busy, remove cancelled\n"); + restore_flags(flags); + return; + } + restore_flags(flags); + deleterule(-1); /* delete all rules and free mem */ + deleteprocs(); + printk(KERN_INFO "dss1_divert module successfully removed \n"); +} /* cleanup_module */ + + diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/divert/divert_procfs.c linux/drivers/isdn/divert/divert_procfs.c --- v2.3.13/linux/drivers/isdn/divert/divert_procfs.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/divert/divert_procfs.c Thu Aug 12 09:42:33 1999 @@ -0,0 +1,456 @@ +/* + * $Id: divert_procfs.c,v 1.4 1999/08/06 07:42:48 calle Exp $ + * + * Filesystem handling for the diversion supplementary services. + * + * Copyright 1998 by Werner Cornelius (werner@isdn4linux.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Log: divert_procfs.c,v $ + * Revision 1.4 1999/08/06 07:42:48 calle + * Added COMPAT_HAS_NEW_WAITQ for rd_queue for newer kernels. + * + * Revision 1.3 1999/07/05 20:21:41 werner + * changes to use diversion sources for all kernel versions. + * removed static device, only proc filesystem used + * + * Revision 1.2 1999/07/04 21:37:31 werner + * Ported from kernel version 2.0 + * + * + * + */ + +#include +#define __NO_VERSION__ +#include +#include +#if (LINUX_VERSION_CODE >= 0x020117) +#include +#endif +#ifdef CONFIG_PROC_FS + #include +#else + #include +#endif +#include +#include +#include "isdn_divert.h" + +/*********************************/ +/* Variables for interface queue */ +/*********************************/ +ulong if_used = 0; /* number of interface users */ +static struct divert_info *divert_info_head = NULL; /* head of queue */ +static struct divert_info *divert_info_tail = NULL; /* pointer to last entry */ +#ifdef COMPAT_HAS_NEW_WAITQ +static wait_queue_head_t rd_queue; +#else +static struct wait_queue *rd_queue = 0; /* Queue IO */ +#endif + +/*********************************/ +/* put an info buffer into queue */ +/*********************************/ +void put_info_buffer(char *cp) +{ struct divert_info *ib; + int flags; + + if (if_used <= 0) return; + if (!cp) return; + if (!*cp) return; + if (!(ib = (struct divert_info *) kmalloc(sizeof(struct divert_info)+strlen(cp), GFP_ATOMIC))) return; /* no memory */ + strcpy(ib->info_start,cp); /* set output string */ + ib->next = NULL; + save_flags(flags); + cli(); + ib->usage_cnt = if_used; + if (!divert_info_head) + divert_info_head = ib; /* new head */ + else + divert_info_tail->next = ib; /* follows existing messages */ + divert_info_tail = ib; /* new tail */ + restore_flags(flags); + + /* delete old entrys */ + while (divert_info_head->next) + { if ((divert_info_head->usage_cnt <= 0) && + (divert_info_head->next->usage_cnt <= 0)) + { ib = divert_info_head; + divert_info_head = divert_info_head->next; + kfree(ib); + } + else break; + } /* divert_info_head->next */ + wake_up_interruptible(&(rd_queue)); +} /* put_info_buffer */ + +/**********************************/ +/* deflection device read routine */ +/**********************************/ +#if (LINUX_VERSION_CODE < 0x020117) +static int isdn_divert_read(struct inode *inode, struct file *file, char *buf, RWARG count) +#else +static ssize_t isdn_divert_read(struct file *file, char *buf, size_t count, loff_t *off) +#endif +{ struct divert_info *inf; + int len; + + if (!*((struct divert_info **)file->private_data)) + { if (file->f_flags & O_NONBLOCK) + return -EAGAIN; + interruptible_sleep_on(&(rd_queue)); + } + if (!(inf = *((struct divert_info **)file->private_data))) return(0); + + inf->usage_cnt--; /* new usage count */ + (struct divert_info **)file->private_data = &inf->next; /* next structure */ + if ((len = strlen(inf->info_start)) <= count) + { if (copy_to_user(buf, inf->info_start, len)) + return -EFAULT; + file->f_pos += len; + return(len); + } + return(0); +} /* isdn_divert_read */ + +/**********************************/ +/* deflection device write routine */ +/**********************************/ +#if (LINUX_VERSION_CODE < 0x020117) +static int isdn_divert_write(struct inode *inode, struct file *file, const char *buf, RWARG count) +#else +static ssize_t isdn_divert_write(struct file *file, const char *buf, size_t count, loff_t *off) +#endif +{ + return(-ENODEV); +} /* isdn_divert_write */ + + +/***************************************/ +/* select routines for various kernels */ +/***************************************/ +#if (LINUX_VERSION_CODE < 0x020117) +static int isdn_divert_select(struct inode *inode, struct file *file, int type, select_table * st) +{ + if (*((struct divert_info **)file->private_data)) + return 1; + else + { if (st) select_wait(&(rd_queue), st); + return 0; + } +} /* isdn_divert_select */ +#else +static unsigned int isdn_divert_poll(struct file *file, poll_table * wait) +{ unsigned int mask = 0; + + poll_wait(file, &(rd_queue), wait); + /* mask = POLLOUT | POLLWRNORM; */ + if (*((struct divert_info **)file->private_data)) + { mask |= POLLIN | POLLRDNORM; + } + return mask; +} /* isdn_divert_poll */ +#endif + +/****************/ +/* Open routine */ +/****************/ +static int isdn_divert_open(struct inode *ino, struct file *filep) +{ int flags; + + MOD_INC_USE_COUNT; + save_flags(flags); + cli(); + if_used++; + if (divert_info_head) + (struct divert_info **)filep->private_data = &(divert_info_tail->next); + else + (struct divert_info **)filep->private_data = &divert_info_head; + restore_flags(flags); + /* start_divert(); */ + return(0); +} /* isdn_divert_open */ + +/*******************/ +/* close routine */ +/*******************/ +#if (LINUX_VERSION_CODE < 0x020117) +static void isdn_divert_close(struct inode *ino, struct file *filep) +#else +static int isdn_divert_close(struct inode *ino, struct file *filep) +#endif +{ struct divert_info *inf; + int flags; + + save_flags(flags); + cli(); + if_used--; + inf = *((struct divert_info **)filep->private_data); + while (inf) + { inf->usage_cnt--; + inf = inf->next; + } + restore_flags(flags); + if (if_used <= 0) + while (divert_info_head) + { inf = divert_info_head; + divert_info_head = divert_info_head->next; + kfree(inf); + } + MOD_DEC_USE_COUNT; +#if (LINUX_VERSION_CODE < 0x020117) +#else + return(0); +#endif +} /* isdn_divert_close */ + +/*********/ +/* IOCTL */ +/*********/ +static int isdn_divert_ioctl(struct inode *inode, struct file *file, + uint cmd, ulong arg) +{ divert_ioctl dioctl; + int i, flags; + divert_rule *rulep; + char *cp; + + if ((i = copy_from_user(&dioctl,(char *) arg, sizeof(dioctl)))) + return(i); + + switch (cmd) + { + case IIOCGETVER: + dioctl.drv_version = DIVERT_IIOC_VERSION ; /* set version */ + break; + + case IIOCGETDRV: + if ((dioctl.getid.drvid = divert_if.name_to_drv(dioctl.getid.drvnam)) < 0) + return(-EINVAL); + break; + + case IIOCGETNAM: + cp = divert_if.drv_to_name(dioctl.getid.drvid); + if (!cp) return(-EINVAL); + if (!*cp) return(-EINVAL); + strcpy(dioctl.getid.drvnam,cp); + break; + + case IIOCGETRULE: + if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx))) + return(-EINVAL); + dioctl.getsetrule.rule = *rulep; /* copy data */ + break; + + case IIOCMODRULE: + if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx))) + return(-EINVAL); + save_flags(flags); + cli(); + *rulep = dioctl.getsetrule.rule; /* copy data */ + restore_flags(flags); + return(0); /* no copy required */ + break; + + case IIOCINSRULE: + return(insertrule(dioctl.getsetrule.ruleidx,&dioctl.getsetrule.rule)); + break; + + case IIOCDELRULE: + return(deleterule(dioctl.getsetrule.ruleidx)); + break; + + case IIOCDODFACT: + return(deflect_extern_action(dioctl.fwd_ctrl.subcmd, + dioctl.fwd_ctrl.callid, + dioctl.fwd_ctrl.to_nr)); + + case IIOCDOCFACT: + case IIOCDOCFDIS: + case IIOCDOCFINT: + if (!divert_if.drv_to_name(dioctl.cf_ctrl.drvid)) + return(-EINVAL); /* invalid driver */ + if ((i = cf_command(dioctl.cf_ctrl.drvid, + (cmd == IIOCDOCFACT) ? 1: (cmd == IIOCDOCFDIS) ? 0:2, + dioctl.cf_ctrl.cfproc, + dioctl.cf_ctrl.msn, + dioctl.cf_ctrl.service, + dioctl.cf_ctrl.fwd_nr, + &dioctl.cf_ctrl.procid))) + return(i); + break; + + default: + return(-EINVAL); + } /* switch cmd */ + return(copy_to_user((char *) arg, &dioctl, sizeof(dioctl))); /* success */ +} /* isdn_divert_ioctl */ + + +#ifdef CONFIG_PROC_FS +#if (LINUX_VERSION_CODE < 0x020117) +static LSTYPE +isdn_divert_lseek(struct inode *inode, struct file *file, LSARG offset, int orig) +#else +static loff_t +isdn_divert_lseek(struct file *file, loff_t offset, int orig) +#endif +{ + return -ESPIPE; +} + +#if (LINUX_VERSION_CODE < 0x020117) +static struct file_operations isdn_fops = +{ + isdn_divert_lseek, + isdn_divert_read, + isdn_divert_write, + NULL, /* isdn_readdir */ + isdn_divert_select, /* isdn_select */ + isdn_divert_ioctl, /* isdn_ioctl */ + NULL, /* isdn_mmap */ + isdn_divert_open, + isdn_divert_close, + NULL /* fsync */ +}; + +#else + +static struct file_operations isdn_fops = +{ + isdn_divert_lseek, + isdn_divert_read, + isdn_divert_write, + NULL, /* isdn_readdir */ + isdn_divert_poll, /* isdn_poll */ + isdn_divert_ioctl, /* isdn_ioctl */ + NULL, /* isdn_mmap */ + isdn_divert_open, + NULL, /* flush */ + isdn_divert_close, + NULL /* fsync */ +}; +#endif /* kernel >= 2.1 */ + + +/* + * proc directories can do almost nothing.. + */ +struct inode_operations proc_isdn_inode_ops = { + &isdn_fops, /* isdn divert special file-ops */ + NULL, /* create */ + NULL, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + NULL, /* readlink */ + NULL, /* follow_link */ + NULL, /* readpage */ + NULL, /* writepage */ + NULL, /* bmap */ + NULL, /* truncate */ + NULL /* permission */ +}; + +/****************************/ +/* isdn subdir in /proc/net */ +/****************************/ +static struct proc_dir_entry isdn_proc_entry = + { 0, 4, "isdn", S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0, 0, + &proc_dir_inode_operations,NULL,NULL,NULL,NULL,NULL + }; + +static struct proc_dir_entry isdn_divert_entry = +{ 0, 6, "divert",S_IFREG | S_IRUGO, 1, 0, 0, 0, &proc_isdn_inode_ops, + NULL + }; + +/*****************************************************************/ +/* variables used for automatic determining existence of proc fs */ +/*****************************************************************/ +static int (*proc_reg_dynamic)(struct proc_dir_entry *, struct proc_dir_entry *) = NULL; +static int (*proc_unreg)(struct proc_dir_entry *, int) = NULL; + +#endif CONFIG_PROC_FS + +/***************************************************************************/ +/* divert_dev_init must be called before the proc filesystem may be used */ +/***************************************************************************/ +int divert_dev_init(void) +{ int i; + +#ifdef COMPAT_HAS_NEW_WAITQ + init_waitqueue_head(&rd_queue); +#endif + +#ifdef CONFIG_PROC_FS +#if (LINUX_VERSION_CODE < 0x020117) + (void *) proc_reg_dynamic = get_module_symbol("","proc_register_dynamic"); + (void *) proc_unreg = get_module_symbol("","proc_unregister"); + if (proc_unreg) + { i = proc_reg_dynamic(&proc_net,&isdn_proc_entry); + if (i) return(i); + i = proc_reg_dynamic(&isdn_proc_entry,&isdn_divert_entry); + if (i) + { proc_unreg(&proc_net,isdn_proc_entry.low_ino); + return(i); + } + } /* proc exists */ +#else + (void *) proc_reg_dynamic = get_module_symbol("","proc_register"); + (void *) proc_unreg = get_module_symbol("","proc_unregister"); + if (proc_unreg) + { i = proc_reg_dynamic(proc_net,&isdn_proc_entry); + if (i) return(i); + i = proc_reg_dynamic(&isdn_proc_entry,&isdn_divert_entry); + if (i) + { proc_unreg(proc_net,isdn_proc_entry.low_ino); + return(i); + } + } /* proc exists */ +#endif +#endif CONFIG_PROC_FS + + return(0); +} /* divert_dev_init */ + +/***************************************************************************/ +/* divert_dev_deinit must be called before leaving isdn when included as */ +/* a module. */ +/***************************************************************************/ +int divert_dev_deinit(void) +{ int i; + +#ifdef CONFIG_PROC_FS + if (proc_unreg) + { i = proc_unreg(&isdn_proc_entry,isdn_divert_entry.low_ino); + if (i) return(i); +#if (LINUX_VERSION_CODE < 0x020117) + i = proc_unreg(&proc_net,isdn_proc_entry.low_ino); +#else + i = proc_unreg(proc_net,isdn_proc_entry.low_ino); +#endif + if (i) return(i); + } /* proc exists */ +#endif CONFIG_PROC_FS + + return(0); +} /* divert_dev_deinit */ + diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/divert/isdn_divert.c linux/drivers/isdn/divert/isdn_divert.c --- v2.3.13/linux/drivers/isdn/divert/isdn_divert.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/divert/isdn_divert.c Sun Aug 15 11:49:08 1999 @@ -0,0 +1,901 @@ +/* + * $Id: isdn_divert.c,v 1.2 1999/07/04 21:37:32 werner Exp $ + * + * DSS1 main diversion supplementary handling for i4l. + * + * Copyright 1999 by Werner Cornelius (werner@isdn4linux.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Log: isdn_divert.c,v $ + * Revision 1.2 1999/07/04 21:37:32 werner + * Ported from kernel version 2.0 + * + * + * + */ + + + +#define __NO_VERSION__ +#include +#include +#include +#include "isdn_divert.h" + +/**********************************/ +/* structure keeping calling info */ +/**********************************/ +struct call_struc + { isdn_ctrl ics; /* delivered setup + driver parameters */ + ulong divert_id; /* Id delivered to user */ + unsigned char akt_state; /* actual state */ + char deflect_dest[35]; /* deflection destination */ + struct timer_list timer; /* timer control structure */ + char info[90]; /* device info output */ + struct call_struc *next; /* pointer to next entry */ + struct call_struc *prev; + }; + + +/********************************************/ +/* structure keeping deflection table entry */ +/********************************************/ +struct deflect_struc + { struct deflect_struc *next,*prev; + divert_rule rule; /* used rule */ + }; + + +/*****************************************/ +/* variables for main diversion services */ +/*****************************************/ +/* diversion/deflection processes */ +static struct call_struc *divert_head = NULL; /* head of remembered entrys */ +static ulong next_id = 1; /* next info id */ +static struct deflect_struc *table_head = NULL; +static struct deflect_struc *table_tail = NULL; +static unsigned char extern_wait_max = 4; /* maximum wait in s for external process */ + +/***************************/ +/* timer callback function */ +/***************************/ +static void deflect_timer_expire(ulong arg) +{ int flags; + struct call_struc *cs = (struct call_struc *) arg; + + save_flags(flags); + cli(); + del_timer(&cs->timer); /* delete active timer */ + restore_flags(flags); + + switch(cs->akt_state) + { case DEFLECT_PROCEED: + cs->ics.command = ISDN_CMD_HANGUP; /* cancel action */ + divert_if.ll_cmd(&cs->ics); + save_flags(flags); + cli(); + cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */ + cs->timer.expires = jiffies + (HZ * AUTODEL_TIME); + add_timer(&cs->timer); + restore_flags(flags); + break; + + case DEFLECT_ALERT: + cs->ics.command = ISDN_CMD_REDIR; /* protocol */ + strcpy(cs->ics.parm.setup.phone,cs->deflect_dest); + strcpy(cs->ics.parm.setup.eazmsn,"Testtext delayed"); + divert_if.ll_cmd(&cs->ics); + save_flags(flags); + cli(); + cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */ + cs->timer.expires = jiffies + (HZ * AUTODEL_TIME); + add_timer(&cs->timer); + restore_flags(flags); + break; + + case DEFLECT_AUTODEL: + default: + save_flags(flags); + cli(); + if (cs->prev) + cs->prev->next = cs->next; /* forward link */ + else + divert_head = cs->next; + if (cs->next) + cs->next->prev = cs->prev; /* back link */ + restore_flags(flags); + kfree(cs); + return; + + } /* switch */ +} /* deflect_timer_func */ + + +/*****************************************/ +/* handle call forwarding de/activations */ +/* 0 = deact, 1 = act, 2 = interrogate */ +/*****************************************/ +int cf_command(int drvid, int mode, + u_char proc, char *msn, + u_char service, char *fwd_nr, ulong *procid) +{ int retval,msnlen,flags; + int fwd_len; + char *p,*ielenp,tmp[60]; + struct call_struc *cs; + + if (strchr(msn,'.')) return(-EINVAL); /* subaddress not allowed in msn */ + if ((proc & 0x7F) > 2) return(-EINVAL); + proc &= 3; + p = tmp; + *p++ = 0x30; /* enumeration */ + ielenp = p++; /* remember total length position */ + *p++ = 0xa; /* proc tag */ + *p++ = 1; /* length */ + *p++ = proc & 0x7F; /* procedure to de/activate/interrogate */ + *p++ = 0xa; /* service tag */ + *p++ = 1; /* length */ + *p++ = service; /* service to handle */ + + if (mode == 1) + { if (!*fwd_nr) return(-EINVAL); /* destination missing */ + if (strchr(fwd_nr,'.')) return(-EINVAL); /* subaddress not allowed */ + fwd_len = strlen(fwd_nr); + *p++ = 0x30; /* number enumeration */ + *p++ = fwd_len + 2; /* complete forward to len */ + *p++ = 0x80; /* fwd to nr */ + *p++ = fwd_len; /* length of number */ + strcpy(p,fwd_nr); /* copy number */ + p += fwd_len; /* pointer beyond fwd */ + } /* activate */ + + msnlen = strlen(msn); + *p++ = 0x80; /* msn number */ + if (msnlen > 1) + { *p++ = msnlen; /* length */ + strcpy(p,msn); + p += msnlen; + } + else *p++ = 0; + + *ielenp = p - ielenp - 1; /* set total IE length */ + + /* allocate mem for information struct */ + if (!(cs = (struct call_struc *) kmalloc(sizeof(struct call_struc), GFP_ATOMIC))) + return(-ENOMEM); /* no memory */ + init_timer(&cs->timer); + cs->info[0] = '\0'; + cs->timer.function = deflect_timer_expire; + cs->timer.data = (ulong) cs; /* pointer to own structure */ + cs->ics.driver = drvid; + cs->ics.command = ISDN_CMD_PROT_IO; /* protocol specific io */ + cs->ics.arg = DSS1_CMD_INVOKE; /* invoke supplementary service */ + cs->ics.parm.dss1_io.proc = (mode == 1) ? 7: (mode == 2) ? 11:8; /* operation */ + cs->ics.parm.dss1_io.timeout = 4000; /* from ETS 300 207-1 */ + cs->ics.parm.dss1_io.datalen = p - tmp; /* total len */ + cs->ics.parm.dss1_io.data = tmp; /* start of buffer */ + + save_flags(flags); + cli(); + cs->ics.parm.dss1_io.ll_id = next_id++; /* id for callback */ + restore_flags(flags); + *procid = cs->ics.parm.dss1_io.ll_id; + + sprintf(cs->info,"%d 0x%lx %s%s 0 %s %0x %d%s%s\n", + (!mode ) ? DIVERT_DEACTIVATE : (mode == 1) ? DIVERT_ACTIVATE : DIVERT_REPORT, + cs->ics.parm.dss1_io.ll_id, + (mode != 2) ? "" : "0 ", + divert_if.drv_to_name(cs->ics.driver), + msn, + service & 0xFF, + proc, + (mode != 1) ? "" : " 0 ", + (mode != 1) ? "" : fwd_nr); + + retval = divert_if.ll_cmd(&cs->ics); /* excute command */ + + if (!retval) + { cs->prev = NULL; + save_flags(flags); + cli(); + cs->next = divert_head; + divert_head = cs; + restore_flags(flags); + } + else + kfree(cs); + return(retval); +} /* cf_command */ + + +/****************************************/ +/* handle a external deflection command */ +/****************************************/ +int deflect_extern_action(u_char cmd, ulong callid, char *to_nr) +{ struct call_struc *cs; + isdn_ctrl ic; + int flags; + int i; + + if ((cmd & 0x7F) > 2) return(-EINVAL); /* invalid command */ + cs = divert_head; /* start of parameter list */ + while (cs) + { if (cs->divert_id == callid) break; /* found */ + cs = cs->next; + } /* search entry */ + if (!cs) return(-EINVAL); /* invalid callid */ + + ic.driver = cs->ics.driver; + ic.arg = cs->ics.arg; + i = -EINVAL; + if (cs->akt_state == DEFLECT_AUTODEL) return(i); /* no valid call */ + switch (cmd & 0x7F) + { case 0: /* hangup */ + del_timer(&cs->timer); + ic.command = ISDN_CMD_HANGUP; + i = divert_if.ll_cmd(&ic); + save_flags(flags); + cli(); + cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */ + cs->timer.expires = jiffies + (HZ * AUTODEL_TIME); + add_timer(&cs->timer); + restore_flags(flags); + break; + + case 1: /* alert */ + if (cs->akt_state == DEFLECT_ALERT) return(0); + cmd &= 0x7F; /* never wait */ + del_timer(&cs->timer); + ic.command = ISDN_CMD_ALERT; + if ((i = divert_if.ll_cmd(&ic))) + { save_flags(flags); + cli(); + cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */ + cs->timer.expires = jiffies + (HZ * AUTODEL_TIME); + add_timer(&cs->timer); + restore_flags(flags); + } + else + cs->akt_state = DEFLECT_ALERT; + break; + + case 2: /* redir */ + del_timer(&cs->timer); + strcpy(cs->ics.parm.setup.phone, to_nr); + strcpy(cs->ics.parm.setup.eazmsn, "Testtext manual"); + ic.command = ISDN_CMD_REDIR; + if ((i = divert_if.ll_cmd(&ic))) + { save_flags(flags); + cli(); + cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */ + cs->timer.expires = jiffies + (HZ * AUTODEL_TIME); + add_timer(&cs->timer); + restore_flags(flags); + } + else + cs->akt_state = DEFLECT_ALERT; + break; + + } /* switch */ + return(i); +} /* deflect_extern_action */ + +/********************************/ +/* insert a new rule before idx */ +/********************************/ +int insertrule(int idx, divert_rule *newrule) +{ struct deflect_struc *ds,*ds1; + int flags; + + if (!(ds = (struct deflect_struc *) kmalloc(sizeof(struct deflect_struc), + GFP_KERNEL))) + return(-ENOMEM); /* no memory */ + + ds->rule = *newrule; /* set rule */ + + save_flags(flags); + cli(); + + if (idx >= 0) + { ds1 = table_head; + while ((ds1) && (idx > 0)) + { idx--; + ds1 = ds1->next; + } + if (!ds1) idx = -1; + } + + if (idx < 0) + { ds->prev = table_tail; /* previous entry */ + ds->next = NULL; /* end of chain */ + if (ds->prev) + ds->prev->next = ds; /* last forward */ + else + table_head = ds; /* is first entry */ + table_tail = ds; /* end of queue */ + } + else + { ds->next = ds1; /* next entry */ + ds->prev = ds1->prev; /* prev entry */ + ds1->prev = ds; /* backward chain old element */ + if (!ds->prev) + table_head = ds; /* first element */ + } + + restore_flags(flags); + return(0); +} /* insertrule */ + +/***********************************/ +/* delete the rule at position idx */ +/***********************************/ +int deleterule(int idx) +{ struct deflect_struc *ds,*ds1; + int flags; + + if (idx < 0) + { save_flags(flags); + cli(); + ds = table_head; + table_head = NULL; + table_tail = NULL; + restore_flags(flags); + while (ds) + { ds1 = ds; + ds = ds->next; + kfree(ds1); + } + return(0); + } + + save_flags(flags); + cli(); + ds = table_head; + + while ((ds) && (idx > 0)) + { idx--; + ds = ds->next; + } + + if (!ds) + { restore_flags(flags); + return(-EINVAL); + } + + if (ds->next) + ds->next->prev = ds->prev; /* backward chain */ + else + table_tail = ds->prev; /* end of chain */ + + if (ds->prev) + ds->prev->next = ds->next; /* forward chain */ + else + table_head = ds->next; /* start of chain */ + + restore_flags(flags); + kfree(ds); + return(0); +} /* deleterule */ + +/*******************************************/ +/* get a pointer to a specific rule number */ +/*******************************************/ +divert_rule *getruleptr(int idx) +{ struct deflect_struc *ds = table_head; + + if (idx < 0) return(NULL); + while ((ds) && (idx >= 0)) + { if (!(idx--)) + { return(&ds->rule); + break; + } + ds = ds->next; + } + return(NULL); +} /* getruleptr */ + +/*************************************************/ +/* called from common module on an incoming call */ +/*************************************************/ +int isdn_divert_icall(isdn_ctrl *ic) +{ int retval = 0; + int flags; + struct call_struc *cs = NULL; + struct deflect_struc *dv; + char *p,*p1; + u_char accept; + + /* first check the internal deflection table */ + for (dv = table_head; dv ; dv = dv->next ) + { /* scan table */ + if (((dv->rule.callopt == 1) && (ic->command == ISDN_STAT_ICALLW)) || + ((dv->rule.callopt == 2) && (ic->command == ISDN_STAT_ICALL))) + continue; /* call option check */ + if (!(dv->rule.drvid & (1L << ic->driver))) + continue; /* driver not matching */ + if ((dv->rule.si1) && (dv->rule.si1 != ic->parm.setup.si1)) + continue; /* si1 not matching */ + if ((dv->rule.si2) && (dv->rule.si2 != ic->parm.setup.si2)) + continue; /* si2 not matching */ + + p = dv->rule.my_msn; + p1 = ic->parm.setup.eazmsn; + accept = 0; + while (*p) + { /* complete compare */ + if (*p == '-') + { accept = 1; /* call accepted */ + break; + } + if (*p++ != *p1++) + break; /* not accepted */ + if ((!*p) && (!*p1)) + accept = 1; + } /* complete compare */ + if (!accept) continue; /* not accepted */ + + if ((strcmp(dv->rule.caller,"0")) || (ic->parm.setup.phone[0])) + { p = dv->rule.caller; + p1 = ic->parm.setup.phone; + accept = 0; + while (*p) + { /* complete compare */ + if (*p == '-') + { accept = 1; /* call accepted */ + break; + } + if (*p++ != *p1++) + break; /* not accepted */ + if ((!*p) && (!*p1)) + accept = 1; + } /* complete compare */ + if (!accept) continue; /* not accepted */ + } + + switch (dv->rule.action) + { case DEFLECT_IGNORE: + return(0); + break; + + case DEFLECT_ALERT: + case DEFLECT_PROCEED: + case DEFLECT_REPORT: + case DEFLECT_REJECT: + if (dv->rule.action == DEFLECT_PROCEED) + if ((!if_used) || ((!extern_wait_max) && (!dv->rule.waittime))) + return(0); /* no external deflection needed */ + if (!(cs = (struct call_struc *) kmalloc(sizeof(struct call_struc), GFP_ATOMIC))) + return(0); /* no memory */ + init_timer(&cs->timer); + cs->info[0] = '\0'; + cs->timer.function = deflect_timer_expire; + cs->timer.data = (ulong) cs; /* pointer to own structure */ + + cs->ics = *ic; /* copy incoming data */ + if (!cs->ics.parm.setup.phone[0]) strcpy(cs->ics.parm.setup.phone,"0"); + if (!cs->ics.parm.setup.eazmsn[0]) strcpy(cs->ics.parm.setup.eazmsn,"0"); + cs->ics.parm.setup.screen = dv->rule.screen; + if (dv->rule.waittime) + cs->timer.expires = jiffies + (HZ * dv->rule.waittime); + else + if (dv->rule.action == DEFLECT_PROCEED) + cs->timer.expires = jiffies + (HZ * extern_wait_max); + else + cs->timer.expires = 0; + cs->akt_state = dv->rule.action; + save_flags(flags); + cli(); + cs->divert_id = next_id++; /* new sequence number */ + restore_flags(flags); + cs->prev = NULL; + if (cs->akt_state == DEFLECT_ALERT) + { strcpy(cs->deflect_dest,dv->rule.to_nr); + if (!cs->timer.expires) + { strcpy(ic->parm.setup.eazmsn,"Testtext direkt"); + ic->parm.setup.screen = dv->rule.screen; + strcpy(ic->parm.setup.phone,dv->rule.to_nr); + cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */ + cs->timer.expires = jiffies + (HZ * AUTODEL_TIME); + retval = 4; + } + else + retval = 1; /* alerting */ + } + else + { cs->deflect_dest[0] = '\0'; + retval = 3; /* only proceed */ + } + sprintf(cs->info,"%d 0x%lx %s %s %s %s 0x%x 0x%x %d %d %s\n", + cs->akt_state, + cs->divert_id, + divert_if.drv_to_name(cs->ics.driver), + (ic->command == ISDN_STAT_ICALLW) ? "1":"0", + cs->ics.parm.setup.phone, + cs->ics.parm.setup.eazmsn, + cs->ics.parm.setup.si1, + cs->ics.parm.setup.si2, + cs->ics.parm.setup.screen, + dv->rule.waittime, + cs->deflect_dest); + if ((dv->rule.action == DEFLECT_REPORT) || + (dv->rule.action == DEFLECT_REJECT)) + { put_info_buffer(cs->info); + kfree(cs); /* remove */ + return((dv->rule.action == DEFLECT_REPORT) ? 0:2); /* nothing to do */ + } + break; + + default: + return(0); /* ignore call */ + break; + } /* switch action */ + break; + } /* scan_table */ + + if (cs) + { cs->prev = NULL; + save_flags(flags); + cli(); + cs->next = divert_head; + divert_head = cs; + if (cs->timer.expires) add_timer(&cs->timer); + restore_flags(flags); + + put_info_buffer(cs->info); + return(retval); + } + else + return(0); +} /* isdn_divert_icall */ + + +void deleteprocs(void) +{ struct call_struc *cs, *cs1; + int flags; + + save_flags(flags); + cli(); + cs = divert_head; + divert_head = NULL; + while (cs) + { del_timer(&cs->timer); + cs1 = cs; + cs = cs->next; + kfree(cs1); + } + restore_flags(flags); +} /* deleteprocs */ + +/****************************************************/ +/* put a address including address type into buffer */ +/****************************************************/ +int put_address(char *st, u_char *p, int len) +{ u_char retval = 0; + u_char adr_typ = 0; /* network standard */ + + if (len < 2) return(retval); + if (*p == 0xA1) + { retval = *(++p) + 2; /* total length */ + if (retval > len) return(0); /* too short */ + len = retval - 2; /* remaining length */ + if (len < 3) return(0); + if ((*(++p) != 0x0A) || (*(++p) != 1)) return(0); + adr_typ = *(++p); + len -= 3; + p++; + if (len < 2) return(0); + if (*p++ != 0x12) return(0); + if (*p > len) return(0); /* check number length */ + len = *p++; + } + else + if (*p == 0x80) + { retval = *(++p) + 2; /* total length */ + if (retval > len) return(0); + len = retval - 2; + p++; + } + else + return(0); /* invalid address information */ + + sprintf(st,"%d ",adr_typ); + st += strlen(st); + if (!len) + *st++ = '-'; + else + while (len--) + *st++ = *p++; + *st = '\0'; + return(retval); +} /* put_address */ + +/*************************************/ +/* report a succesfull interrogation */ +/*************************************/ +int interrogate_success(isdn_ctrl *ic, struct call_struc *cs) +{ char *src = ic->parm.dss1_io.data; + int restlen = ic->parm.dss1_io.datalen; + int cnt = 1; + u_char n,n1; + char st[90], *p, *stp; + + if (restlen < 2) return(-100); /* frame too short */ + if (*src++ != 0x30) return(-101); + if ((n = *src++) > 0x81) return(-102); /* invalid length field */ + restlen -= 2; /* remaining bytes */ + if (n == 0x80) + { if (restlen < 2) return(-103); + if ((*(src+restlen-1)) || (*(src+restlen-2))) return(-104); + restlen -= 2; + } + else + if ( n == 0x81) + { n = *src++; + restlen--; + if (n > restlen) return(-105); + restlen = n; + } + else + if (n > restlen) return(-106); + else + restlen = n; /* standard format */ + if (restlen < 3) return(-107); /* no procedure */ + if ((*src++ != 2) || (*src++ != 1) || (*src++ != 0x0B)) return(-108); + restlen -= 3; + if (restlen < 2) return(-109); /* list missing */ + if (*src == 0x31) + { src++; + if ((n = *src++) > 0x81) return(-110); /* invalid length field */ + restlen -= 2; /* remaining bytes */ + if (n == 0x80) + { if (restlen < 2) return(-111); + if ((*(src+restlen-1)) || (*(src+restlen-2))) return(-112); + restlen -= 2; + } + else + if ( n == 0x81) + { n = *src++; + restlen--; + if (n > restlen) return(-113); + restlen = n; + } + else + if (n > restlen) return(-114); + else + restlen = n; /* standard format */ + } /* result list header */ + + while (restlen >= 2) + { stp = st; + sprintf(stp,"%d 0x%lx %d %s ",DIVERT_REPORT, ic->parm.dss1_io.ll_id, + cnt++,divert_if.drv_to_name(ic->driver)); + stp += strlen(stp); + if (*src++ != 0x30) return(-115); /* invalid enum */ + n = *src++; + restlen -= 2; + if (n > restlen) return(-116); /* enum length wrong */ + restlen -= n; + p = src; /* one entry */ + src += n; + if (!(n1 = put_address(stp,p,n & 0xFF))) continue; + stp += strlen(stp); + p += n1; + n -= n1; + if (n < 6) continue; /* no service and proc */ + if ((*p++ != 0x0A) || (*p++ != 1)) continue; + sprintf(stp," 0x%02x ",(*p++) & 0xFF); + stp += strlen(stp); + if ((*p++ != 0x0A) || (*p++ != 1)) continue; + sprintf(stp,"%d ",(*p++) & 0xFF); + stp += strlen(stp); + n -= 6; + if (n > 2) + { if (*p++ != 0x30) continue; + if (*p > (n-2)) continue; + n = *p++; + if (!(n1 = put_address(stp,p,n & 0xFF))) continue; + stp += strlen(stp); + } + sprintf(stp,"\n"); + put_info_buffer(st); + } /* while restlen */ + if (restlen) return(-117); + return(0); +} /* interrogate_success */ + +/*********************************************/ +/* callback for protocol specific extensions */ +/*********************************************/ +int prot_stat_callback(isdn_ctrl *ic) +{ struct call_struc *cs, *cs1; + int i,flags; + + cs = divert_head; /* start of list */ + cs1 = NULL; + while (cs) + { if (ic->driver == cs->ics.driver) + { switch (cs->ics.arg) + { case DSS1_CMD_INVOKE: + if ((cs->ics.parm.dss1_io.ll_id == ic->parm.dss1_io.ll_id) && + (cs->ics.parm.dss1_io.hl_id == ic->parm.dss1_io.hl_id)) + { switch (ic->arg) + { case DSS1_STAT_INVOKE_ERR: + sprintf(cs->info,"128 0x%lx 0x%x\n", + ic->parm.dss1_io.ll_id, + ic->parm.dss1_io.timeout); + put_info_buffer(cs->info); + break; + + case DSS1_STAT_INVOKE_RES: + switch (cs->ics.parm.dss1_io.proc) + { case 7: + case 8: + put_info_buffer(cs->info); + break; + + case 11: + i = interrogate_success(ic,cs); + if (i) + sprintf(cs->info,"%d 0x%lx %d\n",DIVERT_REPORT, + ic->parm.dss1_io.ll_id,i); + put_info_buffer(cs->info); + break; + + default: + printk(KERN_WARNING "dss1_divert: unknown proc %d\n",cs->ics.parm.dss1_io.proc); + break; + } + + +#if 0 + sprintf(st, "0x%lx 0x%lx",ic->arg, ic->parm.dss1_io.ll_id); + p = st + strlen(st); + p1 = ic->parm.dss1_io.data; + i = ic->parm.dss1_io.datalen; + while ((i > 0) && (p - st < 530)) + { p += sprintf(p," %02x",(*p1++) & 0xFF); + i--; + } + sprintf(p, "\n"); + put_info_buffer(st); +#endif + break; + + default: + printk(KERN_WARNING "dss1_divert unknown invoke answer %lx\n",ic->arg); + break; + } + cs1 = cs; /* remember structure */ + cs = NULL; + continue; /* abort search */ + } /* id found */ + break; + + case DSS1_CMD_INVOKE_ABORT: + printk(KERN_WARNING "dss1_divert unhandled invoke abort\n"); + break; + + default: + printk(KERN_WARNING "dss1_divert unknown cmd 0x%lx\n",cs->ics.arg); + break; + } /* switch ics.arg */ + cs = cs->next; + } /* driver ok */ + } + + if (!cs1) + { printk(KERN_WARNING "dss1_divert unhandled process\n"); + return(0); + } + + if (cs1->ics.driver == -1) + { save_flags(flags); + cli(); + del_timer(&cs1->timer); + if (cs1->prev) + cs1->prev->next = cs1->next; /* forward link */ + else + divert_head = cs1->next; + if (cs1->next) + cs1->next->prev = cs1->prev; /* back link */ + restore_flags(flags); + kfree(cs1); + } + + return(0); +} /* prot_stat_callback */ + + +/***************************/ +/* status callback from HL */ +/***************************/ +int isdn_divert_stat_callback(isdn_ctrl *ic) +{ struct call_struc *cs, *cs1; + int flags, retval; + + retval = -1; + cs = divert_head; /* start of list */ + while (cs) + { if ((ic->driver == cs->ics.driver) && (ic->arg == cs->ics.arg)) + { switch (ic->command) + { case ISDN_STAT_DHUP: + sprintf(cs->info,"129 0x%lx\n",cs->divert_id); + del_timer(&cs->timer); + cs->ics.driver = -1; + break; + + case ISDN_STAT_CAUSE: + sprintf(cs->info,"130 0x%lx %s\n",cs->divert_id,ic->parm.num); + break; + + case ISDN_STAT_REDIR: + sprintf(cs->info,"131 0x%lx\n",cs->divert_id); + del_timer(&cs->timer); + cs->ics.driver = -1; + break; + + default: + sprintf(cs->info,"999 0x%lx 0x%x\n",cs->divert_id,(int)(ic->command)); + break; + } + put_info_buffer(cs->info); + retval = 0; + } + cs1 = cs; + cs = cs->next; + if (cs1->ics.driver == -1) + { + save_flags(flags); + cli(); + if (cs1->prev) + cs1->prev->next = cs1->next; /* forward link */ + else + divert_head = cs1->next; + if (cs1->next) + cs1->next->prev = cs1->prev; /* back link */ + restore_flags(flags); + kfree(cs1); + } + } + return(retval); /* not found */ +} /* isdn_divert_stat_callback */ + + +/********************/ +/* callback from ll */ +/********************/ +int ll_callback(isdn_ctrl *ic) +{ + switch (ic->command) + { case ISDN_STAT_ICALL: + case ISDN_STAT_ICALLW: + return(isdn_divert_icall(ic)); + break; + + case ISDN_STAT_PROT: + if ((ic->arg & 0xFF) == ISDN_PTYPE_EURO) + { if (ic->arg != DSS1_STAT_INVOKE_BRD) + return(prot_stat_callback(ic)); + else + return(0); /* DSS1 invoke broadcast */ + } + else + return(-1); /* protocol not euro */ + + default: + return(isdn_divert_stat_callback(ic)); + } +} /* ll_callback */ + diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/divert/isdn_divert.h linux/drivers/isdn/divert/isdn_divert.h --- v2.3.13/linux/drivers/isdn/divert/isdn_divert.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/divert/isdn_divert.h Sun Aug 15 11:49:08 1999 @@ -0,0 +1,158 @@ +/* + * $Id: isdn_divert.h,v 1.2 1999/07/04 21:37:33 werner Exp $ + * + * Header for the diversion supplementary ioctl interface. + * + * Copyright 1998 by Werner Cornelius (werner@ikt.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Log: isdn_divert.h,v $ + * Revision 1.2 1999/07/04 21:37:33 werner + * Ported from kernel version 2.0 + * + * + * + */ + + + +#include +#include + +/******************************************/ +/* IOCTL codes for interface to user prog */ +/******************************************/ +#define DIVERT_IIOC_VERSION 0x01 /* actual version */ +#define IIOCGETVER _IO('I', 1) /* get version of interface */ +#define IIOCGETDRV _IO('I', 2) /* get driver number */ +#define IIOCGETNAM _IO('I', 3) /* get driver name */ +#define IIOCGETRULE _IO('I', 4) /* read one rule */ +#define IIOCMODRULE _IO('I', 5) /* modify/replace a rule */ +#define IIOCINSRULE _IO('I', 6) /* insert/append one rule */ +#define IIOCDELRULE _IO('I', 7) /* delete a rule */ +#define IIOCDODFACT _IO('I', 8) /* hangup/reject/alert/immediately deflect a call */ +#define IIOCDOCFACT _IO('I', 9) /* activate control forwarding in PBX */ +#define IIOCDOCFDIS _IO('I',10) /* deactivate control forwarding in PBX */ +#define IIOCDOCFINT _IO('I',11) /* interrogate control forwarding in PBX */ + +/*************************************/ +/* states reported through interface */ +/*************************************/ +#define DEFLECT_IGNORE 0 /* ignore incoming call */ +#define DEFLECT_REPORT 1 /* only report */ +#define DEFLECT_PROCEED 2 /* deflect when externally triggered */ +#define DEFLECT_ALERT 3 /* alert and deflect after delay */ +#define DEFLECT_REJECT 4 /* reject immediately */ +#define DIVERT_ACTIVATE 5 /* diversion activate */ +#define DIVERT_DEACTIVATE 6 /* diversion deactivate */ +#define DIVERT_REPORT 7 /* interrogation result */ +#define DEFLECT_AUTODEL 255 /* only for internal use */ + +#define DEFLECT_ALL_IDS 0xFFFFFFFF /* all drivers selected */ + +typedef struct + { ulong drvid; /* driver ids, bit mapped */ + char my_msn[35]; /* desired msn, subaddr allowed */ + char caller[35]; /* caller id, partial string with * + subaddr allowed */ + char to_nr[35]; /* deflected to number incl. subaddress */ + u_char si1,si2; /* service indicators, si1=bitmask, si1+2 0 = all */ + u_char screen; /* screening: 0 = no info, 1 = info, 2 = nfo with nr */ + u_char callopt; /* option for call handling: + 0 = all calls + 1 = only non waiting calls + 2 = only waiting calls */ + u_char action; /* desired action: + 0 = don't report call -> ignore + 1 = report call, do not allow/proceed for deflection + 2 = report call, send proceed, wait max waittime secs + 3 = report call, alert and deflect after waittime + 4 = report call, reject immediately + actions 1-2 only take place if interface is opened + */ + u_char waittime; /* maximum wait time for proceeding */ + } divert_rule; + +typedef union + { int drv_version; /* return of driver version */ + struct + { int drvid; /* id of driver */ + char drvnam[30]; /* name of driver */ + } getid; + struct + { int ruleidx; /* index of rule */ + divert_rule rule; /* rule parms */ + } getsetrule; + struct + { u_char subcmd; /* 0 = hangup/reject, + 1 = alert, + 2 = deflect */ + ulong callid; /* id of call delivered by ascii output */ + char to_nr[35]; /* destination when deflect, + else uus1 string (maxlen 31), + data from rule used if empty */ + } fwd_ctrl; + struct + { int drvid; /* id of driver */ + u_char cfproc; /* cfu = 0, cfb = 1, cfnr = 2 */ + ulong procid; /* process id returned when no error */ + u_char service; /* basically coded service, 0 = all */ + char msn[25]; /* desired msn, empty = all */ + char fwd_nr[35];/* forwarded to number + subaddress */ + } cf_ctrl; + } divert_ioctl; + +#ifdef __KERNEL__ + +#include +#include + +#define AUTODEL_TIME 30 /* timeout in s to delete internal entrys */ + +/**************************************************/ +/* structure keeping ascii info for device output */ +/**************************************************/ +struct divert_info + { struct divert_info *next; + ulong usage_cnt; /* number of files still to work */ + char info_start[2]; /* info string start */ + }; + + +/**************/ +/* Prototypes */ +/**************/ +extern ulong if_used; /* number of interface users */ +extern int divert_dev_deinit(void); +extern int divert_dev_init(void); +extern void put_info_buffer(char *); +extern int ll_callback(isdn_ctrl *); +extern isdn_divert_if divert_if; +extern divert_rule *getruleptr(int); +extern int insertrule(int, divert_rule *); +extern int deleterule(int); +extern void deleteprocs(void); +extern int deflect_extern_action(u_char, ulong, char *); +extern int cf_command(int, int, u_char, char *, u_char, char *, ulong *); + +#endif __KERNEL__ + + + + + + + + diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/eicon/eicon.h linux/drivers/isdn/eicon/eicon.h --- v2.3.13/linux/drivers/isdn/eicon/eicon.h Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/eicon/eicon.h Sun Aug 15 11:49:08 1999 @@ -1,4 +1,4 @@ -/* $Id: eicon.h,v 1.5 1999/03/29 11:19:41 armin Exp $ +/* $Id: eicon.h,v 1.8 1999/07/25 15:12:01 armin Exp $ * * ISDN low-level module for Eicon.Diehl active ISDN-Cards. * @@ -21,6 +21,19 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: eicon.h,v $ + * Revision 1.8 1999/07/25 15:12:01 armin + * fix of some debug logs. + * enabled ISA-cards option. + * + * Revision 1.7 1999/07/11 17:16:23 armin + * Bugfixes in queue handling. + * Added DSP-DTMF decoder functions. + * Reorganized ack_handler. + * + * Revision 1.6 1999/06/09 19:31:24 armin + * Wrong PLX size for request_region() corrected. + * Added first MCA code from Erik Weber. + * * Revision 1.5 1999/03/29 11:19:41 armin * I/O stuff now in seperate file (eicon_io.c) * Old ISA type cards (S,SX,SCOM,Quadro,S2M) implemented. @@ -100,6 +113,7 @@ #define EICON_ISA_BOOT_NORMAL 2 /* Struct for downloading protocol via ioctl for ISA cards */ +/* same struct for downloading protocol via ioctl for MCA cards */ typedef struct { /* start-up parameters */ unsigned char tei; @@ -156,6 +170,7 @@ /* Data for downloading protocol via ioctl */ typedef union { eicon_isa_codebuf isa; + eicon_isa_codebuf mca; eicon_pci_codebuf pci; } eicon_codebuf; @@ -171,6 +186,7 @@ #ifdef __KERNEL__ /* Kernel includes */ +#include #include #include #include @@ -333,19 +349,39 @@ __u16 ref; /* saved reference */ } entity; +#define FAX_MAX_SCANLINE 256 + +typedef struct { + __u8 PrevObject; + __u8 NextObject; + __u8 abLine[FAX_MAX_SCANLINE]; + __u8 abFrame[FAX_MAX_SCANLINE]; + unsigned int LineLen; + unsigned int LineDataLen; + __u32 LineData; + unsigned int NullBytesPos; + __u8 NullByteExist; + int PageCount; + __u8 Dle; + __u8 Eop; +} eicon_ch_fax_buf; typedef struct { int No; /* Channel Number */ unsigned short callref; /* Call Reference */ unsigned short fsm_state; /* Current D-Channel state */ unsigned short eazmask; /* EAZ-Mask for this Channel */ - unsigned int queued; /* User-Data Bytes in TX queue */ - unsigned int waitq; /* User-Data Bytes in wait queue */ - unsigned int waitpq; /* User-Data Bytes in packet queue */ + int queued; /* User-Data Bytes in TX queue */ + int waitq; /* User-Data Bytes in wait queue */ + int waitpq; /* User-Data Bytes in packet queue */ unsigned short plci; unsigned short ncci; unsigned char l2prot; /* Layer 2 protocol */ unsigned char l3prot; /* Layer 3 protocol */ +#ifdef CONFIG_ISDN_TTY_FAX + T30_s *fax; /* pointer to fax data in LL */ + eicon_ch_fax_buf fax2; /* fax related struct */ +#endif entity e; /* Entity */ char cpn[32]; /* remember cpn */ char oad[32]; /* remember oad */ @@ -392,14 +428,10 @@ #define EICON_LOCK_TX 0 #define EICON_LOCK_RX 1 -typedef struct { - int dummy; -} eicon_mca_card; - typedef union { eicon_isa_card isa; eicon_pci_card pci; - eicon_mca_card mca; + eicon_isa_card mca; } eicon_hwif; typedef struct { @@ -465,6 +497,9 @@ char *status_buf_end; isdn_if interface; /* Interface to upper layer */ char regname[35]; /* Name used for request_region */ +#ifdef CONFIG_MCA + int mca_slot; /* # of cards MCA slot */ +#endif } eicon_card; /* -----------------------------------------------------------** @@ -521,6 +556,12 @@ extern void eicon_irq(int irq, void *dev_id, struct pt_regs *regs); extern void eicon_io_rcv_dispatch(eicon_card *ccard); extern void eicon_io_ack_dispatch(eicon_card *ccard); +#ifdef CONFIG_MCA +extern int eicon_mca_find_card(int, int, int, char *); +extern int eicon_mca_probe(int, int, int, int, char *); +extern int eicon_info(char *, int , void *); +#endif /* CONFIG_MCA */ + extern ulong DebugVar; #endif /* __KERNEL__ */ diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/eicon/eicon_dsp.h linux/drivers/isdn/eicon/eicon_dsp.h --- v2.3.13/linux/drivers/isdn/eicon/eicon_dsp.h Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/eicon/eicon_dsp.h Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: eicon_dsp.h,v 1.2 1999/03/29 11:19:42 armin Exp $ +/* $Id: eicon_dsp.h,v 1.4 1999/07/25 15:12:02 armin Exp $ * * ISDN lowlevel-module for Eicon.Diehl active cards. * DSP definitions @@ -21,6 +21,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: eicon_dsp.h,v $ + * Revision 1.4 1999/07/25 15:12:02 armin + * fix of some debug logs. + * enabled ISA-cards option. + * + * Revision 1.3 1999/07/11 17:16:24 armin + * Bugfixes in queue handling. + * Added DSP-DTMF decoder functions. + * Reorganized ack_handler. + * * Revision 1.2 1999/03/29 11:19:42 armin * I/O stuff now in seperate file (eicon_io.c) * Old ISA type cards (S,SX,SCOM,Quadro,S2M) implemented. @@ -31,7 +40,7 @@ * */ -#ifndef DSP_H +#ifndef DSP_H #define DSP_H #define DSP_UDATA_REQUEST_RECONFIGURE 0 @@ -264,6 +273,10 @@ tone duration (ms) gap duration (ms) */ +typedef struct enable_dtmf_s { + __u16 tone; + __u16 gap; +} enable_dtmf_s; #define DSP_UDATA_REQUEST_DISABLE_DTMF_RECEIVER 18 /* @@ -299,6 +312,108 @@ returns: - none - */ + +/* ============= FAX ================ */ + +#define EICON_FAXID_LEN 20 + +typedef struct eicon_t30_s { + __u8 code; + __u8 rate; + __u8 resolution; + __u8 format; + __u8 pages_low; + __u8 pages_high; + __u8 atf; + __u8 control_bits_low; + __u8 control_bits_high; + __u8 feature_bits_low; + __u8 feature_bits_high; + __u8 universal_5; + __u8 universal_6; + __u8 universal_7; + __u8 station_id_len; + __u8 head_line_len; + __u8 station_id[EICON_FAXID_LEN]; +/* __u8 head_line[]; */ +} eicon_t30_s; + + /* EDATA transmit messages */ +#define EDATA_T30_DIS 0x01 +#define EDATA_T30_FTT 0x02 +#define EDATA_T30_MCF 0x03 + + /* EDATA receive messages */ +#define EDATA_T30_DCS 0x81 +#define EDATA_T30_TRAIN_OK 0x82 +#define EDATA_T30_EOP 0x83 +#define EDATA_T30_MPS 0x84 +#define EDATA_T30_EOM 0x85 +#define EDATA_T30_DTC 0x86 + +#define T30_FORMAT_SFF 0 +#define T30_FORMAT_ASCII 1 +#define T30_FORMAT_COUNT 2 + +#define T30_CONTROL_BIT_DISABLE_FINE 0x0001 +#define T30_CONTROL_BIT_ENABLE_ECM 0x0002 +#define T30_CONTROL_BIT_ECM_64_BYTES 0x0004 +#define T30_CONTROL_BIT_ENABLE_2D_CODING 0x0008 +#define T30_CONTROL_BIT_ENABLE_T6_CODING 0x0010 +#define T30_CONTROL_BIT_ENABLE_UNCOMPR 0x0020 +#define T30_CONTROL_BIT_ACCEPT_POLLING 0x0040 +#define T30_CONTROL_BIT_REQUEST_POLLING 0x0080 +#define T30_CONTROL_BIT_MORE_DOCUMENTS 0x0100 + +#define T30_CONTROL_BIT_ALL_FEATURES\ + (T30_CONTROL_BIT_ENABLE_ECM | T30_CONTROL_BIT_ENABLE_2D_CODING |\ + T30_CONTROL_BIT_ENABLE_T6_CODING | T30_CONTROL_BIT_ENABLE_UNCOMPR) + +#define T30_FEATURE_BIT_FINE 0x0001 +#define T30_FEATURE_BIT_ECM 0x0002 +#define T30_FEATURE_BIT_ECM_64_BYTES 0x0004 +#define T30_FEATURE_BIT_2D_CODING 0x0008 +#define T30_FEATURE_BIT_T6_CODING 0x0010 +#define T30_FEATURE_BIT_UNCOMPR_ENABLED 0x0020 +#define T30_FEATURE_BIT_POLLING 0x0040 + +#define FAX_OBJECT_DOCU 1 +#define FAX_OBJECT_PAGE 2 +#define FAX_OBJECT_LINE 3 + +#define T4_EOL 0x800 +#define T4_EOL_BITSIZE 12 +#define T4_EOL_DWORD (T4_EOL << (32 - T4_EOL_BITSIZE)) +#define T4_EOL_MASK_DWORD ((__u32) -1 << (32 - T4_EOL_BITSIZE)) + +#define SFF_LEN_FLD_SIZE 3 + +#define _DLE_ 0x10 +#define _ETX_ 0x03 + +typedef struct eicon_sff_dochead { + __u32 id __attribute__ ((packed)); + __u8 version __attribute__ ((packed)); + __u8 reserved1 __attribute__ ((packed)); + __u16 userinfo __attribute__ ((packed)); + __u16 pagecount __attribute__ ((packed)); + __u16 off1pagehead __attribute__ ((packed)); + __u32 offnpagehead __attribute__ ((packed)); + __u32 offdocend __attribute__ ((packed)); +} eicon_sff_dochead; + +typedef struct eicon_sff_pagehead { + __u8 pageheadid __attribute__ ((packed)); + __u8 pageheadlen __attribute__ ((packed)); + __u8 resvert __attribute__ ((packed)); + __u8 reshoriz __attribute__ ((packed)); + __u8 coding __attribute__ ((packed)); + __u8 reserved2 __attribute__ ((packed)); + __u16 linelength __attribute__ ((packed)); + __u16 pagelength __attribute__ ((packed)); + __u32 offprevpage __attribute__ ((packed)); + __u32 offnextpage __attribute__ ((packed)); +} eicon_sff_pagehead; #endif /* DSP_H */ diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/eicon/eicon_idi.c linux/drivers/isdn/eicon/eicon_idi.c --- v2.3.13/linux/drivers/isdn/eicon/eicon_idi.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/eicon/eicon_idi.c Sun Aug 15 11:49:08 1999 @@ -1,4 +1,4 @@ -/* $Id: eicon_idi.c,v 1.9 1999/03/29 11:19:42 armin Exp $ +/* $Id: eicon_idi.c,v 1.11 1999/07/25 15:12:03 armin Exp $ * * ISDN lowlevel-module for Eicon.Diehl active cards. * IDI interface @@ -21,6 +21,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: eicon_idi.c,v $ + * Revision 1.11 1999/07/25 15:12:03 armin + * fix of some debug logs. + * enabled ISA-cards option. + * + * Revision 1.10 1999/07/11 17:16:24 armin + * Bugfixes in queue handling. + * Added DSP-DTMF decoder functions. + * Reorganized ack_handler. + * * Revision 1.9 1999/03/29 11:19:42 armin * I/O stuff now in seperate file (eicon_io.c) * Old ISA type cards (S,SX,SCOM,Quadro,S2M) implemented. @@ -61,6 +70,7 @@ * */ +#include #define __NO_VERSION__ #include "eicon.h" #include "eicon_idi.h" @@ -68,7 +78,7 @@ #undef EICON_FULL_SERVICE_OKTETT -char *eicon_idi_revision = "$Revision: 1.9 $"; +char *eicon_idi_revision = "$Revision: 1.11 $"; eicon_manifbuf *manbuf; @@ -86,11 +96,15 @@ int eicon_idi_manage_assign(eicon_card *card); int eicon_idi_manage_remove(eicon_card *card); +int idi_fill_in_T30(eicon_chan *chan, unsigned char *buffer); int idi_assign_req(eicon_REQ *reqbuf, int signet, eicon_chan *chan) { int l = 0; + int tmp; + + tmp = 0; if (!signet) { /* Signal Layer */ reqbuf->XBuffer.P[l++] = CAI; @@ -133,10 +147,25 @@ case ISDN_PROTO_L2_MODEM: reqbuf->XBuffer.P[l++] = 2; break; + case ISDN_PROTO_L2_FAX: + if (chan->fsm_state == EICON_STATE_IWAIT) + reqbuf->XBuffer.P[l++] = 3; /* autoconnect on incoming */ + else + reqbuf->XBuffer.P[l++] = 2; + break; default: reqbuf->XBuffer.P[l++] = 1; } switch(chan->l3prot) { + case ISDN_PROTO_L3_FAX: +#ifdef CONFIG_ISDN_TTY_FAX + reqbuf->XBuffer.P[l++] = 6; + reqbuf->XBuffer.P[l++] = NLC; + tmp = idi_fill_in_T30(chan, &reqbuf->XBuffer.P[l+1]); + reqbuf->XBuffer.P[l++] = tmp; + l += tmp; + break; +#endif case ISDN_PROTO_L3_TRANS: default: reqbuf->XBuffer.P[l++] = 4; @@ -210,6 +239,20 @@ reqbuf->XBuffer.P[6] = 128; reqbuf->XBuffer.P[7] = 0; break; + case ISDN_PROTO_L2_FAX: + reqbuf->XBuffer.P[2] = 0x10; + reqbuf->XBuffer.P[3] = 0; + reqbuf->XBuffer.P[4] = 0; + reqbuf->XBuffer.P[5] = 0; + reqbuf->XBuffer.P[6] = 128; + reqbuf->XBuffer.P[7] = 0; + break; + case ISDN_PROTO_L2_TRANS: + switch(chan->l3prot) { + case ISDN_PROTO_L3_TRANSDSP: + reqbuf->XBuffer.P[2] = 22; /* DTMF, audio events on */ + } + break; } reqbuf->XBuffer.P[8] = 0; reqbuf->XBuffer.length = l; @@ -222,8 +265,8 @@ int idi_do_req(eicon_card *card, eicon_chan *chan, int cmd, int layer) { - struct sk_buff *skb; - struct sk_buff *skb2; + struct sk_buff *skb = 0; + struct sk_buff *skb2 = 0; eicon_REQ *reqbuf; eicon_chan_ptr *chan2; @@ -232,7 +275,11 @@ if ((!skb) || (!skb2)) { if (DebugVar & 1) - printk(KERN_WARNING "idi_err: Ch%d: alloc_skb failed\n", chan->No); + printk(KERN_WARNING "idi_err: Ch%d: alloc_skb failed in do_req()\n", chan->No); + if (skb) + dev_kfree_skb(skb); + if (skb2) + dev_kfree_skb(skb2); return -ENOMEM; } @@ -241,7 +288,7 @@ reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ)); if (DebugVar & 8) - printk(KERN_DEBUG "idi_req: Ch%d: 0x%02x (%s)\n", chan->No, cmd, (layer)?"Net":"Sig"); + printk(KERN_DEBUG "idi_req: Ch%d: req %x (%s)\n", chan->No, cmd, (layer)?"Net":"Sig"); if (layer) cmd |= 0x700; switch(cmd) { case ASSIGN: @@ -282,6 +329,8 @@ default: if (DebugVar & 1) printk(KERN_ERR "idi_req: Ch%d: Unknown request\n", chan->No); + dev_kfree_skb(skb); + dev_kfree_skb(skb2); return(-1); } @@ -358,6 +407,9 @@ chan->fsm_state = EICON_STATE_NULL; if (DebugVar & 8) printk(KERN_DEBUG"idi_req: Ch%d: Hangup\n", chan->No); +#ifdef CONFIG_ISDN_TTY_FAX + chan->fax = 0; +#endif return(0); } @@ -389,7 +441,11 @@ if ((!skb) || (!skb2)) { if (DebugVar & 1) - printk(KERN_WARNING "idi_err: Ch%d: alloc_skb failed\n", chan->No); + printk(KERN_WARNING "idi_err: Ch%d: alloc_skb failed in connect_req()\n", chan->No); + if (skb) + dev_kfree_skb(skb); + if (skb2) + dev_kfree_skb(skb2); return -ENOMEM; } @@ -472,6 +528,20 @@ reqbuf->XBuffer.P[l-2] = 128; reqbuf->XBuffer.P[l-1] = 0; break; + case ISDN_PROTO_L2_FAX: + reqbuf->XBuffer.P[l-6] = 0x10; + reqbuf->XBuffer.P[l-5] = 0; + reqbuf->XBuffer.P[l-4] = 0; + reqbuf->XBuffer.P[l-3] = 0; + reqbuf->XBuffer.P[l-2] = 128; + reqbuf->XBuffer.P[l-1] = 0; + break; + case ISDN_PROTO_L2_TRANS: + switch(chan->l3prot) { + case ISDN_PROTO_L3_TRANSDSP: + reqbuf->XBuffer.P[l-6] = 22; /* DTMF, audio events on */ + } + break; } reqbuf->XBuffer.P[l++] = 0; /* end */ @@ -813,6 +883,81 @@ } } + +int +idi_send_udata(eicon_card *card, eicon_chan *chan, int UReq, u_char *buffer, int len) +{ + struct sk_buff *skb; + struct sk_buff *skb2; + eicon_REQ *reqbuf; + eicon_chan_ptr *chan2; + + if ((chan->fsm_state == EICON_STATE_NULL) || (chan->fsm_state == EICON_STATE_LISTEN)) { + if (DebugVar & 1) + printk(KERN_DEBUG"idi_snd: Ch%d: send udata on state %d !\n", chan->No, chan->fsm_state); + return -ENODEV; + } + if (DebugVar & 8) + printk(KERN_DEBUG"idi_snd: Ch%d: udata 0x%x: %d %d %d %d\n", chan->No, + UReq, buffer[0], buffer[1], buffer[2], buffer[3]); + + skb = alloc_skb(sizeof(eicon_REQ) + len + 1, GFP_ATOMIC); + skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC); + + if ((!skb) || (!skb2)) { + if (DebugVar & 1) + printk(KERN_WARNING "idi_err: Ch%d: alloc_skb failed in send_udata()\n", chan->No); + if (skb) + dev_kfree_skb(skb); + if (skb2) + dev_kfree_skb(skb2); + return -ENOMEM; + } + + chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr)); + chan2->ptr = chan; + + reqbuf = (eicon_REQ *)skb_put(skb, 1 + len + sizeof(eicon_REQ)); + + reqbuf->Req = IDI_N_UDATA; + reqbuf->ReqCh = 0; + reqbuf->ReqId = 1; + + reqbuf->XBuffer.length = len + 1; + reqbuf->XBuffer.P[0] = UReq; + memcpy(&reqbuf->XBuffer.P[1], buffer, len); + reqbuf->Reference = 1; /* Net Entity */ + + skb_queue_tail(&chan->e.X, skb); + skb_queue_tail(&card->sndq, skb2); + eicon_schedule_tx(card); + return (0); +} + +void +idi_audio_cmd(eicon_card *ccard, eicon_chan *chan, int cmd, u_char *value) +{ + u_char buf[6]; + struct enable_dtmf_s *dtmf_buf = (struct enable_dtmf_s *)buf; + + memset(buf, 0, 6); + switch(cmd) { + case ISDN_AUDIO_SETDD: + if (value[0]) { + dtmf_buf->tone = (__u16) (value[1] * 5); + dtmf_buf->gap = (__u16) (value[1] * 5); + idi_send_udata(ccard, chan, + DSP_UDATA_REQUEST_ENABLE_DTMF_RECEIVER, + buf, 4); + } else { + idi_send_udata(ccard, chan, + DSP_UDATA_REQUEST_DISABLE_DTMF_RECEIVER, + buf, 0); + } + break; + } +} + void idi_parse_udata(eicon_card *ccard, eicon_chan *chan, unsigned char *buffer, int len) { @@ -822,6 +967,9 @@ {"", "V.21", "V.23", "V.22", "V.22bis", "V.32bis", "V.34", "V.8", "Bell 212A", "Bell 103", "V.29 Leased", "V.33 Leased", "V.90", "V.21 CH2", "V.27ter", "V.29", "V.33", "V.17"}; + static u_char dtmf_code[] = { + '1','4','7','*','2','5','8','0','3','6','9','#','A','B','C','D' + }; switch (buffer[0]) { case DSP_UDATA_INDICATION_SYNC: @@ -863,6 +1011,17 @@ if (DebugVar & 8) printk(KERN_DEBUG"idi_ind: Ch%d: UDATA_DISCONNECT cause %d\n", chan->No, buffer[1]); break; + case DSP_UDATA_INDICATION_DTMF_DIGITS_RECEIVED: + if (DebugVar & 8) + printk(KERN_DEBUG"idi_ind: Ch%d: UDATA_DTMF_REC '%c'\n", chan->No, + dtmf_code[buffer[1]]); + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_AUDIO; + cmd.parm.num[0] = ISDN_AUDIO_DTMF; + cmd.parm.num[1] = dtmf_code[buffer[1]]; + cmd.arg = chan->No; + ccard->interface.statcallb(&cmd); + break; default: if (DebugVar & 8) printk(KERN_WARNING "idi_ind: Ch%d: UNHANDLED UDATA Indication 0x%02x\n", chan->No, buffer[0]); @@ -887,7 +1046,7 @@ if ((DebugVar & 128) || ((DebugVar & 16) && (ind->Ind != 8))) { - printk(KERN_DEBUG "idi_hdl: Ch%d: Ind=%d Id=%d Ch=%d MInd=%d MLen=%d Len=%d\n", chan->No, + printk(KERN_DEBUG "idi_hdl: Ch%d: Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n", chan->No, ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length); } @@ -921,6 +1080,9 @@ cmd.command = ISDN_STAT_DHUP; ccard->interface.statcallb(&cmd); eicon_idi_listen_req(ccard, chan); +#ifdef CONFIG_ISDN_TTY_FAX + chan->fax = 0; +#endif break; case INDICATE_IND: if (DebugVar & 8) @@ -994,9 +1156,17 @@ cmd.command = ISDN_STAT_DCONN; cmd.arg = chan->No; ccard->interface.statcallb(&cmd); - idi_do_req(ccard, chan, IDI_N_CONNECT, 1); + if (chan->l2prot != ISDN_PROTO_L2_FAX) { + idi_do_req(ccard, chan, IDI_N_CONNECT, 1); + } +#ifdef CONFIG_ISDN_TTY_FAX + else { + if (chan->fax) + chan->fax->phase = ISDN_FAX_PHASE_A; + } +#endif } else - idi_hangup(ccard, chan); + idi_hangup(ccard, chan); break; case CALL_CON: if (DebugVar & 8) @@ -1009,6 +1179,12 @@ ccard->interface.statcallb(&cmd); idi_do_req(ccard, chan, ASSIGN, 1); idi_do_req(ccard, chan, IDI_N_CONNECT, 1); +#ifdef CONFIG_ISDN_TTY_FAX + if (chan->l2prot == ISDN_PROTO_L2_FAX) { + if (chan->fax) + chan->fax->phase = ISDN_FAX_PHASE_A; + } +#endif } else idi_hangup(ccard, chan); break; @@ -1038,6 +1214,27 @@ chan->fsm_state = EICON_STATE_WMCONN; break; } + if (chan->l2prot == ISDN_PROTO_L2_FAX) { +#ifdef CONFIG_ISDN_TTY_FAX + chan->fsm_state = EICON_STATE_ACTIVE; + idi_parse_edata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length); + if (chan->fax) { + if (chan->fax->phase == ISDN_FAX_PHASE_B) { + idi_fax_send_header(ccard, chan, 2); + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + chan->fax->r_code = ISDN_TTY_FAX_DCS; + ccard->interface.statcallb(&cmd); + } + } + else { + if (DebugVar & 1) + printk(KERN_DEBUG "idi_ind: N_CONNECT_ACK with NULL fax struct, ERROR\n"); + } +#endif + break; + } chan->fsm_state = EICON_STATE_ACTIVE; cmd.driver = ccard->myid; cmd.command = ISDN_STAT_BCONN; @@ -1048,6 +1245,9 @@ if (DebugVar & 16) printk(KERN_DEBUG"idi_ind: Ch%d: N_Connect\n", chan->No); if (chan->e.B2Id) idi_do_req(ccard, chan, IDI_N_CONNECT_ACK, 1); + if (chan->l2prot == ISDN_PROTO_L2_FAX) { + break; + } if (chan->l2prot == ISDN_PROTO_L2_MODEM) { chan->fsm_state = EICON_STATE_WMCONN; break; @@ -1065,6 +1265,12 @@ idi_do_req(ccard, chan, IDI_N_DISC_ACK, 1); idi_do_req(ccard, chan, REMOVE, 1); } +#ifdef CONFIG_ISDN_TTY_FAX + if (chan->l2prot == ISDN_PROTO_L2_FAX) { + idi_parse_edata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length); + idi_fax_hangup(ccard, chan); + } +#endif chan->queued = 0; chan->waitq = 0; chan->waitpq = 0; @@ -1078,6 +1284,12 @@ case IDI_N_DISC_ACK: if (DebugVar & 16) printk(KERN_DEBUG"idi_ind: Ch%d: N_DISC_ACK\n", chan->No); +#ifdef CONFIG_ISDN_TTY_FAX + if (chan->l2prot == ISDN_PROTO_L2_FAX) { + idi_parse_edata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length); + idi_fax_hangup(ccard, chan); + } +#endif break; case IDI_N_DATA_ACK: if (DebugVar & 16) @@ -1087,12 +1299,23 @@ skb_pull(skb, sizeof(eicon_IND) - 1); if (DebugVar & 128) printk(KERN_DEBUG"idi_rcv: Ch%d: %d bytes\n", chan->No, skb->len); - ccard->interface.rcvcallb_skb(ccard->myid, chan->No, skb); - free_buff = 0; + if (chan->l2prot == ISDN_PROTO_L2_FAX) { +#ifdef CONFIG_ISDN_TTY_FAX + idi_faxdata_rcv(ccard, chan, skb); +#endif + } else { + ccard->interface.rcvcallb_skb(ccard->myid, chan->No, skb); + free_buff = 0; + } break; case IDI_N_UDATA: idi_parse_udata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length); break; +#ifdef CONFIG_ISDN_TTY_FAX + case IDI_N_EDATA: + idi_edata_action(ccard, chan, ind->RBuffer.P, ind->RBuffer.length); + break; +#endif default: if (DebugVar & 8) printk(KERN_WARNING "idi_ind: Ch%d: UNHANDLED NetIndication 0x%02x\n", chan->No, ind->Ind); @@ -1106,89 +1329,134 @@ } void -idi_handle_ack(eicon_card *ccard, struct sk_buff *skb) +idi_handle_ack_ok(eicon_card *ccard, eicon_chan *chan, eicon_RC *ack) { - int j; - eicon_RC *ack = (eicon_RC *)skb->data; - eicon_chan *chan; isdn_ctrl cmd; - if ((ack->Rc != ASSIGN_OK) && (ack->Rc != OK)) { - if ((chan = ccard->IdTable[ack->RcId]) != NULL) { - chan->e.busy = 0; - if (DebugVar & 24) - printk(KERN_ERR "eicon_ack: Ch%d: Not OK: Rc=%d Id=%d Ch=%d\n", chan->No, - ack->Rc, ack->RcId, ack->RcCh); - if (chan->No == ccard->nchannels) { /* Management */ - chan->fsm_state = 2; - } else { /* any other channel */ - /* card reports error: we hangup */ - idi_hangup(ccard, chan); - cmd.driver = ccard->myid; - cmd.command = ISDN_STAT_DHUP; - cmd.arg = chan->No; - ccard->interface.statcallb(&cmd); - } + if (ack->RcId != ((chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id)) { + /* I dont know why this happens, just ignoring this RC */ + if (DebugVar & 16) + printk(KERN_DEBUG "idi_ack: Ch%d: RcId %d not equal to last %d\n", chan->No, + ack->RcId, (chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id); + return; + } + + /* Management Interface */ + if (chan->No == ccard->nchannels) { + /* Managementinterface: changing state */ + if (chan->e.Req == 0x04) + chan->fsm_state = 1; + } + + /* Remove an Id */ + if (chan->e.Req == REMOVE) { + if (ack->Reference != chan->e.ref) { + if (DebugVar & 1) + printk(KERN_DEBUG "idi_ack: Ch%d: Rc-Ref %d not equal to stored %d\n", chan->No, + ack->Reference, chan->e.ref); } - } - else { - if ((chan = ccard->IdTable[ack->RcId]) != NULL) { - if (ack->RcId != ((chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id)) { - if (DebugVar & 16) - printk(KERN_DEBUG "idi_ack: Ch%d: RcId %d not equal to last %d\n", chan->No, - ack->RcId, (chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id); - } else { - if (chan->No == ccard->nchannels) { /* Management */ - if (chan->e.Req == 0x04) chan->fsm_state = 1; - } - if (chan->e.ReqCh) { - switch(chan->e.Req & 0x0f) { - case IDI_N_MDATA: - case IDI_N_DATA: - chan->queued -= chan->waitq; - if (chan->queued < 0) chan->queued = 0; - if ((chan->e.Req & 0x0f) == IDI_N_DATA) { + ccard->IdTable[ack->RcId] = NULL; + if (DebugVar & 16) + printk(KERN_DEBUG "idi_ack: Ch%d: Removed : Id=%d Ch=%d (%s)\n", chan->No, + ack->RcId, ack->RcCh, (chan->e.ReqCh)? "Net":"Sig"); + if (!chan->e.ReqCh) + chan->e.D3Id = 0; + else + chan->e.B2Id = 0; + return; + } + + /* Signal layer */ + if (!chan->e.ReqCh) { + if (DebugVar & 16) + printk(KERN_DEBUG "idi_ack: Ch%d: RC OK Id=%d Ch=%d (ref:%d)\n", chan->No, + ack->RcId, ack->RcCh, ack->Reference); + } else { + /* Network layer */ + switch(chan->e.Req & 0x0f) { + case IDI_N_MDATA: + case IDI_N_DATA: + if ((chan->e.Req & 0x0f) == IDI_N_DATA) { + if (chan->queued) { + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_BSENT; + cmd.arg = chan->No; + cmd.parm.length = chan->waitpq; + ccard->interface.statcallb(&cmd); + } + chan->waitpq = 0; +#ifdef CONFIG_ISDN_TTY_FAX + if (chan->l2prot == ISDN_PROTO_L2_FAX) { + if (((chan->queued - chan->waitq) < 1) && + (chan->fax2.Eop)) { + chan->fax2.Eop = 0; + if (chan->fax) { cmd.driver = ccard->myid; - cmd.command = ISDN_STAT_BSENT; + cmd.command = ISDN_STAT_FAXIND; cmd.arg = chan->No; - cmd.parm.length = chan->waitpq; - chan->waitpq = 0; + chan->fax->r_code = ISDN_TTY_FAX_SENT; ccard->interface.statcallb(&cmd); } - break; - default: - if (DebugVar & 16) - printk(KERN_DEBUG "idi_ack: Ch%d: RC OK Id=%d Ch=%d (ref:%d)\n", chan->No, - ack->RcId, ack->RcCh, ack->Reference); + else { + if (DebugVar & 1) + printk(KERN_DEBUG "idi_ack: Sent with NULL fax struct, ERROR\n"); + } + } } - } - else { - if (DebugVar & 16) - printk(KERN_DEBUG "idi_ack: Ch%d: RC OK Id=%d Ch=%d (ref:%d)\n", chan->No, - ack->RcId, ack->RcCh, ack->Reference); +#endif } + chan->queued -= chan->waitq; + if (chan->queued < 0) chan->queued = 0; + break; + default: + if (DebugVar & 16) + printk(KERN_DEBUG "idi_ack: Ch%d: RC OK Id=%d Ch=%d (ref:%d)\n", chan->No, + ack->RcId, ack->RcCh, ack->Reference); + } + } +} - if (chan->e.Req == REMOVE) { - if (ack->Reference == chan->e.ref) { - ccard->IdTable[ack->RcId] = NULL; - if (DebugVar & 16) - printk(KERN_DEBUG "idi_ack: Ch%d: Removed : Id=%d Ch=%d (%s)\n", chan->No, - ack->RcId, ack->RcCh, (chan->e.ReqCh)? "Net":"Sig"); - if (!chan->e.ReqCh) - chan->e.D3Id = 0; - else - chan->e.B2Id = 0; - } - else { - if (DebugVar & 16) - printk(KERN_DEBUG "idi_ack: Ch%d: Rc-Ref %d not equal to stored %d\n", chan->No, - ack->Reference, chan->e.ref); - } - } - chan->e.busy = 0; +void +idi_handle_ack(eicon_card *ccard, struct sk_buff *skb) +{ + int j; + eicon_RC *ack = (eicon_RC *)skb->data; + eicon_chan *chan; + isdn_ctrl cmd; + int dCh = -1; + + if ((chan = ccard->IdTable[ack->RcId]) != NULL) + dCh = chan->No; + + + switch (ack->Rc) { + case OK_FC: + case N_FLOW_CONTROL: + case ASSIGN_RC: + if (DebugVar & 1) + printk(KERN_ERR "idi_ack: Ch%d: unhandled RC 0x%x\n", + dCh, ack->Rc); + break; + case READY_INT: + case TIMER_INT: + /* we do nothing here */ + break; + + case OK: + if (!chan) { + if (DebugVar & 1) + printk(KERN_ERR "idi_ack: Ch%d: OK on chan without Id\n", dCh); + break; + } + idi_handle_ack_ok(ccard, chan, ack); + break; + + case ASSIGN_OK: + if (chan) { + if (DebugVar & 1) + printk(KERN_ERR "idi_ack: Ch%d: ASSIGN-OK on chan already assigned (%x,%x)\n", + chan->No, chan->e.D3Id, chan->e.B2Id); } - } - else { for(j = 0; j < ccard->nchannels + 1; j++) { if (ccard->bch[j].e.ref == ack->Reference) { if (!ccard->bch[j].e.ReqCh) @@ -1199,7 +1467,7 @@ ccard->bch[j].e.busy = 0; ccard->bch[j].e.ref = 0; if (DebugVar & 16) - printk(KERN_DEBUG"idi_ack: Ch%d: Id %d assigned (%s)\n", j, + printk(KERN_DEBUG"idi_ack: Ch%d: Id %x assigned (%s)\n", j, ack->RcId, (ccard->bch[j].e.ReqCh)? "Net":"Sig"); break; } @@ -1209,14 +1477,40 @@ printk(KERN_DEBUG"idi_ack: Ch??: ref %d not found for Id %d\n", ack->Reference, ack->RcId); } - } + break; + + case OUT_OF_RESOURCES: + case UNKNOWN_COMMAND: + case WRONG_COMMAND: + case WRONG_ID: + case WRONG_CH: + case UNKNOWN_IE: + case WRONG_IE: + default: + chan->e.busy = 0; + if (DebugVar & 24) + printk(KERN_ERR "eicon_ack: Ch%d: Not OK: Rc=%d Id=%d Ch=%d\n", dCh, + ack->Rc, ack->RcId, ack->RcCh); + if (dCh == ccard->nchannels) { /* Management */ + chan->fsm_state = 2; + } else if (dCh >= 0) { + /* any other channel */ + /* card reports error: we hangup */ + idi_hangup(ccard, chan); + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_DHUP; + cmd.arg = chan->No; + ccard->interface.statcallb(&cmd); + } } - dev_kfree_skb(skb); - eicon_schedule_tx(ccard); + if (chan) + chan->e.busy = 0; + dev_kfree_skb(skb); + eicon_schedule_tx(ccard); } int -idi_send_data(eicon_card *card, eicon_chan *chan, int ack, struct sk_buff *skb) +idi_send_data(eicon_card *card, eicon_chan *chan, int ack, struct sk_buff *skb, int que) { struct sk_buff *xmit_skb; struct sk_buff *skb2; @@ -1240,6 +1534,7 @@ return 0; if (DebugVar & 128) printk(KERN_DEBUG"idi_snd: Ch%d: %d bytes\n", chan->No, len); + save_flags(flags); cli(); while(offset < len) { @@ -1249,10 +1544,14 @@ xmit_skb = alloc_skb(plen + sizeof(eicon_REQ), GFP_ATOMIC); skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC); - if ((!skb) || (!skb2)) { + if ((!xmit_skb) || (!skb2)) { restore_flags(flags); if (DebugVar & 1) - printk(KERN_WARNING "idi_err: Ch%d: alloc_skb failed\n", chan->No); + printk(KERN_WARNING "idi_err: Ch%d: alloc_skb failed in send_data()\n", chan->No); + if (xmit_skb) + dev_kfree_skb(skb); + if (skb2) + dev_kfree_skb(skb2); return -ENOMEM; } @@ -1278,7 +1577,8 @@ offset += plen; } - chan->queued += len; + if (que) + chan->queued += len; restore_flags(flags); eicon_schedule_tx(card); dev_kfree_skb(skb); @@ -1303,7 +1603,11 @@ if ((!skb) || (!skb2)) { if (DebugVar & 1) - printk(KERN_WARNING "idi_err: alloc_skb failed\n"); + printk(KERN_WARNING "idi_err: alloc_skb failed in manage_assign()\n"); + if (skb) + dev_kfree_skb(skb); + if (skb2) + dev_kfree_skb(skb2); return -ENOMEM; } @@ -1342,7 +1646,11 @@ if ((!skb) || (!skb2)) { if (DebugVar & 1) - printk(KERN_WARNING "idi_err: alloc_skb failed\n"); + printk(KERN_WARNING "idi_err: alloc_skb failed in manage_remove()\n"); + if (skb) + dev_kfree_skb(skb); + if (skb2) + dev_kfree_skb(skb2); return -ENOMEM; } @@ -1379,7 +1687,8 @@ chan = &(card->bch[card->nchannels]); - if (chan->e.D3Id) return -EBUSY; + if (chan->e.D3Id) + return -EBUSY; chan->e.D3Id = 1; while((skb2 = skb_dequeue(&chan->e.X))) dev_kfree_skb(skb2); @@ -1409,6 +1718,7 @@ return -ENOMEM; } if (copy_from_user(manbuf, mb, sizeof(eicon_manifbuf))) { + kfree(manbuf); chan->e.D3Id = 0; return -EFAULT; } @@ -1418,7 +1728,11 @@ if ((!skb) || (!skb2)) { if (DebugVar & 1) - printk(KERN_WARNING "idi_err_manif: alloc_skb failed\n"); + printk(KERN_WARNING "idi_err_manif: alloc_skb failed in manage()\n"); + if (skb) + dev_kfree_skb(skb); + if (skb2) + dev_kfree_skb(skb2); kfree(manbuf); chan->e.D3Id = 0; return -ENOMEM; @@ -1464,11 +1778,13 @@ } if ((ret = eicon_idi_manage_remove(card))) { + kfree(manbuf); chan->e.D3Id = 0; return(ret); } if (copy_to_user(mb, manbuf, sizeof(eicon_manifbuf))) { + kfree(manbuf); chan->e.D3Id = 0; return -EFAULT; } diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/eicon/eicon_idi.h linux/drivers/isdn/eicon/eicon_idi.h --- v2.3.13/linux/drivers/isdn/eicon/eicon_idi.h Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/eicon/eicon_idi.h Sun Aug 15 11:49:08 1999 @@ -1,4 +1,4 @@ -/* $Id: eicon_idi.h,v 1.4 1999/03/29 11:19:44 armin Exp $ +/* $Id: eicon_idi.h,v 1.6 1999/07/25 15:12:04 armin Exp $ * * ISDN lowlevel-module for the Eicon.Diehl active cards. * IDI-Interface @@ -21,6 +21,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: eicon_idi.h,v $ + * Revision 1.6 1999/07/25 15:12:04 armin + * fix of some debug logs. + * enabled ISA-cards option. + * + * Revision 1.5 1999/07/11 17:16:26 armin + * Bugfixes in queue handling. + * Added DSP-DTMF decoder functions. + * Reorganized ack_handler. + * * Revision 1.4 1999/03/29 11:19:44 armin * I/O stuff now in seperate file (eicon_io.c) * Old ISA type cards (S,SX,SCOM,Quadro,S2M) implemented. @@ -45,6 +54,7 @@ #ifndef IDI_H #define IDI_H +#include #define ASSIGN 0x01 #define REMOVE 0xff @@ -232,6 +242,12 @@ __u8 B[1]; /* buffer space for Req,Ind and Rc */ } eicon_pr_ram; +typedef struct { + __u8 *Data; + unsigned int Size; + unsigned int Len; + __u8 *Next; +} eicon_OBJBUFFER; extern int idi_do_req(eicon_card *card, eicon_chan *chan, int cmd, int layer); extern int idi_hangup(eicon_card *card, eicon_chan *chan); @@ -243,6 +259,11 @@ extern void idi_handle_ack(eicon_card *card, struct sk_buff *skb); extern void idi_handle_ind(eicon_card *card, struct sk_buff *skb); extern int eicon_idi_manage(eicon_card *card, eicon_manifbuf *mb); -extern int idi_send_data(eicon_card *card, eicon_chan *chan, int ack, struct sk_buff *skb); +extern int idi_send_data(eicon_card *card, eicon_chan *chan, int ack, struct sk_buff *skb, int que); +extern void idi_audio_cmd(eicon_card *ccard, eicon_chan *chan, int cmd, u_char *value); +#ifdef CONFIG_ISDN_TTY_FAX +extern void idi_fax_cmd(eicon_card *card, eicon_chan *chan); +extern int idi_faxdata_send(eicon_card *ccard, eicon_chan *chan, struct sk_buff *skb); +#endif #endif diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/eicon/eicon_io.c linux/drivers/isdn/eicon/eicon_io.c --- v2.3.13/linux/drivers/isdn/eicon/eicon_io.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/eicon/eicon_io.c Sun Aug 15 11:49:08 1999 @@ -1,4 +1,4 @@ -/* $Id: eicon_io.c,v 1.1 1999/03/29 11:19:45 armin Exp $ +/* $Id: eicon_io.c,v 1.2 1999/07/25 15:12:05 armin Exp $ * * ISDN low-level module for Eicon.Diehl active ISDN-Cards. * Code for communicating with hardware. @@ -24,6 +24,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: eicon_io.c,v $ + * Revision 1.2 1999/07/25 15:12:05 armin + * fix of some debug logs. + * enabled ISA-cards option. + * * Revision 1.1 1999/03/29 11:19:45 armin * I/O stuff now in seperate file (eicon_io.c) * Old ISA type cards (S,SX,SCOM,Quadro,S2M) implemented. @@ -32,6 +36,7 @@ */ +#include #include "eicon.h" void @@ -57,7 +62,7 @@ break; default: printk(KERN_ERR "idi: Indication for unknown channel Ind=%d Id=%d\n", ind->Ind, ind->IndId); - printk(KERN_DEBUG "idi_hdl: Ch??: Ind=%d Id=%d Ch=%d MInd=%d MLen=%d Len=%d\n", + printk(KERN_DEBUG "idi_hdl: Ch??: Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n", ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length); } } @@ -303,6 +308,7 @@ } switch(ccard->type) { +#ifdef CONFIG_ISDN_DRV_EICON_ISA case EICON_CTYPE_S: case EICON_CTYPE_SX: case EICON_CTYPE_SCOM: @@ -314,6 +320,7 @@ scom = 0; prram = (eicon_pr_ram *)isa_card->shmem; break; +#endif case EICON_CTYPE_MAESTRAP: scom = 0; ram = (char *)pci_card->PCIram; @@ -434,7 +441,7 @@ chan->e.busy = 1; restore_flags(flags); if (DebugVar & 32) - printk(KERN_DEBUG "eicon: Req=%x Id=%x Ch=%x Len=%x Ref=%d\n", + printk(KERN_DEBUG "eicon: Req=%d Id=%x Ch=%d Len=%d Ref=%d\n", reqbuf->Req, ram_inb(ccard, &ReqOut->ReqId), reqbuf->ReqCh, reqbuf->XBuffer.length, @@ -510,6 +517,7 @@ isa_card = &ccard->hwif.isa; switch(ccard->type) { +#ifdef CONFIG_ISDN_DRV_EICON_ISA case EICON_CTYPE_S: case EICON_CTYPE_SX: case EICON_CTYPE_SCOM: @@ -523,6 +531,7 @@ prram = (eicon_pr_ram *)isa_card->shmem; irqprobe = &isa_card->irqprobe; break; +#endif case EICON_CTYPE_MAESTRAP: scom = 0; ram = (char *)pci_card->PCIram; @@ -546,6 +555,7 @@ if (*irqprobe) { switch(ccard->type) { +#ifdef CONFIG_ISDN_DRV_EICON_ISA case EICON_CTYPE_S: case EICON_CTYPE_SX: case EICON_CTYPE_SCOM: @@ -563,6 +573,7 @@ } (*irqprobe)++; break; +#endif case EICON_CTYPE_MAESTRAP: if (readb(&ram[0x3fe])) { writeb(0, &prram->RcOutput); @@ -581,6 +592,7 @@ } switch(ccard->type) { +#ifdef CONFIG_ISDN_DRV_EICON_ISA case EICON_CTYPE_S: case EICON_CTYPE_SX: case EICON_CTYPE_SCOM: @@ -592,6 +604,7 @@ return; } break; +#endif case EICON_CTYPE_MAESTRAP: if (!(readb(&ram[0x3fe]))) { /* card did not interrupt */ if (DebugVar & 1) @@ -629,7 +642,7 @@ ack->RcCh = ram_inb(ccard, &com->RcCh); ack->Reference = ccard->ref_in++; if (DebugVar & 64) - printk(KERN_INFO "eicon: IRQ Rc=%d Id=%d Ch=%d Ref=%d\n", + printk(KERN_INFO "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n", tmp,ack->RcId,ack->RcCh,ack->Reference); skb_queue_tail(&ccard->rackq, skb); eicon_schedule_ack(ccard); @@ -652,7 +665,7 @@ ind->MLength = ram_inw(ccard, &com->MLength); ind->RBuffer.length = len; if (DebugVar & 64) - printk(KERN_INFO "eicon: IRQ Ind=%d Id=%d Ch=%d MInd=%d MLen=%d Len=%d\n", + printk(KERN_INFO "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n", tmp,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len); ram_copyfromcard(ccard, &ind->RBuffer.P, &com->RBuffer.P, len); skb_queue_tail(&ccard->rcvq, skb); @@ -679,7 +692,7 @@ ack->RcCh = ram_inb(ccard, &RcIn->RcCh); ack->Reference = ram_inw(ccard, &RcIn->Reference); if (DebugVar & 64) - printk(KERN_INFO "eicon: IRQ Rc=%d Id=%d Ch=%d Ref=%d\n", + printk(KERN_INFO "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n", Rc,ack->RcId,ack->RcCh,ack->Reference); ram_outb(ccard, &RcIn->Rc, 0); skb_queue_tail(&ccard->rackq, skb); @@ -711,7 +724,7 @@ ind->MLength = ram_inw(ccard, &IndIn->MLength); ind->RBuffer.length = len; if (DebugVar & 64) - printk(KERN_INFO "eicon: IRQ Ind=%d Id=%d Ch=%d MInd=%d MLen=%d Len=%d\n", + printk(KERN_INFO "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n", Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len); ram_copyfromcard(ccard, &ind->RBuffer.P, &IndIn->RBuffer.P, len); skb_queue_tail(&ccard->rcvq, skb); @@ -728,6 +741,7 @@ /* clear interrupt */ switch(ccard->type) { +#ifdef CONFIG_ISDN_DRV_EICON_ISA case EICON_CTYPE_QUADRO: writeb(0, isa_card->intack); writeb(0, &com[0x401]); @@ -738,6 +752,7 @@ case EICON_CTYPE_S2M: writeb(0, isa_card->intack); break; +#endif case EICON_CTYPE_MAESTRAP: writew(MP_IRQ_RESET_VAL, &cfg[MP_IRQ_RESET]); writew(0, &cfg[MP_IRQ_RESET + 2]); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/eicon/eicon_isa.c linux/drivers/isdn/eicon/eicon_isa.c --- v2.3.13/linux/drivers/isdn/eicon/eicon_isa.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/eicon/eicon_isa.c Sun Aug 15 11:49:08 1999 @@ -1,4 +1,4 @@ -/* $Id: eicon_isa.c,v 1.5 1999/04/01 12:48:33 armin Exp $ +/* $Id: eicon_isa.c,v 1.6 1999/07/25 15:12:06 armin Exp $ * * ISDN low-level module for Eicon.Diehl active ISDN-Cards. * Hardware-specific code for old ISA cards. @@ -22,6 +22,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: eicon_isa.c,v $ + * Revision 1.6 1999/07/25 15:12:06 armin + * fix of some debug logs. + * enabled ISA-cards option. + * * Revision 1.5 1999/04/01 12:48:33 armin * Changed some log outputs. * @@ -46,6 +50,7 @@ * */ +#include #include "eicon.h" #include "eicon_isa.h" @@ -53,7 +58,9 @@ #define release_shmem release_region #define request_shmem request_region -char *eicon_isa_revision = "$Revision: 1.5 $"; +char *eicon_isa_revision = "$Revision: 1.6 $"; + +#ifdef CONFIG_ISDN_DRV_EICON_ISA /* Mask for detecting invalid IRQ parameter */ static int eicon_isa_valid_irq[] = { @@ -430,3 +437,5 @@ card->irqprobe = 0; return 0; } + +#endif /* CONFIG_ISDN_DRV_EICON_ISA */ diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/eicon/eicon_mod.c linux/drivers/isdn/eicon/eicon_mod.c --- v2.3.13/linux/drivers/isdn/eicon/eicon_mod.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/eicon/eicon_mod.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: eicon_mod.c,v 1.5 1999/04/01 12:48:35 armin Exp $ +/* $Id: eicon_mod.c,v 1.8 1999/07/25 15:12:08 armin Exp $ * * ISDN lowlevel-module for Eicon.Diehl active cards. * @@ -26,6 +26,19 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: eicon_mod.c,v $ + * Revision 1.8 1999/07/25 15:12:08 armin + * fix of some debug logs. + * enabled ISA-cards option. + * + * Revision 1.7 1999/07/11 17:16:27 armin + * Bugfixes in queue handling. + * Added DSP-DTMF decoder functions. + * Reorganized ack_handler. + * + * Revision 1.6 1999/06/09 19:31:26 armin + * Wrong PLX size for request_region() corrected. + * Added first MCA code from Erik Weber. + * * Revision 1.5 1999/04/01 12:48:35 armin * Changed some log outputs. * @@ -53,14 +66,18 @@ #include #include #include +#ifdef CONFIG_MCA +#include +#endif #include "eicon.h" #define INCLUDE_INLINE_FUNCS -static eicon_card *cards = (eicon_card *) NULL; +static eicon_card *cards = (eicon_card *) NULL; /* glob. var , contains + start of card-list */ -static char *eicon_revision = "$Revision: 1.5 $"; +static char *eicon_revision = "$Revision: 1.8 $"; extern char *eicon_pci_revision; extern char *eicon_isa_revision; @@ -75,19 +92,23 @@ ulong DebugVar; /* Parameters to be set by insmod */ +#ifdef CONFIG_ISDN_DRV_EICON_ISA static int membase = -1; static int irq = -1; +#endif static char *id = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; MODULE_DESCRIPTION( "Driver for Eicon.Diehl active ISDN cards"); MODULE_AUTHOR( "Armin Schindler"); MODULE_SUPPORTED_DEVICE( "ISDN subsystem"); +MODULE_PARM_DESC(id, "ID-String of first card"); +MODULE_PARM(id, "s"); +#ifdef CONFIG_ISDN_DRV_EICON_ISA MODULE_PARM_DESC(membase, "Base address of first ISA card"); MODULE_PARM_DESC(irq, "IRQ of first card"); -MODULE_PARM_DESC(id, "ID-String of first card"); MODULE_PARM(membase, "i"); MODULE_PARM(irq, "i"); -MODULE_PARM(id, "s"); +#endif char *eicon_ctype_name[] = { "ISDN-S", @@ -291,10 +312,10 @@ { switch (card->bus) { case EICON_BUS_ISA: + case EICON_BUS_MCA: case EICON_BUS_PCI: eicon_io_rcv_dispatch(card); break; - case EICON_BUS_MCA: default: if (DebugVar & 1) printk(KERN_WARNING @@ -307,10 +328,10 @@ { switch (card->bus) { case EICON_BUS_ISA: + case EICON_BUS_MCA: case EICON_BUS_PCI: eicon_io_ack_dispatch(card); break; - case EICON_BUS_MCA: default: if (DebugVar & 1) printk(KERN_WARNING @@ -323,10 +344,10 @@ { switch (card->bus) { case EICON_BUS_ISA: + case EICON_BUS_MCA: case EICON_BUS_PCI: eicon_io_transmit(card); break; - case EICON_BUS_MCA: default: if (DebugVar & 1) printk(KERN_WARNING @@ -356,6 +377,7 @@ case EICON_IOCTL_GETMMIO: switch (card->bus) { case EICON_BUS_ISA: + case EICON_BUS_MCA: return (int)card->hwif.isa.shmem; #if CONFIG_PCI case EICON_BUS_PCI: @@ -368,11 +390,13 @@ card->bus); ret = -ENODEV; } +#ifdef CONFIG_ISDN_DRV_EICON_ISA case EICON_IOCTL_SETMMIO: if (card->flags & EICON_FLAGS_LOADED) return -EBUSY; switch (card->bus) { case EICON_BUS_ISA: + case EICON_BUS_MCA: if (eicon_isa_find_card(a, card->hwif.isa.irq, card->regname) < 0) @@ -386,9 +410,11 @@ card->bus); ret = -ENODEV; } +#endif case EICON_IOCTL_GETIRQ: switch (card->bus) { case EICON_BUS_ISA: + case EICON_BUS_MCA: return card->hwif.isa.irq; #if CONFIG_PCI case EICON_BUS_PCI: @@ -408,6 +434,7 @@ return -EFAULT; switch (card->bus) { case EICON_BUS_ISA: + case EICON_BUS_MCA: card->hwif.isa.irq = a; return 0; default: @@ -417,11 +444,13 @@ card->bus); ret = -ENODEV; } +#ifdef CONFIG_ISDN_DRV_EICON_ISA case EICON_IOCTL_LOADBOOT: if (card->flags & EICON_FLAGS_RUNNING) return -EBUSY; switch (card->bus) { case EICON_BUS_ISA: + case EICON_BUS_MCA: ret = eicon_isa_bootload( &(card->hwif.isa), &(((eicon_codebuf *)a)->isa)); @@ -434,11 +463,14 @@ ret = -ENODEV; } return ret; +#endif +#ifdef CONFIG_ISDN_DRV_EICON_ISA case EICON_IOCTL_LOADISA: if (card->flags & EICON_FLAGS_RUNNING) return -EBUSY; switch (card->bus) { case EICON_BUS_ISA: + case EICON_BUS_MCA: ret = eicon_isa_load( &(card->hwif.isa), &(((eicon_codebuf *)a)->isa)); @@ -465,7 +497,7 @@ ret = -ENODEV; } return ret; - +#endif case EICON_IOCTL_MANIF: if (!card->flags & EICON_FLAGS_RUNNING) return -ENODEV; @@ -639,11 +671,6 @@ case ISDN_CMD_SETL3: if (!card->flags & EICON_FLAGS_RUNNING) return -ENODEV; - if ((c->arg >> 8) != ISDN_PROTO_L3_TRANS) { - if (DebugVar & 1) - printk(KERN_WARNING "L3 protocol unknown\n"); - return -1; - } if (!(chan = find_channel(card, c->arg & 0x1f))) break; chan->l3prot = (c->arg >> 8); @@ -678,6 +705,13 @@ case ISDN_CMD_UNLOCK: MOD_DEC_USE_COUNT; return 0; + case ISDN_CMD_AUDIO: + if (!card->flags & EICON_FLAGS_RUNNING) + return -ENODEV; + if (!(chan = find_channel(card, c->arg & 0x1f))) + break; + idi_audio_cmd(card, chan, c->arg >> 8, c->parm.num); + return 0; } return -EINVAL; @@ -753,6 +787,10 @@ { eicon_card *card = eicon_findcard(id); eicon_chan *chan; + int ret = 0; + int len; + + len = skb->len; if (card) { if (!card->flags & EICON_FLAGS_RUNNING) { @@ -763,9 +801,10 @@ dev_kfree_skb(skb); return -ENODEV; } - if (chan->fsm_state == EICON_STATE_ACTIVE) - return (idi_send_data(card, chan, ack, skb)); - else { + if (chan->fsm_state == EICON_STATE_ACTIVE) { + ret = idi_send_data(card, chan, ack, skb, 1); + return (ret); + } else { dev_kfree_skb(skb); return -ENODEV; } @@ -787,7 +826,9 @@ int i; int j; int qloop; +#ifdef CONFIG_ISDN_DRV_EICON_ISA char qid[5]; +#endif eicon_card *card; #if CONFIG_PCI eicon_pci_card *pcic; @@ -828,12 +869,32 @@ card->myid = -1; card->type = Type; switch (Type) { +#ifdef CONFIG_ISDN_DRV_EICON_ISA +#if CONFIG_MCA /* only needed for MCA */ + case EICON_CTYPE_S: + case EICON_CTYPE_SX: + case EICON_CTYPE_SCOM: + if (membase == -1) + membase = EICON_ISA_MEMBASE; + if (irq == -1) + irq = EICON_ISA_IRQ; + card->bus = EICON_BUS_MCA; + card->hwif.isa.card = (void *)card; + card->hwif.isa.shmem = (eicon_isa_shmem *)membase; + card->hwif.isa.master = 1; + + card->hwif.isa.irq = irq; + card->hwif.isa.type = Type; + card->nchannels = 2; + card->interface.channels = 1; + break; +#endif /* CONFIG_MCA */ case EICON_CTYPE_QUADRO: if (membase == -1) membase = EICON_ISA_MEMBASE; if (irq == -1) irq = EICON_ISA_IRQ; - card->bus = EICON_BUS_ISA; + card->bus = EICON_BUS_ISA; card->hwif.isa.card = (void *)card; card->hwif.isa.shmem = (eicon_isa_shmem *)(membase + (i+1) * EICON_ISA_QOFFSET); card->hwif.isa.master = 0; @@ -868,6 +929,7 @@ card->nchannels = 2; card->interface.channels = 1; break; +#endif #if CONFIG_PCI case EICON_CTYPE_MAESTRA: (eicon_pci_card *)pcic = (eicon_pci_card *)membase; @@ -876,7 +938,10 @@ ISDN_FEATURE_L2_V11096 | ISDN_FEATURE_L2_V11019 | ISDN_FEATURE_L2_V11038 | - ISDN_FEATURE_L2_MODEM; + ISDN_FEATURE_L2_MODEM | + ISDN_FEATURE_L2_FAX | + ISDN_FEATURE_L3_TRANSDSP | + ISDN_FEATURE_L3_FAX; card->hwif.pci.card = (void *)card; card->hwif.pci.PCIreg = pcic->PCIreg; card->hwif.pci.PCIcfg = pcic->PCIcfg; @@ -897,7 +962,10 @@ ISDN_FEATURE_L2_V11096 | ISDN_FEATURE_L2_V11019 | ISDN_FEATURE_L2_V11038 | - ISDN_FEATURE_L2_MODEM; + ISDN_FEATURE_L2_MODEM | + ISDN_FEATURE_L2_FAX | + ISDN_FEATURE_L3_TRANSDSP | + ISDN_FEATURE_L3_FAX; card->hwif.pci.card = (void *)card; card->hwif.pci.shmem = (eicon_pci_shmem *)pcic->shmem; card->hwif.pci.PCIreg = pcic->PCIreg; @@ -913,6 +981,7 @@ card->interface.channels = 1; break; #endif +#ifdef CONFIG_ISDN_DRV_EICON_ISA case EICON_CTYPE_ISABRI: if (membase == -1) membase = EICON_ISA_MEMBASE; @@ -932,7 +1001,7 @@ membase = EICON_ISA_MEMBASE; if (irq == -1) irq = EICON_ISA_IRQ; - card->bus = EICON_BUS_ISA; + card->bus = EICON_BUS_ISA; card->hwif.isa.card = (void *)card; card->hwif.isa.shmem = (eicon_isa_shmem *)membase; card->hwif.isa.master = 1; @@ -941,6 +1010,7 @@ card->nchannels = 30; card->interface.channels = 1; break; +#endif default: printk(KERN_WARNING "eicon_alloccard: Invalid type %d\n", Type); kfree(card); @@ -978,15 +1048,21 @@ eicon_registercard(eicon_card * card) { switch (card->bus) { +#ifdef CONFIG_ISDN_DRV_EICON_ISA case EICON_BUS_ISA: /* TODO something to print */ break; +#ifdef CONFIG_MCA + case EICON_BUS_MCA: + eicon_isa_printpar(&card->hwif.isa); + break; +#endif +#endif case EICON_BUS_PCI: #if CONFIG_PCI eicon_pci_printpar(&card->hwif.pci); break; #endif - case EICON_BUS_MCA: default: if (DebugVar & 1) printk(KERN_WARNING @@ -1015,15 +1091,19 @@ cmd.driver = card->myid; card->interface.statcallb(&cmd); switch (card->bus) { +#ifdef CONFIG_ISDN_DRV_EICON_ISA case EICON_BUS_ISA: +#ifdef CONFIG_MCA + case EICON_BUS_MCA: +#endif eicon_isa_release(&card->hwif.isa); break; +#endif case EICON_BUS_PCI: #if CONFIG_PCI eicon_pci_release(&card->hwif.pci); break; #endif - case EICON_BUS_MCA: default: if (DebugVar & 1) printk(KERN_WARNING @@ -1050,9 +1130,11 @@ int added = 0; int failed = 0; +#ifdef CONFIG_ISDN_DRV_EICON_ISA if (!Type) /* ISA */ if ((Type = eicon_isa_find_card(membase, irq, id)) < 0) return 0; +#endif eicon_alloccard(Type, membase, irq, id); p = cards; while (p) { @@ -1063,11 +1145,14 @@ */ added++; switch (p->bus) { +#ifdef CONFIG_ISDN_DRV_EICON_ISA case EICON_BUS_ISA: + case EICON_BUS_MCA: if (eicon_registercard(p)) break; registered = 1; break; +#endif case EICON_BUS_PCI: #if CONFIG_PCI if (eicon_registercard(p)) @@ -1075,7 +1160,6 @@ registered = 1; break; #endif - case EICON_BUS_MCA: default: if (DebugVar & 1) printk(KERN_WARNING @@ -1119,7 +1203,7 @@ __initfunc(int eicon_init(void)) { - int tmp = 0; + int card_count = 0; int release = 0; char tmprev[50]; @@ -1130,10 +1214,18 @@ printk("%s/", eicon_getrev(tmprev)); release += getrel(tmprev); strcpy(tmprev, eicon_pci_revision); +#if CONFIG_PCI printk("%s/", eicon_getrev(tmprev)); +#else + printk("---/"); +#endif release += getrel(tmprev); strcpy(tmprev, eicon_isa_revision); +#ifdef CONFIG_ISDN_DRV_EICON_ISA printk("%s/", eicon_getrev(tmprev)); +#else + printk("---/"); +#endif release += getrel(tmprev); strcpy(tmprev, eicon_idi_revision); printk("%s\n", eicon_getrev(tmprev)); @@ -1142,18 +1234,46 @@ printk(KERN_INFO "%s Release: %s.%s\n", DRIVERNAME, DRIVERRELEASE, tmprev); - tmp = eicon_addcard(0, membase, irq, id); +#ifdef CONFIG_ISDN_DRV_EICON_ISA +#ifdef CONFIG_MCA + /* Check if we have MCA-bus */ + if (!MCA_bus) + { + printk(KERN_INFO + "eicon: No MCA bus, ISDN-interfaces not probed.\n"); + } else { + if (DebugVar & 8) + printk(KERN_DEBUG + "eicon_mca_find_card, irq=%d.\n", + irq); + if (!eicon_mca_find_card(0, membase, irq, id)) + card_count++; + }; +#else + card_count = eicon_addcard(0, membase, irq, id); +#endif /* CONFIG_MCA */ +#endif /* CONFIG_ISDN_DRV_EICON_ISA */ + #if CONFIG_PCI - tmp += eicon_pci_find_card(id); + card_count += eicon_pci_find_card(id); #endif if (!cards) { #ifdef MODULE +#ifndef CONFIG_PCI +#ifndef CONFIG_ISDN_DRV_EICON_ISA + printk(KERN_INFO "Eicon: Driver is neither ISA nor PCI compiled !\n"); +#else printk(KERN_INFO "Eicon: No cards defined, driver not loaded !\n"); #endif +#else + printk(KERN_INFO "Eicon: No PCI-cards found, driver not loaded !\n"); +#endif +#endif return -ENODEV; } else - printk(KERN_INFO "Eicon: %d card%s added\n", tmp, (tmp>1)?"s":""); + printk(KERN_INFO "Eicon: %d card%s added\n", card_count, + (card_count>1)?"s":""); /* No symbols to export, hide all symbols */ EXPORT_NO_SYMBOLS; return 0; @@ -1166,6 +1286,13 @@ eicon_card *card = cards; eicon_card *last; while (card) { +#ifdef CONFIG_MCA + if (MCA_bus) + { + mca_mark_as_unused (card->mca_slot); + mca_set_adapter_procfn(card->mca_slot, NULL, NULL); + }; +#endif unregister_card(card); card = card->next; } @@ -1178,7 +1305,7 @@ printk(KERN_INFO "%s unloaded\n", DRIVERNAME); } -#else +#else /* no module */ __initfunc(void eicon_setup(char *str, int *ints)) { @@ -1207,4 +1334,173 @@ printk(KERN_INFO "eicon: membase=0x%x irq=%d id=%s\n", membase, irq, id); } } -#endif +#endif /* MODULE */ + +#ifdef CONFIG_ISDN_DRV_EICON_ISA +#ifdef CONFIG_MCA + +struct eicon_mca_adapters_struct { + char * name; + int adf_id; +}; +/* possible MCA-brands of eicon cards */ +struct eicon_mca_adapters_struct eicon_mca_adapters[] = { + { "ISDN-P/2 Adapter", 0x6abb }, + { "ISDN-[S|SX|SCOM]/2 Adapter", 0x6a93 }, + { "DIVA /MCA", 0x6336 }, + { NULL, 0 }, +}; + +int eicon_mca_find_card(int type, /* type-idx of eicon-card */ + int membase, + int irq, + char * id) /* name of eicon-isdn-dev */ +{ + int j, curr_slot = 0; + + if (DebugVar & 8) + printk(KERN_DEBUG + "eicon_mca_find_card type: %d, membase: %#x, irq %d \n", + type, membase, irq); + /* find a no-driver-assigned eicon card */ + for (j=0; eicon_mca_adapters[j].adf_id != 0; j++) + { + for ( curr_slot=0; curr_slot<=MCA_MAX_SLOT_NR; curr_slot++) + { + curr_slot = mca_find_unused_adapter( + eicon_mca_adapters[j].adf_id, curr_slot); + if (curr_slot != MCA_NOTFOUND) + { + /* check if pre-set parameters match + these of the card, check cards memory */ + if (!(int) eicon_mca_probe(curr_slot, + j, + membase, + irq, + id)) + { + return 0; + /* means: adapter parms did match */ + }; + }; + break; + /* MCA_NOTFOUND-branch: no matching adapter of + THIS flavor found, next flavor */ + + }; + }; + /* all adapter flavors checked without match, finito with: */ + return ENODEV; +}; + + +/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * stolen from 3c523.c/elmc_getinfo, ewe, 10.5.1999 + */ +int eicon_info(char * buf, int slot, void *d) +{ + int len = 0; + struct eicon_card *dev; + + dev = (struct eicon_card *) d; + + if (dev == NULL) + return len; + len += sprintf(buf+len, "eicon ISDN adapter, type %d.\n",dev->type); + len += sprintf(buf+len, "IRQ: %d\n", dev->hwif.isa.irq); + len += sprintf(buf+len, "MEMBASE: %#lx\n", (unsigned long)dev->hwif.isa.shmem); + + return len; +}; + +int eicon_mca_probe(int slot, /* slot-nr where the card was detected */ + int a_idx, /* idx-nr of probed card in eicon_mca_adapters */ + int membase, + int irq, + char * id) /* name of eicon-isdn-dev */ +{ + unsigned char adf_pos0; + int cards_irq, cards_membase, cards_io; + int type = EICON_CTYPE_S; + int irq_array[]={0,3,4,2}; + int irq_array1[]={3,4,0,0,2,10,11,12}; + + adf_pos0 = mca_read_stored_pos(slot,2); + if (DebugVar & 8) + printk(KERN_DEBUG + "eicon_mca_probe irq=%d, membase=%d\n", + irq, + membase); + switch (a_idx) { + case 0: /* P/2-Adapter (== PRI/S2M ? ) */ + cards_membase= 0xC0000+((adf_pos0>>4)*0x4000); + if (membase == -1) { + membase = cards_membase; + } else { + if (membase != cards_membase) + return ENODEV; + }; + cards_irq=irq_array[((adf_pos0 & 0xC)>>2)]; + if (irq == -1) { + irq = cards_irq; + } else { + if (irq != irq) + return ENODEV; + }; + cards_io= 0xC00 + ((adf_pos0>>4)*0x10); + type = EICON_CTYPE_ISAPRI; + break; + + case 1: /* [S|SX|SCOM]/2 */ + cards_membase= 0xC0000+((adf_pos0>>4)*0x2000); + if (membase == -1) { + membase = cards_membase; + } else { + if (membase != cards_membase) + return ENODEV; + }; + cards_irq=irq_array[((adf_pos0 & 0xC)>>2)]; + if (irq == -1) { + irq = cards_irq; + } else { + if (irq != cards_irq) + return ENODEV; + }; + + cards_io= 0xC00 + ((adf_pos0>>4)*0x10); + type = EICON_CTYPE_SCOM; + break; + + case 2: /* DIVA/MCA */ + cards_io = 0x200+ ((adf_pos0>>4)* 0x20); + cards_irq = irq_array1[(adf_pos0 & 0x7)]; + if (irq == -1) { + irq = cards_irq; + } else { + if (irq != irq) + return ENODEV; + }; + type = 0; + break; + default: + return ENODEV; + }; + /* Uebereinstimmung vorgegebener membase & irq */ + if ( 1 == eicon_addcard(type, membase, irq, id)) { + mca_set_adapter_name(slot, eicon_mca_adapters[a_idx].name); + mca_set_adapter_procfn(slot, (MCA_ProcFn) eicon_info, cards); + + mca_mark_as_used(slot); + cards->mca_slot = slot; + /* card->io noch setzen oder ?? */ + if (DebugVar & 8) + printk("eicon_addcard: erfolgreich fuer slot: %d.\n", + cards->mca_slot+1); + return 0 ; /* eicon_addcard hat eine Karte zugefuegt */ + } else { + return ENODEV; + }; +}; +#endif /* CONFIG_MCA */ +#endif /* CONFIG_ISDN_DRV_EICON_ISA */ + diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/eicon/eicon_pci.c linux/drivers/isdn/eicon/eicon_pci.c --- v2.3.13/linux/drivers/isdn/eicon/eicon_pci.c Wed May 26 16:55:40 1999 +++ linux/drivers/isdn/eicon/eicon_pci.c Sun Aug 15 11:49:08 1999 @@ -1,4 +1,4 @@ -/* $Id: eicon_pci.c,v 1.6 1999/04/01 12:48:37 armin Exp $ +/* $Id: eicon_pci.c,v 1.9 1999/08/11 21:01:11 keil Exp $ * * ISDN low-level module for Eicon.Diehl active ISDN-Cards. * Hardware-specific code for PCI cards. @@ -26,6 +26,16 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: eicon_pci.c,v $ + * Revision 1.9 1999/08/11 21:01:11 keil + * new PCI codefix + * + * Revision 1.8 1999/08/10 16:02:20 calle + * struct pci_dev changed in 2.3.13. Made the necessary changes. + * + * Revision 1.7 1999/06/09 19:31:29 armin + * Wrong PLX size for request_region() corrected. + * Added first MCA code from Erik Weber. + * * Revision 1.6 1999/04/01 12:48:37 armin * Changed some log outputs. * @@ -61,7 +71,7 @@ #include "eicon_pci.h" -char *eicon_pci_revision = "$Revision: 1.6 $"; +char *eicon_pci_revision = "$Revision: 1.9 $"; #if CONFIG_PCI /* intire stuff is only for PCI */ @@ -136,8 +146,8 @@ aparms->type = EICON_CTYPE_MAESTRA; aparms->irq = pdev->irq; - preg = pdev->base_address[2] & 0xfffffffc; - pcfg = pdev->base_address[1] & 0xffffff80; + preg = get_pcibase(pdev, 2) & 0xfffffffc; + pcfg = get_pcibase(pdev, 1) & 0xffffff80; #ifdef EICON_PCI_DEBUG printk(KERN_DEBUG "eicon_pci: irq=%d\n", aparms->irq); @@ -158,9 +168,9 @@ printk(KERN_INFO "Eicon: DIVA Server PRI/PCI detected !\n"); aparms->type = EICON_CTYPE_MAESTRAP; /*includes 9M,30M*/ aparms->irq = pdev->irq; - pram = pdev->base_address[0] & 0xfffff000; - preg = pdev->base_address[2] & 0xfffff000; - pcfg = pdev->base_address[4] & 0xfffff000; + pram = get_pcibase(pdev, 0) & 0xfffff000; + preg = get_pcibase(pdev, 2) & 0xfffff000; + pcfg = get_pcibase(pdev, 4) & 0xfffff000; #ifdef EICON_PCI_DEBUG printk(KERN_DEBUG "eicon_pci: irq=%d\n", aparms->irq); @@ -194,12 +204,13 @@ } else { request_region(aparms->PCIreg, 0x20, "eicon reg"); } - if (check_region((aparms->PCIcfg), 0x100)) { + if (check_region((aparms->PCIcfg), 0x80)) { printk(KERN_WARNING "eicon_pci: cfg port already in use !\n"); aparms->PCIcfg = 0; + release_region(aparms->PCIreg, 0x20); break; } else { - request_region(aparms->PCIcfg, 0x100, "eicon cfg"); + request_region(aparms->PCIcfg, 0x80, "eicon cfg"); } break; case PCI_MAESTRAQ: @@ -327,7 +338,7 @@ outw(0, card->PCIreg + M_DATA); release_region(card->PCIreg, 0x20); - release_region(card->PCIcfg, 0x100); + release_region(card->PCIcfg, 0x80); break; case EICON_CTYPE_MAESTRAQ: case EICON_CTYPE_MAESTRAQ_U: diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/Makefile linux/drivers/isdn/hisax/Makefile --- v2.3.13/linux/drivers/isdn/hisax/Makefile Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/Makefile Thu Aug 12 09:42:33 1999 @@ -25,13 +25,11 @@ endif ISAC_OBJ := -ARCOFI_OBJ := HSCX_OBJ := ISAR_OBJ := HFC_OBJ := HFC_2BDS0 := -RAWHDLC_OBJ := - +JADE_OBJ := ifeq ($(CONFIG_HISAX_16_0),y) O_OBJS += teles0.o ISAC_OBJ := isac.o @@ -78,7 +76,6 @@ O_OBJS += elsa.o ISAC_OBJ := isac.o HSCX_OBJ := hscx.o - ARCOFI_OBJ := arcofi.o endif ifeq ($(CONFIG_HISAX_IX1MICROR2),y) @@ -127,16 +124,15 @@ ifeq ($(CONFIG_HISAX_NETJET),y) O_OBJS += netjet.o ISAC_OBJ := isac.o -# RAWHDLC_OBJ := rawhdlc.o endif -ifeq ($(CONFIG_HISAX_TELES3C),y) - O_OBJS += teles3c.o +ifeq ($(CONFIG_HISAX_HFCS),y) + O_OBJS += hfcscard.o HFC_2BDS0 := hfc_2bds0.o endif -ifeq ($(CONFIG_HISAX_AMD7930),y) - O_OBJS += amd7930.o - RAWHDLC_OBJ := rawhdlc.o + +ifeq ($(CONFIG_HISAX_HFC_PCI),y) + HFC_2BDS0 += hfc_pci.o endif ifeq ($(CONFIG_HISAX_NICCY),y) @@ -145,8 +141,45 @@ HSCX_OBJ := hscx.o endif -O_OBJS += $(ISAC_OBJ) $(HSCX_OBJ) $(ISAR_OBJ) $(ARCOFI_OBJ) -O_OBJS += $(HFC_OBJ) $(HFC_2BDS0) $(RAWHDLC_OBJ) +ifeq ($(CONFIG_HISAX_ISURF),y) + O_OBJS += isurf.o + ISAC_OBJ := isac.o + ISAR_OBJ := isar.o +endif + +ifeq ($(CONFIG_HISAX_HSTSAPHIR),y) + O_OBJS += saphir.o + ISAC_OBJ := isac.o + HSCX_OBJ := hscx.o +endif + +ifeq ($(CONFIG_HISAX_BKM_A4T),y) + O_OBJS += bkm_a4t.o + ISAC_OBJ := isac.o + JADE_OBJ := jade.o +endif +ifeq ($(CONFIG_HISAX_SCT_QUADRO),y) + O_OBJS += bkm_a8.o + ISAC_OBJ := isac.o + HSCX_OBJ := hscx.o +endif + +ifeq ($(CONFIG_HISAX_GAZEL),y) + O_OBJS += gazel.o + ISAC_OBJ := isac.o + HSCX_OBJ := hscx.o +endif + +# ifeq ($(CONFIG_HISAX_TESTEMU),y) +# O_OBJS += testemu.o +# endif + +ifeq ($(ISAC_OBJ), isac.o) + ISAC_OBJ += arcofi.o +endif + +O_OBJS += $(ISAC_OBJ) $(HSCX_OBJ) $(ISAR_OBJ) $(JADE_OBJ) +O_OBJS += $(HFC_OBJ) $(HFC_2BDS0) OX_OBJS += config.o O_TARGET := @@ -164,7 +197,8 @@ include $(TOPDIR)/Rules.make MD5FILES += isac.c isdnl1.c isdnl2.c isdnl3.c \ - tei.c callc.c cert.c l3dss1.c l3_1tr6.c elsa.c + tei.c callc.c cert.c l3dss1.c l3_1tr6.c \ + elsa.c diva.c CERT = $(shell md5sum -c md5sums.asc >> /dev/null;echo $$?) diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/amd7930.c linux/drivers/isdn/hisax/amd7930.c --- v2.3.13/linux/drivers/isdn/hisax/amd7930.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/isdn/hisax/amd7930.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: amd7930.c,v 1.2 1998/02/12 23:07:10 keil Exp $ +/* $Id: amd7930.c,v 1.3 1999/07/12 21:04:52 keil Exp $ * * HiSax ISDN driver - chip specific routines for AMD 7930 * @@ -7,6 +7,10 @@ * * * $Log: amd7930.c,v $ + * Revision 1.3 1999/07/12 21:04:52 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * * Revision 1.2 1998/02/12 23:07:10 keil * change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb() * @@ -105,7 +109,7 @@ #include "rawhdlc.h" #include -static const char *amd7930_revision = "$Revision: 1.2 $"; +static const char *amd7930_revision = "$Revision: 1.3 $"; #define RCV_BUFSIZE 1024 /* Size of raw receive buffer in bytes */ #define RCV_BUFBLKS 4 /* Number of blocks to divide buffer into @@ -734,8 +738,6 @@ case CARD_RELEASE: release_amd7930(cs); return(0); - case CARD_SETIRQ: - return(0); case CARD_INIT: cs->l1cmd = amd7930_l1cmd; amd7930_liu_init(0, &amd7930_liu_callback, (void *)cs); @@ -747,8 +749,8 @@ return(0); } -int __init -setup_amd7930(struct IsdnCard *card) +__initfunc(int +setup_amd7930(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/arcofi.c linux/drivers/isdn/hisax/arcofi.c --- v2.3.13/linux/drivers/isdn/hisax/arcofi.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/arcofi.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: arcofi.c,v 1.6 1998/09/30 22:21:56 keil Exp $ +/* $Id: arcofi.c,v 1.7 1999/07/01 08:11:17 keil Exp $ * arcofi.c Ansteuerung ARCOFI 2165 * @@ -7,6 +7,9 @@ * * * $Log: arcofi.c,v $ + * Revision 1.7 1999/07/01 08:11:17 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.6 1998/09/30 22:21:56 keil * cosmetics * @@ -32,48 +35,120 @@ #include "hisax.h" #include "isdnl1.h" #include "isac.h" +#include "arcofi.h" -int -send_arcofi(struct IsdnCardState *cs, const u_char *msg, int bc, int receive) { +#define ARCOFI_TIMER_VALUE 20 + +static void +add_arcofi_timer(struct IsdnCardState *cs) { + if (test_and_set_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) { + del_timer(&cs->dc.isac.arcofitimer); + } + init_timer(&cs->dc.isac.arcofitimer); + cs->dc.isac.arcofitimer.expires = jiffies + ((ARCOFI_TIMER_VALUE * HZ)/1000); + add_timer(&cs->dc.isac.arcofitimer); +} + +static void +send_arcofi(struct IsdnCardState *cs) { u_char val; - long flags; - int cnt=30; - cs->mon_txp = 0; - cs->mon_txc = msg[0]; - memcpy(cs->mon_tx, &msg[1], cs->mon_txc); - switch(bc) { + add_arcofi_timer(cs); + cs->dc.isac.mon_txp = 0; + cs->dc.isac.mon_txc = cs->dc.isac.arcofi_list->len; + memcpy(cs->dc.isac.mon_tx, cs->dc.isac.arcofi_list->msg, cs->dc.isac.mon_txc); + switch(cs->dc.isac.arcofi_bc) { case 0: break; - case 1: cs->mon_tx[1] |= 0x40; + case 1: cs->dc.isac.mon_tx[1] |= 0x40; break; default: break; } - cs->mocr &= 0x0f; - cs->mocr |= 0xa0; - test_and_clear_bit(HW_MON1_TX_END, &cs->HW_Flags); - if (receive) - test_and_clear_bit(HW_MON1_RX_END, &cs->HW_Flags); - cs->writeisac(cs, ISAC_MOCR, cs->mocr); + cs->dc.isac.mocr &= 0x0f; + cs->dc.isac.mocr |= 0xa0; + cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); val = cs->readisac(cs, ISAC_MOSR); - cs->writeisac(cs, ISAC_MOX1, cs->mon_tx[cs->mon_txp++]); - cs->mocr |= 0x10; - cs->writeisac(cs, ISAC_MOCR, cs->mocr); - save_flags(flags); - sti(); - while (cnt && !test_bit(HW_MON1_TX_END, &cs->HW_Flags)) { - cnt--; - udelay(500); + cs->writeisac(cs, ISAC_MOX1, cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]); + cs->dc.isac.mocr |= 0x10; + cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); +} + +int +arcofi_fsm(struct IsdnCardState *cs, int event, void *data) { + if (cs->debug & L1_DEB_MONITOR) { + debugl1(cs, "arcofi state %d event %d", cs->dc.isac.arcofi_state, event); } - if (receive) { - while (cnt && !test_bit(HW_MON1_RX_END, &cs->HW_Flags)) { - cnt--; - udelay(500); - } + if (event == ARCOFI_TIMEOUT) { + cs->dc.isac.arcofi_state = ARCOFI_NOP; + test_and_set_bit(FLG_ARCOFI_ERROR, &cs->HW_Flags); + wake_up_interruptible(&cs->dc.isac.arcofi_wait); + return(1); } - restore_flags(flags); - if (cnt <= 0) { - printk(KERN_WARNING"HiSax arcofi monitor timed out\n"); - debugl1(cs, "HiSax arcofi monitor timed out"); + switch (cs->dc.isac.arcofi_state) { + case ARCOFI_NOP: + if (event == ARCOFI_START) { + cs->dc.isac.arcofi_list = data; + cs->dc.isac.arcofi_state = ARCOFI_TRANSMIT; + send_arcofi(cs); + } + break; + case ARCOFI_TRANSMIT: + if (event == ARCOFI_TX_END) { + if (cs->dc.isac.arcofi_list->receive) { + add_arcofi_timer(cs); + cs->dc.isac.arcofi_state = ARCOFI_RECEIVE; + } else { + if (cs->dc.isac.arcofi_list->next) { + cs->dc.isac.arcofi_list = + cs->dc.isac.arcofi_list->next; + send_arcofi(cs); + } else { + if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) { + del_timer(&cs->dc.isac.arcofitimer); + } + cs->dc.isac.arcofi_state = ARCOFI_NOP; + wake_up_interruptible(&cs->dc.isac.arcofi_wait); + } + } + } + break; + case ARCOFI_RECEIVE: + if (event == ARCOFI_RX_END) { + if (cs->dc.isac.arcofi_list->next) { + cs->dc.isac.arcofi_list = + cs->dc.isac.arcofi_list->next; + cs->dc.isac.arcofi_state = ARCOFI_TRANSMIT; + send_arcofi(cs); + } else { + if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) { + del_timer(&cs->dc.isac.arcofitimer); + } + cs->dc.isac.arcofi_state = ARCOFI_NOP; + wake_up_interruptible(&cs->dc.isac.arcofi_wait); + } + } + break; + default: + debugl1(cs, "Arcofi unknown state %x", cs->dc.isac.arcofi_state); + return(2); + } + return(0); +} + +static void +arcofi_timer(struct IsdnCardState *cs) { + arcofi_fsm(cs, ARCOFI_TIMEOUT, NULL); +} + +void +clear_arcofi(struct IsdnCardState *cs) { + if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) { + del_timer(&cs->dc.isac.arcofitimer); } - return(cnt); +} + +void +init_arcofi(struct IsdnCardState *cs) { + cs->dc.isac.arcofitimer.function = (void *) arcofi_timer; + cs->dc.isac.arcofitimer.data = (long) cs; + init_timer(&cs->dc.isac.arcofitimer); } diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/arcofi.h linux/drivers/isdn/hisax/arcofi.h --- v2.3.13/linux/drivers/isdn/hisax/arcofi.h Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/arcofi.h Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: arcofi.h,v 1.3 1998/05/25 12:57:39 keil Exp $ +/* $Id: arcofi.h,v 1.4 1999/07/01 08:11:18 keil Exp $ * arcofi.h Ansteuerung ARCOFI 2165 * @@ -7,6 +7,9 @@ * * * $Log: arcofi.h,v $ + * Revision 1.4 1999/07/01 08:11:18 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.3 1998/05/25 12:57:39 keil * HiSax golden code from certification, Don't use !!! * No leased lines, no X75, but many changes. @@ -21,4 +24,16 @@ #define ARCOFI_USE 1 -extern int send_arcofi(struct IsdnCardState *cs, const u_char *msg, int bc, int receive); +/* states */ +#define ARCOFI_NOP 0 +#define ARCOFI_TRANSMIT 1 +#define ARCOFI_RECEIVE 2 +/* events */ +#define ARCOFI_START 1 +#define ARCOFI_TX_END 2 +#define ARCOFI_RX_END 3 +#define ARCOFI_TIMEOUT 4 + +extern int arcofi_fsm(struct IsdnCardState *cs, int event, void *data); +extern void init_arcofi(struct IsdnCardState *cs); +extern void clear_arcofi(struct IsdnCardState *cs); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/asuscom.c linux/drivers/isdn/hisax/asuscom.c --- v2.3.13/linux/drivers/isdn/hisax/asuscom.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/isdn/hisax/asuscom.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: asuscom.c,v 1.5 1998/11/15 23:54:19 keil Exp $ +/* $Id: asuscom.c,v 1.7 1999/07/12 21:04:53 keil Exp $ * asuscom.c low level stuff for ASUSCOM NETWORK INC. ISDNLink cards * @@ -8,6 +8,13 @@ * * * $Log: asuscom.c,v $ + * Revision 1.7 1999/07/12 21:04:53 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 1.6 1999/07/01 08:11:18 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.5 1998/11/15 23:54:19 keil * changes from 2.0 * @@ -32,7 +39,7 @@ extern const char *CardType[]; -const char *Asuscom_revision = "$Revision: 1.5 $"; +const char *Asuscom_revision = "$Revision: 1.7 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -181,7 +188,7 @@ asuscom_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; - u_char val, stat = 0; + u_char val; if (!cs) { printk(KERN_WARNING "ISDNLink: Spurious interrupt!\n"); @@ -189,16 +196,12 @@ } val = readreg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_ISTA + 0x40); Start_HSCX: - if (val) { + if (val) hscx_int_main(cs, val); - stat |= 1; - } val = readreg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_ISTA); Start_ISAC: - if (val) { + if (val) isac_interrupt(cs, val); - stat |= 2; - } val = readreg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_ISTA + 0x40); if (val) { if (cs->debug & L1_DEB_HSCX) @@ -211,23 +214,19 @@ debugl1(cs, "ISAC IntStat after IntRoutine"); goto Start_ISAC; } - if (stat & 1) { - writereg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_MASK, 0xFF); - writereg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_MASK + 0x40, 0xFF); - writereg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_MASK, 0x0); - writereg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_MASK + 0x40, 0x0); - } - if (stat & 2) { - writereg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_MASK, 0x0); - } + writereg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_MASK, 0xFF); + writereg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_MASK + 0x40, 0xFF); + writereg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_MASK, 0xFF); + writereg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_MASK, 0x0); + writereg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_MASK, 0x0); + writereg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_MASK + 0x40, 0x0); } static void asuscom_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; - u_char ista, val, icnt = 20; + u_char ista, val, icnt = 5; if (!cs) { printk(KERN_WARNING "ISDNLink: Spurious interrupt!\n"); @@ -290,13 +289,13 @@ save_flags(flags); sti(); current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout((10*HZ)/1000); if (cs->subtyp == ASUS_IPAC) writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_POTA2, 0x0); else byteout(cs->hw.asus.adr, 0); /* Reset Off */ current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout((10*HZ)/1000); if (cs->subtyp == ASUS_IPAC) { writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_CONF, 0x0); writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_ACFG, 0xff); @@ -317,13 +316,6 @@ case CARD_RELEASE: release_io_asuscom(cs); return(0); - case CARD_SETIRQ: - if (cs->subtyp == ASUS_IPAC) - return(request_irq(cs->irq, &asuscom_interrupt_ipac, - I4L_IRQ_FLAG, "HiSax", cs)); - else - return(request_irq(cs->irq, &asuscom_interrupt, - I4L_IRQ_FLAG, "HiSax", cs)); case CARD_INIT: cs->debug |= L1_DEB_IPAC; inithscxisac(cs, 3); @@ -334,8 +326,8 @@ return(0); } -int __init -setup_asuscom(struct IsdnCard *card) +__initfunc(int +setup_asuscom(struct IsdnCard *card)) { int bytecnt; struct IsdnCardState *cs = card->cs; @@ -378,6 +370,7 @@ cs->writeisac = &WriteISAC_IPAC; cs->readisacfifo = &ReadISACfifo_IPAC; cs->writeisacfifo = &WriteISACfifo_IPAC; + cs->irq_func = &asuscom_interrupt_ipac; printk(KERN_INFO "Asus: IPAC version %x\n", val); } else { cs->subtyp = ASUS_ISACHSCX; @@ -390,6 +383,7 @@ cs->writeisac = &WriteISAC; cs->readisacfifo = &ReadISACfifo; cs->writeisacfifo = &WriteISACfifo; + cs->irq_func = &asuscom_interrupt; ISACVersion(cs, "ISDNLink:"); if (HscxVersion(cs, "ISDNLink:")) { printk(KERN_WARNING diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/avm_a1.c linux/drivers/isdn/hisax/avm_a1.c --- v2.3.13/linux/drivers/isdn/hisax/avm_a1.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/isdn/hisax/avm_a1.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: avm_a1.c,v 2.10 1998/11/15 23:54:21 keil Exp $ +/* $Id: avm_a1.c,v 2.11 1999/07/12 21:04:54 keil Exp $ * avm_a1.c low level stuff for AVM A1 (Fritz) isdn cards * @@ -6,6 +6,10 @@ * * * $Log: avm_a1.c,v $ + * Revision 2.11 1999/07/12 21:04:54 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * * Revision 2.10 1998/11/15 23:54:21 keil * changes from 2.0 * @@ -66,7 +70,7 @@ #include "isdnl1.h" extern const char *CardType[]; -static const char *avm_revision = "$Revision: 2.10 $"; +static const char *avm_revision = "$Revision: 2.11 $"; #define AVM_A1_STAT_ISAC 0x01 #define AVM_A1_STAT_HSCX 0x02 @@ -153,7 +157,7 @@ avm_a1_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; - u_char val, sval, stat = 0; + u_char val, sval; if (!cs) { printk(KERN_WARNING "AVM A1: Spurious interrupt!\n"); @@ -167,29 +171,21 @@ debugl1(cs, "avm IntStatus %x", sval); if (!(sval & AVM_A1_STAT_HSCX)) { val = readreg(cs->hw.avm.hscx[1], HSCX_ISTA); - if (val) { + if (val) hscx_int_main(cs, val); - stat |= 1; - } } if (!(sval & AVM_A1_STAT_ISAC)) { val = readreg(cs->hw.avm.isac, ISAC_ISTA); - if (val) { + if (val) isac_interrupt(cs, val); - stat |= 2; - } } } - if (stat & 1) { - writereg(cs->hw.avm.hscx[0], HSCX_MASK, 0xFF); - writereg(cs->hw.avm.hscx[1], HSCX_MASK, 0xFF); - writereg(cs->hw.avm.hscx[0], HSCX_MASK, 0x0); - writereg(cs->hw.avm.hscx[1], HSCX_MASK, 0x0); - } - if (stat & 2) { - writereg(cs->hw.avm.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.avm.isac, ISAC_MASK, 0x0); - } + writereg(cs->hw.avm.hscx[0], HSCX_MASK, 0xFF); + writereg(cs->hw.avm.hscx[1], HSCX_MASK, 0xFF); + writereg(cs->hw.avm.isac, ISAC_MASK, 0xFF); + writereg(cs->hw.avm.isac, ISAC_MASK, 0x0); + writereg(cs->hw.avm.hscx[0], HSCX_MASK, 0x0); + writereg(cs->hw.avm.hscx[1], HSCX_MASK, 0x0); } inline static void @@ -219,9 +215,6 @@ case CARD_RELEASE: release_ioregs(cs, 0x3f); return(0); - case CARD_SETIRQ: - return(request_irq(cs->irq, &avm_a1_interrupt, - I4L_IRQ_FLAG, "HiSax", cs)); case CARD_INIT: inithscxisac(cs, 1); byteout(cs->hw.avm.cfg_reg, 0x16); @@ -234,8 +227,8 @@ return(0); } -int __init -setup_avm_a1(struct IsdnCard *card) +__initfunc(int +setup_avm_a1(struct IsdnCard *card)) { u_char val; struct IsdnCardState *cs = card->cs; @@ -378,6 +371,7 @@ cs->BC_Write_Reg = &WriteHSCX; cs->BC_Send_Data = &hscx_fill_fifo; cs->cardmsg = &AVM_card_msg; + cs->irq_func = &avm_a1_interrupt; ISACVersion(cs, "AVM A1:"); if (HscxVersion(cs, "AVM A1:")) { printk(KERN_WARNING diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/avm_a1p.c linux/drivers/isdn/hisax/avm_a1p.c --- v2.3.13/linux/drivers/isdn/hisax/avm_a1p.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/avm_a1p.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: avm_a1p.c,v 2.3 1998/11/15 23:54:22 keil Exp $ +/* $Id: avm_a1p.c,v 2.4 1999/07/12 21:04:55 keil Exp $ * * avm_a1p.c low level stuff for the following AVM cards: * A1 PCMCIA @@ -8,6 +8,10 @@ * Author Carsten Paeth (calle@calle.in-berlin.de) * * $Log: avm_a1p.c,v $ + * Revision 2.4 1999/07/12 21:04:55 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * * Revision 2.3 1998/11/15 23:54:22 keil * changes from 2.0 * @@ -67,7 +71,7 @@ #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) -static const char *avm_revision = "$Revision: 2.3 $"; +static const char *avm_revision = "$Revision: 2.4 $"; static inline u_char ReadISAC(struct IsdnCardState *cs, u_char offset) @@ -195,7 +199,7 @@ avm_a1p_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; - u_char val, sval, stat = 0; + u_char val, sval; if (!cs) { printk(KERN_WARNING "AVM A1 PCMCIA: Spurious interrupt!\n"); @@ -206,35 +210,26 @@ debugl1(cs, "avm IntStatus %x", sval); if (sval & ASL0_R_HSCX) { val = ReadHSCX(cs, 1, HSCX_ISTA); - if (val) { + if (val) hscx_int_main(cs, val); - stat |= 1; - } } if (sval & ASL0_R_ISAC) { val = ReadISAC(cs, ISAC_ISTA); - if (val) { + if (val) isac_interrupt(cs, val); - stat |= 2; - } } } - if (stat & 1) { - WriteHSCX(cs, 0, HSCX_MASK, 0xff); - WriteHSCX(cs, 1, HSCX_MASK, 0xff); - WriteHSCX(cs, 0, HSCX_MASK, 0x00); - WriteHSCX(cs, 1, HSCX_MASK, 0x00); - } - if (stat & 2) { - WriteISAC(cs, ISAC_MASK, 0xff); - WriteISAC(cs, ISAC_MASK, 0x00); - } + WriteHSCX(cs, 0, HSCX_MASK, 0xff); + WriteHSCX(cs, 1, HSCX_MASK, 0xff); + WriteISAC(cs, ISAC_MASK, 0xff); + WriteISAC(cs, ISAC_MASK, 0x00); + WriteHSCX(cs, 0, HSCX_MASK, 0x00); + WriteHSCX(cs, 1, HSCX_MASK, 0x00); } static int AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg) { - int ret; switch (mt) { case CARD_RESET: byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00); @@ -249,15 +244,6 @@ /* free_irq(cs->irq, cs); */ return 0; - case CARD_SETIRQ: - ret = request_irq(cs->irq, &avm_a1p_interrupt, - I4L_IRQ_FLAG, "HiSax", cs); - if (ret) - return ret; - byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET, - ASL0_W_TDISABLE|ASL0_W_TRESET|ASL0_W_IRQENABLE); - return 0; - case CARD_INIT: clear_pending_isac_ints(cs); clear_pending_hscx_ints(cs); @@ -323,6 +309,7 @@ cs->BC_Write_Reg = &WriteHSCX; cs->BC_Send_Data = &hscx_fill_fifo; cs->cardmsg = &AVM_card_msg; + cs->irq_func = &avm_a1p_interrupt; ISACVersion(cs, "AVM A1 PCMCIA:"); if (HscxVersion(cs, "AVM A1 PCMCIA:")) { diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/avm_pci.c linux/drivers/isdn/hisax/avm_pci.c --- v2.3.13/linux/drivers/isdn/hisax/avm_pci.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/avm_pci.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: avm_pci.c,v 1.7 1999/02/22 18:26:30 keil Exp $ +/* $Id: avm_pci.c,v 1.11 1999/08/11 21:01:18 keil Exp $ * avm_pci.c low level stuff for AVM Fritz!PCI and ISA PnP isdn cards * Thanks to AVM, Berlin for informations @@ -7,6 +7,19 @@ * * * $Log: avm_pci.c,v $ + * Revision 1.11 1999/08/11 21:01:18 keil + * new PCI codefix + * + * Revision 1.10 1999/08/10 16:01:44 calle + * struct pci_dev changed in 2.3.13. Made the necessary changes. + * + * Revision 1.9 1999/07/12 21:04:57 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 1.8 1999/07/01 08:11:19 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.7 1999/02/22 18:26:30 keil * Argh ! ISAC address was only set with PCI * @@ -37,10 +50,13 @@ #include "isac.h" #include "isdnl1.h" #include +#ifndef COMPAT_HAS_NEW_PCI +#include +#endif #include extern const char *CardType[]; -static const char *avm_pci_rev = "$Revision: 1.7 $"; +static const char *avm_pci_rev = "$Revision: 1.11 $"; #define AVM_FRITZ_PCI 1 #define AVM_FRITZ_PNP 2 @@ -466,7 +482,7 @@ if (bcs->st->lli.l1writewakeup && (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hdlc.count); - dev_kfree_skb(bcs->tx_skb); + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); bcs->hw.hdlc.count = 0; bcs->tx_skb = NULL; } @@ -593,7 +609,7 @@ discard_queue(&bcs->rqueue); discard_queue(&bcs->squeue); if (bcs->tx_skb) { - dev_kfree_skb(bcs->tx_skb); + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); } @@ -687,7 +703,7 @@ avm_pcipnp_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; - u_char val, stat = 0; + u_char val; u_char sval; if (!cs) { @@ -701,15 +717,12 @@ if (!(sval & AVM_STATUS0_IRQ_ISAC)) { val = ReadISAC(cs, ISAC_ISTA); isac_interrupt(cs, val); - stat |= 2; } if (!(sval & AVM_STATUS0_IRQ_HDLC)) { HDLC_irq_main(cs); } - if (stat & 2) { - WriteISAC(cs, ISAC_MASK, 0xFF); - WriteISAC(cs, ISAC_MASK, 0x0); - } + WriteISAC(cs, ISAC_MASK, 0xFF); + WriteISAC(cs, ISAC_MASK, 0x0); } static void @@ -733,8 +746,6 @@ static int AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg) { - u_int irq_flag; - switch (mt) { case CARD_RESET: reset_avmpcipnp(cs); @@ -743,13 +754,6 @@ outb(0, cs->hw.avm.cfg_reg + 2); release_region(cs->hw.avm.cfg_reg, 32); return(0); - case CARD_SETIRQ: - if (cs->subtyp == AVM_FRITZ_PCI) - irq_flag = I4L_IRQ_FLAG | SA_SHIRQ; - else - irq_flag = I4L_IRQ_FLAG; - return(request_irq(cs->irq, &avm_pcipnp_interrupt, - irq_flag, "HiSax", cs)); case CARD_INIT: clear_pending_isac_ints(cs); initisac(cs); @@ -769,7 +773,11 @@ return(0); } +#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *dev_avm __initdata = NULL; +#else +static int pci_index __initdata = 0; +#endif __initfunc(int setup_avm_pcipnp(struct IsdnCard *card)) @@ -788,6 +796,7 @@ cs->subtyp = AVM_FRITZ_PNP; } else { #if CONFIG_PCI +#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_ERR "FritzPCI: no PCI bus present\n"); return(0); @@ -799,7 +808,7 @@ printk(KERN_WARNING "FritzPCI: No IRQ for PCI card found\n"); return(0); } - cs->hw.avm.cfg_reg = dev_avm->base_address[1] & + cs->hw.avm.cfg_reg = get_pcibase(dev_avm, 1) & PCI_BASE_ADDRESS_IO_MASK; if (!cs->hw.avm.cfg_reg) { printk(KERN_WARNING "FritzPCI: No IO-Adr for PCI card found\n"); @@ -811,6 +820,37 @@ return(0); } #else + for (; pci_index < 255; pci_index++) { + unsigned char pci_bus, pci_device_fn; + unsigned int ioaddr; + unsigned char irq; + + if (pcibios_find_device (PCI_VENDOR_AVM, + PCI_FRITZPCI_ID, pci_index, + &pci_bus, &pci_device_fn) != 0) { + continue; + } + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_INTERRUPT_LINE, &irq); + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_1, &ioaddr); + cs->irq = irq; + cs->hw.avm.cfg_reg = ioaddr & PCI_BASE_ADDRESS_IO_MASK; + if (!cs->hw.avm.cfg_reg) { + printk(KERN_WARNING "FritzPCI: No IO-Adr for PCI card found\n"); + return(0); + } + cs->subtyp = AVM_FRITZ_PCI; + break; + } + if (pci_index == 255) { + printk(KERN_WARNING "FritzPCI: No PCI card found\n"); + return(0); + } + pci_index++; +#endif /* COMPAT_HAS_NEW_PCI */ + cs->irq_flags |= SA_SHIRQ; +#else printk(KERN_WARNING "FritzPCI: NO_PCI_BIOS\n"); return (0); #endif /* CONFIG_PCI */ @@ -846,8 +886,6 @@ break; default: printk(KERN_WARNING "AVM unknown subtype %d\n", cs->subtyp); - outb(0, cs->hw.avm.cfg_reg + 2); - release_region(cs->hw.avm.cfg_reg, 32); return(0); } printk(KERN_INFO "HiSax: %s config irq:%d base:0x%X\n", @@ -860,6 +898,7 @@ cs->writeisacfifo = &WriteISACfifo; cs->BC_Send_Data = &fill_hdlc; cs->cardmsg = &AVM_card_msg; + cs->irq_func = &avm_pcipnp_interrupt; ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:"); return (1); } diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/bkm_a4t.c linux/drivers/isdn/hisax/bkm_a4t.c --- v2.3.13/linux/drivers/isdn/hisax/bkm_a4t.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/hisax/bkm_a4t.c Sun Aug 15 11:49:08 1999 @@ -0,0 +1,404 @@ +/* $Id: bkm_a4t.c,v 1.6 1999/08/11 21:01:22 keil Exp $ + * bkm_a4t.c low level stuff for T-Berkom A4T + * derived from the original file sedlbauer.c + * derived from the original file niccy.c + * derived from the original file netjet.c + * + * Author Roland Klabunde (R.Klabunde@Berkom.de) + * + * $Log: bkm_a4t.c,v $ + * Revision 1.6 1999/08/11 21:01:22 keil + * new PCI codefix + * + * Revision 1.5 1999/08/10 16:01:46 calle + * struct pci_dev changed in 2.3.13. Made the necessary changes. + * + * Revision 1.4 1999/07/14 11:43:14 keil + * correct PCI_SUBSYSTEM_VENDOR_ID + * + * Revision 1.3 1999/07/12 21:04:58 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 1.2 1999/07/01 08:07:53 keil + * Initial version + * + * + */ + +#define __NO_VERSION__ + +#include +#include "hisax.h" +#include "isac.h" +#include "hscx.h" +#include "jade.h" +#include "isdnl1.h" +#include "bkm_ax.h" +#include +#ifndef COMPAT_HAS_NEW_PCI +#include +#endif + +extern const char *CardType[]; + +const char *bkm_a4t_revision = "$Revision: 1.6 $"; + + +static inline u_char +readreg(unsigned int ale, unsigned int adr, u_char off) +{ + register u_int ret; + long flags; + unsigned int *po = (unsigned int *) adr; /* Postoffice */ + save_flags(flags); + cli(); + *po = (GCS_2 | PO_WRITE | off); + __WAITI20__(po); + *po = (ale | PO_READ); + __WAITI20__(po); + ret = *po; + restore_flags(flags); + return ((unsigned char) ret); +} + + +static inline void +readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size) +{ + /* fifo read without cli because it's allready done */ + int i; + for (i = 0; i < size; i++) + *data++ = readreg(ale, adr, off); +} + + +static inline void +writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) +{ + long flags; + unsigned int *po = (unsigned int *) adr; /* Postoffice */ + save_flags(flags); + cli(); + *po = (GCS_2 | PO_WRITE | off); + __WAITI20__(po); + *po = (ale | PO_WRITE | data); + __WAITI20__(po); + restore_flags(flags); +} + + +static inline void +writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size) +{ + /* fifo write without cli because it's allready done */ + int i; + + for (i = 0; i < size; i++) + writereg(ale, adr, off, *data++); +} + + +/* Interface functions */ + +static u_char +ReadISAC(struct IsdnCardState *cs, u_char offset) +{ + return (readreg(cs->hw.ax.isac_ale, cs->hw.ax.isac_adr, offset)); +} + +static void +WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) +{ + writereg(cs->hw.ax.isac_ale, cs->hw.ax.isac_adr, offset, value); +} + +static void +ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size) +{ + readfifo(cs->hw.ax.isac_ale, cs->hw.ax.isac_adr, 0, data, size); +} + +static void +WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size) +{ + writefifo(cs->hw.ax.isac_ale, cs->hw.ax.isac_adr, 0, data, size); +} + +static u_char +ReadJADE(struct IsdnCardState *cs, int jade, u_char offset) +{ + return (readreg(cs->hw.ax.jade_ale, cs->hw.ax.jade_adr, offset + (jade == -1 ? 0 : (jade ? 0xC0 : 0x80)))); +} + +static void +WriteJADE(struct IsdnCardState *cs, int jade, u_char offset, u_char value) +{ + writereg(cs->hw.ax.jade_ale, cs->hw.ax.jade_adr, offset + (jade == -1 ? 0 : (jade ? 0xC0 : 0x80)), value); +} + +/* + * fast interrupt JADE stuff goes here + */ + +#define READJADE(cs, nr, reg) readreg(cs->hw.ax.jade_ale,\ + cs->hw.ax.jade_adr, reg + (nr == -1 ? 0 : (nr ? 0xC0 : 0x80))) +#define WRITEJADE(cs, nr, reg, data) writereg(cs->hw.ax.jade_ale,\ + cs->hw.ax.jade_adr, reg + (nr == -1 ? 0 : (nr ? 0xC0 : 0x80)), data) + +#define READJADEFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.ax.jade_ale,\ + cs->hw.ax.jade_adr, (nr == -1 ? 0 : (nr ? 0xC0 : 0x80)), ptr, cnt) +#define WRITEJADEFIFO(cs, nr, ptr, cnt) writefifo( cs->hw.ax.jade_ale,\ + cs->hw.ax.jade_adr, (nr == -1 ? 0 : (nr ? 0xC0 : 0x80)), ptr, cnt) + +#include "jade_irq.c" + +static void +bkm_interrupt(int intno, void *dev_id, struct pt_regs *regs) +{ + struct IsdnCardState *cs = dev_id; + u_char val = 0; + I20_REGISTER_FILE *pI20_Regs; + + if (!cs) { + printk(KERN_WARNING "HiSax: Telekom A4T: Spurious interrupt!\n"); + return; + } + pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); + + /* ISDN interrupt pending? */ + if (pI20_Regs->i20IntStatus & intISDN) { + /* Reset the ISDN interrupt */ + pI20_Regs->i20IntStatus = intISDN; + /* Disable ISDN interrupt */ + pI20_Regs->i20IntCtrl &= ~intISDN; + /* Channel A first */ + val = readreg(cs->hw.ax.jade_ale, cs->hw.ax.jade_adr, jade_HDLC_ISR + 0x80); + if (val) { + jade_int_main(cs, val, 0); + } + /* Channel B */ + val = readreg(cs->hw.ax.jade_ale, cs->hw.ax.jade_adr, jade_HDLC_ISR + 0xC0); + if (val) { + jade_int_main(cs, val, 1); + } + /* D-Channel */ + val = readreg(cs->hw.ax.isac_ale, cs->hw.ax.isac_adr, ISAC_ISTA); + if (val) { + isac_interrupt(cs, val); + } + /* Reenable ISDN interrupt */ + pI20_Regs->i20IntCtrl |= intISDN; + } +} + +void +release_io_bkm(struct IsdnCardState *cs) +{ + if (cs->hw.ax.base) { + iounmap((void *) cs->hw.ax.base); + cs->hw.ax.base = 0; + } +} + +static void +enable_bkm_int(struct IsdnCardState *cs, unsigned bEnable) +{ + if (cs->typ == ISDN_CTYPE_BKM_A4T) { + I20_REGISTER_FILE *pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); + if (bEnable) + pI20_Regs->i20IntCtrl |= (intISDN | intPCI); + else + /* CAUTION: This disables the video capture driver too */ + pI20_Regs->i20IntCtrl &= ~(intISDN | intPCI); + } +} + +static void +reset_bkm(struct IsdnCardState *cs) +{ + long flags; + + if (cs->typ == ISDN_CTYPE_BKM_A4T) { + I20_REGISTER_FILE *pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); + save_flags(flags); + sti(); + /* Issue the I20 soft reset */ + pI20_Regs->i20SysControl = 0xFF; /* all in */ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((10 * HZ) / 1000); + /* Remove the soft reset */ + pI20_Regs->i20SysControl = sysRESET | 0xFF; + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((10 * HZ) / 1000); + /* Set our configuration */ + pI20_Regs->i20SysControl = sysRESET | sysCFG; + /* Issue ISDN reset */ + pI20_Regs->i20GuestControl = guestWAIT_CFG | + g_A4T_JADE_RES | + g_A4T_ISAR_RES | + g_A4T_ISAC_RES | + g_A4T_JADE_BOOTR | + g_A4T_ISAR_BOOTR; + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((10 * HZ) / 1000); + + /* Remove RESET state from ISDN */ + pI20_Regs->i20GuestControl &= ~(g_A4T_ISAC_RES | + g_A4T_JADE_RES | + g_A4T_ISAR_RES); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((10 * HZ) / 1000); + restore_flags(flags); + } +} + +static int +BKM_card_msg(struct IsdnCardState *cs, int mt, void *arg) +{ + switch (mt) { + case CARD_RESET: + /* Disable ints */ + enable_bkm_int(cs, 0); + reset_bkm(cs); + return (0); + case CARD_RELEASE: + /* Sanity */ + enable_bkm_int(cs, 0); + reset_bkm(cs); + release_io_bkm(cs); + return (0); + case CARD_INIT: + clear_pending_isac_ints(cs); + clear_pending_jade_ints(cs); + initisac(cs); + initjade(cs); + /* Enable ints */ + enable_bkm_int(cs, 1); + return (0); + case CARD_TEST: + return (0); + } + return (0); +} + +#ifdef COMPAT_HAS_NEW_PCI +static struct pci_dev *dev_a4t __initdata = NULL; +#else +static int pci_index __initdata = 0; +#endif + +__initfunc(int + setup_bkm_a4t(struct IsdnCard *card)) +{ + struct IsdnCardState *cs = card->cs; + char tmp[64]; + u_int pci_memaddr = 0, found = 0; + I20_REGISTER_FILE *pI20_Regs; +#if CONFIG_PCI +#ifndef COMPAT_HAS_NEW_PCI + u_char pci_bus, pci_device_fn, pci_irq = 0; +#endif +#endif + + strcpy(tmp, bkm_a4t_revision); + printk(KERN_INFO "HiSax: T-Berkom driver Rev. %s\n", HiSax_getrev(tmp)); + if (cs->typ == ISDN_CTYPE_BKM_A4T) { + cs->subtyp = BKM_A4T; + } else + return (0); + +#if CONFIG_PCI +#ifdef COMPAT_HAS_NEW_PCI + if (!pci_present()) { + printk(KERN_ERR "bkm_a4t: no PCI bus present\n"); + return (0); + } + if ((dev_a4t = pci_find_device(I20_VENDOR_ID, I20_DEVICE_ID, dev_a4t))) { + u_int sub_sys_id = 0; + + pci_read_config_dword(dev_a4t, PCI_SUBSYSTEM_VENDOR_ID, + &sub_sys_id); + if (sub_sys_id == ((A4T_SUBSYS_ID << 16) | A4T_SUBVEN_ID)) { + found = 1; + pci_memaddr = get_pcibase(dev_a4t, 0); + cs->irq = dev_a4t->irq; + } + } +#else + for (; pci_index < 0xff; pci_index++) { + if (pcibios_find_device(I20_VENDOR_ID, + I20_DEVICE_ID, + pci_index, + &pci_bus, + &pci_device_fn) == PCIBIOS_SUCCESSFUL) { + u_int sub_sys_id = 0; + + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_SUBSYSTEM_VENDOR_ID, &sub_sys_id); + if (sub_sys_id == ((A4T_SUBSYS_ID << 16) | A4T_SUBVEN_ID)) { + found = 1; + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_INTERRUPT_LINE, &pci_irq); + cs->irq = pci_irq; + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_0, &pci_memaddr); + break; + } + } + } +#endif /* COMPAT_HAS_NEW_PCI */ + if (!found) { + printk(KERN_WARNING "HiSax: %s: Card not found\n", CardType[card->typ]); + return (0); + } +#ifndef COMPAT_HAS_NEW_PCI + pci_index++; +#endif + if (!cs->irq) { /* IRQ range check ?? */ + printk(KERN_WARNING "HiSax: %s: No IRQ\n", CardType[card->typ]); + return (0); + } + if (!pci_memaddr) { + printk(KERN_WARNING "HiSax: %s: No Memory base address\n", CardType[card->typ]); + return (0); + } + pci_memaddr &= PCI_BASE_ADDRESS_MEM_MASK; + cs->hw.ax.base = (u_int) ioremap(pci_memaddr, 4096); + /* Check suspecious address */ + pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); + if ((pI20_Regs->i20IntStatus & 0x8EFFFFFF) != 0) { + printk(KERN_WARNING "HiSax: %s address %x-%x suspecious\n", + CardType[card->typ], cs->hw.ax.base, cs->hw.ax.base + 4096); + iounmap((void *) cs->hw.ax.base); + cs->hw.ax.base = 0; + return (0); + } + cs->hw.ax.isac_adr = cs->hw.ax.base + PO_OFFSET; + cs->hw.ax.jade_adr = cs->hw.ax.base + PO_OFFSET; + cs->hw.ax.isac_ale = GCS_1; + cs->hw.ax.jade_ale = GCS_3; +#else + printk(KERN_WARNING "HiSax: %s: NO_PCI_BIOS\n", CardType[card->typ]); + printk(KERN_WARNING "HiSax: %s: unable to configure\n", CardType[card->typ]); + return (0); +#endif /* CONFIG_PCI */ + printk(KERN_INFO "HiSax: %s: Card configured at 0x%X IRQ %d\n", + CardType[card->typ], cs->hw.ax.base, cs->irq); + + reset_bkm(cs); + cs->readisac = &ReadISAC; + cs->writeisac = &WriteISAC; + cs->readisacfifo = &ReadISACfifo; + cs->writeisacfifo = &WriteISACfifo; + cs->BC_Read_Reg = &ReadJADE; + cs->BC_Write_Reg = &WriteJADE; + cs->BC_Send_Data = &jade_fill_fifo; + cs->cardmsg = &BKM_card_msg; + cs->irq_func = &bkm_interrupt; + cs->irq_flags |= SA_SHIRQ; + ISACVersion(cs, "Telekom A4T:"); + /* Jade version */ + JadeVersion(cs, "Telekom A4T:"); + return (1); +} diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/bkm_a8.c linux/drivers/isdn/hisax/bkm_a8.c --- v2.3.13/linux/drivers/isdn/hisax/bkm_a8.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/hisax/bkm_a8.c Sun Aug 15 11:49:08 1999 @@ -0,0 +1,530 @@ +/* $Id: bkm_a8.c,v 1.6 1999/08/11 21:01:24 keil Exp $ + * bkm_a8.c low level stuff for Scitel Quadro (4*S0, passive) + * derived from the original file sedlbauer.c + * derived from the original file niccy.c + * derived from the original file netjet.c + * + * Author Roland Klabunde (R.Klabunde@Berkom.de) + * + * $Log: bkm_a8.c,v $ + * Revision 1.6 1999/08/11 21:01:24 keil + * new PCI codefix + * + * Revision 1.5 1999/08/10 16:01:48 calle + * struct pci_dev changed in 2.3.13. Made the necessary changes. + * + * Revision 1.4 1999/07/14 11:43:15 keil + * correct PCI_SUBSYSTEM_VENDOR_ID + * + * Revision 1.3 1999/07/12 21:04:59 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 1.2 1999/07/01 08:07:54 keil + * Initial version + * + * + */ +#define __NO_VERSION__ + +#include +#include "hisax.h" +#include "isac.h" +#include "ipac.h" +#include "hscx.h" +#include "isdnl1.h" +#include "bkm_ax.h" +#include +#ifndef COMPAT_HAS_NEW_PCI +#include +#endif + +#define ATTEMPT_PCI_REMAPPING /* Required for PLX rev 1 */ + +extern const char *CardType[]; + +const char sct_quadro_revision[] = "$Revision: 1.6 $"; + +/* To survive the startup phase */ +typedef struct { + u_int active; /* true/false */ + u_int base; /* ipac base address */ +} IPAC_STATE; + +static IPAC_STATE ipac_state[4 + 1] __initdata = +{ + {0, 0}, /* dummy */ + {0, 0}, /* SCT_1 */ + {0, 0}, /* SCT_2 */ + {0, 0}, /* SCT_3 */ + {0, 0} /* SCT_4 */ +}; + +static const char *sct_quadro_subtypes[] = +{ + "", + "#1", + "#2", + "#3", + "#4" +}; + + +#define wordout(addr,val) outw(val,addr) +#define wordin(addr) inw(addr) + +static inline u_char +readreg(unsigned int ale, unsigned int adr, u_char off) +{ + register u_char ret; + long flags; + save_flags(flags); + cli(); + wordout(ale, off); + ret = wordin(adr) & 0xFF; + restore_flags(flags); + return (ret); +} + +static inline void +readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size) +{ + /* fifo read without cli because it's allready done */ + int i; + wordout(ale, off); + for (i = 0; i < size; i++) + data[i] = wordin(adr) & 0xFF; +} + + +static inline void +writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) +{ + long flags; + save_flags(flags); + cli(); + wordout(ale, off); + wordout(adr, data); + restore_flags(flags); +} + +static inline void +writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size) +{ + /* fifo write without cli because it's allready done */ + int i; + wordout(ale, off); + for (i = 0; i < size; i++) + wordout(adr, data[i]); +} + +/* Interface functions */ + +static u_char +ReadISAC(struct IsdnCardState *cs, u_char offset) +{ + return (readreg(cs->hw.ax.base, cs->hw.ax.data_adr, offset | 0x80)); +} + +static void +WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) +{ + writereg(cs->hw.ax.base, cs->hw.ax.data_adr, offset | 0x80, value); +} + +static void +ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size) +{ + readfifo(cs->hw.ax.base, cs->hw.ax.data_adr, 0x80, data, size); +} + +static void +WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size) +{ + writefifo(cs->hw.ax.base, cs->hw.ax.data_adr, 0x80, data, size); +} + + +static u_char +ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) +{ + return (readreg(cs->hw.ax.base, cs->hw.ax.data_adr, offset + (hscx ? 0x40 : 0))); +} + +static void +WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) +{ + writereg(cs->hw.ax.base, cs->hw.ax.data_adr, offset + (hscx ? 0x40 : 0), value); +} + +/* Check whether the specified ipac is already active or not */ +static int +is_ipac_active(u_int ipac_nr) +{ + return (ipac_state[ipac_nr].active); +} + +/* Set the specific ipac to active */ +static void +set_ipac_active(u_int ipac_nr, u_int active) +{ + /* set activation state */ + ipac_state[ipac_nr].active = active; +} + +/* + * fast interrupt HSCX stuff goes here + */ + +#define READHSCX(cs, nr, reg) readreg(cs->hw.ax.base, \ + cs->hw.ax.data_adr, reg + (nr ? 0x40 : 0)) +#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.ax.base, \ + cs->hw.ax.data_adr, reg + (nr ? 0x40 : 0), data) +#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.ax.base, \ + cs->hw.ax.data_adr, (nr ? 0x40 : 0), ptr, cnt) +#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.ax.base, \ + cs->hw.ax.data_adr, (nr ? 0x40 : 0), ptr, cnt) + +#include "hscx_irq.c" + +static void +bkm_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs) +{ + struct IsdnCardState *cs = dev_id; + u_char ista, val, icnt = 5; + int i; + if (!cs) { + printk(KERN_WARNING "HiSax: Scitel Quadro: Spurious interrupt!\n"); + return; + } + ista = readreg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_ISTA); + + Start_IPAC: + if (cs->debug & L1_DEB_IPAC) + debugl1(cs, "IPAC ISTA %02X", ista); + if (ista & 0x0f) { + val = readreg(cs->hw.ax.base, cs->hw.ax.data_adr, HSCX_ISTA + 0x40); + if (ista & 0x01) + val |= 0x01; + if (ista & 0x04) + val |= 0x02; + if (ista & 0x08) + val |= 0x04; + if (val) { + hscx_int_main(cs, val); + } + } + if (ista & 0x20) { + val = 0xfe & readreg(cs->hw.ax.base, cs->hw.ax.data_adr, ISAC_ISTA | 0x80); + if (val) { + isac_interrupt(cs, val); + } + } + if (ista & 0x10) { + val = 0x01; + isac_interrupt(cs, val); + } + ista = readreg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_ISTA); + if ((ista & 0x3f) && icnt) { + icnt--; + goto Start_IPAC; + } + if (!icnt) + printk(KERN_WARNING "HiSax: %s (%s) IRQ LOOP\n", + CardType[cs->typ], + sct_quadro_subtypes[cs->subtyp]); + writereg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_MASK, 0xFF); + writereg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_MASK, 0xC0); + + /* Read out all interrupt sources from currently not active ipacs */ + /* "Handle" all interrupts from currently not active ipac by reading the regs */ + for (i = SCT_1; i <= SCT_4; i++) + if (!is_ipac_active(i)) { + u_int base = ipac_state[i].base; + if (readreg(base, base + 4, 0xC1)) { + readreg(base, base + 4, 0xA0); + readreg(base, base + 4, 0xA4); + readreg(base, base + 4, 0x20); + readreg(base, base + 4, 0x24); + readreg(base, base + 4, 0x60); + readreg(base, base + 4, 0x64); + readreg(base, base + 4, 0xC1); + readreg(base, base + 4, ISAC_CIR0 + 0x80); + } + } +} + + +void +release_io_sct_quadro(struct IsdnCardState *cs) +{ + /* ?? */ +} + +static void +enable_bkm_int(struct IsdnCardState *cs, unsigned bEnable) +{ + if (cs->typ == ISDN_CTYPE_SCT_QUADRO) { + if (bEnable) + wordout(cs->hw.ax.plx_adr + 0x4C, (wordin(cs->hw.ax.plx_adr + 0x4C) | 0x41)); + else + /* Issue general di only if no ipac is active */ + if (!is_ipac_active(SCT_1) && + !is_ipac_active(SCT_2) && + !is_ipac_active(SCT_3) && + !is_ipac_active(SCT_4)) + wordout(cs->hw.ax.plx_adr + 0x4C, (wordin(cs->hw.ax.plx_adr + 0x4C) & ~0x41)); + } +} + +static void +reset_bkm(struct IsdnCardState *cs) +{ + long flags; + + if (cs->typ == ISDN_CTYPE_SCT_QUADRO) { + if (!is_ipac_active(SCT_1) && + !is_ipac_active(SCT_2) && + !is_ipac_active(SCT_3) && + !is_ipac_active(SCT_4)) { + /* Issue total reset only if no ipac is active */ + wordout(cs->hw.ax.plx_adr + 0x50, (wordin(cs->hw.ax.plx_adr + 0x50) & ~4)); + + save_flags(flags); + sti(); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((10 * HZ) / 1000); + + /* Remove the soft reset */ + wordout(cs->hw.ax.plx_adr + 0x50, (wordin(cs->hw.ax.plx_adr + 0x50) | 4)); + + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((10 * HZ) / 1000); + restore_flags(flags); + } + } +} + +static int +BKM_card_msg(struct IsdnCardState *cs, int mt, void *arg) +{ + switch (mt) { + case CARD_RESET: + /* Disable ints */ + set_ipac_active(cs->subtyp, 0); + enable_bkm_int(cs, 0); + reset_bkm(cs); + return (0); + case CARD_RELEASE: + /* Sanity */ + set_ipac_active(cs->subtyp, 0); + enable_bkm_int(cs, 0); + reset_bkm(cs); + release_io_sct_quadro(cs); + return (0); + case CARD_INIT: + cs->debug |= L1_DEB_IPAC; + set_ipac_active(cs->subtyp, 1); + inithscxisac(cs, 3); + /* Enable ints */ + enable_bkm_int(cs, 1); + return (0); + case CARD_TEST: + return (0); + } + return (0); +} + +#ifdef COMPAT_HAS_NEW_PCI +static struct pci_dev *dev_a8 __initdata = NULL; +#else +static int pci_index __initdata = 0; +#endif + +__initfunc(int + setup_sct_quadro(struct IsdnCard *card)) +{ + struct IsdnCardState *cs = card->cs; + char tmp[64]; +#if CONFIG_PCI + u_char pci_bus = 0, pci_device_fn = 0, pci_irq = 0, pci_rev_id; + u_int found = 0; + u_int pci_ioaddr1, pci_ioaddr2, pci_ioaddr3, pci_ioaddr4, pci_ioaddr5; +#endif + + strcpy(tmp, sct_quadro_revision); + printk(KERN_INFO "HiSax: T-Berkom driver Rev. %s\n", HiSax_getrev(tmp)); + if (cs->typ == ISDN_CTYPE_SCT_QUADRO) { + cs->subtyp = SCT_1; /* Preset */ + } else + return (0); + + /* Identify subtype by para[0] */ + if (card->para[0] >= SCT_1 && card->para[0] <= SCT_4) + cs->subtyp = card->para[0]; + else + printk(KERN_WARNING "HiSax: %s: Invalid subcontroller in configuration, default to 1\n", + CardType[card->typ]); +#if CONFIG_PCI +#ifdef COMPAT_HAS_NEW_PCI + if (!pci_present()) { + printk(KERN_ERR "bkm_a4t: no PCI bus present\n"); + return (0); + } + if ((dev_a8 = pci_find_device(PLX_VENDOR_ID, PLX_DEVICE_ID, dev_a8))) { + u_int sub_sys_id = 0; + + pci_read_config_dword(dev_a8, PCI_SUBSYSTEM_VENDOR_ID, + &sub_sys_id); + if (sub_sys_id == ((SCT_SUBSYS_ID << 16) | SCT_SUBVEN_ID)) { + found = 1; + pci_ioaddr1 = get_pcibase(dev_a8, 1); + pci_irq = dev_a8->irq; + pci_bus = dev_a8->bus->number; + pci_device_fn = dev_a8->devfn; + } + } +#else + for (; pci_index < 0xff; pci_index++) { + if (pcibios_find_device( + PLX_VENDOR_ID, + PLX_DEVICE_ID, + pci_index, + &pci_bus, + &pci_device_fn) == PCIBIOS_SUCCESSFUL) { + + u_int sub_sys_id = 0; + + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_SUBSYSTEM_VENDOR_ID, &sub_sys_id); + if (sub_sys_id == ((SCT_SUBSYS_ID << 16) | SCT_SUBVEN_ID)) { + found = 1; + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_INTERRUPT_LINE, &pci_irq); + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_1, &pci_ioaddr1); + cs->irq = pci_irq; + break; + } + } + } +#endif /* COMPAT_HAS_NEW_PCI */ + if (!found) { + printk(KERN_WARNING "HiSax: %s (%s): Card not found\n", + CardType[card->typ], + sct_quadro_subtypes[cs->subtyp]); + return (0); + } +#ifndef COMPAT_HAS_NEW_PCI + pci_index++; /* need for more as one card */ +#endif + if (!pci_irq) { /* IRQ range check ?? */ + printk(KERN_WARNING "HiSax: %s (%s): No IRQ\n", + CardType[card->typ], + sct_quadro_subtypes[cs->subtyp]); + return (0); + } +#ifdef ATTEMPT_PCI_REMAPPING +/* HACK: PLX revision 1 bug: PLX address bit 7 must not be set */ + pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_REVISION_ID, &pci_rev_id); + if ((pci_ioaddr1 & 0x80) && (pci_rev_id == 1)) { + printk(KERN_WARNING "HiSax: %s (%s): PLX rev 1, remapping required!\n", + CardType[card->typ], + sct_quadro_subtypes[cs->subtyp]); + /* Restart PCI negotiation */ + pcibios_write_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_1, (u_int) - 1); + /* Move up by 0x80 byte */ + pci_ioaddr1 += 0x80; + pci_ioaddr1 &= PCI_BASE_ADDRESS_IO_MASK; + pcibios_write_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_1, pci_ioaddr1); +#ifdef COMPAT_HAS_NEW_PCI + get_pcibase(dev_a8, 1) = pci_ioaddr1; +#endif /* COMPAT_HAS_NEW_PCI */ + } +/* End HACK */ +#endif + pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_1, &pci_ioaddr1); + pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_2, &pci_ioaddr2); + pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_3, &pci_ioaddr3); + pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_4, &pci_ioaddr4); + pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_5, &pci_ioaddr5); + if (!pci_ioaddr1 || !pci_ioaddr2 || !pci_ioaddr3 || !pci_ioaddr4 || !pci_ioaddr5) { + printk(KERN_WARNING "HiSax: %s (%s): No IO base address(es)\n", + CardType[card->typ], + sct_quadro_subtypes[cs->subtyp]); + return (0); + } + pci_ioaddr1 &= PCI_BASE_ADDRESS_IO_MASK; + pci_ioaddr2 &= PCI_BASE_ADDRESS_IO_MASK; + pci_ioaddr3 &= PCI_BASE_ADDRESS_IO_MASK; + pci_ioaddr4 &= PCI_BASE_ADDRESS_IO_MASK; + pci_ioaddr5 &= PCI_BASE_ADDRESS_IO_MASK; + /* Take over */ + cs->irq = pci_irq; + cs->irq_flags |= SA_SHIRQ; + /* pci_ioaddr1 is unique to all subdevices */ + /* pci_ioaddr2 is for the fourth subdevice only */ + /* pci_ioaddr3 is for the third subdevice only */ + /* pci_ioaddr4 is for the second subdevice only */ + /* pci_ioaddr5 is for the first subdevice only */ + cs->hw.ax.plx_adr = pci_ioaddr1; + /* Enter all ipac_base addresses */ + ipac_state[SCT_1].base = pci_ioaddr5 + 0x00; + ipac_state[SCT_2].base = pci_ioaddr4 + 0x08; + ipac_state[SCT_3].base = pci_ioaddr3 + 0x10; + ipac_state[SCT_4].base = pci_ioaddr2 + 0x20; + /* For isac and hscx control path */ + cs->hw.ax.base = ipac_state[cs->subtyp].base; + /* For isac and hscx data path */ + cs->hw.ax.data_adr = cs->hw.ax.base + 4; +#else + printk(KERN_WARNING "HiSax: %s (%s): NO_PCI_BIOS\n", + CardType[card->typ], + sct_quadro_subtypes[cs->subtyp]); + printk(KERN_WARNING "HiSax: %s (%s): Unable to configure\n", + CardType[card->typ], + sct_quadro_subtypes[cs->subtyp]); + return (0); +#endif /* CONFIG_PCI */ + printk(KERN_INFO "HiSax: %s (%s) configured at 0x%.4X, 0x%.4X, 0x%.4X and IRQ %d\n", + CardType[card->typ], + sct_quadro_subtypes[cs->subtyp], + cs->hw.ax.plx_adr, + cs->hw.ax.base, + cs->hw.ax.data_adr, + cs->irq); + + test_and_set_bit(HW_IPAC, &cs->HW_Flags); + + /* Disable all currently not active ipacs */ + if (!is_ipac_active(SCT_1)) + set_ipac_active(SCT_1, 0); + if (!is_ipac_active(SCT_2)) + set_ipac_active(SCT_2, 0); + if (!is_ipac_active(SCT_3)) + set_ipac_active(SCT_3, 0); + if (!is_ipac_active(SCT_4)) + set_ipac_active(SCT_4, 0); + + /* Perfom general reset (if possible) */ + reset_bkm(cs); + + cs->readisac = &ReadISAC; + cs->writeisac = &WriteISAC; + cs->readisacfifo = &ReadISACfifo; + cs->writeisacfifo = &WriteISACfifo; + + cs->BC_Read_Reg = &ReadHSCX; + cs->BC_Write_Reg = &WriteHSCX; + cs->BC_Send_Data = &hscx_fill_fifo; + cs->cardmsg = &BKM_card_msg; + cs->irq_func = &bkm_interrupt_ipac; + + printk(KERN_INFO "HiSax: %s (%s): IPAC Version %d\n", + CardType[card->typ], + sct_quadro_subtypes[cs->subtyp], + readreg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_ID)); + return (1); +} diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/bkm_ax.h linux/drivers/isdn/hisax/bkm_ax.h --- v2.3.13/linux/drivers/isdn/hisax/bkm_ax.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/hisax/bkm_ax.h Thu Aug 12 09:42:33 1999 @@ -0,0 +1,133 @@ +/* $Id: bkm_ax.h,v 1.2 1999/07/01 08:07:55 keil Exp $ + * bkm_ax.h low level decls for T-Berkom cards A4T and Scitel Quadro (4*S0, passive) + * + * Author Roland Klabunde (R.Klabunde@Berkom.de) + * + * $Log: bkm_ax.h,v $ + * Revision 1.2 1999/07/01 08:07:55 keil + * Initial version + * + * + * + */ + +#ifndef __BKM_AX_H__ +#define __BKM_AX_H__ + +/* Supported boards (subtypes) */ +#define SCT_1 1 +#define SCT_2 2 +#define SCT_3 3 +#define SCT_4 4 +#define BKM_A4T 5 + + +/* A4T */ +#define I20_DEVICE_ID 0x6120 /* I20 PCI device ID */ +#define I20_VENDOR_ID 0x11DE /* I20 PCI vendor ID */ +#define A4T_SUBVEN_ID 0x0871 +#define A4T_SUBSYS_ID 0xFFA4 +/* Scitel Quadro */ +#define PLX_DEVICE_ID 0x9050 /* Scitel Quadro PLX */ +#define PLX_VENDOR_ID 0x10B5 +#define SCT_SUBVEN_ID 0x0871 +#define SCT_SUBSYS_ID 0xFFA8 + + +#define PLX_ADDR_PLX 0x14 /* Addr PLX configuration */ +#define PLX_ADDR_ISAC 0x18 /* Addr ISAC */ +#define PLX_ADDR_HSCX 0x1C /* Addr HSCX */ +#define PLX_ADDR_ALE 0x20 /* Addr ALE */ +#define PLX_ADDR_ALEPLUS 0x24 /* Next Addr behind ALE */ + +#define PLX_SUBVEN 0x2C /* Offset SubVendor */ +#define PLX_SUBSYS 0x2E /* Offset SubSystem */ + + +/* Application specific registers I20 (Siemens SZB6120H) */ +typedef struct { + /* Video front end horizontal configuration register */ + volatile u_int i20VFEHorzCfg; /* Offset 00 */ + /* Video front end vertical configuration register */ + volatile u_int i20VFEVertCfg; /* Offset 04 */ + /* Video front end scaler and pixel format register */ + volatile u_int i20VFEScaler; /* Offset 08 */ + /* Video display top register */ + volatile u_int i20VDispTop; /* Offset 0C */ + /* Video display bottom register */ + volatile u_int i20VDispBottom; /* Offset 10 */ + /* Video stride, status and frame grab register */ + volatile u_int i20VidFrameGrab;/* Offset 14 */ + /* Video display configuration register */ + volatile u_int i20VDispCfg; /* Offset 18 */ + /* Video masking map top */ + volatile u_int i20VMaskTop; /* Offset 1C */ + /* Video masking map bottom */ + volatile u_int i20VMaskBottom; /* Offset 20 */ + /* Overlay control register */ + volatile u_int i20OvlyControl; /* Offset 24 */ + /* System, PCI and general purpose pins control register */ + volatile u_int i20SysControl; /* Offset 28 */ +#define sysRESET 0x01000000 /* bit 24:Softreset (Low) */ + /* GPIO 4...0: Output fixed for our cfg! */ +#define sysCFG 0x000000E0 /* GPIO 7,6,5: Input */ + /* General purpose pins and guest bus control register */ + volatile u_int i20GuestControl;/* Offset 2C */ +#define guestWAIT_CFG 0x00005555 /* 4 PCI waits for all */ +#define guestISDN_INT_E 0x01000000 /* ISDN Int en (low) */ +#define guestVID_INT_E 0x02000000 /* Video interrupt en (low) */ +#define guestADI1_INT_R 0x04000000 /* ADI #1 int req (low) */ +#define guestADI2_INT_R 0x08000000 /* ADI #2 int req (low) */ +#define guestISDN_RES 0x10000000 /* ISDN reset bit (high) */ +#define guestADI1_INT_S 0x20000000 /* ADI #1 int pending (low) */ +#define guestADI2_INT_S 0x40000000 /* ADI #2 int pending (low) */ +#define guestISDN_INT_S 0x80000000 /* ISAC int pending (low) */ + +#define g_A4T_JADE_RES 0x01000000 /* JADE Reset (High) */ +#define g_A4T_ISAR_RES 0x02000000 /* ISAR Reset (High) */ +#define g_A4T_ISAC_RES 0x04000000 /* ISAC Reset (High) */ +#define g_A4T_JADE_BOOTR 0x08000000 /* JADE enable boot SRAM (Low) NOT USED */ +#define g_A4T_ISAR_BOOTR 0x10000000 /* ISAR enable boot SRAM (Low) NOT USED */ +#define g_A4T_JADE_INT_S 0x20000000 /* JADE interrupt pnd (Low) */ +#define g_A4T_ISAR_INT_S 0x40000000 /* ISAR interrupt pnd (Low) */ +#define g_A4T_ISAC_INT_S 0x80000000 /* ISAC interrupt pnd (Low) */ + + volatile u_int i20CodeSource; /* Offset 30 */ + volatile u_int i20CodeXferCtrl;/* Offset 34 */ + volatile u_int i20CodeMemPtr; /* Offset 38 */ + + volatile u_int i20IntStatus; /* Offset 3C */ + volatile u_int i20IntCtrl; /* Offset 40 */ +#define intISDN 0x40000000 /* GIRQ1En (ISAC/ADI) (High) */ +#define intVID 0x20000000 /* GIRQ0En (VSYNC) (High) */ +#define intCOD 0x10000000 /* CodRepIrqEn (High) */ +#define intPCI 0x01000000 /* PCI IntA enable (High) */ + + volatile u_int i20I2CCtrl; /* Offset 44 */ +} I20_REGISTER_FILE, *PI20_REGISTER_FILE; + +/* + * Postoffice structure for A4T + * + */ +#define PO_OFFSET 0x00000200 /* Postoffice offset from base */ + +#define GCS_0 0x00000000 /* Guest bus chip selects */ +#define GCS_1 0x00100000 +#define GCS_2 0x00200000 +#define GCS_3 0x00300000 + +#define PO_READ 0x00000000 /* R/W from/to guest bus */ +#define PO_WRITE 0x00800000 + +#define PO_PEND 0x02000000 + +#define POSTOFFICE(postoffice) *(volatile unsigned int*)(postoffice) + +/* Wait unlimited (don't worry) */ +#define __WAITI20__(postoffice) \ +do { \ + while ((POSTOFFICE(postoffice) & PO_PEND)) ; \ +} while (0) + +#endif /* __BKM_AX_H__ */ diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/callc.c linux/drivers/isdn/hisax/callc.c --- v2.3.13/linux/drivers/isdn/hisax/callc.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/callc.c Sun Aug 15 11:49:08 1999 @@ -1,4 +1,4 @@ -/* $Id: callc.c,v 2.25 1999/01/02 11:17:20 keil Exp $ +/* $Id: callc.c,v 2.31 1999/08/05 20:43:10 keil Exp $ * Author Karsten Keil (keil@isdn4linux.de) * based on the teles driver from Jan den Ouden @@ -11,6 +11,25 @@ * Fritz Elfert * * $Log: callc.c,v $ + * Revision 2.31 1999/08/05 20:43:10 keil + * ISAR analog modem support + * + * Revision 2.30 1999/07/25 16:24:04 keil + * Fixed TEI now working again + * + * Revision 2.29 1999/07/13 21:05:41 werner + * Modified set_channel_limit to use new callback ISDN_STAT_DISCH. + * + * Revision 2.28 1999/07/09 08:30:02 keil + * cosmetics + * + * Revision 2.27 1999/07/05 23:51:38 werner + * Allow limiting of available HiSax B-chans per card. Controlled by hisaxctrl + * hisaxctrl id 10 + * + * Revision 2.26 1999/07/01 08:11:21 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 2.25 1999/01/02 11:17:20 keil * Changes for 2.2 * @@ -107,15 +126,21 @@ * */ +#include #define __NO_VERSION__ #include "hisax.h" #include "../avmb1/capicmd.h" /* this should be moved in a common place */ #ifdef MODULE +#ifdef COMPAT_HAS_NEW_SYMTAB #define MOD_USE_COUNT ( GET_USE_COUNT (&__this_module)) -#endif /* MODULE */ +#else +extern long mod_use_count_; +#define MOD_USE_COUNT mod_use_count_ +#endif /* COMPAT_HAS_NEW_SYMTAB */ +#endif /* MODULE */ -const char *lli_revision = "$Revision: 2.25 $"; +const char *lli_revision = "$Revision: 2.31 $"; extern struct IsdnCard cards[]; extern int nrcards; @@ -146,28 +171,7 @@ /* Flags for remembering action done in lli */ -#define FLG_START_D 0 -#define FLG_ESTAB_D 1 -#define FLG_CALL_SEND 2 -#define FLG_CALL_REC 3 -#define FLG_CALL_ALERT 4 -#define FLG_START_B 5 -#define FLG_CONNECT_B 6 -#define FLG_LL_DCONN 7 -#define FLG_LL_BCONN 8 -#define FLG_DISC_SEND 9 -#define FLG_DISC_REC 10 -#define FLG_REL_REC 11 -#define FLG_DO_ALERT 12 -#define FLG_DO_HANGUP 13 -#define FLG_DO_CONNECT 14 -#define FLG_DO_ESTAB 15 -#define FLG_RESUME 16 - -/* - * Because of callback it's a good idea to delay the shutdown of the d-channel - */ -#define DREL_TIMER_VALUE 40000 +#define FLG_START_B 0 /* * Find card with given driverId @@ -192,7 +196,7 @@ int ret=0; while ((skb = skb_dequeue(q))) { - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); ret++; } return(ret); @@ -211,44 +215,40 @@ va_end(args); } - enum { - ST_NULL, /* 0 inactive */ - ST_OUT_WAIT_D, /* 1 outgoing, awaiting d-channel establishment */ - ST_IN_WAIT_D, /* 2 incoming, awaiting d-channel establishment */ - ST_OUT_DIAL, /* 3 outgoing, SETUP send; awaiting confirm */ - ST_IN_WAIT_LL, /* 4 incoming call received; wait for LL confirm */ - ST_IN_ALERT_SEND, /* 5 incoming call received; ALERT send */ - ST_IN_WAIT_CONN_ACK, /* 6 incoming CONNECT send; awaiting CONN_ACK */ - ST_WAIT_BCONN, /* 7 CONNECT/CONN_ACK received, awaiting b-channel prot. estbl. */ - ST_ACTIVE, /* 8 active, b channel prot. established */ - ST_WAIT_BRELEASE, /* 9 call clear. (initiator), awaiting b channel prot. rel. */ - ST_WAIT_BREL_DISC, /* 10 call clear. (receiver), DISCONNECT req. received */ - ST_WAIT_DCOMMAND, /* 11 call clear. (receiver), awaiting DCHANNEL message */ - ST_WAIT_DRELEASE, /* 12 DISCONNECT sent, awaiting RELEASE */ - ST_WAIT_D_REL_CNF, /* 13 RELEASE sent, awaiting RELEASE confirm */ - ST_WAIT_DSHUTDOWN, /* 14 awaiting d-channel shutdown */ + ST_NULL, /* 0 inactive */ + ST_OUT_DIAL, /* 1 outgoing, SETUP send; awaiting confirm */ + ST_IN_WAIT_LL, /* 2 incoming call received; wait for LL confirm */ + ST_IN_ALERT_SENT, /* 3 incoming call received; ALERT send */ + ST_IN_WAIT_CONN_ACK, /* 4 incoming CONNECT send; awaiting CONN_ACK */ + ST_WAIT_BCONN, /* 5 CONNECT/CONN_ACK received, awaiting b-channel prot. estbl. */ + ST_ACTIVE, /* 6 active, b channel prot. established */ + ST_WAIT_BRELEASE, /* 7 call clear. (initiator), awaiting b channel prot. rel. */ + ST_WAIT_BREL_DISC, /* 8 call clear. (receiver), DISCONNECT req. received */ + ST_WAIT_DCOMMAND, /* 9 call clear. (receiver), awaiting DCHANNEL message */ + ST_WAIT_DRELEASE, /* 10 DISCONNECT sent, awaiting RELEASE */ + ST_WAIT_D_REL_CNF, /* 11 RELEASE sent, awaiting RELEASE confirm */ + ST_IN_PROCEED_SEND, /* 12 incoming call, proceeding send */ }; + -#define STATE_COUNT (ST_WAIT_DSHUTDOWN +1) +#define STATE_COUNT (ST_IN_PROCEED_SEND + 1) -static char *strState[] = -{ - "ST_NULL", - "ST_OUT_WAIT_D", - "ST_IN_WAIT_D", - "ST_OUT_DIAL", - "ST_IN_WAIT_LL", - "ST_IN_ALERT_SEND", - "ST_IN_WAIT_CONN_ACK", - "ST_WAIT_BCONN", - "ST_ACTIVE", + static char *strState[] = + { + "ST_NULL", + "ST_OUT_DIAL", + "ST_IN_WAIT_LL", + "ST_IN_ALERT_SENT", + "ST_IN_WAIT_CONN_ACK", + "ST_WAIT_BCONN", + "ST_ACTIVE", "ST_WAIT_BRELEASE", "ST_WAIT_BREL_DISC", "ST_WAIT_DCOMMAND", "ST_WAIT_DRELEASE", "ST_WAIT_D_REL_CNF", - "ST_WAIT_DSHUTDOWN", + "ST_IN_PROCEED_SEND", }; enum { @@ -256,29 +256,28 @@ EV_SETUP_CNF, /* 1 */ EV_ACCEPTB, /* 2 */ EV_DISCONNECT_IND, /* 3 */ - EV_RELEASE_CNF, /* 4 */ - EV_DLEST, /* 5 */ - EV_DLRL, /* 6 */ + EV_RELEASE, /* 4 */ + EV_LEASED, /* 5 */ + EV_LEASED_REL, /* 6 */ EV_SETUP_IND, /* 7 */ - EV_RELEASE_IND, /* 8 */ - EV_ACCEPTD, /* 9 */ - EV_SETUP_CMPL_IND, /* 10 */ - EV_BC_EST, /* 11 */ - EV_WRITEBUF, /* 12 */ - EV_ESTABLISH, /* 13 */ - EV_HANGUP, /* 14 */ - EV_BC_REL, /* 15 */ - EV_CINF, /* 16 */ - EV_SUSPEND, /* 17 */ - EV_RESUME, /* 18 */ - EV_SHUTDOWN_D, /* 19 */ - EV_NOSETUP_RSP, /* 20 */ - EV_SETUP_ERR, /* 21 */ - EV_CONNECT_ERR, /* 22 */ - EV_RELEASE_ERR, /* 23 */ + EV_ACCEPTD, /* 8 */ + EV_SETUP_CMPL_IND, /* 9 */ + EV_BC_EST, /* 10 */ + EV_WRITEBUF, /* 11 */ + EV_HANGUP, /* 12 */ + EV_BC_REL, /* 13 */ + EV_CINF, /* 14 */ + EV_SUSPEND, /* 15 */ + EV_RESUME, /* 16 */ + EV_NOSETUP_RSP, /* 17 */ + EV_SETUP_ERR, /* 18 */ + EV_CONNECT_ERR, /* 19 */ + EV_PROCEED, /* 20 */ + EV_ALERT, /* 21 */ + EV_REDIR, /* 22 */ }; -#define EVENT_COUNT (EV_RELEASE_ERR +1) +#define EVENT_COUNT (EV_REDIR + 1) static char *strEvent[] = { @@ -286,150 +285,152 @@ "EV_SETUP_CNF", "EV_ACCEPTB", "EV_DISCONNECT_IND", - "EV_RELEASE_CNF", - "EV_DLEST", - "EV_DLRL", + "EV_RELEASE", + "EV_LEASED", + "EV_LEASED_REL", "EV_SETUP_IND", - "EV_RELEASE_IND", "EV_ACCEPTD", "EV_SETUP_CMPL_IND", "EV_BC_EST", "EV_WRITEBUF", - "EV_ESTABLISH", "EV_HANGUP", "EV_BC_REL", "EV_CINF", "EV_SUSPEND", "EV_RESUME", - "EV_SHUTDOWN_D", "EV_NOSETUP_RSP", "EV_SETUP_ERR", "EV_CONNECT_ERR", - "EV_RELEASE_ERR", + "EV_PROCEED", + "EV_ALERT", + "EV_REDIR", }; + static inline void -lli_deliver_cause(struct Channel *chanp, isdn_ctrl *ic) +HL_LL(struct Channel *chanp, int command) { - if (chanp->proc->para.cause < 0) + isdn_ctrl ic; + + ic.driver = chanp->cs->myid; + ic.command = command; + ic.arg = chanp->chan; + chanp->cs->iif.statcallb(&ic); +} + +static inline void +lli_deliver_cause(struct Channel *chanp) +{ + isdn_ctrl ic; + + if (chanp->proc->para.cause == NO_CAUSE) return; - ic->driver = chanp->cs->myid; - ic->command = ISDN_STAT_CAUSE; - ic->arg = chanp->chan; + ic.driver = chanp->cs->myid; + ic.command = ISDN_STAT_CAUSE; + ic.arg = chanp->chan; if (chanp->cs->protocol == ISDN_PTYPE_EURO) - sprintf(ic->parm.num, "E%02X%02X", chanp->proc->para.loc & 0x7f, + sprintf(ic.parm.num, "E%02X%02X", chanp->proc->para.loc & 0x7f, chanp->proc->para.cause & 0x7f); else - sprintf(ic->parm.num, "%02X%02X", chanp->proc->para.loc & 0x7f, + sprintf(ic.parm.num, "%02X%02X", chanp->proc->para.loc & 0x7f, chanp->proc->para.cause & 0x7f); - chanp->cs->iif.statcallb(ic); + chanp->cs->iif.statcallb(&ic); } -static void -lli_d_established(struct FsmInst *fi, int event, void *arg) +static inline void +lli_close(struct FsmInst *fi) { - struct Channel *chanp = fi->userdata; + struct Channel *chanp = fi->userdata; - test_and_set_bit(FLG_ESTAB_D, &chanp->Flags); - if (chanp->leased) { - isdn_ctrl ic; - int ret; - - chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan); - FsmChangeState(fi, ST_IN_WAIT_LL); - test_and_set_bit(FLG_CALL_REC, &chanp->Flags); - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_ICALL_LEASED"); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_ICALL; - ic.arg = chanp->chan; - ic.parm.setup.si1 = 7; - ic.parm.setup.si2 = 0; - ic.parm.setup.plan = 0; - ic.parm.setup.screen = 0; - sprintf(ic.parm.setup.eazmsn,"%d", chanp->chan + 1); - sprintf(ic.parm.setup.phone,"LEASED%d", chanp->cs->myid); - ret = chanp->cs->iif.statcallb(&ic); - if (chanp->debug & 1) - link_debug(chanp, 1, "statcallb ret=%d", ret); - if (!ret) { - chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); - FsmChangeState(fi, ST_NULL); - } - } else if (fi->state == ST_WAIT_DSHUTDOWN) - FsmChangeState(fi, ST_NULL); + FsmChangeState(fi, ST_NULL); + chanp->Flags = 0; + chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); +} + + static void +lli_leased_in(struct FsmInst *fi, int event, void *arg) +{ + struct Channel *chanp = fi->userdata; + + isdn_ctrl ic; + int ret; + + chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan); + FsmChangeState(fi, ST_IN_WAIT_LL); + if (chanp->debug & 1) + link_debug(chanp, 0, "STAT_ICALL_LEASED"); + ic.driver = chanp->cs->myid; + ic.command = ((chanp->chan < 2) ? ISDN_STAT_ICALL : ISDN_STAT_ICALLW); + ic.arg = chanp->chan; + ic.parm.setup.si1 = 7; + ic.parm.setup.si2 = 0; + ic.parm.setup.plan = 0; + ic.parm.setup.screen = 0; + sprintf(ic.parm.setup.eazmsn,"%d", chanp->chan + 1); + sprintf(ic.parm.setup.phone,"LEASED%d", chanp->cs->myid); + ret = chanp->cs->iif.statcallb(&ic); + if (chanp->debug & 1) + link_debug(chanp, 1, "statcallb ret=%d", ret); + + if (!ret) { + chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); + FsmChangeState(fi, ST_NULL); + } } -static void -lli_d_released(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - test_and_clear_bit(FLG_START_D, &chanp->Flags); -} /* * Dial out */ static void +lli_init_bchan_out(struct FsmInst *fi, int event, void *arg) +{ + struct Channel *chanp = fi->userdata; + + FsmChangeState(fi, ST_WAIT_BCONN); + if (chanp->debug & 1) + link_debug(chanp, 0, "STAT_DCONN"); + HL_LL(chanp, ISDN_STAT_DCONN); + init_b_st(chanp, 0); + chanp->b_st->lli.l4l3(chanp->b_st, DL_ESTABLISH | REQUEST, NULL); +} + +static void lli_prep_dialout(struct FsmInst *fi, int event, void *arg) { struct Channel *chanp = fi->userdata; - FsmChangeState(fi, ST_OUT_WAIT_D); FsmDelTimer(&chanp->drel_timer, 60); FsmDelTimer(&chanp->dial_timer, 73); chanp->l2_active_protocol = chanp->l2_protocol; chanp->incoming = 0; - if (test_bit(FLG_ESTAB_D, &chanp->Flags)) { - FsmEvent(fi, EV_DLEST, NULL); - } else { - chanp->Flags = 0; - if (EV_RESUME == event) - test_and_set_bit(FLG_RESUME, &chanp->Flags); - test_and_set_bit(FLG_START_D, &chanp->Flags); - chanp->d_st->lli.l4l3(chanp->d_st, DL_ESTABLISH | REQUEST, NULL); - } -} -static void -lli_do_dialout(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - int ev; - - FsmChangeState(fi, ST_OUT_DIAL); - chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan); - if (test_and_clear_bit(FLG_RESUME, &chanp->Flags)) - ev = CC_RESUME | REQUEST; - else - ev = CC_SETUP | REQUEST; - if (chanp->leased) { - FsmEvent(&chanp->fi, EV_SETUP_CNF, NULL); - } else { - test_and_set_bit(FLG_ESTAB_D, &chanp->Flags); - chanp->d_st->lli.l4l3(chanp->d_st, ev, chanp); - test_and_set_bit(FLG_CALL_SEND, &chanp->Flags); - } + chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan); + if (chanp->leased) { + lli_init_bchan_out(fi, event, arg); + } else { + FsmChangeState(fi, ST_OUT_DIAL); + chanp->d_st->lli.l4l3(chanp->d_st, CC_SETUP | REQUEST, chanp); + } } static void -lli_init_bchan_out(struct FsmInst *fi, int event, void *arg) +lli_resume(struct FsmInst *fi, int event, void *arg) { struct Channel *chanp = fi->userdata; - isdn_ctrl ic; - FsmChangeState(fi, ST_WAIT_BCONN); - test_and_set_bit(FLG_LL_DCONN, &chanp->Flags); - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_DCONN"); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_DCONN; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - init_b_st(chanp, 0); - test_and_set_bit(FLG_START_B, &chanp->Flags); - chanp->b_st->lli.l4l3(chanp->b_st, DL_ESTABLISH | REQUEST, NULL); + FsmDelTimer(&chanp->drel_timer, 60); + FsmDelTimer(&chanp->dial_timer, 73); + chanp->l2_active_protocol = chanp->l2_protocol; + chanp->incoming = 0; + + chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan); + if (chanp->leased) { + lli_init_bchan_out(fi, event, arg); + } else { + FsmChangeState(fi, ST_OUT_DIAL); + chanp->d_st->lli.l4l3(chanp->d_st, CC_RESUME | REQUEST, chanp); + } } static void @@ -438,12 +439,15 @@ struct Channel *chanp = fi->userdata; isdn_ctrl ic; + FsmChangeState(fi, ST_ACTIVE); chanp->data_open = !0; - test_and_set_bit(FLG_CONNECT_B, &chanp->Flags); + if (chanp->bcs->conmsg) + strcpy(ic.parm.num, chanp->bcs->conmsg); + else + ic.parm.num[0] = 0; if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_BCONN"); - test_and_set_bit(FLG_LL_BCONN, &chanp->Flags); + link_debug(chanp, 0, "STAT_BCONN %s", ic.parm.num); ic.driver = chanp->cs->myid; ic.command = ISDN_STAT_BCONN; ic.arg = chanp->chan; @@ -451,6 +455,7 @@ chanp->cs->cardmsg(chanp->cs, MDL_INFO_CONN, (void *) (long)chanp->chan); } + /* * RESUME */ @@ -458,27 +463,6 @@ /* incomming call */ static void -lli_start_dchan(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - - FsmChangeState(fi, ST_IN_WAIT_D); - FsmDelTimer(&chanp->drel_timer, 61); - if (event == EV_ACCEPTD) - test_and_set_bit(FLG_DO_CONNECT, &chanp->Flags); - else if (event == EV_HANGUP) { - test_and_set_bit(FLG_DO_HANGUP, &chanp->Flags); -#ifdef ALERT_REJECT - test_and_set_bit(FLG_DO_ALERT, &chanp->Flags); -#endif - } - if (test_bit(FLG_ESTAB_D, &chanp->Flags)) { - FsmEvent(fi, EV_DLEST, NULL); - } else if (!test_and_set_bit(FLG_START_D, &chanp->Flags)) - chanp->d_st->lli.l4l3(chanp->d_st, DL_ESTABLISH | REQUEST, NULL); -} - -static void lli_deliver_call(struct FsmInst *fi, int event, void *arg) { struct Channel *chanp = fi->userdata; @@ -493,11 +477,11 @@ */ if (1) { /* for only one TEI */ FsmChangeState(fi, ST_IN_WAIT_LL); - test_and_set_bit(FLG_CALL_REC, &chanp->Flags); if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_ICALL"); + link_debug(chanp, 0, (chanp->chan < 2) ? "STAT_ICALL" : "STAT_ICALLW"); ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_ICALL; + ic.command = ((chanp->chan < 2) ? ISDN_STAT_ICALL : ISDN_STAT_ICALLW); + ic.arg = chanp->chan; /* * No need to return "unknown" for calls without OAD, @@ -507,118 +491,95 @@ ret = chanp->cs->iif.statcallb(&ic); if (chanp->debug & 1) link_debug(chanp, 1, "statcallb ret=%d", ret); + switch (ret) { - case 1: /* OK, anybody likes this call */ + case 1: /* OK, someone likes this call */ FsmDelTimer(&chanp->drel_timer, 61); - if (test_bit(FLG_ESTAB_D, &chanp->Flags)) { - FsmChangeState(fi, ST_IN_ALERT_SEND); - test_and_set_bit(FLG_CALL_ALERT, &chanp->Flags); - chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc); - } else { - test_and_set_bit(FLG_DO_ALERT, &chanp->Flags); - FsmChangeState(fi, ST_IN_WAIT_D); - test_and_set_bit(FLG_START_D, &chanp->Flags); - chanp->d_st->lli.l4l3(chanp->d_st, - DL_ESTABLISH | REQUEST, NULL); - } + FsmChangeState(fi, ST_IN_ALERT_SENT); + chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc); + break; + case 4: /* direct redirect */ + case 3: /* Proceeding desired */ + FsmDelTimer(&chanp->drel_timer, 61); + FsmChangeState(fi, ST_IN_PROCEED_SEND); + chanp->d_st->lli.l4l3(chanp->d_st, CC_PROCEED_SEND | REQUEST, chanp->proc); + if (ret == 4) + { chanp->setup = ic.parm.setup; + chanp->d_st->lli.l4l3(chanp->d_st, CC_REDIR | REQUEST, chanp->proc); + } break; case 2: /* Rejecting Call */ - test_and_clear_bit(FLG_CALL_REC, &chanp->Flags); break; case 0: /* OK, nobody likes this call */ default: /* statcallb problems */ chanp->d_st->lli.l4l3(chanp->d_st, CC_IGNORE | REQUEST, chanp->proc); chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); FsmChangeState(fi, ST_NULL); - if (test_bit(FLG_ESTAB_D, &chanp->Flags) && - !test_bit(FLG_PTP, &chanp->d_st->l2.flag)) - FsmRestartTimer(&chanp->drel_timer, DREL_TIMER_VALUE, EV_SHUTDOWN_D, NULL, 61); break; } } else { chanp->d_st->lli.l4l3(chanp->d_st, CC_IGNORE | REQUEST, chanp->proc); chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); - FsmChangeState(fi, ST_NULL); - if (test_bit(FLG_ESTAB_D, &chanp->Flags) && - !test_bit(FLG_PTP, &chanp->d_st->l2.flag)) - FsmRestartTimer(&chanp->drel_timer, DREL_TIMER_VALUE, EV_SHUTDOWN_D, NULL, 62); } } static void -lli_establish_d(struct FsmInst *fi, int event, void *arg) +lli_send_dconnect(struct FsmInst *fi, int event, void *arg) { - /* This establish the D-channel for pending L3 messages - * without blocking the channel - */ struct Channel *chanp = fi->userdata; - test_and_set_bit(FLG_DO_ESTAB, &chanp->Flags); - FsmChangeState(fi, ST_IN_WAIT_D); - test_and_set_bit(FLG_START_D, &chanp->Flags); - chanp->d_st->lli.l4l3(chanp->d_st, DL_ESTABLISH | REQUEST, NULL); + FsmChangeState(fi, ST_IN_WAIT_CONN_ACK); + chanp->d_st->lli.l4l3(chanp->d_st, CC_SETUP | RESPONSE, chanp->proc); } static void -lli_do_action(struct FsmInst *fi, int event, void *arg) +lli_send_alert(struct FsmInst *fi, int event, void *arg) { struct Channel *chanp = fi->userdata; - test_and_set_bit(FLG_ESTAB_D, &chanp->Flags); - if (chanp->leased) { - FsmChangeState(fi, ST_IN_WAIT_CONN_ACK); - test_and_clear_bit(FLG_DO_ALERT, &chanp->Flags); - test_and_clear_bit(FLG_DO_CONNECT, &chanp->Flags); - FsmEvent(&chanp->fi, EV_SETUP_CMPL_IND, NULL); - } else if (test_and_clear_bit(FLG_DO_CONNECT, &chanp->Flags) && - !test_bit(FLG_DO_HANGUP, &chanp->Flags)) { - FsmChangeState(fi, ST_IN_WAIT_CONN_ACK); - test_and_clear_bit(FLG_DO_ALERT, &chanp->Flags); - chanp->d_st->lli.l4l3(chanp->d_st, CC_SETUP | RESPONSE, chanp->proc); - } else if (test_and_clear_bit(FLG_DO_ALERT, &chanp->Flags)) { - if (test_bit(FLG_DO_HANGUP, &chanp->Flags)) - FsmRestartTimer(&chanp->drel_timer, 40, EV_HANGUP, NULL, 63); - FsmChangeState(fi, ST_IN_ALERT_SEND); - test_and_set_bit(FLG_CALL_ALERT, &chanp->Flags); - chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc); - } else if (test_and_clear_bit(FLG_DO_HANGUP, &chanp->Flags)) { - FsmChangeState(fi, ST_WAIT_DRELEASE); - chanp->proc->para.cause = 0x15; /* Call Rejected */ - chanp->d_st->lli.l4l3(chanp->d_st, CC_REJECT | REQUEST, chanp->proc); - test_and_set_bit(FLG_DISC_SEND, &chanp->Flags); - } + FsmChangeState(fi, ST_IN_ALERT_SENT); + chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc); } static void -lli_send_dconnect(struct FsmInst *fi, int event, void *arg) +lli_send_redir(struct FsmInst *fi, int event, void *arg) { struct Channel *chanp = fi->userdata; - FsmChangeState(fi, ST_IN_WAIT_CONN_ACK); - chanp->d_st->lli.l4l3(chanp->d_st, CC_SETUP | RESPONSE, chanp->proc); + chanp->d_st->lli.l4l3(chanp->d_st, CC_REDIR | REQUEST, chanp->proc); } static void lli_init_bchan_in(struct FsmInst *fi, int event, void *arg) { struct Channel *chanp = fi->userdata; - isdn_ctrl ic; FsmChangeState(fi, ST_WAIT_BCONN); - test_and_set_bit(FLG_LL_DCONN, &chanp->Flags); if (chanp->debug & 1) link_debug(chanp, 0, "STAT_DCONN"); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_DCONN; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); + HL_LL(chanp, ISDN_STAT_DCONN); chanp->l2_active_protocol = chanp->l2_protocol; chanp->incoming = !0; init_b_st(chanp, !0); - test_and_set_bit(FLG_START_B, &chanp->Flags); chanp->b_st->lli.l4l3(chanp->b_st, DL_ESTABLISH | REQUEST, NULL); } +static void +lli_setup_rsp(struct FsmInst *fi, int event, void *arg) +{ + struct Channel *chanp = fi->userdata; + + if (chanp->leased) { + lli_init_bchan_in(fi, event, arg); + } else { + FsmChangeState(fi, ST_IN_WAIT_CONN_ACK); +#ifdef WANT_ALERT + chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc); +#endif + chanp->d_st->lli.l4l3(chanp->d_st, CC_SETUP | RESPONSE, chanp->proc); + } +} + /* Call suspend */ static void @@ -632,82 +593,52 @@ /* Call clearing */ static void -lli_cancel_call(struct FsmInst *fi, int event, void *arg) +lli_disconnect_req(struct FsmInst *fi, int event, void *arg) { struct Channel *chanp = fi->userdata; - isdn_ctrl ic; FsmChangeState(fi, ST_WAIT_DRELEASE); - if (test_and_clear_bit(FLG_LL_BCONN, &chanp->Flags)) { - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_BHUP"); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_BHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - } - if (test_and_clear_bit(FLG_START_B, &chanp->Flags)) - release_b_st(chanp); - chanp->proc->para.cause = 0x10; /* Normal Call Clearing */ + chanp->proc->para.cause = 0x10; /* Normal Call Clearing */ chanp->d_st->lli.l4l3(chanp->d_st, CC_DISCONNECT | REQUEST, chanp->proc); - test_and_set_bit(FLG_DISC_SEND, &chanp->Flags); } static void -lli_shutdown_d(struct FsmInst *fi, int event, void *arg) +lli_disconnect_reject(struct FsmInst *fi, int event, void *arg) { - struct Channel *chanp = fi->userdata; + struct Channel *chanp = fi->userdata; - FsmDelTimer(&chanp->drel_timer, 62); - if (test_bit(FLG_PTP, &chanp->d_st->l2.flag)) { - FsmChangeState(fi, ST_NULL); - } else { - if (!test_bit(FLG_TWO_DCHAN, &chanp->cs->HW_Flags)) { - if (chanp->chan) { - if (chanp->cs->channel[0].fi.state != ST_NULL) - return; - } else { - if (chanp->cs->channel[1].fi.state != ST_NULL) - return; - } - } - FsmChangeState(fi, ST_WAIT_DSHUTDOWN); - test_and_clear_bit(FLG_ESTAB_D, &chanp->Flags); - chanp->d_st->lli.l4l3(chanp->d_st, DL_RELEASE | REQUEST, NULL); - } + FsmChangeState(fi, ST_WAIT_DRELEASE); + chanp->proc->para.cause = 0x15; /* Call Rejected */ + chanp->d_st->lli.l4l3(chanp->d_st, CC_DISCONNECT | REQUEST, chanp->proc); } static void -lli_timeout_d(struct FsmInst *fi, int event, void *arg) +lli_dhup_close(struct FsmInst *fi, int event, void *arg) { - struct Channel *chanp = fi->userdata; - isdn_ctrl ic; + struct Channel *chanp = fi->userdata; - test_and_clear_bit(FLG_LL_DCONN, &chanp->Flags); - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_DHUP"); - lli_deliver_cause(chanp, &ic); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_DHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - FsmChangeState(fi, ST_NULL); - chanp->Flags = 0; - test_and_set_bit(FLG_ESTAB_D, &chanp->Flags); - if (!test_bit(FLG_PTP, &chanp->d_st->l2.flag)) - FsmAddTimer(&chanp->drel_timer, DREL_TIMER_VALUE, EV_SHUTDOWN_D, NULL, 60); - chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); + if (chanp->debug & 1) + link_debug(chanp, 0, "STAT_DHUP"); + lli_deliver_cause(chanp); + HL_LL(chanp, ISDN_STAT_DHUP); + + lli_close(fi); } static void -lli_go_null(struct FsmInst *fi, int event, void *arg) +lli_reject_req(struct FsmInst *fi, int event, void *arg) { - struct Channel *chanp = fi->userdata; + struct Channel *chanp = fi->userdata; - FsmChangeState(fi, ST_NULL); - chanp->Flags = 0; - FsmDelTimer(&chanp->drel_timer, 63); - chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); +#ifndef ALERT_REJECT + chanp->proc->para.cause = 0x15; /* Call Rejected */ + chanp->d_st->lli.l4l3(chanp->d_st, CC_REJECT | REQUEST, chanp->proc); + lli_dhup_close(fi, event, arg); +#else + FsmRestartTimer(&chanp->drel_timer, 40, EV_HANGUP, NULL, 63); + FsmChangeState(fi, ST_IN_ALERT_SENT); + chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc); +#endif } static void @@ -717,30 +648,15 @@ chanp->data_open = 0; FsmChangeState(fi, ST_WAIT_BRELEASE); - test_and_clear_bit(FLG_CONNECT_B, &chanp->Flags); chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL); } static void -lli_send_d_disc(struct FsmInst *fi, int event, void *arg) +lli_start_disc(struct FsmInst *fi, int event, void *arg) { struct Channel *chanp = fi->userdata; isdn_ctrl ic; - if (test_bit(FLG_DISC_REC, &chanp->Flags) || - test_bit(FLG_REL_REC, &chanp->Flags)) - return; - FsmChangeState(fi, ST_WAIT_DRELEASE); - if (test_and_clear_bit(FLG_LL_BCONN, &chanp->Flags)) { - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_BHUP"); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_BHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - } - if (test_and_clear_bit(FLG_START_B, &chanp->Flags)) - release_b_st(chanp); if (chanp->leased) { ic.command = ISDN_STAT_CAUSE; ic.arg = chanp->chan; @@ -748,43 +664,46 @@ chanp->cs->iif.statcallb(&ic); if (chanp->debug & 1) link_debug(chanp, 0, "STAT_DHUP"); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_DHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - FsmChangeState(fi, ST_WAIT_DSHUTDOWN); - test_and_clear_bit(FLG_ESTAB_D, &chanp->Flags); - chanp->d_st->lli.l4l3(chanp->d_st, DL_RELEASE | REQUEST, NULL); + HL_LL(chanp, ISDN_STAT_DHUP); + lli_close(fi); } else { - if (test_and_clear_bit(FLG_DO_HANGUP, &chanp->Flags)) - chanp->proc->para.cause = 0x15; /* Call Reject */ - else - chanp->proc->para.cause = 0x10; /* Normal Call Clearing */ - chanp->d_st->lli.l4l3(chanp->d_st, CC_DISCONNECT | REQUEST, chanp->proc); - test_and_set_bit(FLG_DISC_SEND, &chanp->Flags); + lli_disconnect_req(fi, event, arg); } } static void -lli_released_bchan(struct FsmInst *fi, int event, void *arg) +lli_rel_b_disc(struct FsmInst *fi, int event, void *arg) { - struct Channel *chanp = fi->userdata; - isdn_ctrl ic; + struct Channel *chanp = fi->userdata; + + release_b_st(chanp); + lli_start_disc(fi, event, arg); +} - FsmChangeState(fi, ST_WAIT_DCOMMAND); - chanp->data_open = 0; - if (test_and_clear_bit(FLG_LL_BCONN, &chanp->Flags)) { - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_BHUP"); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_BHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - } - release_b_st(chanp); - test_and_clear_bit(FLG_START_B, &chanp->Flags); +static void +lli_bhup_disc(struct FsmInst *fi, int event, void *arg) +{ + struct Channel *chanp = fi->userdata; + + if (chanp->debug & 1) + link_debug(chanp, 0, "STAT_BHUP"); + HL_LL(chanp, ISDN_STAT_BHUP); + + lli_rel_b_disc(fi, event, arg); } +static void +lli_bhup_rel_b(struct FsmInst *fi, int event, void *arg) +{ + struct Channel *chanp = fi->userdata; + + FsmChangeState(fi, ST_WAIT_DCOMMAND); + chanp->data_open = 0; + if (chanp->debug & 1) + link_debug(chanp, 0, "STAT_BHUP"); + HL_LL(chanp, ISDN_STAT_BHUP); + release_b_st(chanp); +} static void lli_release_bchan(struct FsmInst *fi, int event, void *arg) @@ -792,387 +711,235 @@ struct Channel *chanp = fi->userdata; chanp->data_open = 0; - test_and_set_bit(FLG_DISC_REC, &chanp->Flags); FsmChangeState(fi, ST_WAIT_BREL_DISC); - test_and_clear_bit(FLG_CONNECT_B, &chanp->Flags); chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL); } + static void -lli_received_d_rel(struct FsmInst *fi, int event, void *arg) +lli_rel_b_dhup(struct FsmInst *fi, int event, void *arg) { - struct Channel *chanp = fi->userdata; - isdn_ctrl ic; + struct Channel *chanp = fi->userdata; - chanp->data_open = 0; - FsmChangeState(fi, ST_NULL); - test_and_set_bit(FLG_REL_REC, &chanp->Flags); - if (test_and_clear_bit(FLG_CONNECT_B, &chanp->Flags)) { - chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL); - } - if (test_and_clear_bit(FLG_LL_BCONN, &chanp->Flags)) { - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_BHUP"); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_BHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - } - if (test_and_clear_bit(FLG_START_B, &chanp->Flags)) - release_b_st(chanp); - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_DHUP"); - lli_deliver_cause(chanp, &ic); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_DHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - test_and_clear_bit(FLG_DISC_SEND, &chanp->Flags); - test_and_clear_bit(FLG_CALL_REC, &chanp->Flags); - test_and_clear_bit(FLG_CALL_ALERT, &chanp->Flags); - test_and_clear_bit(FLG_LL_DCONN, &chanp->Flags); - test_and_clear_bit(FLG_CALL_SEND, &chanp->Flags); - lli_timeout_d(fi, event, arg); + release_b_st(chanp); + lli_dhup_close(fi, event, arg); } static void -lli_received_d_relcnf(struct FsmInst *fi, int event, void *arg) +lli_bhup_dhup(struct FsmInst *fi, int event, void *arg) { - struct Channel *chanp = fi->userdata; - isdn_ctrl ic; + struct Channel *chanp = fi->userdata; - chanp->data_open = 0; - FsmChangeState(fi, ST_NULL); - if (test_and_clear_bit(FLG_CONNECT_B, &chanp->Flags)) { - chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL); - } - if (test_and_clear_bit(FLG_LL_BCONN, &chanp->Flags)) { - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_BHUP"); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_BHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - } - if (test_and_clear_bit(FLG_START_B, &chanp->Flags)) - release_b_st(chanp); - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_DHUP"); - lli_deliver_cause(chanp, &ic); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_DHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - test_and_clear_bit(FLG_DISC_SEND, &chanp->Flags); - test_and_clear_bit(FLG_CALL_REC, &chanp->Flags); - test_and_clear_bit(FLG_CALL_ALERT, &chanp->Flags); - test_and_clear_bit(FLG_LL_DCONN, &chanp->Flags); - test_and_clear_bit(FLG_CALL_SEND, &chanp->Flags); - lli_timeout_d(fi, event, arg); + if (chanp->debug & 1) + link_debug(chanp, 0, "STAT_BHUP"); + HL_LL(chanp, ISDN_STAT_BHUP); + + lli_rel_b_dhup(fi, event, arg); } static void -lli_received_d_disc(struct FsmInst *fi, int event, void *arg) +lli_abort(struct FsmInst *fi, int event, void *arg) { - struct Channel *chanp = fi->userdata; - isdn_ctrl ic; + struct Channel *chanp = fi->userdata; - chanp->data_open = 0; - FsmChangeState(fi, ST_WAIT_D_REL_CNF); - test_and_set_bit(FLG_DISC_REC, &chanp->Flags); - if (test_and_clear_bit(FLG_LL_BCONN, &chanp->Flags)) { - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_BHUP"); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_BHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - } - if (test_and_clear_bit(FLG_START_B, &chanp->Flags)) - release_b_st(chanp); - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_DHUP"); - lli_deliver_cause(chanp, &ic); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_DHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - test_and_clear_bit(FLG_CALL_ALERT, &chanp->Flags); - test_and_clear_bit(FLG_LL_DCONN, &chanp->Flags); - test_and_clear_bit(FLG_CALL_SEND, &chanp->Flags); - chanp->d_st->lli.l4l3(chanp->d_st, CC_RELEASE | REQUEST, chanp->proc); + chanp->data_open = 0; + chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL); + + lli_bhup_dhup(fi, event, arg); } - -/* processing charge info */ + static void -lli_charge_info(struct FsmInst *fi, int event, void *arg) +lli_release_req(struct FsmInst *fi, int event, void *arg) { - struct Channel *chanp = fi->userdata; - isdn_ctrl ic; - - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_CINF; - ic.arg = chanp->chan; - sprintf(ic.parm.num, "%d", chanp->proc->para.chargeinfo); - chanp->cs->iif.statcallb(&ic); + struct Channel *chanp = fi->userdata; + + FsmChangeState(fi, ST_WAIT_D_REL_CNF); + chanp->d_st->lli.l4l3(chanp->d_st, CC_RELEASE | REQUEST, chanp->proc); } -/* error procedures */ - static void -lli_no_dchan(struct FsmInst *fi, int event, void *arg) +lli_rel_b_release_req(struct FsmInst *fi, int event, void *arg) { - struct Channel *chanp = fi->userdata; - isdn_ctrl ic; - - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_NODCH"); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_NODCH; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - chanp->Flags = 0; - FsmChangeState(fi, ST_NULL); - chanp->d_st->lli.l4l3(chanp->d_st, DL_RELEASE | REQUEST, NULL); + struct Channel *chanp = fi->userdata; + + release_b_st(chanp); + lli_release_req(fi, event, arg); } static void -lli_no_dchan_ready(struct FsmInst *fi, int event, void *arg) +lli_bhup_release_req(struct FsmInst *fi, int event, void *arg) { - struct Channel *chanp = fi->userdata; - isdn_ctrl ic; - - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_DHUP"); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_DHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); + struct Channel *chanp = fi->userdata; + + if (chanp->debug & 1) + link_debug(chanp, 0, "STAT_BHUP"); + HL_LL(chanp, ISDN_STAT_BHUP); + + lli_rel_b_release_req(fi, event, arg); } + +/* processing charge info */ static void -lli_no_dchan_in(struct FsmInst *fi, int event, void *arg) +lli_charge_info(struct FsmInst *fi, int event, void *arg) { struct Channel *chanp = fi->userdata; isdn_ctrl ic; - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_DHUP"); ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_DHUP; + ic.command = ISDN_STAT_CINF; ic.arg = chanp->chan; + sprintf(ic.parm.num, "%d", chanp->proc->para.chargeinfo); chanp->cs->iif.statcallb(&ic); - chanp->d_st->lli.l4l3(chanp->d_st, CC_DLRL | REQUEST, chanp->proc); - chanp->Flags = 0; - FsmChangeState(fi, ST_NULL); - chanp->d_st->lli.l4l3(chanp->d_st, DL_RELEASE | REQUEST, NULL); } +/* error procedures */ + static void -lli_no_setup_rsp(struct FsmInst *fi, int event, void *arg) +lli_dchan_not_ready(struct FsmInst *fi, int event, void *arg) { struct Channel *chanp = fi->userdata; - isdn_ctrl ic; - FsmChangeState(fi, ST_NULL); - test_and_clear_bit(FLG_CALL_SEND, &chanp->Flags); if (chanp->debug & 1) link_debug(chanp, 0, "STAT_DHUP"); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_DHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - lli_shutdown_d(fi, event, arg); + HL_LL(chanp, ISDN_STAT_DHUP); } static void -lli_setup_err(struct FsmInst *fi, int event, void *arg) +lli_no_setup_rsp(struct FsmInst *fi, int event, void *arg) { struct Channel *chanp = fi->userdata; - isdn_ctrl ic; - FsmChangeState(fi, ST_WAIT_DRELEASE); - test_and_clear_bit(FLG_LL_DCONN, &chanp->Flags); if (chanp->debug & 1) link_debug(chanp, 0, "STAT_DHUP"); - lli_deliver_cause(chanp, &ic); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_DHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - test_and_set_bit(FLG_DISC_SEND, &chanp->Flags); /* DISCONN was sent from L3 */ + HL_LL(chanp, ISDN_STAT_DHUP); + lli_close(fi); } static void -lli_connect_err(struct FsmInst *fi, int event, void *arg) +lli_error(struct FsmInst *fi, int event, void *arg) { - struct Channel *chanp = fi->userdata; - isdn_ctrl ic; - - FsmChangeState(fi, ST_WAIT_DRELEASE); - test_and_clear_bit(FLG_LL_DCONN, &chanp->Flags); - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_DHUP"); - lli_deliver_cause(chanp, &ic); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_DHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - test_and_set_bit(FLG_DISC_SEND, &chanp->Flags); /* DISCONN was sent from L3 */ + FsmChangeState(fi, ST_WAIT_DRELEASE); } static void -lli_got_dlrl(struct FsmInst *fi, int event, void *arg) -{ - struct Channel *chanp = fi->userdata; - isdn_ctrl ic; - - chanp->data_open = 0; - FsmChangeState(fi, ST_NULL); - if (test_and_clear_bit(FLG_CONNECT_B, &chanp->Flags)) { - chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL); - } - if (test_and_clear_bit(FLG_LL_BCONN, &chanp->Flags)) { - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_BHUP"); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_BHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - } - if (test_and_clear_bit(FLG_START_B, &chanp->Flags)) - release_b_st(chanp); - if (chanp->leased) { - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_CAUSE; - ic.arg = chanp->chan; - sprintf(ic.parm.num, "L%02X%02X", 0, 0x2f); - chanp->cs->iif.statcallb(&ic); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_DHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - chanp->Flags = 0; - } else { - test_and_clear_bit(FLG_LL_DCONN, &chanp->Flags); - if (chanp->debug & 1) - link_debug(chanp, 0, "STAT_DHUP"); - if (chanp->cs->protocol == ISDN_PTYPE_EURO) { - chanp->proc->para.cause = 0x2f; - chanp->proc->para.loc = 0; - } else { - chanp->proc->para.cause = 0x70; - chanp->proc->para.loc = 0; - } - lli_deliver_cause(chanp, &ic); - ic.driver = chanp->cs->myid; - ic.command = ISDN_STAT_DHUP; - ic.arg = chanp->chan; - chanp->cs->iif.statcallb(&ic); - chanp->d_st->lli.l4l3(chanp->d_st, CC_DLRL | REQUEST, chanp->proc); - chanp->Flags = 0; - chanp->d_st->lli.l4l3(chanp->d_st, DL_RELEASE | REQUEST, NULL); - } - chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); -} - -/* *INDENT-OFF* */ -static struct FsmNode fnlist[] HISAX_INITDATA = -{ - {ST_NULL, EV_DIAL, lli_prep_dialout}, - {ST_NULL, EV_RESUME, lli_prep_dialout}, - {ST_NULL, EV_SETUP_IND, lli_deliver_call}, - {ST_NULL, EV_SHUTDOWN_D, lli_shutdown_d}, - {ST_NULL, EV_DLRL, lli_go_null}, - {ST_NULL, EV_DLEST, lli_d_established}, - {ST_NULL, EV_ESTABLISH, lli_establish_d}, - {ST_OUT_WAIT_D, EV_DLEST, lli_do_dialout}, - {ST_OUT_WAIT_D, EV_DLRL, lli_no_dchan}, - {ST_OUT_WAIT_D, EV_HANGUP, lli_no_dchan}, - {ST_IN_WAIT_D, EV_DLEST, lli_do_action}, - {ST_IN_WAIT_D, EV_DLRL, lli_no_dchan_in}, - {ST_IN_WAIT_D, EV_ACCEPTD, lli_start_dchan}, - {ST_IN_WAIT_D, EV_HANGUP, lli_start_dchan}, - {ST_OUT_DIAL, EV_SETUP_CNF, lli_init_bchan_out}, - {ST_OUT_DIAL, EV_HANGUP, lli_cancel_call}, - {ST_OUT_DIAL, EV_DISCONNECT_IND, lli_received_d_disc}, - {ST_OUT_DIAL, EV_RELEASE_IND, lli_received_d_rel}, - {ST_OUT_DIAL, EV_RELEASE_CNF, lli_received_d_relcnf}, - {ST_OUT_DIAL, EV_NOSETUP_RSP, lli_no_setup_rsp}, - {ST_OUT_DIAL, EV_SETUP_ERR, lli_setup_err}, - {ST_OUT_DIAL, EV_DLRL, lli_got_dlrl}, - {ST_IN_WAIT_LL, EV_DLEST, lli_d_established}, - {ST_IN_WAIT_LL, EV_DLRL, lli_d_released}, - {ST_IN_WAIT_LL, EV_ACCEPTD, lli_start_dchan}, - {ST_IN_WAIT_LL, EV_HANGUP, lli_start_dchan}, - {ST_IN_WAIT_LL, EV_DISCONNECT_IND, lli_received_d_disc}, - {ST_IN_WAIT_LL, EV_RELEASE_IND, lli_received_d_rel}, - {ST_IN_WAIT_LL, EV_RELEASE_CNF, lli_received_d_relcnf}, - {ST_IN_ALERT_SEND, EV_SETUP_CMPL_IND, lli_init_bchan_in}, - {ST_IN_ALERT_SEND, EV_ACCEPTD, lli_send_dconnect}, - {ST_IN_ALERT_SEND, EV_HANGUP, lli_send_d_disc}, - {ST_IN_ALERT_SEND, EV_DISCONNECT_IND, lli_received_d_disc}, - {ST_IN_ALERT_SEND, EV_RELEASE_IND, lli_received_d_rel}, - {ST_IN_ALERT_SEND, EV_RELEASE_CNF, lli_received_d_relcnf}, - {ST_IN_ALERT_SEND, EV_DLRL, lli_got_dlrl}, - {ST_IN_WAIT_CONN_ACK, EV_SETUP_CMPL_IND, lli_init_bchan_in}, - {ST_IN_WAIT_CONN_ACK, EV_HANGUP, lli_send_d_disc}, - {ST_IN_WAIT_CONN_ACK, EV_DISCONNECT_IND, lli_received_d_disc}, - {ST_IN_WAIT_CONN_ACK, EV_RELEASE_IND, lli_received_d_rel}, - {ST_IN_WAIT_CONN_ACK, EV_RELEASE_CNF, lli_received_d_relcnf}, - {ST_IN_WAIT_CONN_ACK, EV_CONNECT_ERR, lli_connect_err}, - {ST_IN_WAIT_CONN_ACK, EV_DLRL, lli_got_dlrl}, - {ST_WAIT_BCONN, EV_BC_EST, lli_go_active}, - {ST_WAIT_BCONN, EV_BC_REL, lli_send_d_disc}, - {ST_WAIT_BCONN, EV_HANGUP, lli_send_d_disc}, - {ST_WAIT_BCONN, EV_DISCONNECT_IND, lli_received_d_disc}, - {ST_WAIT_BCONN, EV_RELEASE_IND, lli_received_d_rel}, - {ST_WAIT_BCONN, EV_RELEASE_CNF, lli_received_d_relcnf}, - {ST_WAIT_BCONN, EV_DLRL, lli_got_dlrl}, - {ST_WAIT_BCONN, EV_CINF, lli_charge_info}, - {ST_ACTIVE, EV_CINF, lli_charge_info}, - {ST_ACTIVE, EV_BC_REL, lli_released_bchan}, - {ST_ACTIVE, EV_SUSPEND, lli_suspend}, - {ST_ACTIVE, EV_HANGUP, lli_disconn_bchan}, - {ST_ACTIVE, EV_DISCONNECT_IND, lli_release_bchan}, - {ST_ACTIVE, EV_RELEASE_CNF, lli_received_d_relcnf}, - {ST_ACTIVE, EV_RELEASE_IND, lli_received_d_rel}, - {ST_ACTIVE, EV_DLRL, lli_got_dlrl}, - {ST_WAIT_BRELEASE, EV_BC_REL, lli_send_d_disc}, - {ST_WAIT_BRELEASE, EV_DISCONNECT_IND, lli_received_d_disc}, - {ST_WAIT_BRELEASE, EV_RELEASE_CNF, lli_received_d_relcnf}, - {ST_WAIT_BRELEASE, EV_RELEASE_IND, lli_received_d_rel}, - {ST_WAIT_BRELEASE, EV_DLRL, lli_got_dlrl}, - {ST_WAIT_BREL_DISC, EV_BC_REL, lli_received_d_disc}, - {ST_WAIT_BREL_DISC, EV_RELEASE_CNF, lli_received_d_relcnf}, - {ST_WAIT_BREL_DISC, EV_RELEASE_IND, lli_received_d_rel}, - {ST_WAIT_BREL_DISC, EV_DLRL, lli_got_dlrl}, - {ST_WAIT_DCOMMAND, EV_HANGUP, lli_send_d_disc}, - {ST_WAIT_DCOMMAND, EV_DISCONNECT_IND, lli_received_d_disc}, - {ST_WAIT_DCOMMAND, EV_RELEASE_CNF, lli_received_d_relcnf}, - {ST_WAIT_DCOMMAND, EV_RELEASE_IND, lli_received_d_rel}, - {ST_WAIT_DCOMMAND, EV_DLRL, lli_got_dlrl}, - {ST_WAIT_DRELEASE, EV_RELEASE_IND, lli_timeout_d}, - {ST_WAIT_DRELEASE, EV_RELEASE_CNF, lli_timeout_d}, - {ST_WAIT_DRELEASE, EV_RELEASE_ERR, lli_timeout_d}, - {ST_WAIT_DRELEASE, EV_DIAL, lli_no_dchan_ready}, - {ST_WAIT_DRELEASE, EV_DLRL, lli_got_dlrl}, - {ST_WAIT_D_REL_CNF, EV_RELEASE_CNF, lli_timeout_d}, - {ST_WAIT_D_REL_CNF, EV_RELEASE_ERR, lli_timeout_d}, -/* ETS 300-104 16.1 */ - {ST_WAIT_D_REL_CNF, EV_RELEASE_IND, lli_timeout_d}, - {ST_WAIT_D_REL_CNF, EV_DIAL, lli_no_dchan_ready}, - {ST_WAIT_D_REL_CNF, EV_DLRL, lli_got_dlrl}, - {ST_WAIT_DSHUTDOWN, EV_DLRL, lli_go_null}, - {ST_WAIT_DSHUTDOWN, EV_DLEST, lli_d_established}, - {ST_WAIT_DSHUTDOWN, EV_DIAL, lli_prep_dialout}, - {ST_WAIT_DSHUTDOWN, EV_RESUME, lli_prep_dialout}, - {ST_WAIT_DSHUTDOWN, EV_SETUP_IND, lli_deliver_call}, +lli_failure_l(struct FsmInst *fi, int event, void *arg) +{ + struct Channel *chanp = fi->userdata; + isdn_ctrl ic; + + FsmChangeState(fi, ST_NULL); + ic.driver = chanp->cs->myid; + ic.command = ISDN_STAT_CAUSE; + ic.arg = chanp->chan; + sprintf(ic.parm.num, "L%02X%02X", 0, 0x2f); + chanp->cs->iif.statcallb(&ic); + HL_LL(chanp, ISDN_STAT_DHUP); + chanp->Flags = 0; + chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan); +} + +static void +lli_rel_b_fail(struct FsmInst *fi, int event, void *arg) +{ + struct Channel *chanp = fi->userdata; + + release_b_st(chanp); + lli_failure_l(fi, event, arg); +} + +static void +lli_bhup_fail(struct FsmInst *fi, int event, void *arg) +{ + struct Channel *chanp = fi->userdata; + + if (chanp->debug & 1) + link_debug(chanp, 0, "STAT_BHUP"); + HL_LL(chanp, ISDN_STAT_BHUP); + + lli_rel_b_fail(fi, event, arg); +} + +static void +lli_failure_a(struct FsmInst *fi, int event, void *arg) +{ + struct Channel *chanp = fi->userdata; + + chanp->data_open = 0; + chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL); + + lli_bhup_fail(fi, event, arg); +} + + /* *INDENT-OFF* */ + static struct FsmNode fnlist[] HISAX_INITDATA = + { + {ST_NULL, EV_DIAL, lli_prep_dialout}, + {ST_NULL, EV_RESUME, lli_resume}, + {ST_NULL, EV_SETUP_IND, lli_deliver_call}, + {ST_NULL, EV_LEASED, lli_leased_in}, + {ST_OUT_DIAL, EV_SETUP_CNF, lli_init_bchan_out}, + {ST_OUT_DIAL, EV_HANGUP, lli_disconnect_req}, + {ST_OUT_DIAL, EV_DISCONNECT_IND, lli_release_req}, + {ST_OUT_DIAL, EV_RELEASE, lli_dhup_close}, + {ST_OUT_DIAL, EV_NOSETUP_RSP, lli_no_setup_rsp}, + {ST_OUT_DIAL, EV_SETUP_ERR, lli_error}, + {ST_IN_WAIT_LL, EV_LEASED_REL, lli_failure_l}, + {ST_IN_WAIT_LL, EV_ACCEPTD, lli_setup_rsp}, + {ST_IN_WAIT_LL, EV_HANGUP, lli_reject_req}, + {ST_IN_WAIT_LL, EV_DISCONNECT_IND, lli_release_req}, + {ST_IN_WAIT_LL, EV_RELEASE, lli_dhup_close}, + {ST_IN_ALERT_SENT, EV_SETUP_CMPL_IND, lli_init_bchan_in}, + {ST_IN_ALERT_SENT, EV_ACCEPTD, lli_send_dconnect}, + {ST_IN_ALERT_SENT, EV_HANGUP, lli_disconnect_reject}, + {ST_IN_ALERT_SENT, EV_DISCONNECT_IND, lli_release_req}, + {ST_IN_ALERT_SENT, EV_RELEASE, lli_dhup_close}, + {ST_IN_ALERT_SENT, EV_REDIR, lli_send_redir}, + {ST_IN_PROCEED_SEND, EV_REDIR, lli_send_redir}, + {ST_IN_PROCEED_SEND, EV_ALERT, lli_send_alert}, + {ST_IN_PROCEED_SEND, EV_ACCEPTD, lli_send_dconnect}, + {ST_IN_PROCEED_SEND, EV_HANGUP, lli_disconnect_reject}, + {ST_IN_PROCEED_SEND, EV_DISCONNECT_IND, lli_dhup_close}, + {ST_IN_ALERT_SENT, EV_RELEASE, lli_dhup_close}, + {ST_IN_WAIT_CONN_ACK, EV_SETUP_CMPL_IND, lli_init_bchan_in}, + {ST_IN_WAIT_CONN_ACK, EV_HANGUP, lli_disconnect_req}, + {ST_IN_WAIT_CONN_ACK, EV_DISCONNECT_IND, lli_release_req}, + {ST_IN_WAIT_CONN_ACK, EV_RELEASE, lli_dhup_close}, + {ST_IN_WAIT_CONN_ACK, EV_CONNECT_ERR, lli_error}, + {ST_WAIT_BCONN, EV_BC_EST, lli_go_active}, + {ST_WAIT_BCONN, EV_BC_REL, lli_rel_b_disc}, + {ST_WAIT_BCONN, EV_HANGUP, lli_rel_b_disc}, + {ST_WAIT_BCONN, EV_DISCONNECT_IND, lli_rel_b_release_req}, + {ST_WAIT_BCONN, EV_RELEASE, lli_rel_b_dhup}, + {ST_WAIT_BCONN, EV_LEASED_REL, lli_rel_b_fail}, + {ST_WAIT_BCONN, EV_CINF, lli_charge_info}, + {ST_ACTIVE, EV_CINF, lli_charge_info}, + {ST_ACTIVE, EV_BC_REL, lli_bhup_rel_b}, + {ST_ACTIVE, EV_SUSPEND, lli_suspend}, + {ST_ACTIVE, EV_HANGUP, lli_disconn_bchan}, + {ST_ACTIVE, EV_DISCONNECT_IND, lli_release_bchan}, + {ST_ACTIVE, EV_RELEASE, lli_abort}, + {ST_ACTIVE, EV_LEASED_REL, lli_failure_a}, + {ST_WAIT_BRELEASE, EV_BC_REL, lli_bhup_disc}, + {ST_WAIT_BRELEASE, EV_DISCONNECT_IND, lli_bhup_release_req}, + {ST_WAIT_BRELEASE, EV_RELEASE, lli_bhup_dhup}, + {ST_WAIT_BRELEASE, EV_LEASED_REL, lli_bhup_fail}, + {ST_WAIT_BREL_DISC, EV_BC_REL, lli_bhup_release_req}, + {ST_WAIT_BREL_DISC, EV_RELEASE, lli_bhup_dhup}, + {ST_WAIT_DCOMMAND, EV_HANGUP, lli_start_disc}, + {ST_WAIT_DCOMMAND, EV_DISCONNECT_IND, lli_release_req}, + {ST_WAIT_DCOMMAND, EV_RELEASE, lli_dhup_close}, + {ST_WAIT_DCOMMAND, EV_LEASED_REL, lli_failure_l}, + {ST_WAIT_DRELEASE, EV_RELEASE, lli_dhup_close}, + {ST_WAIT_DRELEASE, EV_DIAL, lli_dchan_not_ready}, + /* ETS 300-104 16.1 */ + {ST_WAIT_D_REL_CNF, EV_RELEASE, lli_dhup_close}, + {ST_WAIT_D_REL_CNF, EV_DIAL, lli_dchan_not_ready}, }; -/* *INDENT-ON* */ + /* *INDENT-ON* */ -#define FNCOUNT (sizeof(fnlist)/sizeof(struct FsmNode)) + #define FNCOUNT (sizeof(fnlist)/sizeof(struct FsmNode)) HISAX_INITFUNC(void CallcNew(void)) @@ -1195,21 +962,23 @@ { struct PStack *st = chanp->b_st; - chanp->bcs->BC_Close(chanp->bcs); - switch (chanp->l2_active_protocol) { - case (ISDN_PROTO_L2_X75I): - releasestack_isdnl2(st); - break; - case (ISDN_PROTO_L2_HDLC): - case (ISDN_PROTO_L2_TRANS): -// case (ISDN_PROTO_L2_MODEM): - releasestack_transl2(st); - break; - } + if(test_and_clear_bit(FLG_START_B, &chanp->Flags)) { + chanp->bcs->BC_Close(chanp->bcs); + switch (chanp->l2_active_protocol) { + case (ISDN_PROTO_L2_X75I): + releasestack_isdnl2(st); + break; + case (ISDN_PROTO_L2_HDLC): + case (ISDN_PROTO_L2_TRANS): + case (ISDN_PROTO_L2_MODEM): + releasestack_transl2(st); + break; + } + } } struct Channel -*selectfreechannel(struct PStack *st) +*selectfreechannel(struct PStack *st, int bch) { struct IsdnCardState *cs = st->l1.hardware; struct Channel *chanp = st->lli.userdata; @@ -1219,74 +988,60 @@ i=1; else i=0; - while (i<2) { + + if (!bch) + { i = 2; /* virtual channel */ + chanp += 2; + } + + while (i < ((bch) ? cs->chanlimit : (2 + MAX_WAITING_CALLS))) { if (chanp->fi.state == ST_NULL) return (chanp); chanp++; i++; } - return (NULL); -} - -int -is_activ(struct PStack *st) -{ - struct IsdnCardState *cs = st->l1.hardware; - struct Channel *chanp = st->lli.userdata; - int i; - if (test_bit(FLG_TWO_DCHAN, &cs->HW_Flags)) - i=1; - else - i=0; - while (i<2) { - if (test_bit(FLG_ESTAB_D, &chanp->Flags)) - return (1); + if (bch) /* number of channels is limited */ + { i = 2; /* virtual channel */ + chanp = st->lli.userdata; + chanp += i; + while (i < (2 + MAX_WAITING_CALLS)) { + if (chanp->fi.state == ST_NULL) + return (chanp); chanp++; i++; - } - return (0); + } + } + return (NULL); } +static void stat_redir_result(struct IsdnCardState *cs, int chan, ulong result) +{ isdn_ctrl ic; + + ic.driver = cs->myid; + ic.command = ISDN_STAT_REDIR; + ic.arg = chan; + (ulong)(ic.parm.num[0]) = result; + cs->iif.statcallb(&ic); +} /* stat_redir_result */ + static void dchan_l3l4(struct PStack *st, int pr, void *arg) { struct l3_process *pc = arg; - struct IsdnCardState *cs = st->l1.hardware; + struct IsdnCardState *cs = st->l1.hardware; struct Channel *chanp; - int event; - switch (pr) { - case (DL_ESTABLISH | INDICATION): - event = EV_DLEST; - break; - case (DL_RELEASE | INDICATION): - event = EV_DLRL; - break; - default: - event = -1; - break; - } - if (event >= 0) { - int i; - - chanp = st->lli.userdata; - if (test_bit(FLG_TWO_DCHAN, &cs->HW_Flags)) - i = 1; - else - i = 0; - while (i < 2) { - FsmEvent(&chanp->fi, event, NULL); - chanp++; - i++; - } - return; - } else if (pr == (CC_SETUP | INDICATION)) { - if (!(chanp = selectfreechannel(pc->st))) { - pc->st->lli.l4l3(pc->st, CC_DLRL | REQUEST, pc); - } else { - chanp->proc = pc; - pc->chan = chanp; + if(!pc) + return; + + if (pr == (CC_SETUP | INDICATION)) { + if (!(chanp = selectfreechannel(pc->st, pc->para.bchannel))) { + pc->para.cause = 0x11; /* User busy */ + pc->st->lli.l4l3(pc->st, CC_REJECT | REQUEST, pc); + } else { + chanp->proc = pc; + pc->chan = chanp; FsmEvent(&chanp->fi, EV_SETUP_IND, NULL); } return; @@ -1299,19 +1054,19 @@ FsmEvent(&chanp->fi, EV_DISCONNECT_IND, NULL); break; case (CC_RELEASE | CONFIRM): - FsmEvent(&chanp->fi, EV_RELEASE_CNF, NULL); + FsmEvent(&chanp->fi, EV_RELEASE, NULL); break; case (CC_SUSPEND | CONFIRM): - FsmEvent(&chanp->fi, EV_RELEASE_CNF, NULL); + FsmEvent(&chanp->fi, EV_RELEASE, NULL); break; case (CC_RESUME | CONFIRM): FsmEvent(&chanp->fi, EV_SETUP_CNF, NULL); break; case (CC_RESUME_ERR): - FsmEvent(&chanp->fi, EV_RELEASE_CNF, NULL); + FsmEvent(&chanp->fi, EV_RELEASE, NULL); break; case (CC_RELEASE | INDICATION): - FsmEvent(&chanp->fi, EV_RELEASE_IND, NULL); + FsmEvent(&chanp->fi, EV_RELEASE, NULL); break; case (CC_SETUP_COMPL | INDICATION): FsmEvent(&chanp->fi, EV_SETUP_CMPL_IND, NULL); @@ -1332,15 +1087,21 @@ FsmEvent(&chanp->fi, EV_CONNECT_ERR, NULL); break; case (CC_RELEASE_ERR): - FsmEvent(&chanp->fi, EV_RELEASE_ERR, NULL); + FsmEvent(&chanp->fi, EV_RELEASE, NULL); break; + case (CC_PROCEED_SEND | INDICATION): case (CC_PROCEEDING | INDICATION): case (CC_ALERTING | INDICATION): + case (CC_PROGRESS | INDICATION): + case (CC_NOTIFY | INDICATION): break; + case (CC_REDIR | INDICATION): + stat_redir_result(cs, chanp->chan, pc->redir_result); + break; default: if (chanp->debug & 0x800) { HiSax_putstatus(chanp->cs, "Ch", - "%d L3->L4 unknown primitiv %x", + "%d L3->L4 unknown primitiv %#x", chanp->chan, pr); } } @@ -1406,6 +1167,7 @@ (*stp)->l2.l2l1 = dummy_pstack; (*stp)->l2.l2l3 = dummy_pstack; (*stp)->l3.l3l2 = dummy_pstack; + (*stp)->l3.l3ml3 = dummy_pstack; (*stp)->l3.l3l4 = dummy_pstack; (*stp)->lli.l4l3 = dummy_pstack; (*stp)->ma.layer = dummy_pstack; @@ -1446,14 +1208,19 @@ int CallcNewChan(struct IsdnCardState *csta) -{ +{ int i; + chancount += 2; init_chan(0, csta); init_chan(1, csta); printk(KERN_INFO "HiSax: 2 channels added\n"); + + for (i = 0; i < MAX_WAITING_CALLS; i++) + init_chan(i+2,csta); + printk(KERN_INFO "HiSax: MAX_WAITING_CALLS added\n"); + if (test_bit(FLG_PTP, &csta->channel->d_st->l2.flag)) { printk(KERN_INFO "LAYER2 WATCHING ESTABLISH\n"); - test_and_set_bit(FLG_START_D, &csta->channel->Flags); csta->channel->d_st->lli.l4l3(csta->channel->d_st, DL_ESTABLISH | REQUEST, NULL); } @@ -1482,14 +1249,13 @@ for (i = 0; i < 2; i++) { FsmDelTimer(&csta->channel[i].drel_timer, 74); FsmDelTimer(&csta->channel[i].dial_timer, 75); - if (i || test_bit(FLG_TWO_DCHAN, &csta->HW_Flags)) - release_d_st(csta->channel + i); - if (csta->channel[i].b_st) { - if (test_and_clear_bit(FLG_START_B, &csta->channel[i].Flags)) - release_b_st(csta->channel + i); - kfree(csta->channel[i].b_st); - csta->channel[i].b_st = NULL; - } else + if (i || test_bit(FLG_TWO_DCHAN, &csta->HW_Flags)) + release_d_st(csta->channel + i); + if (csta->channel[i].b_st) { + release_b_st(csta->channel + i); + kfree(csta->channel[i].b_st); + csta->channel[i].b_st = NULL; + } else printk(KERN_WARNING "CallcFreeChan b_st ch%d allready freed\n", i); if (i || test_bit(FLG_TWO_DCHAN, &csta->HW_Flags)) { release_d_st(csta->channel + i); @@ -1509,7 +1275,7 @@ if (chanp->data_open) chanp->cs->iif.rcvcallb_skb(chanp->cs->myid, chanp->chan, skb); else { - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); } break; case (DL_ESTABLISH | INDICATION): @@ -1521,7 +1287,7 @@ FsmEvent(&chanp->fi, EV_BC_REL, NULL); break; default: - printk(KERN_WARNING "lldata_handler unknown primitive %x\n", + printk(KERN_WARNING "lldata_handler unknown primitive %#x\n", pr); break; } @@ -1539,7 +1305,7 @@ chanp->cs->iif.rcvcallb_skb(chanp->cs->myid, chanp->chan, skb); else { link_debug(chanp, 0, "channel not open"); - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); } break; case (PH_ACTIVATE | INDICATION): @@ -1551,7 +1317,7 @@ FsmEvent(&chanp->fi, EV_BC_REL, NULL); break; default: - printk(KERN_WARNING "lltrans_handler unknown primitive %x\n", + printk(KERN_WARNING "lltrans_handler unknown primitive %#x\n", pr); break; } @@ -1566,7 +1332,7 @@ ic.driver = chanp->cs->myid; ic.command = ISDN_STAT_BSENT; ic.arg = chanp->chan; -// ic.parm.length = len; + ic.parm.length = len; chanp->cs->iif.statcallb(&ic); } @@ -1590,12 +1356,11 @@ case (ISDN_PROTO_L2_TRANS): st->l1.mode = L1_MODE_TRANS; break; -#if 0 case (ISDN_PROTO_L2_MODEM): - st->l1.mode = L1_MODE_MODEM; + st->l1.mode = L1_MODE_V32; break; -#endif } + chanp->bcs->conmsg = NULL; if (chanp->bcs->BC_SetStack(st, chanp->bcs)) return (-1); st->l2.flag = 0; @@ -1622,7 +1387,7 @@ break; case (ISDN_PROTO_L2_HDLC): case (ISDN_PROTO_L2_TRANS): -// case (ISDN_PROTO_L2_MODEM): + case (ISDN_PROTO_L2_MODEM): st->l1.l1l2 = lltrans_handler; st->lli.userdata = chanp; st->lli.l1writewakeup = ll_writewakeup; @@ -1630,6 +1395,8 @@ setstack_l3bc(st, chanp); break; } + test_and_set_bit(FLG_START_B, &chanp->Flags); + return (0); } @@ -1642,7 +1409,7 @@ switch (pr) { case (DL_DATA | REQUEST): link_debug(chanp, 0, "leased line d-channel DATA"); - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); break; case (DL_ESTABLISH | REQUEST): st->l2.l2l1(st, PH_ACTIVATE | REQUEST, NULL); @@ -1650,7 +1417,7 @@ case (DL_RELEASE | REQUEST): break; default: - printk(KERN_WARNING "transd_l4l3 unknown primitive %x\n", + printk(KERN_WARNING "transd_l4l3 unknown primitive %#x\n", pr); break; } @@ -1661,16 +1428,16 @@ { struct Channel *chanp = (struct Channel *) st->lli.userdata; struct sk_buff *skb = arg; - int i,event = EV_DLRL; + int i,event = EV_LEASED_REL; switch (pr) { case (PH_DATA | INDICATION): link_debug(chanp, 0, "leased line d-channel DATA"); - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); break; case (PH_ACTIVATE | INDICATION): case (PH_ACTIVATE | CONFIRM): - event = EV_DLEST; + event = EV_LEASED; case (PH_DEACTIVATE | INDICATION): case (PH_DEACTIVATE | CONFIRM): if (test_bit(FLG_TWO_DCHAN, &chanp->cs->HW_Flags)) @@ -1685,7 +1452,7 @@ break; default: printk(KERN_WARNING - "transd_l1l2 unknown primitive %x\n", pr); + "transd_l1l2 unknown primitive %#x\n", pr); break; } } @@ -1701,7 +1468,7 @@ int i; struct Channel *chanp = csta->channel; - for (i = 0; i < 2; i++) { + for (i = 0; i < (2 + MAX_WAITING_CALLS) ; i++) { chanp[i].debug = debugflags; chanp[i].fi.debug = debugflags & 2; chanp[i].d_st->l2.l2m.debug = debugflags & 8; @@ -1774,10 +1541,40 @@ } } + +/***************************************************************/ +/* Limit the available number of channels for the current card */ +/***************************************************************/ +static int +set_channel_limit(struct IsdnCardState *cs, int chanmax) +{ isdn_ctrl ic; + int i, ii; + + if ((chanmax < 0) || (chanmax > 2)) + return(-EINVAL); + cs->chanlimit = 0; + for (ii = 0; ii < 2; ii++) { + ic.driver = cs->myid; + ic.command = ISDN_STAT_DISCH; + ic.arg = ii; + if (ii >= chanmax) + ic.parm.num[0] = 0; /* disabled */ + else + ic.parm.num[0] = 1; /* enabled */ + i = cs->iif.statcallb(&ic); + if (i) return(-EINVAL); + if (ii < chanmax) + cs->chanlimit++; + } + return(0); +} /* set_channel_limit */ + + int HiSax_command(isdn_ctrl * ic) { struct IsdnCardState *csta = hisax_findcard(ic->driver); + struct PStack *st; struct Channel *chanp; int i; u_int num; @@ -1868,7 +1665,7 @@ HiSax_mod_inc_use_count(); #ifdef MODULE if (csta->channel[0].debug & 0x400) - HiSax_putstatus(csta, " LOCK ", "modcnt %x", + HiSax_putstatus(csta, " LOCK ", "modcnt %lx", MOD_USE_COUNT); #endif /* MODULE */ break; @@ -1876,7 +1673,7 @@ HiSax_mod_dec_use_count(); #ifdef MODULE if (csta->channel[0].debug & 0x400) - HiSax_putstatus(csta, " UNLOCK ", "modcnt %x", + HiSax_putstatus(csta, " UNLOCK ", "modcnt %lx", MOD_USE_COUNT); #endif /* MODULE */ break; @@ -1949,8 +1746,6 @@ HiSax_putstatus(csta, "set card ", "in PTP mode"); printk(KERN_DEBUG "HiSax: set card in PTP mode\n"); printk(KERN_INFO "LAYER2 WATCHING ESTABLISH\n"); - test_and_set_bit(FLG_START_D, &csta->channel[0].Flags); - test_and_set_bit(FLG_START_D, &csta->channel[1].Flags); csta->channel[0].d_st->lli.l4l3(csta->channel[0].d_st, DL_ESTABLISH | REQUEST, NULL); } else { @@ -1969,6 +1764,8 @@ HiSax_putstatus(csta, "set card ", "in FIXED TEI (%d) mode", num); printk(KERN_DEBUG "HiSax: set card in FIXED TEI (%d) mode\n", num); + chanp->d_st->lli.l4l3(chanp->d_st, + DL_ESTABLISH | REQUEST, NULL); break; case (9): /* load firmware */ memcpy(&adr, ic->parm.num, sizeof(ulong)); @@ -1977,8 +1774,7 @@ break; #ifdef MODULE case (55): - while ( MOD_USE_COUNT > 0) - MOD_DEC_USE_COUNT; + MOD_USE_COUNT = 0; HiSax_mod_inc_use_count(); break; #endif /* MODULE */ @@ -2001,12 +1797,58 @@ printk(KERN_DEBUG "HiSax: l3 debugging flags card %d set to %x\n", csta->cardnr + 1, *(unsigned int *) ic->parm.num); break; + case (10): + i = *(unsigned int *) ic->parm.num; + if ((i < 0) || (i > 2)) + return(-EINVAL); /* invalid number */ + return(set_channel_limit(csta, i)); + break; + case (12): + i = *(unsigned int *) ic->parm.num; +#ifdef CONFIG_HISAX_HFC_PCI + if (csta->typ != ISDN_CTYPE_HFC_PCI) + return(-EINVAL); + return(hfcpci_set_echo(csta,i)); +#else + return(-EINVAL); +#endif + break; default: printk(KERN_DEBUG "HiSax: invalid ioclt %d\n", (int) ic->arg); return (-EINVAL); } break; + + case (ISDN_CMD_PROCEED): + chanp = csta->channel + ic->arg; + if (chanp->debug & 1) + link_debug(chanp, 1, "PROCEED"); + FsmEvent(&chanp->fi, EV_PROCEED, NULL); + break; + + case (ISDN_CMD_ALERT): + chanp = csta->channel + ic->arg; + if (chanp->debug & 1) + link_debug(chanp, 1, "ALERT"); + FsmEvent(&chanp->fi, EV_ALERT, NULL); + break; + + case (ISDN_CMD_REDIR): + chanp = csta->channel + ic->arg; + if (chanp->debug & 1) + link_debug(chanp, 1, "REDIR"); + chanp->setup = ic->parm.setup; + FsmEvent(&chanp->fi, EV_REDIR, NULL); + break; + + /* protocol specific io commands */ + case (ISDN_CMD_PROT_IO): + for (st = csta->stlist; st; st = st->next) + if (st->protocol == (ic->arg & 0xFF)) + return(st->lli.l4l3_proto(st, ic)); + return(-EINVAL); + break; default: break; } @@ -2049,7 +1891,8 @@ if (chanp->debug & 0x800) link_debug(chanp, 1, "writebuf: no buffers for %d bytes", len); return 0; - } + } else if (chanp->debug & 0x800) + link_debug(chanp, 1, "writebuf %d/%d/%d", len, chanp->bcs->tx_cnt,MAX_DATA_MEM); save_flags(flags); cli(); nskb = skb_clone(skb, GFP_ATOMIC); @@ -2062,7 +1905,7 @@ chanp->bcs->tx_cnt += len; st->l2.l2l1(st, PH_DATA | REQUEST, nskb); } - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_WRITE); } else len = 0; restore_flags(flags); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/cert.c linux/drivers/isdn/hisax/cert.c --- v2.3.13/linux/drivers/isdn/hisax/cert.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/cert.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: cert.c,v 2.1 1998/11/15 23:51:15 keil Exp $ +/* $Id: cert.c,v 2.2 1999/08/07 17:35:05 keil Exp $ * Author Karsten Keil (keil@isdn4linux.de) * @@ -7,6 +7,9 @@ * ../../../Documentation/isdn/HiSax.cert * * $Log: cert.c,v $ + * Revision 2.2 1999/08/07 17:35:05 keil + * approval for Eicon Technology Diva 2.01 PCI + * * Revision 2.1 1998/11/15 23:51:15 keil * certification stuff * @@ -29,6 +32,7 @@ printk(KERN_INFO "HiSax: Approval registration numbers:\n"); printk(KERN_INFO "HiSax: German D133361J CETECOM ICT Services GmbH\n"); printk(KERN_INFO "HiSax: EU (D133362J) CETECOM ICT Services GmbH\n"); + printk(KERN_INFO "HiSax: Approved with Eicon Technology Diva 2.01 PCI cards\n"); } return(0); #endif diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/config.c linux/drivers/isdn/hisax/config.c --- v2.3.13/linux/drivers/isdn/hisax/config.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/isdn/hisax/config.c Thu Aug 12 09:42:33 1999 @@ -1,10 +1,33 @@ -/* $Id: config.c,v 2.23 1999/02/17 10:53:02 cpetig Exp $ +/* $Id: config.c,v 2.30 1999/08/05 20:43:14 keil Exp $ * Author Karsten Keil (keil@isdn4linux.de) * based on the teles driver from Jan den Ouden * * * $Log: config.c,v $ + * Revision 2.30 1999/08/05 20:43:14 keil + * ISAR analog modem support + * + * Revision 2.29 1999/07/21 14:46:00 keil + * changes from EICON certification + * + * Revision 2.28 1999/07/14 12:38:36 werner + * Added changes for echo channel handling + * + * Revision 2.27 1999/07/12 21:05:00 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 2.26 1999/07/08 21:27:17 keil + * version 3.2 + * + * Revision 2.25 1999/07/05 23:51:44 werner + * Allow limiting of available HiSax B-chans per card. Controlled by hisaxctrl + * hisaxctrl id 10 + * + * Revision 2.24 1999/07/01 08:11:26 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 2.23 1999/02/17 10:53:02 cpetig * Added Hisax_closecard to exported symbols. * As indicated by Oliver Schoett . @@ -139,7 +162,13 @@ * 26 AVM A1 PCMCIA (Fritz) p0=irq p1=iobase * 27 AVM PnP/PCI p0=irq p1=iobase (PCI no parameter) * 28 Sedlbauer Speed Fax+ p0=irq p1=iobase (from isapnp setup) - * + * 29 Siemens I-Surf p0=irq p1=iobase p2=memory (from isapnp setup) + * 30 ACER P10 p0=irq p1=iobase (from isapnp setup) + * 31 HST Saphir p0=irq p1=iobase + * 32 Telekom A4T none + * 33 Scitel Quadro p0=subcontroller (4*S0, subctrl 1...4) + * 34 Gazel ISDN cards + * 35 HFC 2BDS0 PCI none * protocol can be either ISDN_PTYPE_EURO or ISDN_PTYPE_1TR6 or ISDN_PTYPE_NI1 * * @@ -152,15 +181,27 @@ "Sedlbauer Speed Card", "USR Sportster", "ith mic Linux", "Elsa PCI", "Compaq ISA", "NETjet", "Teles PCI", "Sedlbauer Speed Star (PCMCIA)", "AMD 7930", "NICCY", "S0Box", "AVM A1 (PCMCIA)", "AVM Fritz PnP/PCI", - "Sedlbauer Speed Fax +" + "Sedlbauer Speed Fax +", "Siemens I-Surf", "Acer P10", "HST Saphir", + "Telekom A4T", "Scitel Quadro", "Gazel", "HFC 2BDS0 PCI", }; +void HiSax_closecard(int cardnr); + #ifdef CONFIG_HISAX_ELSA #define DEFAULT_CARD ISDN_CTYPE_ELSA #define DEFAULT_CFG {0,0,0,0} int elsa_init_pcmcia(void*, int, int*, int); +#ifdef COMPAT_HAS_NEW_SYMTAB EXPORT_SYMBOL(elsa_init_pcmcia); -#endif +#else +static struct symbol_table hisax_syms_elsa = { +#include + X(elsa_init_pcmcia), +#include +}; +#endif /* COMPAT_HAS_NEW_SYMTAB */ +#endif /* CONFIG_HISAX_ELSA */ + #ifdef CONFIG_HISAX_AVM_A1 #undef DEFAULT_CARD #undef DEFAULT_CFG @@ -174,8 +215,17 @@ #define DEFAULT_CARD ISDN_CTYPE_A1_PCMCIA #define DEFAULT_CFG {11,0x170,0,0} int avm_a1_init_pcmcia(void*, int, int*, int); +#ifdef COMPAT_HAS_NEW_SYMTAB EXPORT_SYMBOL(avm_a1_init_pcmcia); -#endif +#else +static struct symbol_table hisax_syms_avm_a1= { +#include + X(avm_a1_init_pcmcia), + X(HiSax_closecard), +#include +}; +#endif /* COMPAT_HAS_NEW_SYMTAB */ +#endif /* CONFIG_HISAX_AVM_A1_PCMCIA */ #ifdef CONFIG_HISAX_FRITZPCI #undef DEFAULT_CARD @@ -190,12 +240,14 @@ #define DEFAULT_CARD ISDN_CTYPE_16_3 #define DEFAULT_CFG {15,0x180,0,0} #endif + #ifdef CONFIG_HISAX_S0BOX #undef DEFAULT_CARD #undef DEFAULT_CFG #define DEFAULT_CARD ISDN_CTYPE_S0BOX #define DEFAULT_CFG {7,0x378,0,0} #endif + #ifdef CONFIG_HISAX_16_0 #undef DEFAULT_CARD #undef DEFAULT_CFG @@ -244,8 +296,16 @@ #define DEFAULT_CARD ISDN_CTYPE_SEDLBAUER #define DEFAULT_CFG {11,0x270,0,0} int sedl_init_pcmcia(void*, int, int*, int); +#ifdef COMPAT_HAS_NEW_SYMTAB EXPORT_SYMBOL(sedl_init_pcmcia); -#endif +#else +static struct symbol_table hisax_syms_sedl= { +#include + X(sedl_init_pcmcia), +#include +}; +#endif /* COMPAT_HAS_NEW_SYMTAB */ +#endif /* CONFIG_HISAX_SEDLBAUER */ #ifdef CONFIG_HISAX_SPORTSTER #undef DEFAULT_CARD @@ -268,13 +328,21 @@ #define DEFAULT_CFG {0,0,0,0} #endif -#ifdef CONFIG_HISAX_TELES3C +#ifdef CONFIG_HISAX_HFCS #undef DEFAULT_CARD #undef DEFAULT_CFG #define DEFAULT_CARD ISDN_CTYPE_TELES3C #define DEFAULT_CFG {5,0x500,0,0} #endif +#ifdef CONFIG_HISAX_HFC_PCI +#undef DEFAULT_CARD +#undef DEFAULT_CFG +#define DEFAULT_CARD ISDN_CTYPE_HFC_PCI +#define DEFAULT_CFG {0,0,0,0} +#endif + + #ifdef CONFIG_HISAX_AMD7930 #undef DEFAULT_CARD #undef DEFAULT_CFG @@ -289,6 +357,41 @@ #define DEFAULT_CFG {0,0x0,0,0} #endif +#ifdef CONFIG_HISAX_ISURF +#undef DEFAULT_CARD +#undef DEFAULT_CFG +#define DEFAULT_CARD ISDN_CTYPE_ISURF +#define DEFAULT_CFG {5,0x100,0xc8000,0} +#endif + +#ifdef CONFIG_HISAX_HSTSAPHIR +#undef DEFAULT_CARD +#undef DEFAULT_CFG +#define DEFAULT_CARD ISDN_CTYPE_HSTSAPHIR +#define DEFAULT_CFG {5,0x250,0,0} +#endif + +#ifdef CONFIG_HISAX_BKM_A4T +#undef DEFAULT_CARD +#undef DEFAULT_CFG +#define DEFAULT_CARD ISDN_CTYPE_BKM_A4T +#define DEFAULT_CFG {0,0x0,0,0} +#endif + +#ifdef CONFIG_HISAX_SCT_QUADRO +#undef DEFAULT_CARD +#undef DEFAULT_CFG +#define DEFAULT_CARD ISDN_CTYPE_SCT_QUADRO +#define DEFAULT_CFG {1,0x0,0,0} +#endif + +#ifdef CONFIG_HISAX_GAZEL +#undef DEFAULT_CARD +#undef DEFAULT_CFG +#define DEFAULT_CARD ISDN_CTYPE_GAZEL +#define DEFAULT_CFG {15,0x180,0,0} +#endif + #ifdef CONFIG_HISAX_1TR6 #define DEFAULT_PROTO ISDN_PTYPE_1TR6 #define DEFAULT_PROTO_NAME "1TR6" @@ -366,6 +469,7 @@ {0, 0, 0, 0, 0, 0, 0, 0}; static char *id HISAX_INITDATA = HiSaxID; +#ifdef COMPAT_HAS_NEW_SYMTAB MODULE_AUTHOR("Karsten Keil"); MODULE_PARM(type, "1-8i"); MODULE_PARM(protocol, "1-8i"); @@ -377,7 +481,7 @@ MODULE_PARM(io0, "1-8i"); MODULE_PARM(io1, "1-8i"); #endif /* CONFIG_HISAX_16_3 */ - +#endif /* COMPAT_HAS_NEW_SYMTAB */ #endif /* MODULE */ int nrcards; @@ -410,9 +514,9 @@ printk(KERN_INFO "HiSax: Linux Driver for passive ISDN cards\n"); #ifdef MODULE - printk(KERN_INFO "HiSax: Version 3.1a (module)\n"); + printk(KERN_INFO "HiSax: Version 3.3 (module)\n"); #else - printk(KERN_INFO "HiSax: Version 3.1a (kernel)\n"); + printk(KERN_INFO "HiSax: Version 3.3 (kernel)\n"); #endif strcpy(tmp, l1_revision); printk(KERN_INFO "HiSax: Layer1 Revision %s\n", HiSax_getrev(tmp)); @@ -442,8 +546,8 @@ #ifdef MODULE #define HiSax_init init_module #else -void __init -HiSax_setup(char *str, int *ints) +__initfunc(void +HiSax_setup(char *str, int *ints)) { int i, j, argc; @@ -552,8 +656,12 @@ extern int setup_netjet(struct IsdnCard *card); #endif -#if CARD_TELES3C -extern int setup_t163c(struct IsdnCard *card); +#if CARD_HFCS +extern int setup_hfcs(struct IsdnCard *card); +#endif + +#if CARD_HFC_PCI +extern int setup_hfcpci(struct IsdnCard *card); #endif #if CARD_AMD7930 @@ -564,6 +672,30 @@ extern int setup_niccy(struct IsdnCard *card); #endif +#if CARD_ISURF +extern int setup_isurf(struct IsdnCard *card); +#endif + +#if CARD_HSTSAPHIR +extern int setup_saphir(struct IsdnCard *card); +#endif + +#if CARD_TESTEMU +extern int setup_testemu(struct IsdnCard *card); +#endif + +#if CARD_BKM_A4T +extern int setup_bkm_a4t(struct IsdnCard *card); +#endif + +#if CARD_SCT_QUADRO +extern int setup_sct_quadro(struct IsdnCard *card); +#endif + +#if CARD_GAZEL +extern int setup_gazel(struct IsdnCard *card); +#endif + /* * Find card with given driverId */ @@ -579,6 +711,18 @@ return (NULL); } +/* + * Find card with given card number + */ +struct IsdnCardState +*hisax_get_card(int cardnr) +{ + if ((cardnr <= nrcards) && (cardnr>0)) + if (cards[cardnr-1].cs) + return (cards[cardnr-1].cs); + return (NULL); +} + int HiSax_readstatus(u_char * buf, int len, int user, int id, int channel) { @@ -782,23 +926,18 @@ csta->bcs->BC_Close(csta->bcs); } + discard_queue(&csta->rq); + discard_queue(&csta->sq); if (csta->rcvbuf) { kfree(csta->rcvbuf); csta->rcvbuf = NULL; } - discard_queue(&csta->rq); - discard_queue(&csta->sq); if (csta->tx_skb) { - dev_kfree_skb(csta->tx_skb); + idev_kfree_skb(csta->tx_skb, FREE_WRITE); csta->tx_skb = NULL; } - if (csta->mon_rx) { - kfree(csta->mon_rx); - csta->mon_rx = NULL; - } - if (csta->mon_tx) { - kfree(csta->mon_tx); - csta->mon_tx = NULL; + if (csta->DC_Close != NULL) { + csta->DC_Close(csta); } csta->cardmsg(csta, CARD_RELEASE, NULL); if (csta->dbusytimer.function != NULL) @@ -811,12 +950,14 @@ int irq_cnt, cnt = 3; long flags; + if (!cs->irq) + return(cs->cardmsg(cs, CARD_INIT, NULL)); save_flags(flags); cli(); irq_cnt = kstat_irqs(cs->irq); printk(KERN_INFO "%s: IRQ %d count %d\n", CardType[cs->typ], cs->irq, irq_cnt); - if (cs->cardmsg(cs, CARD_SETIRQ, NULL)) { + if (request_irq(cs->irq, cs->irq_func, cs->irq_flags, "HiSax", cs)) { printk(KERN_WARNING "HiSax: couldn't get interrupt %d\n", cs->irq); restore_flags(flags); @@ -827,7 +968,7 @@ sti(); current->state = TASK_INTERRUPTIBLE; /* Timeout 10ms */ - schedule_timeout((10 * HZ) / 1000); + schedule_timeout((10*HZ)/1000); restore_flags(flags); printk(KERN_INFO "%s: IRQ %d count %d\n", CardType[cs->typ], cs->irq, kstat_irqs(cs->irq)); @@ -871,198 +1012,229 @@ } memset(cs, 0, sizeof(struct IsdnCardState)); card->cs = cs; + cs->chanlimit = 2; /* maximum B-channel number */ + cs->logecho = 0; /* No echo logging */ cs->cardnr = cardnr; cs->debug = L1_DEB_WARN; cs->HW_Flags = 0; cs->busy_flag = busy_flag; + cs->irq_flags = I4L_IRQ_FLAG; #if TEI_PER_CARD #else test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags); #endif cs->protocol = card->protocol; - if ((card->typ > 0) && (card->typ < 31)) { - if (!((1 << card->typ) & SUPORTED_CARDS)) { + if ((card->typ > 0) && (card->typ <= ISDN_CTYPE_COUNT)) { + if (!(cs->dlog = kmalloc(MAX_DLOG_SPACE, GFP_ATOMIC))) { printk(KERN_WARNING - "HiSax: Support for %s Card not selected\n", - CardType[card->typ]); + "HiSax: No memory for dlog(card %d)\n", + cardnr + 1); restore_flags(flags); return (0); } - } else { - printk(KERN_WARNING - "HiSax: Card Type %d out of range\n", - card->typ); - restore_flags(flags); - return (0); - } - if (!(cs->dlog = kmalloc(MAX_DLOG_SPACE, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for dlog(card %d)\n", - cardnr + 1); - restore_flags(flags); - return (0); - } - if (!(cs->status_buf = kmalloc(HISAX_STATUS_BUFSIZE, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for status_buf(card %d)\n", - cardnr + 1); - kfree(cs->dlog); - restore_flags(flags); - return (0); - } - cs->stlist = NULL; - cs->mon_tx = NULL; - cs->mon_rx = NULL; - cs->status_read = cs->status_buf; - cs->status_write = cs->status_buf; - cs->status_end = cs->status_buf + HISAX_STATUS_BUFSIZE - 1; - cs->typ = card->typ; - strcpy(cs->iif.id, id); - cs->iif.channels = 2; - cs->iif.maxbufsize = MAX_DATA_SIZE; - cs->iif.hl_hdrlen = MAX_HEADER_LEN; - cs->iif.features = - ISDN_FEATURE_L2_X75I | - ISDN_FEATURE_L2_HDLC | - ISDN_FEATURE_L2_MODEM | - ISDN_FEATURE_L2_TRANS | - ISDN_FEATURE_L3_TRANS | + if (!(cs->status_buf = kmalloc(HISAX_STATUS_BUFSIZE, GFP_ATOMIC))) { + printk(KERN_WARNING + "HiSax: No memory for status_buf(card %d)\n", + cardnr + 1); + kfree(cs->dlog); + restore_flags(flags); + return (0); + } + cs->stlist = NULL; + cs->status_read = cs->status_buf; + cs->status_write = cs->status_buf; + cs->status_end = cs->status_buf + HISAX_STATUS_BUFSIZE - 1; + cs->typ = card->typ; + strcpy(cs->iif.id, id); + cs->iif.channels = 2; + cs->iif.maxbufsize = MAX_DATA_SIZE; + cs->iif.hl_hdrlen = MAX_HEADER_LEN; + cs->iif.features = + ISDN_FEATURE_L2_X75I | + ISDN_FEATURE_L2_HDLC | + ISDN_FEATURE_L2_MODEM | + ISDN_FEATURE_L2_TRANS | + ISDN_FEATURE_L3_TRANS | #ifdef CONFIG_HISAX_1TR6 - ISDN_FEATURE_P_1TR6 | + ISDN_FEATURE_P_1TR6 | #endif #ifdef CONFIG_HISAX_EURO - ISDN_FEATURE_P_EURO | + ISDN_FEATURE_P_EURO | #endif -#ifdef CONFIG_HISAX_NI1 - ISDN_FEATURE_P_NI1 | +#ifdef CONFIG_HISAX_NI1 + ISDN_FEATURE_P_NI1 | #endif - 0; + 0; - cs->iif.command = HiSax_command; - cs->iif.writecmd = NULL; - cs->iif.writebuf_skb = HiSax_writebuf_skb; - cs->iif.readstat = HiSax_readstatus; - register_isdn(&cs->iif); - cs->myid = cs->iif.channels; - printk(KERN_INFO - "HiSax: Card %d Protocol %s Id=%s (%d)\n", cardnr + 1, - (card->protocol == ISDN_PTYPE_1TR6) ? "1TR6" : - (card->protocol == ISDN_PTYPE_EURO) ? "EDSS1" : - (card->protocol == ISDN_PTYPE_LEASED) ? "LEASED" : - (card->protocol == ISDN_PTYPE_NI1) ? "NI1" : - "NONE", cs->iif.id, cs->myid); - switch (card->typ) { + cs->iif.command = HiSax_command; + cs->iif.writecmd = NULL; + cs->iif.writebuf_skb = HiSax_writebuf_skb; + cs->iif.readstat = HiSax_readstatus; + register_isdn(&cs->iif); + cs->myid = cs->iif.channels; + printk(KERN_INFO + "HiSax: Card %d Protocol %s Id=%s (%d)\n", cardnr + 1, + (card->protocol == ISDN_PTYPE_1TR6) ? "1TR6" : + (card->protocol == ISDN_PTYPE_EURO) ? "EDSS1" : + (card->protocol == ISDN_PTYPE_LEASED) ? "LEASED" : + (card->protocol == ISDN_PTYPE_NI1) ? "NI1" : + "NONE", cs->iif.id, cs->myid); + switch (card->typ) { #if CARD_TELES0 - case ISDN_CTYPE_16_0: - case ISDN_CTYPE_8_0: - ret = setup_teles0(card); - break; + case ISDN_CTYPE_16_0: + case ISDN_CTYPE_8_0: + ret = setup_teles0(card); + break; #endif #if CARD_TELES3 - case ISDN_CTYPE_16_3: - case ISDN_CTYPE_PNP: - case ISDN_CTYPE_TELESPCMCIA: - case ISDN_CTYPE_COMPAQ_ISA: - ret = setup_teles3(card); - break; + case ISDN_CTYPE_16_3: + case ISDN_CTYPE_PNP: + case ISDN_CTYPE_TELESPCMCIA: + case ISDN_CTYPE_COMPAQ_ISA: + ret = setup_teles3(card); + break; #endif #if CARD_S0BOX - case ISDN_CTYPE_S0BOX: - ret = setup_s0box(card); - break; + case ISDN_CTYPE_S0BOX: + ret = setup_s0box(card); + break; #endif #if CARD_TELESPCI - case ISDN_CTYPE_TELESPCI: - ret = setup_telespci(card); - break; + case ISDN_CTYPE_TELESPCI: + ret = setup_telespci(card); + break; #endif #if CARD_AVM_A1 - case ISDN_CTYPE_A1: - ret = setup_avm_a1(card); - break; + case ISDN_CTYPE_A1: + ret = setup_avm_a1(card); + break; #endif #if CARD_AVM_A1_PCMCIA - case ISDN_CTYPE_A1_PCMCIA: - ret = setup_avm_a1_pcmcia(card); - break; + case ISDN_CTYPE_A1_PCMCIA: + ret = setup_avm_a1_pcmcia(card); + break; #endif #if CARD_FRITZPCI - case ISDN_CTYPE_FRITZPCI: - ret = setup_avm_pcipnp(card); - break; + case ISDN_CTYPE_FRITZPCI: + ret = setup_avm_pcipnp(card); + break; #endif #if CARD_ELSA - case ISDN_CTYPE_ELSA: - case ISDN_CTYPE_ELSA_PNP: - case ISDN_CTYPE_ELSA_PCMCIA: - case ISDN_CTYPE_ELSA_PCI: - ret = setup_elsa(card); - break; + case ISDN_CTYPE_ELSA: + case ISDN_CTYPE_ELSA_PNP: + case ISDN_CTYPE_ELSA_PCMCIA: + case ISDN_CTYPE_ELSA_PCI: + ret = setup_elsa(card); + break; #endif #if CARD_IX1MICROR2 - case ISDN_CTYPE_IX1MICROR2: - ret = setup_ix1micro(card); - break; + case ISDN_CTYPE_IX1MICROR2: + ret = setup_ix1micro(card); + break; #endif #if CARD_DIEHLDIVA - case ISDN_CTYPE_DIEHLDIVA: - ret = setup_diva(card); - break; + case ISDN_CTYPE_DIEHLDIVA: + ret = setup_diva(card); + break; #endif #if CARD_ASUSCOM - case ISDN_CTYPE_ASUSCOM: - ret = setup_asuscom(card); - break; + case ISDN_CTYPE_ASUSCOM: + ret = setup_asuscom(card); + break; #endif #if CARD_TELEINT - case ISDN_CTYPE_TELEINT: - ret = setup_TeleInt(card); - break; + case ISDN_CTYPE_TELEINT: + ret = setup_TeleInt(card); + break; #endif #if CARD_SEDLBAUER - case ISDN_CTYPE_SEDLBAUER: - case ISDN_CTYPE_SEDLBAUER_PCMCIA: - case ISDN_CTYPE_SEDLBAUER_FAX: - ret = setup_sedlbauer(card); - break; + case ISDN_CTYPE_SEDLBAUER: + case ISDN_CTYPE_SEDLBAUER_PCMCIA: + case ISDN_CTYPE_SEDLBAUER_FAX: + ret = setup_sedlbauer(card); + break; #endif #if CARD_SPORTSTER - case ISDN_CTYPE_SPORTSTER: - ret = setup_sportster(card); - break; + case ISDN_CTYPE_SPORTSTER: + ret = setup_sportster(card); + break; #endif #if CARD_MIC - case ISDN_CTYPE_MIC: - ret = setup_mic(card); - break; + case ISDN_CTYPE_MIC: + ret = setup_mic(card); + break; #endif #if CARD_NETJET - case ISDN_CTYPE_NETJET: - ret = setup_netjet(card); - break; + case ISDN_CTYPE_NETJET: + ret = setup_netjet(card); + break; #endif -#if CARD_TELES3C - case ISDN_CTYPE_TELES3C: - ret = setup_t163c(card); - break; +#if CARD_HFCS + case ISDN_CTYPE_TELES3C: + case ISDN_CTYPE_ACERP10: + ret = setup_hfcs(card); + break; +#endif +#if CARD_HFC_PCI + case ISDN_CTYPE_HFC_PCI: + ret = setup_hfcpci(card); + break; #endif #if CARD_NICCY - case ISDN_CTYPE_NICCY: - ret = setup_niccy(card); - break; + case ISDN_CTYPE_NICCY: + ret = setup_niccy(card); + break; #endif #if CARD_AMD7930 - case ISDN_CTYPE_AMD7930: - ret = setup_amd7930(card); + case ISDN_CTYPE_AMD7930: + ret = setup_amd7930(card); + break; +#endif +#if CARD_ISURF + case ISDN_CTYPE_ISURF: + ret = setup_isurf(card); + break; +#endif +#if CARD_HSTSAPHIR + case ISDN_CTYPE_HSTSAPHIR: + ret = setup_saphir(card); + break; +#endif +#if CARD_TESTEMU + case ISDN_CTYPE_TESTEMU: + ret = setup_testemu(card); + break; +#endif +#if CARD_BKM_A4T + case ISDN_CTYPE_BKM_A4T: + ret = setup_bkm_a4t(card); break; #endif +#if CARD_SCT_QUADRO + case ISDN_CTYPE_SCT_QUADRO: + ret = setup_sct_quadro(card); + break; +#endif +#if CARD_GAZEL + case ISDN_CTYPE_GAZEL: + ret = setup_gazel(card); + break; +#endif default: - printk(KERN_WARNING "HiSax: Unknown Card Typ %d\n", - card->typ); + printk(KERN_WARNING + "HiSax: Support for %s Card not selected\n", + CardType[card->typ]); ll_unload(cs); restore_flags(flags); return (0); + } + } else { + printk(KERN_WARNING + "HiSax: Card Type %d out of range\n", + card->typ); + restore_flags(flags); + return (0); } if (!ret) { ll_unload(cs); @@ -1168,7 +1340,8 @@ ll_stop(cards[cardnr].cs); release_tei(cards[cardnr].cs); closecard(cardnr); - free_irq(cards[cardnr].cs->irq, cards[cardnr].cs); + if (cards[cardnr].cs->irq) + free_irq(cards[cardnr].cs->irq, cards[cardnr].cs); kfree((void *) cards[cardnr].cs); cards[cardnr].cs = NULL; } @@ -1180,8 +1353,6 @@ nrcards--; } -EXPORT_SYMBOL(HiSax_closecard); - void HiSax_reportcard(int cardnr) { @@ -1202,11 +1373,13 @@ cs->bcs[0].mode, cs->bcs[0].channel); printk(KERN_DEBUG "HiSax: bcs 1 mode %d ch%d\n", cs->bcs[1].mode, cs->bcs[1].channel); + printk(KERN_DEBUG "HiSax: cs setstack_d 0x%lX\n", (ulong) cs->setstack_d); printk(KERN_DEBUG "HiSax: cs stl 0x%lX\n", (ulong) & (cs->stlist)); stptr = cs->stlist; while (stptr != NULL) { printk(KERN_DEBUG "HiSax: dst%d 0x%lX\n", i, (ulong) stptr); printk(KERN_DEBUG "HiSax: dst%d stp 0x%lX\n", i, (ulong) stptr->l1.stlistp); + printk(KERN_DEBUG "HiSax: dst%d l1.l1hw 0x%lX\n", i, (ulong) stptr->l1.l1hw); printk(KERN_DEBUG "HiSax: tei %d sapi %d\n", stptr->l2.tei, stptr->l2.sap); printk(KERN_DEBUG "HiSax: man 0x%lX\n", (ulong) stptr->ma.layer); @@ -1236,8 +1409,8 @@ } -int __init -HiSax_init(void) +__initfunc(int +HiSax_init(void)) { int i; @@ -1246,18 +1419,27 @@ #ifdef CONFIG_HISAX_ELSA if (type[0] == ISDN_CTYPE_ELSA_PCMCIA) { /* we have exported and return in this case */ +#ifndef COMPAT_HAS_NEW_SYMTAB + register_symtab(&hisax_syms_elsa); +#endif return 0; } #endif #ifdef CONFIG_HISAX_SEDLBAUER if (type[0] == ISDN_CTYPE_SEDLBAUER_PCMCIA) { /* we have to export and return in this case */ +#ifndef COMPAT_HAS_NEW_SYMTAB + register_symtab(&hisax_syms_sedl); +#endif return 0; } #endif #ifdef CONFIG_HISAX_AVM_A1_PCMCIA if (type[0] == ISDN_CTYPE_A1_PCMCIA) { /* we have to export and return in this case */ +#ifndef COMPAT_HAS_NEW_SYMTAB + register_symtab(&hisax_syms_avm_a1); +#endif return 0; } #endif @@ -1318,16 +1500,29 @@ case ISDN_CTYPE_SPORTSTER: case ISDN_CTYPE_MIC: case ISDN_CTYPE_TELES3C: + case ISDN_CTYPE_ACERP10: case ISDN_CTYPE_S0BOX: case ISDN_CTYPE_FRITZPCI: + case ISDN_CTYPE_HSTSAPHIR: + case ISDN_CTYPE_GAZEL: + cards[i].para[0] = irq[i]; + cards[i].para[1] = io[i]; + break; + case ISDN_CTYPE_ISURF: cards[i].para[0] = irq[i]; cards[i].para[1] = io[i]; + cards[i].para[2] = mem[i]; break; case ISDN_CTYPE_ELSA_PCI: case ISDN_CTYPE_NETJET: case ISDN_CTYPE_AMD7930: case ISDN_CTYPE_TELESPCI: break; + case ISDN_CTYPE_BKM_A4T: + break; + case ISDN_CTYPE_SCT_QUADRO: + cards[i].para[0] = irq[i]; + break; } } if (!nzproto) { @@ -1353,11 +1548,13 @@ Isdnl1New(); if (HiSax_inithardware(NULL)) { /* Install only, if at least one card found */ - /* No symbols to export, hide all symbols */ - #ifdef MODULE +#ifndef COMPAT_HAS_NEW_SYMTAB + /* No symbols to export, hide all symbols */ + register_symtab(NULL); printk(KERN_INFO "HiSax: module installed\n"); -#endif +#endif /* COMPAT_HAS_NEW_SYMTAB */ +#endif /* MODULE */ return (0); } else { Isdnl1Free(); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/diva.c linux/drivers/isdn/hisax/diva.c --- v2.3.13/linux/drivers/isdn/hisax/diva.c Mon Aug 9 14:59:20 1999 +++ linux/drivers/isdn/hisax/diva.c Thu Aug 12 09:42:33 1999 @@ -1,13 +1,36 @@ -/* $Id: diva.c,v 1.10 1998/11/15 23:54:31 keil Exp $ +/* $Id: diva.c,v 1.16 1999/08/11 21:01:25 keil Exp $ * diva.c low level stuff for Eicon.Diehl Diva Family ISDN cards * * Author Karsten Keil (keil@isdn4linux.de) * - * Thanks to Eicon Technology Diehl GmbH & Co. oHG for documents and informations + * This file is (c) under GNU PUBLIC LICENSE + * For changes and modifications please read + * ../../../Documentation/isdn/HiSax.cert + * + * Thanks to Eicon Technology for documents and informations * * * $Log: diva.c,v $ + * Revision 1.16 1999/08/11 21:01:25 keil + * new PCI codefix + * + * Revision 1.15 1999/08/10 16:01:49 calle + * struct pci_dev changed in 2.3.13. Made the necessary changes. + * + * Revision 1.14 1999/08/07 17:35:08 keil + * approval for Eicon Technology Diva 2.01 PCI + * + * Revision 1.13 1999/07/21 14:46:07 keil + * changes from EICON certification + * + * Revision 1.12 1999/07/12 21:05:04 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 1.11 1999/07/01 08:11:29 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.10 1998/11/15 23:54:31 keil * changes from 2.0 * @@ -51,10 +74,13 @@ #include "ipac.h" #include "isdnl1.h" #include +#ifndef COMPAT_HAS_NEW_PCI +#include +#endif extern const char *CardType[]; -const char *Diva_revision = "$Revision: 1.10 $"; +const char *Diva_revision = "$Revision: 1.16 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -75,6 +101,7 @@ #define DIVA_ISA 1 #define DIVA_PCI 2 #define DIVA_IPAC_ISA 3 +#define DIVA_IPAC_PCI 4 /* PCI stuff */ #define PCI_VENDOR_EICON_DIEHL 0x1133 @@ -82,10 +109,12 @@ #define PCI_DIVA20_ID 0xe002 #define PCI_DIVA20PRO_U_ID 0xe003 #define PCI_DIVA20_U_ID 0xe004 +#define PCI_DIVA_201 0xe005 /* CTRL (Read) */ #define DIVA_IRQ_STAT 0x01 #define DIVA_EEPROM_SDA 0x02 + /* CTRL (Write) */ #define DIVA_IRQ_REQ 0x01 #define DIVA_RESET 0x08 @@ -96,6 +125,13 @@ #define DIVA_ISA_LED_B 0x40 #define DIVA_IRQ_CLR 0x80 +/* Siemens PITA */ +#define PITA_MISC_REG 0x1c +#define PITA_PARA_SOFTRESET 0x01000000 +#define PITA_PARA_MPX_MODE 0x04000000 +#define PITA_INT0_ENABLE 0x00020000 +#define PITA_INT0_STATUS 0x00000002 + static inline u_char readreg(unsigned int ale, unsigned int adr, u_char off) { @@ -140,6 +176,22 @@ outsb(adr, data, size); } +static inline u_char +memreadreg(unsigned long adr, u_char off) +{ + return(0xff & *((unsigned int *) + (((unsigned int *)adr) + off))); +} + +static inline void +memwritereg(unsigned long adr, u_char off, u_char data) +{ + register u_char *p; + + p = (unsigned char *)(((unsigned int *)adr) + off); + *p = data; +} + /* Interface functions */ static u_char @@ -204,6 +256,44 @@ cs->hw.diva.hscx, offset + (hscx ? 0x40 : 0), value); } +static u_char +MemReadISAC_IPAC(struct IsdnCardState *cs, u_char offset) +{ + return (memreadreg(cs->hw.diva.cfg_reg, offset+0x80)); +} + +static void +MemWriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value) +{ + memwritereg(cs->hw.diva.cfg_reg, offset|0x80, value); +} + +static void +MemReadISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size) +{ + while(size--) + *data++ = memreadreg(cs->hw.diva.cfg_reg, 0x80); +} + +static void +MemWriteISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size) +{ + while(size--) + memwritereg(cs->hw.diva.cfg_reg, 0x80, *data++); +} + +static u_char +MemReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) +{ + return(memreadreg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0))); +} + +static void +MemWriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) +{ + memwritereg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0), value); +} + /* * fast interrupt HSCX stuff goes here */ @@ -225,8 +315,8 @@ diva_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; - u_char val, sval, stat = 0; - int cnt=8; + u_char val, sval; + int cnt=5; if (!cs) { printk(KERN_WARNING "Diva: Spurious interrupt!\n"); @@ -234,44 +324,36 @@ } while (((sval = bytein(cs->hw.diva.ctrl)) & DIVA_IRQ_REQ) && cnt) { val = readreg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_ISTA + 0x40); - if (val) { + if (val) hscx_int_main(cs, val); - stat |= 1; - } val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_ISTA); - if (val) { + if (val) isac_interrupt(cs, val); - stat |= 2; - } cnt--; } if (!cnt) printk(KERN_WARNING "Diva: IRQ LOOP\n"); - if (stat & 1) { - writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK, 0xFF); - writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK + 0x40, 0xFF); - writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK, 0x0); - writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK + 0x40, 0x0); - } - if (stat & 2) { - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_MASK, 0x0); - } + writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK, 0xFF); + writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK + 0x40, 0xFF); + writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_MASK, 0xFF); + writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_MASK, 0x0); + writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK, 0x0); + writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK + 0x40, 0x0); } static void -diva_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs) +diva_irq_ipac_isa(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char ista,val; - int icnt=20; + int icnt=5; if (!cs) { printk(KERN_WARNING "Diva: Spurious interrupt!\n"); return; } ista = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ISTA); -Start_IPAC: +Start_IPACISA: if (cs->debug & L1_DEB_IPAC) debugl1(cs, "IPAC ISTA %02X", ista); if (ista & 0x0f) { @@ -298,7 +380,7 @@ ista = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ISTA); if ((ista & 0x3f) && icnt) { icnt--; - goto Start_IPAC; + goto Start_IPACISA; } if (!icnt) printk(KERN_WARNING "DIVA IPAC IRQ LOOP\n"); @@ -306,13 +388,348 @@ writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xC0); } +static inline void +MemwaitforCEC(struct IsdnCardState *cs, int hscx) +{ + int to = 50; + + while ((MemReadHSCX(cs, hscx, HSCX_STAR) & 0x04) && to) { + udelay(1); + to--; + } + if (!to) + printk(KERN_WARNING "HiSax: waitforCEC timeout\n"); +} + + +static inline void +MemwaitforXFW(struct IsdnCardState *cs, int hscx) +{ + int to = 50; + + while ((!(MemReadHSCX(cs, hscx, HSCX_STAR) & 0x44) == 0x40) && to) { + udelay(1); + to--; + } + if (!to) + printk(KERN_WARNING "HiSax: waitforXFW timeout\n"); +} + +static inline void +MemWriteHSCXCMDR(struct IsdnCardState *cs, int hscx, u_char data) +{ + long flags; + + save_flags(flags); + cli(); + MemwaitforCEC(cs, hscx); + MemWriteHSCX(cs, hscx, HSCX_CMDR, data); + restore_flags(flags); +} + +static void +Memhscx_empty_fifo(struct BCState *bcs, int count) +{ + u_char *ptr; + struct IsdnCardState *cs = bcs->cs; + long flags; + int cnt; + + if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) + debugl1(cs, "hscx_empty_fifo"); + + if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) { + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "hscx_empty_fifo: incoming packet too large"); + MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80); + bcs->hw.hscx.rcvidx = 0; + return; + } + save_flags(flags); + cli(); + ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; + cnt = count; + while (cnt--) + *ptr++ = memreadreg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0); + MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80); + ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; + bcs->hw.hscx.rcvidx += count; + restore_flags(flags); + if (cs->debug & L1_DEB_HSCX_FIFO) { + char *t = bcs->blog; + + t += sprintf(t, "hscx_empty_fifo %c cnt %d", + bcs->hw.hscx.hscx ? 'B' : 'A', count); + QuickHex(t, ptr, count); + debugl1(cs, bcs->blog); + } +} + +static void +Memhscx_fill_fifo(struct BCState *bcs) +{ + struct IsdnCardState *cs = bcs->cs; + int more, count, cnt; + int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32; + u_char *ptr,*p; + long flags; + + + if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) + debugl1(cs, "hscx_fill_fifo"); + + if (!bcs->tx_skb) + return; + if (bcs->tx_skb->len <= 0) + return; + + more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0; + if (bcs->tx_skb->len > fifo_size) { + more = !0; + count = fifo_size; + } else + count = bcs->tx_skb->len; + cnt = count; + MemwaitforXFW(cs, bcs->hw.hscx.hscx); + save_flags(flags); + cli(); + p = ptr = bcs->tx_skb->data; + skb_pull(bcs->tx_skb, count); + bcs->tx_cnt -= count; + bcs->hw.hscx.count += count; + while(cnt--) + memwritereg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0, + *p++); + MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, more ? 0x8 : 0xa); + restore_flags(flags); + if (cs->debug & L1_DEB_HSCX_FIFO) { + char *t = bcs->blog; + + t += sprintf(t, "hscx_fill_fifo %c cnt %d", + bcs->hw.hscx.hscx ? 'B' : 'A', count); + QuickHex(t, ptr, count); + debugl1(cs, bcs->blog); + } +} + +static inline void +Memhscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx) +{ + u_char r; + struct BCState *bcs = cs->bcs + hscx; + struct sk_buff *skb; + int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32; + int count; + + if (!test_bit(BC_FLG_INIT, &bcs->Flag)) + return; + + if (val & 0x80) { /* RME */ + r = MemReadHSCX(cs, hscx, HSCX_RSTA); + if ((r & 0xf0) != 0xa0) { + if (!(r & 0x80)) + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "HSCX invalid frame"); + if ((r & 0x40) && bcs->mode) + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "HSCX RDO mode=%d", + bcs->mode); + if (!(r & 0x20)) + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "HSCX CRC error"); + MemWriteHSCXCMDR(cs, hscx, 0x80); + } else { + count = MemReadHSCX(cs, hscx, HSCX_RBCL) & ( + test_bit(HW_IPAC, &cs->HW_Flags)? 0x3f: 0x1f); + if (count == 0) + count = fifo_size; + Memhscx_empty_fifo(bcs, count); + if ((count = bcs->hw.hscx.rcvidx - 1) > 0) { + if (cs->debug & L1_DEB_HSCX_FIFO) + debugl1(cs, "HX Frame %d", count); + if (!(skb = dev_alloc_skb(count))) + printk(KERN_WARNING "HSCX: receive out of memory\n"); + else { + SET_SKB_FREE(skb); + memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count); + skb_queue_tail(&bcs->rqueue, skb); + } + } + } + bcs->hw.hscx.rcvidx = 0; + hscx_sched_event(bcs, B_RCVBUFREADY); + } + if (val & 0x40) { /* RPF */ + Memhscx_empty_fifo(bcs, fifo_size); + if (bcs->mode == L1_MODE_TRANS) { + /* receive audio data */ + if (!(skb = dev_alloc_skb(fifo_size))) + printk(KERN_WARNING "HiSax: receive out of memory\n"); + else { + SET_SKB_FREE(skb); + memcpy(skb_put(skb, fifo_size), bcs->hw.hscx.rcvbuf, fifo_size); + skb_queue_tail(&bcs->rqueue, skb); + } + bcs->hw.hscx.rcvidx = 0; + hscx_sched_event(bcs, B_RCVBUFREADY); + } + } + if (val & 0x10) { /* XPR */ + if (bcs->tx_skb) { + if (bcs->tx_skb->len) { + Memhscx_fill_fifo(bcs); + return; + } else { + if (bcs->st->lli.l1writewakeup && + (PACKET_NOACK != bcs->tx_skb->pkt_type)) + bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count); + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + bcs->hw.hscx.count = 0; + bcs->tx_skb = NULL; + } + } + if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { + bcs->hw.hscx.count = 0; + test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); + Memhscx_fill_fifo(bcs); + } else { + test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); + hscx_sched_event(bcs, B_XMTBUFREADY); + } + } +} + +static inline void +Memhscx_int_main(struct IsdnCardState *cs, u_char val) +{ + + u_char exval; + struct BCState *bcs; + + if (val & 0x01) { + bcs = cs->bcs + 1; + exval = MemReadHSCX(cs, 1, HSCX_EXIR); + if (exval & 0x40) { + if (bcs->mode == 1) + Memhscx_fill_fifo(bcs); + else { + /* Here we lost an TX interrupt, so + * restart transmitting the whole frame. + */ + if (bcs->tx_skb) { + skb_push(bcs->tx_skb, bcs->hw.hscx.count); + bcs->tx_cnt += bcs->hw.hscx.count; + bcs->hw.hscx.count = 0; + } + MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01); + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "HSCX B EXIR %x Lost TX", exval); + } + } else if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "HSCX B EXIR %x", exval); + } + if (val & 0xf8) { + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "HSCX B interrupt %x", val); + Memhscx_interrupt(cs, val, 1); + } + if (val & 0x02) { + bcs = cs->bcs; + exval = MemReadHSCX(cs, 0, HSCX_EXIR); + if (exval & 0x40) { + if (bcs->mode == L1_MODE_TRANS) + Memhscx_fill_fifo(bcs); + else { + /* Here we lost an TX interrupt, so + * restart transmitting the whole frame. + */ + if (bcs->tx_skb) { + skb_push(bcs->tx_skb, bcs->hw.hscx.count); + bcs->tx_cnt += bcs->hw.hscx.count; + bcs->hw.hscx.count = 0; + } + MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01); + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "HSCX A EXIR %x Lost TX", exval); + } + } else if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "HSCX A EXIR %x", exval); + } + if (val & 0x04) { + exval = MemReadHSCX(cs, 0, HSCX_ISTA); + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "HSCX A interrupt %x", exval); + Memhscx_interrupt(cs, exval, 0); + } +} + +static void +diva_irq_ipac_pci(int intno, void *dev_id, struct pt_regs *regs) +{ + struct IsdnCardState *cs = dev_id; + u_char ista,val; + int icnt=5; + u_char *cfg; + + if (!cs) { + printk(KERN_WARNING "Diva: Spurious interrupt!\n"); + return; + } + cfg = (u_char *) cs->hw.diva.pci_cfg; + val = *cfg; + if (!(val & PITA_INT0_STATUS)) + return; /* other shared IRQ */ + *cfg = PITA_INT0_STATUS; /* Reset pending INT0 */ + ista = memreadreg(cs->hw.diva.cfg_reg, IPAC_ISTA); +Start_IPACPCI: + if (cs->debug & L1_DEB_IPAC) + debugl1(cs, "IPAC ISTA %02X", ista); + if (ista & 0x0f) { + val = memreadreg(cs->hw.diva.cfg_reg, HSCX_ISTA + 0x40); + if (ista & 0x01) + val |= 0x01; + if (ista & 0x04) + val |= 0x02; + if (ista & 0x08) + val |= 0x04; + if (val) + Memhscx_int_main(cs, val); + } + if (ista & 0x20) { + val = 0xfe & memreadreg(cs->hw.diva.cfg_reg, ISAC_ISTA + 0x80); + if (val) { + isac_interrupt(cs, val); + } + } + if (ista & 0x10) { + val = 0x01; + isac_interrupt(cs, val); + } + ista = memreadreg(cs->hw.diva.cfg_reg, IPAC_ISTA); + if ((ista & 0x3f) && icnt) { + icnt--; + goto Start_IPACPCI; + } + if (!icnt) + printk(KERN_WARNING "DIVA IPAC PCI IRQ LOOP\n"); + memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xFF); + memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xC0); +} void release_io_diva(struct IsdnCardState *cs) { int bytecnt; - if (cs->subtyp != DIVA_IPAC_ISA) { + if (cs->subtyp == DIVA_IPAC_PCI) { + u_int *cfg = (unsigned int *)cs->hw.diva.pci_cfg; + + *cfg = 0; /* disable INT0/1 */ + *cfg = 2; /* reset pending INT0 */ + iounmap((void *)cs->hw.diva.cfg_reg); + iounmap((void *)cs->hw.diva.pci_cfg); + return; + } else if (cs->subtyp != DIVA_IPAC_ISA) { del_timer(&cs->hw.diva.tl); if (cs->hw.diva.cfg_reg) byteout(cs->hw.diva.ctrl, 0); /* LED off, Reset */ @@ -336,24 +753,37 @@ if (cs->subtyp == DIVA_IPAC_ISA) { writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x20); current->state = TASK_INTERRUPTIBLE; - schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ + schedule_timeout((10*HZ)/1000); writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x00); current->state = TASK_INTERRUPTIBLE; - schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ + schedule_timeout((10*HZ)/1000); writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xc0); - } else { + } else if (cs->subtyp == DIVA_IPAC_PCI) { + unsigned int *ireg = (unsigned int *)(cs->hw.diva.pci_cfg + + PITA_MISC_REG); + *ireg = PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE; + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((10*HZ)/1000); + *ireg = PITA_PARA_MPX_MODE; + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((10*HZ)/1000); + memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xc0); + } else { /* DIVA 2.0 */ cs->hw.diva.ctrl_reg = 0; /* Reset On */ byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); current->state = TASK_INTERRUPTIBLE; - schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ + schedule_timeout((10*HZ)/1000); cs->hw.diva.ctrl_reg |= DIVA_RESET; /* Reset Off */ byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); current->state = TASK_INTERRUPTIBLE; - schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ + schedule_timeout((10*HZ)/1000); if (cs->subtyp == DIVA_ISA) cs->hw.diva.ctrl_reg |= DIVA_ISA_LED_A; - else + else { + /* Workaround PCI9060 */ + byteout(cs->hw.diva.pci_cfg + 0x69, 9); cs->hw.diva.ctrl_reg |= DIVA_PCI_LED_A; + } byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); } restore_flags(flags); @@ -366,7 +796,7 @@ { int blink = 0; - if (cs->subtyp == DIVA_IPAC_ISA) + if ((cs->subtyp == DIVA_IPAC_ISA) || (cs->subtyp == DIVA_IPAC_PCI)) return; del_timer(&cs->hw.diva.tl); if (cs->hw.diva.status & DIVA_ASSIGN) @@ -399,7 +829,7 @@ static int Diva_card_msg(struct IsdnCardState *cs, int mt, void *arg) { - u_int irq_flag = I4L_IRQ_FLAG; + u_int *ireg; switch (mt) { case CARD_RESET: @@ -408,17 +838,11 @@ case CARD_RELEASE: release_io_diva(cs); return(0); - case CARD_SETIRQ: - if (cs->subtyp == DIVA_PCI) - irq_flag |= SA_SHIRQ; - if (cs->subtyp == DIVA_IPAC_ISA) { - return(request_irq(cs->irq, &diva_interrupt_ipac, - irq_flag, "HiSax", cs)); - } else { - return(request_irq(cs->irq, &diva_interrupt, - irq_flag, "HiSax", cs)); - } case CARD_INIT: + if (cs->subtyp == DIVA_IPAC_PCI) { + ireg = (unsigned int *)cs->hw.diva.pci_cfg; + *ireg = PITA_INT0_ENABLE; + } inithscxisac(cs, 3); return(0); case CARD_TEST: @@ -451,16 +875,21 @@ } break; } - if (cs->subtyp != DIVA_IPAC_ISA) + if ((cs->subtyp != DIVA_IPAC_ISA) && (cs->subtyp != DIVA_IPAC_PCI)) diva_led_handler(cs); return(0); } +#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *dev_diva __initdata = NULL; static struct pci_dev *dev_diva_u __initdata = NULL; +static struct pci_dev *dev_diva201 __initdata = NULL; +#else +static int pci_index __initdata = 0; +#endif -int __init -setup_diva(struct IsdnCard *card) +__initfunc(int +setup_diva(struct IsdnCard *card)) { int bytecnt; u_char val; @@ -478,7 +907,7 @@ val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR, cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID); printk(KERN_INFO "Diva: IPAC version %x\n", val); - if (val == 1) { + if ((val == 1) || (val==2)) { cs->subtyp = DIVA_IPAC_ISA; cs->hw.diva.ctrl = 0; cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA; @@ -498,6 +927,7 @@ bytecnt = 8; } else { #if CONFIG_PCI +#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_ERR "Diva: no PCI bus present\n"); return(0); @@ -506,20 +936,26 @@ cs->subtyp = 0; if ((dev_diva = pci_find_device(PCI_VENDOR_EICON_DIEHL, PCI_DIVA20_ID, dev_diva))) { - cs->subtyp = DIVA_PCI; - /* get IRQ */ + cs->subtyp = DIVA_PCI; cs->irq = dev_diva->irq; - /* get IO address */ - cs->hw.diva.cfg_reg = dev_diva->resource[2].start + cs->hw.diva.cfg_reg = get_pcibase(dev_diva, 2) & PCI_BASE_ADDRESS_IO_MASK; } else if ((dev_diva_u = pci_find_device(PCI_VENDOR_EICON_DIEHL, PCI_DIVA20_U_ID, dev_diva_u))) { - cs->subtyp = DIVA_PCI; - /* get IRQ */ + cs->subtyp = DIVA_PCI; cs->irq = dev_diva_u->irq; - /* get IO address */ - cs->hw.diva.cfg_reg = dev_diva_u->resource[2].start + cs->hw.diva.cfg_reg = get_pcibase(dev_diva_u, 2) & PCI_BASE_ADDRESS_IO_MASK; + } else if ((dev_diva201 = pci_find_device(PCI_VENDOR_EICON_DIEHL, + PCI_DIVA_201, dev_diva201))) { + cs->subtyp = DIVA_IPAC_PCI; + cs->irq = dev_diva201->irq; + cs->hw.diva.pci_cfg = + (ulong) ioremap((get_pcibase(dev_diva201, 0) + & PCI_BASE_ADDRESS_IO_MASK), 4096); + cs->hw.diva.cfg_reg = + (ulong) ioremap((get_pcibase(dev_diva201, 1) + & PCI_BASE_ADDRESS_IO_MASK), 4096); } else { printk(KERN_WARNING "Diva: No PCI card found\n"); return(0); @@ -534,35 +970,112 @@ printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); return(0); } - cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL; - cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA; - cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA; - cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR; - cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR; - bytecnt = 32; +#else + u_char pci_bus, pci_device_fn, pci_irq; + u_int pci_ioaddr; + + cs->subtyp = 0; + for (; pci_index < 0xff; pci_index++) { + if (pcibios_find_device(PCI_VENDOR_EICON_DIEHL, + PCI_DIVA20_ID, pci_index, &pci_bus, &pci_device_fn) + == PCIBIOS_SUCCESSFUL) + cs->subtyp = DIVA_PCI; + else if (pcibios_find_device(PCI_VENDOR_EICON_DIEHL, + PCI_DIVA20_U_ID, pci_index, &pci_bus, &pci_device_fn) + == PCIBIOS_SUCCESSFUL) + cs->subtyp = DIVA_PCI; + else if (pcibios_find_device(PCI_VENDOR_EICON_DIEHL, + PCI_DIVA_201, pci_index, &pci_bus, &pci_device_fn) + == PCIBIOS_SUCCESSFUL) + cs->subtyp = DIVA_IPAC_PCI; + else + break; + /* get IRQ */ + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_INTERRUPT_LINE, &pci_irq); + + /* get IO address */ + if (cs->subtyp == DIVA_IPAC_PCI) { + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_0, &pci_ioaddr); + cs->hw.diva.pci_cfg = (ulong) ioremap(pci_ioaddr, + 4096); + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_1, &pci_ioaddr); + cs->hw.diva.cfg_reg = (ulong) ioremap(pci_ioaddr, + 4096); + } else { + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_1, &pci_ioaddr); + cs->hw.diva.pci_cfg = pci_ioaddr & ~3; + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_2, &pci_ioaddr); + cs->hw.diva.cfg_reg = pci_ioaddr & ~3; + } + if (cs->subtyp) + break; + } + if (!cs->subtyp) { + printk(KERN_WARNING "Diva: No PCI card found\n"); + return(0); + } + pci_index++; + if (!pci_irq) { + printk(KERN_WARNING "Diva: No IRQ for PCI card found\n"); + return(0); + } + if (!pci_ioaddr) { + printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); + return(0); + } + cs->irq = pci_irq; +#endif /* COMPAT_HAS_NEW_PCI */ + cs->irq_flags |= SA_SHIRQ; #else printk(KERN_WARNING "Diva: cfgreg 0 and NO_PCI_BIOS\n"); printk(KERN_WARNING "Diva: unable to config DIVA PCI\n"); return (0); #endif /* CONFIG_PCI */ + if (cs->subtyp == DIVA_IPAC_PCI) { + cs->hw.diva.ctrl = 0; + cs->hw.diva.isac = 0; + cs->hw.diva.hscx = 0; + cs->hw.diva.isac_adr = 0; + cs->hw.diva.hscx_adr = 0; + test_and_set_bit(HW_IPAC, &cs->HW_Flags); + bytecnt = 0; + } else { + cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL; + cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA; + cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA; + cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR; + cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR; + bytecnt = 32; + } } printk(KERN_INFO - "Diva: %s card configured at 0x%x IRQ %d\n", + "Diva: %s card configured at %#lx IRQ %d\n", (cs->subtyp == DIVA_PCI) ? "PCI" : - (cs->subtyp == DIVA_ISA) ? "ISA" : "IPAC", + (cs->subtyp == DIVA_ISA) ? "ISA" : + (cs->subtyp == DIVA_IPAC_ISA) ? "IPAC ISA" : "IPAC PCI", cs->hw.diva.cfg_reg, cs->irq); - if (check_region(cs->hw.diva.cfg_reg, bytecnt)) { - printk(KERN_WARNING - "HiSax: %s config port %x-%x already in use\n", - CardType[card->typ], - cs->hw.diva.cfg_reg, - cs->hw.diva.cfg_reg + bytecnt); - return (0); - } else { - request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn"); + if ((cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_PCI)) + printk(KERN_INFO "Diva: %s PCI space at %#lx\n", + (cs->subtyp == DIVA_PCI) ? "PCI" : "IPAC PCI", + cs->hw.diva.pci_cfg); + if (cs->subtyp != DIVA_IPAC_PCI) { + if (check_region(cs->hw.diva.cfg_reg, bytecnt)) { + printk(KERN_WARNING + "HiSax: %s config port %lx-%lx already in use\n", + CardType[card->typ], + cs->hw.diva.cfg_reg, + cs->hw.diva.cfg_reg + bytecnt); + return (0); + } else { + request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn"); + } } - reset_diva(cs); cs->BC_Read_Reg = &ReadHSCX; cs->BC_Write_Reg = &WriteHSCX; @@ -573,9 +1086,21 @@ cs->writeisac = &WriteISAC_IPAC; cs->readisacfifo = &ReadISACfifo_IPAC; cs->writeisacfifo = &WriteISACfifo_IPAC; + cs->irq_func = &diva_irq_ipac_isa; val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ID); printk(KERN_INFO "Diva: IPAC version %x\n", val); - } else { + } else if (cs->subtyp == DIVA_IPAC_PCI) { + cs->readisac = &MemReadISAC_IPAC; + cs->writeisac = &MemWriteISAC_IPAC; + cs->readisacfifo = &MemReadISACfifo_IPAC; + cs->writeisacfifo = &MemWriteISACfifo_IPAC; + cs->BC_Read_Reg = &MemReadHSCX; + cs->BC_Write_Reg = &MemWriteHSCX; + cs->BC_Send_Data = &Memhscx_fill_fifo; + cs->irq_func = &diva_irq_ipac_pci; + val = memreadreg(cs->hw.diva.cfg_reg, IPAC_ID); + printk(KERN_INFO "Diva: IPAC version %x\n", val); + } else { /* DIVA 2.0 */ cs->hw.diva.tl.function = (void *) diva_led_handler; cs->hw.diva.tl.data = (long) cs; init_timer(&cs->hw.diva.tl); @@ -583,6 +1108,7 @@ cs->writeisac = &WriteISAC; cs->readisacfifo = &ReadISACfifo; cs->writeisacfifo = &WriteISACfifo; + cs->irq_func = &diva_interrupt; ISACVersion(cs, "Diva:"); if (HscxVersion(cs, "Diva:")) { printk(KERN_WARNING diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/elsa.c linux/drivers/isdn/hisax/elsa.c --- v2.3.13/linux/drivers/isdn/hisax/elsa.c Mon Aug 9 14:59:20 1999 +++ linux/drivers/isdn/hisax/elsa.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: elsa.c,v 2.12 1998/11/15 23:54:35 keil Exp $ +/* $Id: elsa.c,v 2.17 1999/08/11 20:57:40 keil Exp $ * elsa.c low level stuff for Elsa isdn cards * @@ -13,8 +13,26 @@ * Klaus Lichtenwalder (Klaus.Lichtenwalder@WebForum.DE) * for ELSA PCMCIA support * - * * $Log: elsa.c,v $ + * Revision 2.17 1999/08/11 20:57:40 keil + * bugfix IPAC version 1.1 + * new PCI codefix + * + * Revision 2.16 1999/08/10 16:01:51 calle + * struct pci_dev changed in 2.3.13. Made the necessary changes. + * + * Revision 2.15 1999/08/09 19:25:21 keil + * Support (alpha version) for the '98 model of ELSA Microlink ISDN/MC + * by Christer Weinigel, Cendio Systems AB + * Add support for IPAC 1.2 + * + * Revision 2.14 1999/07/12 21:05:07 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 2.13 1999/07/01 08:11:31 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 2.12 1998/11/15 23:54:35 keil * changes from 2.0 * @@ -70,16 +88,19 @@ #include "hscx.h" #include "isdnl1.h" #include - -//#define KDEBUG_DEF -//#include "../kdebug.h" +#ifndef COMPAT_HAS_NEW_PCI +#include +#endif +#include +#include extern const char *CardType[]; -static const char *Elsa_revision = "$Revision: 2.12 $"; +const char *Elsa_revision = "$Revision: 2.17 $"; const char *Elsa_Types[] = {"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro", - "PCMCIA", "QS 1000", "QS 3000", "QS 1000 PCI", "QS 3000 PCI"}; + "PCMCIA", "QS 1000", "QS 3000", "QS 1000 PCI", "QS 3000 PCI", + "PCMCIA-IPAC" }; const char *ITACVer[] = {"?0?", "?1?", "?2?", "?3?", "?4?", "V2.2", @@ -109,6 +130,7 @@ #define ELSA_QS3000 8 #define ELSA_QS1000PCI 9 #define ELSA_QS3000PCI 10 +#define ELSA_PCMCIA_IPAC 11 /* PCI stuff */ #define PCI_VENDOR_ELSA 0x1048 @@ -158,16 +180,26 @@ #define ELSA_IPAC_LINE_LED 0x40 /* Bit 6 Gelbe LED */ #define ELSA_IPAC_STAT_LED 0x80 /* Bit 7 Gruene LED */ -const u_char ARCOFI_VERSION[] = {2,0xa0,0}; -const u_char ARCOFI_COP_5[] = {4,0xa1,0x25,0xbb,0x4a}; /* GTX */ -const u_char ARCOFI_COP_6[] = {6,0xa1,0x26,0,0,0x82,0x7c}; /* GRL GRH */ -const u_char ARCOFI_COP_7[] = {4,0xa1,0x27,0x80,0x80}; /* GZ */ -const u_char ARCOFI_COP_8[] = {10,0xa1,0x28,0x49,0x31,0x8,0x13,0x6e,0x88,0x2a,0x61}; /* TX */ -const u_char ARCOFI_COP_9[] = {10,0xa1,0x29,0x80,0xcb,0xe9,0x88,0x00,0xc8,0xd8,0x80}; /* RX */ -const u_char ARCOFI_XOP_0[] = {2,0xa1,0x30}; /* PWR Down */ -const u_char ARCOFI_XOP_1[] = {2,0xa1,0x31}; /* PWR UP */ -const u_char ARCOFI_XOP_F[] = {2,0xa1,0x3f}; /* Normal OP */ -const u_char ARCOFI_SOP_F[] = {10,0xa1,0x1f,0x00,0x50,0x10,0x00,0x00,0x80,0x02,0x12}; +static struct arcofi_msg ARCOFI_XOP_F = + {NULL,0,2,{0xa1,0x3f,0,0,0,0,0,0,0,0}}; /* Normal OP */ +static struct arcofi_msg ARCOFI_XOP_1 = + {&ARCOFI_XOP_F,0,2,{0xa1,0x31,0,0,0,0,0,0,0,0}}; /* PWR UP */ +static struct arcofi_msg ARCOFI_SOP_F = + {&ARCOFI_XOP_1,0,10,{0xa1,0x1f,0x00,0x50,0x10,0x00,0x00,0x80,0x02,0x12}}; +static struct arcofi_msg ARCOFI_COP_9 = + {&ARCOFI_SOP_F,0,10,{0xa1,0x29,0x80,0xcb,0xe9,0x88,0x00,0xc8,0xd8,0x80}}; /* RX */ +static struct arcofi_msg ARCOFI_COP_8 = + {&ARCOFI_COP_9,0,10,{0xa1,0x28,0x49,0x31,0x8,0x13,0x6e,0x88,0x2a,0x61}}; /* TX */ +static struct arcofi_msg ARCOFI_COP_7 = + {&ARCOFI_COP_8,0,4,{0xa1,0x27,0x80,0x80,0,0,0,0,0,0}}; /* GZ */ +static struct arcofi_msg ARCOFI_COP_6 = + {&ARCOFI_COP_7,0,6,{0xa1,0x26,0,0,0x82,0x7c,0,0,0,0}}; /* GRL GRH */ +static struct arcofi_msg ARCOFI_COP_5 = + {&ARCOFI_COP_6,0,4,{0xa1,0x25,0xbb,0x4a,0,0,0,0,0,0}}; /* GTX */ +static struct arcofi_msg ARCOFI_VERSION = + {NULL,1,2,{0xa0,0,0,0,0,0,0,0,0,0}}; +static struct arcofi_msg ARCOFI_XOP_0 = + {NULL,0,2,{0xa1,0x30,0,0,0,0,0,0,0,0}}; /* PWR Down */ static void set_arcofi(struct IsdnCardState *cs, int bc); @@ -343,7 +375,7 @@ { struct IsdnCardState *cs = dev_id; u_char val; - int icnt=20; + int icnt=5; if (!cs) { printk(KERN_WARNING "Elsa: Spurious interrupt!\n"); @@ -420,15 +452,17 @@ { struct IsdnCardState *cs = dev_id; u_char ista,val; - int icnt=20; + int icnt=5; if (!cs) { printk(KERN_WARNING "Elsa: Spurious interrupt!\n"); return; } - val = bytein(cs->hw.elsa.cfg + 0x4c); /* PCI IRQ */ - if (!(val & ELSA_PCI_IRQ_MASK)) - return; + if (cs->subtyp == ELSA_QS1000PCI || cs->subtyp == ELSA_QS3000PCI) { + val = bytein(cs->hw.elsa.cfg + 0x4c); /* PCI IRQ */ + if (!(val & ELSA_PCI_IRQ_MASK)) + return; + } #if ARCOFI_USE if (cs->hw.elsa.MFlag) { val = serial_inp(cs, UART_IIR); @@ -480,6 +514,7 @@ int bytecnt = 8; del_timer(&cs->hw.elsa.tl); + clear_arcofi(cs); if (cs->hw.elsa.ctrl) byteout(cs->hw.elsa.ctrl, 0); /* LEDs Out */ if (cs->subtyp == ELSA_QS1000PCI) { @@ -493,6 +528,9 @@ writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ATX, 0xff); release_region(cs->hw.elsa.cfg, 0x80); } + if (cs->subtyp == ELSA_PCMCIA_IPAC) { + writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ATX, 0xff); + } if ((cs->subtyp == ELSA_PCFPRO) || (cs->subtyp == ELSA_QS3000) || (cs->subtyp == ELSA_PCF) || @@ -527,19 +565,25 @@ if (cs->hw.elsa.trig) byteout(cs->hw.elsa.trig, 0xff); } - if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI)) { + if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI) || (cs->subtyp == ELSA_PCMCIA_IPAC)) { save_flags(flags); sti(); writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_POTA2, 0x20); current->state = TASK_INTERRUPTIBLE; - schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ + schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_POTA2, 0x00); current->state = TASK_INTERRUPTIBLE; - schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_MASK, 0xc0); + schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ restore_flags(flags); - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ACFG, 0x0); - writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_AOE, 0x3c); + if (cs->subtyp != ELSA_PCMCIA_IPAC) { + writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ACFG, 0x0); + writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_AOE, 0x3c); + } else { + writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_PCFG, 0x10); + writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ACFG, 0x4); + writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_AOE, 0xf8); + } writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ATX, 0xff); if (cs->subtyp == ELSA_QS1000PCI) byteout(cs->hw.elsa.cfg + 0x4c, 0x41); /* enable ELSA PCI IRQ */ @@ -549,40 +593,10 @@ } static void -init_arcofi(struct IsdnCardState *cs) { - send_arcofi(cs, ARCOFI_XOP_0, 1, 0); -/* send_arcofi(cs, ARCOFI_XOP_F, 1); -*/ -} - -#define ARCDEL 500 - -static void set_arcofi(struct IsdnCardState *cs, int bc) { - long flags; - - debugl1(cs,"set_arcofi bc=%d", bc); - save_flags(flags); - sti(); - send_arcofi(cs, ARCOFI_XOP_0, bc, 0); - udelay(ARCDEL); - send_arcofi(cs, ARCOFI_COP_5, bc, 0); - udelay(ARCDEL); - send_arcofi(cs, ARCOFI_COP_6, bc, 0); - udelay(ARCDEL); - send_arcofi(cs, ARCOFI_COP_7, bc, 0); - udelay(ARCDEL); - send_arcofi(cs, ARCOFI_COP_8, bc, 0); - udelay(ARCDEL); - send_arcofi(cs, ARCOFI_COP_9, bc, 0); - udelay(ARCDEL); - send_arcofi(cs, ARCOFI_SOP_F, bc, 0); - udelay(ARCDEL); - send_arcofi(cs, ARCOFI_XOP_1, bc, 0); - udelay(ARCDEL); - send_arcofi(cs, ARCOFI_XOP_F, bc, 0); - restore_flags(flags); - debugl1(cs,"end set_arcofi bc=%d", bc); + cs->dc.isac.arcofi_bc = bc; + arcofi_fsm(cs, ARCOFI_START, &ARCOFI_COP_5); + interruptible_sleep_on(&cs->dc.isac.arcofi_wait); } static int @@ -594,23 +608,24 @@ char *t; u_char *p; - if (!cs->mon_tx) - if (!(cs->mon_tx=kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) { + if (!cs->dc.isac.mon_tx) + if (!(cs->dc.isac.mon_tx=kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "ISAC MON TX out of buffers!"); return(0); } - send_arcofi(cs, ARCOFI_VERSION, 0, 1); - if (test_and_clear_bit(HW_MON1_TX_END, &cs->HW_Flags)) { - if (test_and_clear_bit(HW_MON1_RX_END, &cs->HW_Flags)) { - debugl1(cs, "Arcofi response received %d bytes", cs->mon_rxp); - p = cs->mon_rx; + cs->dc.isac.arcofi_bc = 0; + arcofi_fsm(cs, ARCOFI_START, &ARCOFI_VERSION); + interruptible_sleep_on(&cs->dc.isac.arcofi_wait); + if (!test_and_clear_bit(FLG_ARCOFI_ERROR, &cs->HW_Flags)) { + debugl1(cs, "Arcofi response received %d bytes", cs->dc.isac.mon_rxp); + p = cs->dc.isac.mon_rx; t = tmp; t += sprintf(tmp, "Arcofi data"); - QuickHex(t, p, cs->mon_rxp); + QuickHex(t, p, cs->dc.isac.mon_rxp); debugl1(cs, tmp); - if ((cs->mon_rxp == 2) && (cs->mon_rx[0] == 0xa0)) { - switch(cs->mon_rx[1]) { + if ((cs->dc.isac.mon_rxp == 2) && (cs->dc.isac.mon_rx[0] == 0xa0)) { + switch(cs->dc.isac.mon_rx[1]) { case 0x80: debugl1(cs, "Arcofi 2160 detected"); arcofi_present = 1; @@ -629,9 +644,8 @@ } } else debugl1(cs, "undefined Monitor response"); - cs->mon_rxp = 0; - } - } else if (cs->mon_tx) { + cs->dc.isac.mon_rxp = 0; + } else if (cs->dc.isac.mon_tx) { debugl1(cs, "Arcofi not detected"); } if (arcofi_present) { @@ -672,7 +686,8 @@ "Elsa: %s detected modem at 0x%x\n", Elsa_Types[cs->subtyp], cs->hw.elsa.base+8); - init_arcofi(cs); + arcofi_fsm(cs, ARCOFI_START, &ARCOFI_XOP_0); + interruptible_sleep_on(&cs->dc.isac.arcofi_wait); return(1); } #endif @@ -684,7 +699,7 @@ { int blink = 0; - if (cs->subtyp == ELSA_PCMCIA) + if (cs->subtyp == ELSA_PCMCIA || cs->subtyp == ELSA_PCMCIA_IPAC) return; del_timer(&cs->hw.elsa.tl); if (cs->hw.elsa.status & ELSA_ASSIGN) @@ -734,15 +749,6 @@ case CARD_RELEASE: release_io_elsa(cs); return(0); - case CARD_SETIRQ: - if ((cs->subtyp == ELSA_QS1000PCI) || - (cs->subtyp == ELSA_QS3000PCI)) - ret = request_irq(cs->irq, &elsa_interrupt_ipac, - I4L_IRQ_FLAG | SA_SHIRQ, "HiSax", cs); - else - ret = request_irq(cs->irq, &elsa_interrupt, - I4L_IRQ_FLAG, "HiSax", cs); - return(ret); case CARD_INIT: cs->debug |= L1_DEB_IPAC; inithscxisac(cs, 1); @@ -757,6 +763,7 @@ return(0); case CARD_TEST: if ((cs->subtyp == ELSA_PCMCIA) || + (cs->subtyp == ELSA_PCMCIA_IPAC) || (cs->subtyp == ELSA_QS1000PCI)) { return(0); } else if (cs->subtyp == ELSA_QS3000PCI) { @@ -770,7 +777,6 @@ byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg); byteout(cs->hw.elsa.timer, 0); current->state = TASK_INTERRUPTIBLE; - /* Timeout 110ms */ schedule_timeout((110*HZ)/1000); restore_flags(flags); cs->hw.elsa.ctrl_reg &= ~ELSA_ENA_TIMER_INT; @@ -908,8 +914,12 @@ return (CARD_portlist[i]); } +#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *dev_qs1000 __initdata = NULL; static struct pci_dev *dev_qs3000 __initdata = NULL; +#else +static int pci_index __initdata = 0; +#endif int setup_elsa(struct IsdnCard *card) @@ -1004,10 +1014,19 @@ } else if (cs->typ == ISDN_CTYPE_ELSA_PCMCIA) { cs->hw.elsa.base = card->para[1]; cs->irq = card->para[0]; - cs->subtyp = ELSA_PCMCIA; - cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE_PCM; - cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC_PCM; - cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; + val = readreg(cs->hw.elsa.base + 0, cs->hw.elsa.base + 2, IPAC_ID); + if ((val == 1) || (val == 2)) { /* IPAC version 1.1/1.2 */ + cs->subtyp = ELSA_PCMCIA_IPAC; + cs->hw.elsa.ale = cs->hw.elsa.base + 0; + cs->hw.elsa.isac = cs->hw.elsa.base + 2; + cs->hw.elsa.hscx = cs->hw.elsa.base + 2; + test_and_set_bit(HW_IPAC, &cs->HW_Flags); + } else { + cs->subtyp = ELSA_PCMCIA; + cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE_PCM; + cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC_PCM; + cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; + } cs->hw.elsa.timer = 0; cs->hw.elsa.trig = 0; cs->hw.elsa.ctrl = 0; @@ -1018,6 +1037,7 @@ cs->irq); } else if (cs->typ == ISDN_CTYPE_ELSA_PCI) { #if CONFIG_PCI +#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_ERR "Elsa: no PCI bus present\n"); return(0); @@ -1027,17 +1047,17 @@ dev_qs1000))) { cs->subtyp = ELSA_QS1000PCI; cs->irq = dev_qs1000->irq; - cs->hw.elsa.cfg = dev_qs1000->resource[1].start & + cs->hw.elsa.cfg = get_pcibase(dev_qs1000, 1) & PCI_BASE_ADDRESS_IO_MASK; - cs->hw.elsa.base = dev_qs1000->resource[3].start & + cs->hw.elsa.base = get_pcibase(dev_qs1000, 3) & PCI_BASE_ADDRESS_IO_MASK; } else if ((dev_qs3000 = pci_find_device(PCI_VENDOR_ELSA, PCI_QS3000_ID, dev_qs3000))) { cs->subtyp = ELSA_QS3000PCI; cs->irq = dev_qs3000->irq; - cs->hw.elsa.cfg = dev_qs3000->resource[1].start & + cs->hw.elsa.cfg = get_pcibase(dev_qs3000, 1) & PCI_BASE_ADDRESS_IO_MASK; - cs->hw.elsa.base = dev_qs3000->resource[3].start & + cs->hw.elsa.base = get_pcibase(dev_qs3000, 3) & PCI_BASE_ADDRESS_IO_MASK; } else { printk(KERN_WARNING "Elsa: No PCI card found\n"); @@ -1052,18 +1072,6 @@ printk(KERN_WARNING "Elsa: No IO-Adr for PCI card found\n"); return(0); } - cs->hw.elsa.ale = cs->hw.elsa.base; - cs->hw.elsa.isac = cs->hw.elsa.base +1; - cs->hw.elsa.hscx = cs->hw.elsa.base +1; - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - cs->hw.elsa.timer = 0; - cs->hw.elsa.trig = 0; - printk(KERN_INFO - "Elsa: %s defined at 0x%x/0x%x IRQ %d\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base, - cs->hw.elsa.cfg, - cs->irq); if ((cs->hw.elsa.cfg & 0xff) || (cs->hw.elsa.base & 0xf)) { printk(KERN_WARNING "Elsa: You may have a wrong PCI bios\n"); printk(KERN_WARNING "Elsa: If your system hangs now, read\n"); @@ -1075,6 +1083,67 @@ restore_flags(flags); } #else + u_char pci_bus, pci_device_fn, pci_irq; + u_int pci_ioaddr; + + cs->subtyp = 0; + for (; pci_index < 0xff; pci_index++) { + if (pcibios_find_device(PCI_VENDOR_ELSA, + PCI_QS1000_ID, pci_index, &pci_bus, &pci_device_fn) + == PCIBIOS_SUCCESSFUL) + cs->subtyp = ELSA_QS1000PCI; + else if (pcibios_find_device(PCI_VENDOR_ELSA, + PCI_QS3000_ID, pci_index, &pci_bus, &pci_device_fn) + == PCIBIOS_SUCCESSFUL) + cs->subtyp = ELSA_QS3000PCI; + else + break; + /* get IRQ */ + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_INTERRUPT_LINE, &pci_irq); + + /* get IO address */ + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_1, &pci_ioaddr); + pci_ioaddr &= ~3; /* remove io/mem flag */ + cs->hw.elsa.cfg = pci_ioaddr; + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_3, &pci_ioaddr); + if (cs->subtyp) + break; + } + if (!cs->subtyp) { + printk(KERN_WARNING "Elsa: No PCI card found\n"); + return(0); + } + pci_index++; + if (!pci_irq) { + printk(KERN_WARNING "Elsa: No IRQ for PCI card found\n"); + return(0); + } + + if (!pci_ioaddr) { + printk(KERN_WARNING "Elsa: No IO-Adr for PCI card found\n"); + return(0); + } + pci_ioaddr &= ~3; /* remove io/mem flag */ + cs->hw.elsa.base = pci_ioaddr; + cs->irq = pci_irq; +#endif /* COMPAT_HAS_NEW_PCI */ + cs->hw.elsa.ale = cs->hw.elsa.base; + cs->hw.elsa.isac = cs->hw.elsa.base +1; + cs->hw.elsa.hscx = cs->hw.elsa.base +1; + test_and_set_bit(HW_IPAC, &cs->HW_Flags); + cs->hw.elsa.timer = 0; + cs->hw.elsa.trig = 0; + cs->irq_flags |= SA_SHIRQ; + printk(KERN_INFO + "Elsa: %s defined at 0x%x/0x%x IRQ %d\n", + Elsa_Types[cs->subtyp], + cs->hw.elsa.base, + cs->hw.elsa.cfg, + cs->irq); +#else printk(KERN_WARNING "Elsa: Elsa PCI and NO_PCI_BIOS\n"); printk(KERN_WARNING "Elsa: unable to config Elsa PCI\n"); return (0); @@ -1088,6 +1157,7 @@ case ELSA_PCC16: case ELSA_QS1000: case ELSA_PCMCIA: + case ELSA_PCMCIA_IPAC: bytecnt = 8; break; case ELSA_PCFPRO: @@ -1129,6 +1199,7 @@ request_region(cs->hw.elsa.cfg, 0x80, "elsa isdn pci"); } } + init_arcofi(cs); cs->hw.elsa.tl.function = (void *) elsa_led_handler; cs->hw.elsa.tl.data = (long) cs; init_timer(&cs->hw.elsa.tl); @@ -1161,11 +1232,12 @@ cs->BC_Send_Data = &hscx_fill_fifo; cs->cardmsg = &Elsa_card_msg; reset_elsa(cs); - if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI)) { + if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI) || (cs->subtyp == ELSA_PCMCIA_IPAC)) { cs->readisac = &ReadISAC_IPAC; cs->writeisac = &WriteISAC_IPAC; cs->readisacfifo = &ReadISACfifo_IPAC; cs->writeisacfifo = &WriteISACfifo_IPAC; + cs->irq_func = &elsa_interrupt_ipac; val = readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ID); printk(KERN_INFO "Elsa: IPAC version %x\n", val); } else { @@ -1173,6 +1245,7 @@ cs->writeisac = &WriteISAC; cs->readisacfifo = &ReadISACfifo; cs->writeisacfifo = &WriteISACfifo; + cs->irq_func = &elsa_interrupt; ISACVersion(cs, "Elsa:"); if (HscxVersion(cs, "Elsa:")) { printk(KERN_WARNING diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/elsa_ser.c linux/drivers/isdn/hisax/elsa_ser.c --- v2.3.13/linux/drivers/isdn/hisax/elsa_ser.c Tue Jun 1 23:25:48 1999 +++ linux/drivers/isdn/hisax/elsa_ser.c Sun Aug 15 11:49:08 1999 @@ -298,7 +298,7 @@ (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count); - dev_kfree_skb(bcs->tx_skb); + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); bcs->tx_skb = NULL; } } @@ -510,13 +510,13 @@ bcs->hw.hscx.rcvbuf = NULL; } while ((skb = skb_dequeue(&bcs->rqueue))) { - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); } while ((skb = skb_dequeue(&bcs->squeue))) { - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_WRITE); } if (bcs->tx_skb) { - dev_kfree_skb(bcs->tx_skb); + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); } @@ -664,7 +664,9 @@ st->l1.bcs->cs->hw.elsa.MFlag=2; } else if (pr == (PH_DEACTIVATE | REQUEST)) { test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); - send_arcofi(st->l1.bcs->cs, ARCOFI_XOP_0, st->l1.bc, 0); + st->l1.bcs->cs->dc.isac.arcofi_bc = st->l1.bc; + arcofi_fsm(st->l1.bcs->cs, ARCOFI_START, &ARCOFI_XOP_0); + interruptible_sleep_on(&st->l1.bcs->cs->dc.isac.arcofi_wait); st->l1.bcs->cs->hw.elsa.MFlag=1; } else { printk(KERN_WARNING"ElsaSer: unknown pr %x\n", pr); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/gazel.c linux/drivers/isdn/hisax/gazel.c --- v2.3.13/linux/drivers/isdn/hisax/gazel.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/hisax/gazel.c Sun Aug 15 11:49:08 1999 @@ -0,0 +1,752 @@ +/* $Id: gazel.c,v 2.5 1999/08/11 21:01:26 keil Exp $ + + * gazel.c low level stuff for Gazel isdn cards + * + * Author BeWan Systems + * based on source code from Karsten Keil + * + * $Log: gazel.c,v $ + * Revision 2.5 1999/08/11 21:01:26 keil + * new PCI codefix + * + * Revision 2.4 1999/08/10 16:01:54 calle + * struct pci_dev changed in 2.3.13. Made the necessary changes. + * + * Revision 2.3 1999/07/12 21:05:09 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 2.1 1999/07/08 21:26:17 keil + * new card + * + * Revision 1.0 1999/28/06 + * Initial revision + * + */ +#include +#define __NO_VERSION__ +#include "hisax.h" +#include "isac.h" +#include "hscx.h" +#include "isdnl1.h" +#include "ipac.h" +#include +#ifndef COMPAT_HAS_NEW_PCI +#include +#endif + +extern const char *CardType[]; +const char *gazel_revision = "$Revision: 2.5 $"; + +#define R647 1 +#define R685 2 +#define R753 3 +#define R742 4 + +/* Gazel R685 stuff */ +#define GAZEL_MANUFACTURER 0x10b5 +#define GAZEL_R685 0x1030 +#define GAZEL_R753 0x1152 +#define GAZEL_DJINN_ITOO 0x1151 + +#define PLX_CNTRL 0x50 /* registre de controle PLX */ +#define RESET_GAZEL 0x4 +#define RESET_9050 0x40000000 +#define PLX_INCSR 0x4C /* registre d'IT du 9050 */ +#define INT_ISAC_EN 0x8 /* 1 = enable IT isac */ +#define INT_ISAC 0x20 /* 1 = IT isac en cours */ +#define INT_HSCX_EN 0x1 /* 1 = enable IT hscx */ +#define INT_HSCX 0x4 /* 1 = IT hscx en cours */ +#define INT_PCI_EN 0x40 /* 1 = enable IT PCI */ +#define INT_IPAC_EN 0x3 /* enable IT ipac */ + + +#define byteout(addr,val) outb(val,addr) +#define bytein(addr) inb(addr) + +static inline u_char +readreg(unsigned int adr, u_short off) +{ + return bytein(adr + off); +} + +static inline void +writereg(unsigned int adr, u_short off, u_char data) +{ + byteout(adr + off, data); +} + + +static inline void +read_fifo(unsigned int adr, u_char * data, int size) +{ + insb(adr, data, size); +} + +static void +write_fifo(unsigned int adr, u_char * data, int size) +{ + outsb(adr, data, size); +} + +static inline u_char +readreg_ipac(unsigned int adr, u_short off) +{ + register u_char ret; + long flags; + + save_flags(flags); + cli(); + byteout(adr, off); + ret = bytein(adr + 4); + restore_flags(flags); + return ret; +} + +static inline void +writereg_ipac(unsigned int adr, u_short off, u_char data) +{ + long flags; + + save_flags(flags); + cli(); + byteout(adr, off); + byteout(adr + 4, data); + restore_flags(flags); +} + + +static inline void +read_fifo_ipac(unsigned int adr, u_short off, u_char * data, int size) +{ + byteout(adr, off); + insb(adr + 4, data, size); +} + +static void +write_fifo_ipac(unsigned int adr, u_short off, u_char * data, int size) +{ + byteout(adr, off); + outsb(adr + 4, data, size); +} + +/* Interface functions */ + +static u_char +ReadISAC(struct IsdnCardState *cs, u_char offset) +{ + u_short off2 = offset; + + switch (cs->subtyp) { + case R647: + off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf)); + case R685: + return (readreg(cs->hw.gazel.isac, off2)); + case R753: + case R742: + return (readreg_ipac(cs->hw.gazel.ipac, 0x80 + off2)); + } + return 0; +} + +static void +WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) +{ + u_short off2 = offset; + + switch (cs->subtyp) { + case R647: + off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf)); + case R685: + writereg(cs->hw.gazel.isac, off2, value); + break; + case R753: + case R742: + writereg_ipac(cs->hw.gazel.ipac, 0x80 + off2, value); + break; + } +} + +static void +ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size) +{ + switch (cs->subtyp) { + case R647: + case R685: + read_fifo(cs->hw.gazel.isacfifo, data, size); + break; + case R753: + case R742: + read_fifo_ipac(cs->hw.gazel.ipac, 0x80, data, size); + break; + } +} + +static void +WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size) +{ + switch (cs->subtyp) { + case R647: + case R685: + write_fifo(cs->hw.gazel.isacfifo, data, size); + break; + case R753: + case R742: + write_fifo_ipac(cs->hw.gazel.ipac, 0x80, data, size); + break; + } +} + +static void +ReadHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size) +{ + switch (cs->subtyp) { + case R647: + case R685: + read_fifo(cs->hw.gazel.hscxfifo[hscx], data, size); + break; + case R753: + case R742: + read_fifo_ipac(cs->hw.gazel.ipac, hscx * 0x40, data, size); + break; + } +} + +static void +WriteHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size) +{ + switch (cs->subtyp) { + case R647: + case R685: + write_fifo(cs->hw.gazel.hscxfifo[hscx], data, size); + break; + case R753: + case R742: + write_fifo_ipac(cs->hw.gazel.ipac, hscx * 0x40, data, size); + break; + } +} + +static u_char +ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) +{ + u_short off2 = offset; + + switch (cs->subtyp) { + case R647: + off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf)); + case R685: + return (readreg(cs->hw.gazel.hscx[hscx], off2)); + case R753: + case R742: + return (readreg_ipac(cs->hw.gazel.ipac, hscx * 0x40 + off2)); + } + return 0; +} + +static void +WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) +{ + u_short off2 = offset; + + switch (cs->subtyp) { + case R647: + off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf)); + case R685: + writereg(cs->hw.gazel.hscx[hscx], off2, value); + break; + case R753: + case R742: + writereg_ipac(cs->hw.gazel.ipac, hscx * 0x40 + off2, value); + break; + } +} + +/* + * fast interrupt HSCX stuff goes here + */ + +#define READHSCX(cs, nr, reg) ReadHSCX(cs, nr, reg) +#define WRITEHSCX(cs, nr, reg, data) WriteHSCX(cs, nr, reg, data) +#define READHSCXFIFO(cs, nr, ptr, cnt) ReadHSCXfifo(cs, nr, ptr, cnt) +#define WRITEHSCXFIFO(cs, nr, ptr, cnt) WriteHSCXfifo(cs, nr, ptr, cnt) + +#include "hscx_irq.c" + +static void +gazel_interrupt(int intno, void *dev_id, struct pt_regs *regs) +{ +#define MAXCOUNT 5 + struct IsdnCardState *cs = dev_id; + u_char valisac, valhscx; + int count = 0; + + if (!cs) { + printk(KERN_WARNING "Gazel: Spurious interrupt!\n"); + return; + } + do { + valhscx = ReadHSCX(cs, 1, HSCX_ISTA); + if (valhscx) + hscx_int_main(cs, valhscx); + valisac = ReadISAC(cs, ISAC_ISTA); + if (valisac) + isac_interrupt(cs, valisac); + count++; + } while ((valhscx || valisac) && (count < MAXCOUNT)); + + WriteHSCX(cs, 0, HSCX_MASK, 0xFF); + WriteHSCX(cs, 1, HSCX_MASK, 0xFF); + WriteISAC(cs, ISAC_MASK, 0xFF); + WriteISAC(cs, ISAC_MASK, 0x0); + WriteHSCX(cs, 0, HSCX_MASK, 0x0); + WriteHSCX(cs, 1, HSCX_MASK, 0x0); +} + + +static void +gazel_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs) +{ + struct IsdnCardState *cs = dev_id; + u_char ista, val; + int count = 0; + + if (!cs) { + printk(KERN_WARNING "Gazel: Spurious interrupt!\n"); + return; + } + ista = ReadISAC(cs, IPAC_ISTA - 0x80); + do { + if (ista & 0x0f) { + val = ReadHSCX(cs, 1, HSCX_ISTA); + if (ista & 0x01) + val |= 0x01; + if (ista & 0x04) + val |= 0x02; + if (ista & 0x08) + val |= 0x04; + if (val) { + hscx_int_main(cs, val); + } + } + if (ista & 0x20) { + val = 0xfe & ReadISAC(cs, ISAC_ISTA); + if (val) { + isac_interrupt(cs, val); + } + } + if (ista & 0x10) { + val = 0x01; + isac_interrupt(cs, val); + } + ista = ReadISAC(cs, IPAC_ISTA - 0x80); + count++; + } + while ((ista & 0x3f) && (count < MAXCOUNT)); + + WriteISAC(cs, IPAC_MASK - 0x80, 0xFF); + WriteISAC(cs, IPAC_MASK - 0x80, 0xC0); +} +void +release_io_gazel(struct IsdnCardState *cs) +{ + unsigned int i; + + switch (cs->subtyp) { + case R647: + for (i = 0x0000; i < 0xC000; i += 0x1000) + release_region(i + cs->hw.gazel.hscx[0], 16); + release_region(0xC000 + cs->hw.gazel.hscx[0], 1); + break; + + case R685: + release_region(cs->hw.gazel.hscx[0], 0x100); + release_region(cs->hw.gazel.cfg_reg, 0x80); + break; + + case R753: + release_region(cs->hw.gazel.ipac, 0x8); + release_region(cs->hw.gazel.cfg_reg, 0x80); + break; + + case R742: + release_region(cs->hw.gazel.ipac, 8); + break; + } +} + +static int +reset_gazel(struct IsdnCardState *cs) +{ + long flags; + unsigned long plxcntrl, addr = cs->hw.gazel.cfg_reg; + + switch (cs->subtyp) { + case R647: + save_flags(flags); + cli(); + writereg(addr, 0, 0); + HZDELAY(10); + writereg(addr, 0, 1); + HZDELAY(2); + restore_flags(flags); + break; + case R685: + plxcntrl = inl(addr + PLX_CNTRL); + plxcntrl |= (RESET_9050 + RESET_GAZEL); + outl(plxcntrl, addr + PLX_CNTRL); + plxcntrl &= ~(RESET_9050 + RESET_GAZEL); + HZDELAY(4); + outl(plxcntrl, addr + PLX_CNTRL); + HZDELAY(10); + outb(INT_ISAC_EN + INT_HSCX_EN + INT_PCI_EN, addr + PLX_INCSR); + break; + case R753: + plxcntrl = inl(addr + PLX_CNTRL); + plxcntrl |= (RESET_9050 + RESET_GAZEL); + outl(plxcntrl, addr + PLX_CNTRL); + plxcntrl &= ~(RESET_9050 + RESET_GAZEL); + WriteISAC(cs, IPAC_POTA2 - 0x80, 0x20); + HZDELAY(4); + outl(plxcntrl, addr + PLX_CNTRL); + HZDELAY(10); + WriteISAC(cs, IPAC_POTA2 - 0x80, 0x00); + WriteISAC(cs, IPAC_ACFG - 0x80, 0xff); + WriteISAC(cs, IPAC_AOE - 0x80, 0x0); + WriteISAC(cs, IPAC_MASK - 0x80, 0xff); + WriteISAC(cs, IPAC_CONF - 0x80, 0x1); + outb(INT_IPAC_EN + INT_PCI_EN, addr + PLX_INCSR); + WriteISAC(cs, IPAC_MASK - 0x80, 0xc0); + break; + case R742: + WriteISAC(cs, IPAC_POTA2 - 0x80, 0x20); + HZDELAY(4); + WriteISAC(cs, IPAC_POTA2 - 0x80, 0x00); + WriteISAC(cs, IPAC_ACFG - 0x80, 0xff); + WriteISAC(cs, IPAC_AOE - 0x80, 0x0); + WriteISAC(cs, IPAC_MASK - 0x80, 0xff); + WriteISAC(cs, IPAC_CONF - 0x80, 0x1); + WriteISAC(cs, IPAC_MASK - 0x80, 0xc0); + break; + } + return (0); +} + +static int +Gazel_card_msg(struct IsdnCardState *cs, int mt, void *arg) +{ + switch (mt) { + case CARD_RESET: + reset_gazel(cs); + return (0); + case CARD_RELEASE: + release_io_gazel(cs); + return (0); + case CARD_INIT: + inithscxisac(cs, 1); + if ((cs->subtyp==R647)||(cs->subtyp==R685)) { + int i; + for (i=0;i<(2+MAX_WAITING_CALLS);i++) { + cs->bcs[i].hw.hscx.tsaxr0 = 0x1f; + cs->bcs[i].hw.hscx.tsaxr1 = 0x23; + } + } + return (0); + case CARD_TEST: + return (0); + } + return (0); +} + +static int +reserve_regions(struct IsdnCard *card, struct IsdnCardState *cs) +{ + unsigned int i, base = 0, adr = 0, len = 0; + long flags; + + save_flags(flags); + cli(); + + switch (cs->subtyp) { + case R647: + base = cs->hw.gazel.hscx[0]; + for (i = 0x0000; i < 0xC000; i += 0x1000) { + if (check_region(adr = (i + base), len = 16)) + goto error; + } + if (check_region(adr = (0xC000 + base), len = 1)) + goto error; + + for (i = 0x0000; i < 0xC000; i += 0x1000) + request_region(i + base, 16, "gazel"); + request_region(0xC000 + base, 1, "gazel"); + + break; + + case R685: + if (check_region(adr = cs->hw.gazel.hscx[0], len = 0x100)) + goto error; + if (check_region(adr = cs->hw.gazel.cfg_reg, len = 0x80)) + goto error; + + request_region(cs->hw.gazel.hscx[0], 0x100, "gazel"); + request_region(cs->hw.gazel.cfg_reg, 0x80, "gazel"); + break; + + case R753: + if (check_region(adr = cs->hw.gazel.ipac, len = 0x8)) + goto error; + if (check_region(adr = cs->hw.gazel.cfg_reg, len = 0x80)) + goto error; + + request_region(cs->hw.gazel.ipac, 0x8, "gazel"); + request_region(cs->hw.gazel.cfg_reg, 0x80, "gazel"); + break; + + case R742: + if (check_region(adr = cs->hw.gazel.ipac, len = 0x8)) + goto error; + request_region(cs->hw.gazel.ipac, 0x8, "gazel"); + break; + } + + restore_flags(flags); + return 0; + + error: + restore_flags(flags); + printk(KERN_WARNING "Gazel: %s io ports 0x%x-0x%x already in use\n", + CardType[cs->typ], adr, adr + len); + return 1; +} + +static int +setup_gazelisa(struct IsdnCard *card, struct IsdnCardState *cs) +{ + printk(KERN_INFO "Gazel: ISA PnP card automatic recognition\n"); + // we got an irq parameter, assume it is an ISA card + // R742 decodes address even in not started... + // R647 returns FF if not present or not started + // eventually needs improvment + if (readreg_ipac(card->para[1], IPAC_ID) == 1) + cs->subtyp = R742; + else + cs->subtyp = R647; + + cs->hw.gazel.cfg_reg = card->para[1] + 0xC000; + cs->hw.gazel.ipac = card->para[1]; + cs->hw.gazel.isac = card->para[1] + 0x8000; + cs->hw.gazel.hscx[0] = card->para[1]; + cs->hw.gazel.hscx[1] = card->para[1] + 0x4000; + cs->irq = card->para[0]; + cs->hw.gazel.isacfifo = cs->hw.gazel.isac; + cs->hw.gazel.hscxfifo[0] = cs->hw.gazel.hscx[0]; + cs->hw.gazel.hscxfifo[1] = cs->hw.gazel.hscx[1]; + + switch (cs->subtyp) { + case R647: + printk(KERN_INFO "Gazel: Card ISA R647/R648 found\n"); + cs->dc.isac.adf2 = 0x87; + printk(KERN_INFO + "Gazel: config irq:%d isac:0x%X cfg:0x%X\n", + cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg); + printk(KERN_INFO + "Gazel: hscx A:0x%X hscx B:0x%X\n", + cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]); + + break; + case R742: + printk(KERN_INFO "Gazel: Card ISA R742 found\n"); + test_and_set_bit(HW_IPAC, &cs->HW_Flags); + printk(KERN_INFO + "Gazel: config irq:%d ipac:0x%X\n", + cs->irq, cs->hw.gazel.ipac); + break; + } + + return (0); +} + +#ifdef COMPAT_HAS_NEW_PCI +static struct pci_dev *dev_tel __initdata = NULL; +#else +static int pci_index __initdata = 0; +#endif + +static int +setup_gazelpci(struct IsdnCardState *cs) +{ + u_int pci_ioaddr0 = 0, pci_ioaddr1 = 0; + u_char pci_irq = 0, found; + u_int nbseek, seekcard; + + printk(KERN_WARNING "Gazel: PCI card automatic recognition\n"); + + found = 0; +#ifdef COMPAT_HAS_NEW_PCI + if (!pci_present()) { + printk(KERN_WARNING "Gazel: No PCI bus present\n"); + return 1; + } +#endif + seekcard = GAZEL_R685; + for (nbseek = 0; nbseek < 3; nbseek++) { +#ifdef COMPAT_HAS_NEW_PCI + if ((dev_tel = pci_find_device(GAZEL_MANUFACTURER, seekcard, dev_tel))) { + + pci_irq = dev_tel->irq; + pci_ioaddr0 = get_pcibase(dev_tel, 1); + pci_ioaddr1 = get_pcibase(dev_tel, 2); + found = 1; + } +#else + for (; pci_index < 0xff; pci_index++) { + u_char pci_bus, pci_device_fn; + + if (pcibios_find_device(GAZEL_MANUFACTURER, seekcard, + pci_index, &pci_bus, &pci_device_fn) + != PCIBIOS_SUCCESSFUL) + break; + /* get IRQ */ + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_INTERRUPT_LINE, &pci_irq); + /* get IO address */ + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_1, &pci_ioaddr0); + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_2, &pci_ioaddr1); + found = 1; + break; + } +#endif /* COMPAT_HAS_NEW_PCI */ + if (found) + break; + else { + switch (seekcard) { + case GAZEL_R685: + seekcard = GAZEL_R753; + break; + case GAZEL_R753: + seekcard = GAZEL_DJINN_ITOO; + break; + } +#ifndef COMPAT_HAS_NEW_PCI + pci_index = 0; +#endif + } + } + if (!found) { + printk(KERN_WARNING "Gazel: No PCI card found\n"); + return (1); + } + if (!pci_irq) { + printk(KERN_WARNING "Gazel: No IRQ for PCI card found\n"); + return 1; + } + cs->hw.gazel.pciaddr[0] = pci_ioaddr0; + cs->hw.gazel.pciaddr[1] = pci_ioaddr1; + + pci_ioaddr1 &= 0xfffe; + cs->hw.gazel.cfg_reg = pci_ioaddr0 & 0xfffe; + cs->hw.gazel.ipac = pci_ioaddr1; + cs->hw.gazel.isac = pci_ioaddr1 + 0x80; + cs->hw.gazel.hscx[0] = pci_ioaddr1; + cs->hw.gazel.hscx[1] = pci_ioaddr1 + 0x40; + cs->hw.gazel.isacfifo = cs->hw.gazel.isac; + cs->hw.gazel.hscxfifo[0] = cs->hw.gazel.hscx[0]; + cs->hw.gazel.hscxfifo[1] = cs->hw.gazel.hscx[1]; + cs->irq = pci_irq; + cs->irq_flags |= SA_SHIRQ; + + switch (seekcard) { + case GAZEL_R685: + printk(KERN_INFO "Gazel: Card PCI R685 found\n"); + cs->subtyp = R685; + cs->dc.isac.adf2 = 0x87; + printk(KERN_INFO + "Gazel: config irq:%d isac:0x%X cfg:0x%X\n", + cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg); + printk(KERN_INFO + "Gazel: hscx A:0x%X hscx B:0x%X\n", + cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]); + break; + case GAZEL_R753: + case GAZEL_DJINN_ITOO: + printk(KERN_INFO "Gazel: Card PCI R753 found\n"); + cs->subtyp = R753; + test_and_set_bit(HW_IPAC, &cs->HW_Flags); + printk(KERN_INFO + "Gazel: config irq:%d ipac:0x%X cfg:0x%X\n", + cs->irq, cs->hw.gazel.ipac, cs->hw.gazel.cfg_reg); + break; + } + + return (0); +} + +__initfunc(int + setup_gazel(struct IsdnCard *card)) +{ + struct IsdnCardState *cs = card->cs; + char tmp[64]; + u_char val; + + strcpy(tmp, gazel_revision); + printk(KERN_INFO "Gazel: Driver Revision %s\n", HiSax_getrev(tmp)); + + if (cs->typ != ISDN_CTYPE_GAZEL) + return (0); + + if (card->para[0]) { + if (setup_gazelisa(card, cs)) + return (0); + } else { + +#if CONFIG_PCI + if (setup_gazelpci(cs)) + return (0); +#else + printk(KERN_WARNING "Gazel: Card PCI requested and NO_PCI_BIOS, unable to config\n"); + return (0); +#endif /* CONFIG_PCI */ + } + + if (reserve_regions(card, cs)) { + return (0); + } + if (reset_gazel(cs)) { + printk(KERN_WARNING "Gazel: wrong IRQ\n"); + release_io_gazel(cs); + return (0); + } + cs->readisac = &ReadISAC; + cs->writeisac = &WriteISAC; + cs->readisacfifo = &ReadISACfifo; + cs->writeisacfifo = &WriteISACfifo; + cs->BC_Read_Reg = &ReadHSCX; + cs->BC_Write_Reg = &WriteHSCX; + cs->BC_Send_Data = &hscx_fill_fifo; + cs->cardmsg = &Gazel_card_msg; + + switch (cs->subtyp) { + case R647: + case R685: + cs->irq_func = &gazel_interrupt; + ISACVersion(cs, "Gazel:"); + if (HscxVersion(cs, "Gazel:")) { + printk(KERN_WARNING + "Gazel: wrong HSCX versions check IO address\n"); + release_io_gazel(cs); + return (0); + } + break; + case R742: + case R753: + cs->irq_func = &gazel_interrupt_ipac; + val = ReadISAC(cs, IPAC_ID - 0x80); + printk(KERN_INFO "Gazel: IPAC version %x\n", val); + break; + } + + return (1); +} diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/hfc_2bds0.c linux/drivers/isdn/hisax/hfc_2bds0.c --- v2.3.13/linux/drivers/isdn/hisax/hfc_2bds0.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/isdn/hisax/hfc_2bds0.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: hfc_2bds0.c,v 1.8 1998/11/15 23:54:40 keil Exp $ +/* $Id: hfc_2bds0.c,v 1.9 1999/07/01 08:11:35 keil Exp $ * * specific routines for CCD's HFC 2BDS0 * @@ -6,6 +6,9 @@ * * * $Log: hfc_2bds0.c,v $ + * Revision 1.9 1999/07/01 08:11:35 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.8 1998/11/15 23:54:40 keil * changes from 2.0 * @@ -264,6 +267,7 @@ } else if (!(skb = dev_alloc_skb(count - 3))) printk(KERN_WARNING "HFC: receive out of memory\n"); else { + SET_SKB_FREE(skb); ptr = skb_put(skb, count - 3); idx = 0; cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel); @@ -281,7 +285,7 @@ sti(); debugl1(cs, "RFIFO BUSY error"); printk(KERN_WARNING "HFC FIFO channel %d BUSY Error\n", bcs->channel); - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); skb = NULL; } else { cli(); @@ -297,7 +301,7 @@ bcs->channel, chksum, stat); if (stat) { debugl1(cs, "FIFO CRC error"); - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); skb = NULL; } } @@ -386,7 +390,7 @@ if (bcs->st->lli.l1writewakeup && (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->tx_skb->len); - dev_kfree_skb(bcs->tx_skb); + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); bcs->tx_skb = NULL; } WaitForBusy(cs); @@ -588,7 +592,7 @@ discard_queue(&bcs->rqueue); discard_queue(&bcs->squeue); if (bcs->tx_skb) { - dev_kfree_skb(bcs->tx_skb); + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); } @@ -642,7 +646,7 @@ } #endif if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) { - switch (cs->ph_state) { + switch (cs->dc.hfcd.ph_state) { case (0): l1_msg(cs, HW_RESET | INDICATION, NULL); break; @@ -733,6 +737,7 @@ while ((idx++ < rcnt) && WaitNoBusy(cs)) ReadReg(cs, HFCD_DATA_NODEB, cip); } else if ((skb = dev_alloc_skb(rcnt - 3))) { + SET_SKB_FREE(skb); ptr = skb_put(skb, rcnt - 3); while (idx < (rcnt - 3)) { cli(); @@ -747,7 +752,7 @@ sti(); debugl1(cs, "RFIFO D BUSY error"); printk(KERN_WARNING "HFC DFIFO channel BUSY Error\n"); - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); skb = NULL; } else { cli(); @@ -763,7 +768,7 @@ chksum, stat); if (stat) { debugl1(cs, "FIFO CRC error"); - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); skb = NULL; } else { skb_queue_tail(&cs->rq, skb); @@ -860,7 +865,7 @@ cli(); WaitNoBusy(cs); ReadReg(cs, HFCD_DATA, HFCD_FIFO | HFCD_F1_INC | HFCD_SEND); - dev_kfree_skb(cs->tx_skb); + idev_kfree_skb(cs->tx_skb, FREE_WRITE); cs->tx_skb = NULL; sti(); WaitForBusy(cs); @@ -895,9 +900,9 @@ if (val & 0x40) { /* TE state machine irq */ exval = cs->readisac(cs, HFCD_STATES) & 0xf; if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ph_state chg %d->%d", cs->ph_state, + debugl1(cs, "ph_state chg %d->%d", cs->dc.hfcd.ph_state, exval); - cs->ph_state = exval; + cs->dc.hfcd.ph_state = exval; sched_event_D(cs, D_L1STATECHANGE); val &= ~0x40; } @@ -984,7 +989,7 @@ del_timer(&cs->dbusytimer); if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) sched_event_D(cs, D_CLEARBUSY); - if (cs->tx_skb) + if (cs->tx_skb) { if (cs->tx_skb->len) { if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { hfc_fill_dfifo(cs); @@ -994,10 +999,11 @@ } goto afterXPR; } else { - dev_kfree_skb(cs->tx_skb); + idev_kfree_skb(cs->tx_skb, FREE_WRITE); cs->tx_cnt = 0; cs->tx_skb = NULL; } + } if ((cs->tx_skb = skb_dequeue(&cs->sq))) { cs->tx_cnt = 0; if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { @@ -1166,8 +1172,8 @@ #endif } -unsigned int __init -*init_send_hfcd(int cnt) +__initfunc(unsigned int +*init_send_hfcd(int cnt)) { int i, *send; @@ -1181,8 +1187,8 @@ return(send); } -void __init -init2bds0(struct IsdnCardState *cs) +__initfunc(void +init2bds0(struct IsdnCardState *cs)) { cs->setstack_d = setstack_hfcd; cs->dbusytimer.function = (void *) hfc_dbusy_timer; diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/hfc_2bs0.c linux/drivers/isdn/hisax/hfc_2bs0.c --- v2.3.13/linux/drivers/isdn/hisax/hfc_2bs0.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/isdn/hisax/hfc_2bs0.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: hfc_2bs0.c,v 1.8 1998/11/15 23:54:43 keil Exp $ +/* $Id: hfc_2bs0.c,v 1.9 1999/07/01 08:11:36 keil Exp $ * specific routines for CCD's HFC 2BS0 * @@ -6,6 +6,9 @@ * * * $Log: hfc_2bs0.c,v $ + * Revision 1.9 1999/07/01 08:11:36 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.8 1998/11/15 23:54:43 keil * changes from 2.0 * @@ -219,6 +222,7 @@ if (!(skb = dev_alloc_skb(count - 3))) printk(KERN_WARNING "HFC: receive out of memory\n"); else { + SET_SKB_FREE(skb); ptr = skb_put(skb, count - 3); idx = 0; cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel); @@ -229,7 +233,7 @@ if (idx != count - 3) { debugl1(cs, "RFIFO BUSY error"); printk(KERN_WARNING "HFC FIFO channel %d BUSY Error\n", bcs->channel); - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); WaitNoBusy(cs); stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC | HFC_CHANNEL(bcs->channel)); @@ -247,7 +251,7 @@ bcs->channel, chksum, stat); if (stat) { debugl1(cs, "FIFO CRC error"); - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); skb = NULL; } WaitNoBusy(cs); @@ -321,7 +325,7 @@ bcs->tx_cnt -= count; if (PACKET_NOACK == bcs->tx_skb->pkt_type) count = -1; - dev_kfree_skb(bcs->tx_skb); + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); bcs->tx_skb = NULL; WaitForBusy(cs); WaitNoBusy(cs); @@ -519,7 +523,7 @@ discard_queue(&bcs->rqueue); discard_queue(&bcs->squeue); if (bcs->tx_skb) { - dev_kfree_skb(bcs->tx_skb); + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); } @@ -555,8 +559,8 @@ return (0); } -void __init -init_send(struct BCState *bcs) +__initfunc(void +init_send(struct BCState *bcs)) { int i; @@ -569,8 +573,8 @@ bcs->hw.hfc.send[i] = 0x1fff; } -void __init -inithfc(struct IsdnCardState *cs) +__initfunc(void +inithfc(struct IsdnCardState *cs)) { init_send(&cs->bcs[0]); init_send(&cs->bcs[1]); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/hfc_pci.c linux/drivers/isdn/hisax/hfc_pci.c --- v2.3.13/linux/drivers/isdn/hisax/hfc_pci.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/hisax/hfc_pci.c Sun Aug 15 11:49:08 1999 @@ -0,0 +1,1585 @@ +/* $Id: hfc_pci.c,v 1.13 1999/08/11 21:01:28 keil Exp $ + + * hfc_pci.c low level driver for CCDŽs hfc-pci based cards + * + * Author Werner Cornelius (werner@isdn4linux.de) + * based on existing driver for CCD hfc ISA cards + * + * Copyright 1999 by Werner Cornelius (werner@isdn4linux.de) + * Copyright 1999 by Karsten Keil (keil@isdn4linux.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Log: hfc_pci.c,v $ + * Revision 1.13 1999/08/11 21:01:28 keil + * new PCI codefix + * + * Revision 1.12 1999/08/10 16:01:58 calle + * struct pci_dev changed in 2.3.13. Made the necessary changes. + * + * Revision 1.11 1999/08/09 19:13:32 werner + * moved constant pci ids to pci id table + * + * Revision 1.10 1999/08/08 10:17:34 werner + * added new PCI vendor and card ids for Manufacturer 0x1043 + * + * Revision 1.9 1999/08/07 21:09:10 werner + * Fixed another memcpy problem in fifo handling. + * Thanks for debugging aid by Olaf Kordwittenborg. + * + * Revision 1.8 1999/07/23 14:25:15 werner + * Some smaller bug fixes and prepared support for GCI/IOM bus + * + * Revision 1.7 1999/07/14 21:24:20 werner + * fixed memcpy problem when using E-channel feature + * + * Revision 1.6 1999/07/13 21:08:08 werner + * added echo channel logging feature. + * + * Revision 1.5 1999/07/12 21:05:10 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 1.4 1999/07/04 21:51:39 werner + * Changes to solve problems with irq sharing and smp machines + * Thanks to Karsten Keil and Alex Holden for giving aid with + * testing and debugging + * + * Revision 1.3 1999/07/01 09:43:19 keil + * removed additional schedules in timeouts + * + * Revision 1.2 1999/07/01 08:07:51 keil + * Initial version + * + * + * + */ + +#include +#define __NO_VERSION__ +#include "hisax.h" +#include "hfc_pci.h" +#include "isdnl1.h" +#include +#ifndef COMPAT_HAS_NEW_PCI +#include +#endif +#include + +extern const char *CardType[]; + +static const char *hfcpci_revision = "$Revision: 1.13 $"; + +static const int CCD_VENDOR_IDS[] = { + 0x1043, /* Asuscom */ + 0x1051, /* Motorola MC145575 */ + 0x1397, /* CCD and Billion */ + 0, +}; + +static const int CCD_DEVICE_IDS[] = { + 0x675, /* Asuscom */ + 0x100, /* Motorola MC145575 */ + 0x2BD0, /* CCD and Billion */ + 0, +}; + + +#if CONFIG_PCI +/*****************************/ +/* release D- and B-channels */ +/*****************************/ +void +releasehfcpci(struct IsdnCardState *cs) +{ + if (cs->bcs[0].hw.hfc.send) { + kfree(cs->bcs[0].hw.hfc.send); + cs->bcs[0].hw.hfc.send = NULL; + } + if (cs->bcs[1].hw.hfc.send) { + kfree(cs->bcs[1].hw.hfc.send); + cs->bcs[1].hw.hfc.send = NULL; + } +} + +/******************************************/ +/* free hardware resources used by driver */ +/******************************************/ +void +release_io_hfcpci(struct IsdnCardState *cs) +{ +#if CONFIG_PCI + pcibios_write_config_word(cs->hw.hfcpci.pci_bus, cs->hw.hfcpci.pci_device_fn, PCI_COMMAND, 0); /* disabe memory mapped ports + busmaster */ +#endif /* CONFIG_PCI */ + releasehfcpci(cs); + del_timer(&cs->hw.hfcpci.timer); + kfree(cs->hw.hfcpci.share_start); + cs->hw.hfcpci.share_start = NULL; + vfree(cs->hw.hfcpci.pci_io); +} + +/********************************************************************************/ +/* function called to reset the HFC PCI chip. A complete software reset of chip */ +/* and fifos is done. */ +/********************************************************************************/ +static void +reset_hfcpci(struct IsdnCardState *cs) +{ + long flags; + + pcibios_write_config_word(cs->hw.hfcpci.pci_bus, cs->hw.hfcpci.pci_device_fn, PCI_COMMAND, PCI_ENA_MEMIO); /* enable memory mapped ports, disable busmaster */ + printk(KERN_INFO "HFC_PCI: resetting card\n"); + pcibios_write_config_word(cs->hw.hfcpci.pci_bus, cs->hw.hfcpci.pci_device_fn, PCI_COMMAND, PCI_ENA_MEMIO + PCI_ENA_MASTER); /* enable memory ports + busmaster */ + Write_hfc(cs, HFCPCI_CIRM, HFCPCI_RESET); /* Reset On */ + save_flags(flags); + sti(); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((30 * HZ) / 1000); /* Timeout 30ms */ + Write_hfc(cs, HFCPCI_CIRM, 0); /* Reset Off */ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((20 * HZ) / 1000); /* Timeout 20ms */ + if (Read_hfc(cs, HFCPCI_STATUS) & 2) + printk(KERN_WARNING "HFC-PCI init bit busy\n"); + + cs->hw.hfcpci.fifo_en = 0x30; /* only D fifos enabled */ + Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); + + cs->hw.hfcpci.trm = 0; /* no echo connect */ + Write_hfc(cs, HFCPCI_TRM, cs->hw.hfcpci.trm); + + Write_hfc(cs, HFCPCI_CLKDEL, 0x0e); /* ST-Bit delay for TE-Mode */ + cs->hw.hfcpci.sctrl_e = HFCPCI_AUTO_AWAKE; + Write_hfc(cs, HFCPCI_SCTRL_E, cs->hw.hfcpci.sctrl_e); /* S/T Auto awake */ + cs->hw.hfcpci.bswapped = 0; /* no exchange */ + cs->hw.hfcpci.ctmt = HFCPCI_TIM3_125 | HFCPCI_AUTO_TIMER; + Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt); + + cs->hw.hfcpci.int_m2 = HFCPCI_IRQ_ENABLE; + cs->hw.hfcpci.int_m1 = HFCPCI_INTS_DTRANS | HFCPCI_INTS_DREC | + HFCPCI_INTS_L1STATE | HFCPCI_CLTIMER; + Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); + Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); + + /* Clear already pending ints */ + if (Read_hfc(cs, HFCPCI_INT_S1)); + if (Read_hfc(cs, HFCPCI_INT_S2)); + + Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 2); /* HFC ST 2 */ + udelay(10); + Write_hfc(cs, HFCPCI_STATES, 2); /* HFC ST 2 */ + cs->hw.hfcpci.mst_m = HFCPCI_MASTER; /* HFC Master Mode */ + + Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); + cs->hw.hfcpci.sctrl = 0; + Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl); + cs->hw.hfcpci.sctrl_r = 0; + Write_hfc(cs, HFCPCI_SCTRL_R, cs->hw.hfcpci.sctrl_r); + + /* Init GCI/IOM2 in master mode */ + /* Slots 0 and 1 are set for B-chan 1 and 2 */ + /* D- and monitor/CI channel are not enabled */ + /* STIO1 is used as output for data, B1+B2 from ST->IOM+HFC */ + /* STIO2 is used as data input, B1+B2 from IOM->ST */ + /* ST B-channel send disabled -> continous 1s */ + /* The IOM slots are always enabled */ + cs->hw.hfcpci.conn = 0x36; /* set data flow directions */ + Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); + Write_hfc(cs, HFCPCI_B1_SSL, 0x80); /* B1-Slot 0 STIO1 out enabled */ + Write_hfc(cs, HFCPCI_B2_SSL, 0x81); /* B2-Slot 1 STIO1 out enabled */ + Write_hfc(cs, HFCPCI_B1_RSL, 0x80); /* B1-Slot 0 STIO2 in enabled */ + Write_hfc(cs, HFCPCI_B2_RSL, 0x81); /* B2-Slot 1 STIO2 in enabled */ + restore_flags(flags); +} + +/***************************************************/ +/* Timer function called when kernel timer expires */ +/***************************************************/ +static void +hfcpci_Timer(struct IsdnCardState *cs) +{ + cs->hw.hfcpci.timer.expires = jiffies + 75; + /* WD RESET */ +/* WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcpci.ctmt | 0x80); + add_timer(&cs->hw.hfcpci.timer); + */ +} + + +/*********************************/ +/* schedule a new D-channel task */ +/*********************************/ +static void +sched_event_D_pci(struct IsdnCardState *cs, int event) +{ + test_and_set_bit(event, &cs->event); + queue_task(&cs->tqueue, &tq_immediate); + mark_bh(IMMEDIATE_BH); +} + +/*********************************/ +/* schedule a new b_channel task */ +/*********************************/ +static void +hfcpci_sched_event(struct BCState *bcs, int event) +{ + bcs->event |= 1 << event; + queue_task(&bcs->tqueue, &tq_immediate); + mark_bh(IMMEDIATE_BH); +} + +/************************************************/ +/* select a b-channel entry matching and active */ +/************************************************/ +static +struct BCState * +Sel_BCS(struct IsdnCardState *cs, int channel) +{ + if (cs->bcs[0].mode && (cs->bcs[0].channel == channel)) + return (&cs->bcs[0]); + else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel)) + return (&cs->bcs[1]); + else + return (NULL); +} + +/*********************************************/ +/* read a complete B-frame out of the buffer */ +/*********************************************/ +static struct sk_buff +* +hfcpci_empty_fifo(struct BCState *bcs, bzfifo_type * bz, u_char * bdata, int count) +{ + u_char *ptr, *ptr1, new_f2; + struct sk_buff *skb; + struct IsdnCardState *cs = bcs->cs; + int flags, total, maxlen, new_z2; + z_type *zp; + + save_flags(flags); + sti(); + if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) + debugl1(cs, "hfcpci_empty_fifo"); + zp = &bz->za[bz->f2]; /* point to Z-Regs */ + new_z2 = zp->z2 + count; /* new position in fifo */ + if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) + new_z2 -= B_FIFO_SIZE; /* buffer wrap */ + new_f2 = (bz->f2 + 1) & MAX_B_FRAMES; + if ((count > HSCX_BUFMAX + 3) || (count < 4) || + (*(bdata + (zp->z1 - B_SUB_VAL)))) { + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "hfcpci_empty_fifo: incoming packet invalid length %d or crc", count); + bz->za[new_f2].z2 = new_z2; + bz->f2 = new_f2; /* next buffer */ + skb = NULL; + } else if (!(skb = dev_alloc_skb(count - 3))) + printk(KERN_WARNING "HFCPCI: receive out of memory\n"); + else { + SET_SKB_FREE(skb); + total = count; + count -= 3; + ptr = skb_put(skb, count); + + if (zp->z2 + count <= B_FIFO_SIZE + B_SUB_VAL) + maxlen = count; /* complete transfer */ + else + maxlen = B_FIFO_SIZE + B_SUB_VAL - zp->z2; /* maximum */ + + ptr1 = bdata + (zp->z2 - B_SUB_VAL); /* start of data */ + memcpy(ptr, ptr1, maxlen); /* copy data */ + count -= maxlen; + + if (count) { /* rest remaining */ + ptr += maxlen; + ptr1 = bdata; /* start of buffer */ + memcpy(ptr, ptr1, count); /* rest */ + } + bz->za[new_f2].z2 = new_z2; + bz->f2 = new_f2; /* next buffer */ + + } + restore_flags(flags); + return (skb); +} + +/*******************************/ +/* D-channel receive procedure */ +/*******************************/ +static +int +receive_dmsg(struct IsdnCardState *cs) +{ + struct sk_buff *skb; + int maxlen; + int rcnt, total; + int count = 5; + u_char *ptr, *ptr1; + dfifo_type *df; + z_type *zp; + + df = &((fifo_area *) (cs->hw.hfcpci.fifos))->d_chan.d_rx; + if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { + debugl1(cs, "rec_dmsg blocked"); + return (1); + } + while (((df->f1 & D_FREG_MASK) != (df->f2 & D_FREG_MASK)) && count--) { + zp = &df->za[df->f2 & D_FREG_MASK]; + rcnt = zp->z1 - zp->z2; + if (rcnt < 0) + rcnt += D_FIFO_SIZE; + rcnt++; + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "hfcpci recd f1(%d) f2(%d) z1(%x) z2(%x) cnt(%d)", + df->f1, df->f2, zp->z1, zp->z2, rcnt); + + if ((rcnt > MAX_DFRAME_LEN + 3) || (rcnt < 4) || + (df->data[zp->z1])) { + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "empty_fifo hfcpci paket inv. len %d or crc %d", rcnt, df->data[zp->z1]); + df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) | (MAX_D_FRAMES + 1); /* next buffer */ + df->za[df->f2 & D_FREG_MASK].z2 = (zp->z2 + rcnt) & (D_FIFO_SIZE - 1); + } else if ((skb = dev_alloc_skb(rcnt - 3))) { + SET_SKB_FREE(skb); + total = rcnt; + rcnt -= 3; + ptr = skb_put(skb, rcnt); + + if (zp->z2 + rcnt <= D_FIFO_SIZE) + maxlen = rcnt; /* complete transfer */ + else + maxlen = D_FIFO_SIZE - zp->z2; /* maximum */ + + ptr1 = df->data + zp->z2; /* start of data */ + memcpy(ptr, ptr1, maxlen); /* copy data */ + rcnt -= maxlen; + + if (rcnt) { /* rest remaining */ + ptr += maxlen; + ptr1 = df->data; /* start of buffer */ + memcpy(ptr, ptr1, rcnt); /* rest */ + } + df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) | (MAX_D_FRAMES + 1); /* next buffer */ + df->za[df->f2 & D_FREG_MASK].z2 = (zp->z2 + total) & (D_FIFO_SIZE - 1); + + skb_queue_tail(&cs->rq, skb); + sched_event_D_pci(cs, D_RCVBUFREADY); + } else + printk(KERN_WARNING "HFC-PCI: D receive out of memory\n"); + } + test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); + return (1); +} + +/**********************************/ +/* B-channel main receive routine */ +/**********************************/ +void +main_rec_hfcpci(struct BCState *bcs) +{ + long flags; + struct IsdnCardState *cs = bcs->cs; + int rcnt; + int receive, count = 5; + struct sk_buff *skb; + bzfifo_type *bz; + u_char *bdata; + z_type *zp; + + + save_flags(flags); + if ((bcs->channel) && (!cs->hw.hfcpci.bswapped)) { + bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2; + bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxdat_b2; + } else { + bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b1; + bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxdat_b1; + } + Begin: + count--; + cli(); + if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { + debugl1(cs, "rec_data %d blocked", bcs->channel); + restore_flags(flags); + return; + } + sti(); + if (bz->f1 != bz->f2) { + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "hfcpci rec %d f1(%d) f2(%d)", + bcs->channel, bz->f1, bz->f2); + zp = &bz->za[bz->f2]; + + rcnt = zp->z1 - zp->z2; + if (rcnt < 0) + rcnt += B_FIFO_SIZE; + rcnt++; + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "hfcpci rec %d z1(%x) z2(%x) cnt(%d)", + bcs->channel, zp->z1, zp->z2, rcnt); + if ((skb = hfcpci_empty_fifo(bcs, bz, bdata, rcnt))) { + cli(); + skb_queue_tail(&bcs->rqueue, skb); + sti(); + hfcpci_sched_event(bcs, B_RCVBUFREADY); + } + rcnt = bz->f1 - bz->f2; + if (rcnt < 0) + rcnt += MAX_B_FRAMES + 1; + if (rcnt > 1) + receive = 1; + else + receive = 0; + } else + receive = 0; + test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); + if (count && receive) + goto Begin; + restore_flags(flags); + return; +} + +/**************************/ +/* D-channel send routine */ +/**************************/ +static void +hfcpci_fill_dfifo(struct IsdnCardState *cs) +{ + long flags; + int fcnt; + int count, new_z1, maxlen; + dfifo_type *df; + u_char *src, *dst, new_f1; + + if (!cs->tx_skb) + return; + if (cs->tx_skb->len <= 0) + return; + + df = &((fifo_area *) (cs->hw.hfcpci.fifos))->d_chan.d_tx; + + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "hfcpci_fill_Dfifo f1(%d) f2(%d) z1(f1)(%x)", + df->f1, df->f2, + df->za[df->f1 & D_FREG_MASK].z1); + fcnt = df->f1 - df->f2; /* frame count actually buffered */ + if (fcnt < 0) + fcnt += (MAX_D_FRAMES + 1); /* if wrap around */ + if (fcnt > (MAX_D_FRAMES - 1)) { + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "hfcpci_fill_Dfifo more as 14 frames"); + return; + } + /* now determine free bytes in FIFO buffer */ + count = df->za[df->f1 & D_FREG_MASK].z2 - df->za[df->f1 & D_FREG_MASK].z1; + if (count <= 0) + count += D_FIFO_SIZE; /* count now contains available bytes */ + + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "hfcpci_fill_Dfifo count(%ld/%d)", + cs->tx_skb->len, count); + if (count < cs->tx_skb->len) { + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "hfcpci_fill_Dfifo no fifo mem"); + return; + } + count = cs->tx_skb->len; /* get frame len */ + new_z1 = (df->za[df->f1 & D_FREG_MASK].z1 + count) & (D_FIFO_SIZE - 1); + new_f1 = ((df->f1 + 1) & D_FREG_MASK) | (D_FREG_MASK + 1); + src = cs->tx_skb->data; /* source pointer */ + dst = df->data + df->za[df->f1 & D_FREG_MASK].z1; + maxlen = D_FIFO_SIZE - df->za[df->f1 & D_FREG_MASK].z1; /* end fifo */ + if (maxlen > count) + maxlen = count; /* limit size */ + memcpy(dst, src, maxlen); /* first copy */ + + count -= maxlen; /* remaining bytes */ + if (count) { + dst = df->data; /* start of buffer */ + src += maxlen; /* new position */ + memcpy(dst, src, count); + } + save_flags(flags); + cli(); + df->za[new_f1 & D_FREG_MASK].z1 = new_z1; /* for next buffer */ + df->za[df->f1 & D_FREG_MASK].z1 = new_z1; /* new pos actual buffer */ + df->f1 = new_f1; /* next frame */ + restore_flags(flags); + + idev_kfree_skb(cs->tx_skb, FREE_WRITE); + cs->tx_skb = NULL; + return; +} + +/**************************/ +/* B-channel send routine */ +/**************************/ +static void +hfcpci_fill_fifo(struct BCState *bcs) +{ + struct IsdnCardState *cs = bcs->cs; + int flags, maxlen, fcnt; + int count, new_z1; + bzfifo_type *bz; + u_char *bdata; + u_char new_f1, *src, *dst; + + if (!bcs->tx_skb) + return; + if (bcs->tx_skb->len <= 0) + return; + + save_flags(flags); + sti(); + + if ((bcs->channel) && (!cs->hw.hfcpci.bswapped)) { + bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b2; + bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txdat_b2; + } else { + bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b1; + bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txdat_b1; + } + + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "hfcpci_fill_fifo %d f1(%d) f2(%d) z1(f1)(%x)", + bcs->channel, bz->f1, bz->f2, + bz->za[bz->f1].z1); + + fcnt = bz->f1 - bz->f2; /* frame count actually buffered */ + if (fcnt < 0) + fcnt += (MAX_B_FRAMES + 1); /* if wrap around */ + if (fcnt > (MAX_B_FRAMES - 1)) { + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "hfcpci_fill_Bfifo more as 14 frames"); + restore_flags(flags); + return; + } + /* now determine free bytes in FIFO buffer */ + count = bz->za[bz->f1].z2 - bz->za[bz->f1].z1; + if (count <= 0) + count += B_FIFO_SIZE; /* count now contains available bytes */ + + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "hfcpci_fill_fifo %d count(%ld/%d),%lx", + bcs->channel, bcs->tx_skb->len, + count, current->state); + + if (count < bcs->tx_skb->len) { + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "hfcpci_fill_fifo no fifo mem"); + restore_flags(flags); + return; + } + count = bcs->tx_skb->len; /* get frame len */ + new_z1 = bz->za[bz->f1].z1 + count; /* new buffer Position */ + if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL)) + new_z1 -= B_FIFO_SIZE; /* buffer wrap */ + + new_f1 = ((bz->f1 + 1) & MAX_B_FRAMES); + src = bcs->tx_skb->data; /* source pointer */ + dst = bdata + (bz->za[bz->f1].z1 - B_SUB_VAL); + maxlen = (B_FIFO_SIZE + B_SUB_VAL) - bz->za[bz->f1].z1; /* end fifo */ + if (maxlen > count) + maxlen = count; /* limit size */ + memcpy(dst, src, maxlen); /* first copy */ + + count -= maxlen; /* remaining bytes */ + if (count) { + dst = bdata; /* start of buffer */ + src += maxlen; /* new position */ + memcpy(dst, src, count); + } + bcs->tx_cnt -= bcs->tx_skb->len; + if (bcs->st->lli.l1writewakeup && + (PACKET_NOACK != bcs->tx_skb->pkt_type)) + bcs->st->lli.l1writewakeup(bcs->st, bcs->tx_skb->len); + + cli(); + bz->za[new_f1].z1 = new_z1; /* for next buffer */ + bz->f1 = new_f1; /* next frame */ + restore_flags(flags); + + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + bcs->tx_skb = NULL; + test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); + return; +} + +/***********************/ +/* set/reset echo mode */ +/***********************/ +int hfcpci_set_echo(struct IsdnCardState *cs, int i) +{ int flags; + + if (cs->chanlimit > 1) + return(-EINVAL); + + save_flags(flags); + cli(); + if (i) { + cs->logecho = 1; + cs->hw.hfcpci.trm |= 0x20; /* enable echo chan */ + cs->hw.hfcpci.int_m1 |= HFCPCI_INTS_B2REC; + cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2RX; + } + else { + cs->logecho = 0; + cs->hw.hfcpci.trm &= ~0x20; /* enable echo chan */ + cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_B2REC; + cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2RX; + } + cs->hw.hfcpci.sctrl_r &= ~SCTRL_B2_ENA; + cs->hw.hfcpci.sctrl &= ~SCTRL_B2_ENA; + cs->hw.hfcpci.conn |= 0x10; /* B2-IOM -> B2-ST */ + cs->hw.hfcpci.ctmt &= ~2; + Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt); + Write_hfc(cs, HFCPCI_SCTRL_R, cs->hw.hfcpci.sctrl_r); + Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl); + Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); + Write_hfc(cs, HFCPCI_TRM, cs->hw.hfcpci.trm); + Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); + Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); + restore_flags(flags); + return(0); +} /* hfcpci_set_echo */ + +/*****************************/ +/* E-channel receive routine */ +/*****************************/ +static void receive_emsg(struct IsdnCardState *cs) +{ + long flags; + int rcnt; + int receive, count = 5; + bzfifo_type *bz; + u_char *bdata; + z_type *zp; + u_char *ptr, *ptr1, new_f2; + int total, maxlen, new_z2; + u_char e_buffer[256]; + + save_flags(flags); + bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2; + bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxdat_b2; + Begin: + count--; + cli(); + if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { + debugl1(cs, "echo_rec_data blocked"); + restore_flags(flags); + return; + } + sti(); + if (bz->f1 != bz->f2) { + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "hfcpci e_rec f1(%d) f2(%d)", + bz->f1, bz->f2); + zp = &bz->za[bz->f2]; + + rcnt = zp->z1 - zp->z2; + if (rcnt < 0) + rcnt += B_FIFO_SIZE; + rcnt++; + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "hfcpci e_rec z1(%x) z2(%x) cnt(%d)", + zp->z1, zp->z2, rcnt); + new_z2 = zp->z2 + rcnt; /* new position in fifo */ + if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) + new_z2 -= B_FIFO_SIZE; /* buffer wrap */ + new_f2 = (bz->f2 + 1) & MAX_B_FRAMES; + if ((rcnt > 256 + 3) || (count < 4) || + (*(bdata + (zp->z1 - B_SUB_VAL)))) { + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "hfcpci_empty_echan: incoming packet invalid length %d or crc", rcnt); + bz->za[new_f2].z2 = new_z2; + bz->f2 = new_f2; /* next buffer */ + } else { + total = rcnt; + rcnt -= 3; + ptr = e_buffer; + + if (zp->z2 <= B_FIFO_SIZE + B_SUB_VAL) + maxlen = rcnt; /* complete transfer */ + else + maxlen = B_FIFO_SIZE + B_SUB_VAL - zp->z2; /* maximum */ + + ptr1 = bdata + (zp->z2 - B_SUB_VAL); /* start of data */ + memcpy(ptr, ptr1, maxlen); /* copy data */ + rcnt -= maxlen; + + if (rcnt) { /* rest remaining */ + ptr += maxlen; + ptr1 = bdata; /* start of buffer */ + memcpy(ptr, ptr1, rcnt); /* rest */ + } + bz->za[new_f2].z2 = new_z2; + bz->f2 = new_f2; /* next buffer */ + if (cs->debug & DEB_DLOG_HEX) { + ptr = cs->dlog; + if ((total - 3) < MAX_DLOG_SPACE / 3 - 10) { + *ptr++ = 'E'; + *ptr++ = 'C'; + *ptr++ = 'H'; + *ptr++ = 'O'; + *ptr++ = ':'; + ptr += QuickHex(ptr, e_buffer, total - 3); + ptr--; + *ptr++ = '\n'; + *ptr = 0; + HiSax_putstatus(cs, NULL, cs->dlog); + } else + HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", total - 3); + } + + } + + rcnt = bz->f1 - bz->f2; + if (rcnt < 0) + rcnt += MAX_B_FRAMES + 1; + if (rcnt > 1) + receive = 1; + else + receive = 0; + } else + receive = 0; + test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); + if (count && receive) + goto Begin; + restore_flags(flags); + return; +} /* receive_emsg */ + +/*********************/ +/* Interrupt handler */ +/*********************/ +static void +hfcpci_interrupt(int intno, void *dev_id, struct pt_regs *regs) +{ + struct IsdnCardState *cs = dev_id; + u_char exval; + struct BCState *bcs; + int count = 15; + long flags; + u_char val, stat; + + if (!cs) { + printk(KERN_WARNING "HFC-PCI: Spurious interrupt!\n"); + return; + } + if (HFCPCI_ANYINT & (stat = Read_hfc(cs, HFCPCI_STATUS))) { + val = Read_hfc(cs, HFCPCI_INT_S1); + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "HFC-PCI: stat(%02x) s1(%02x)", stat, val); + } else + return; + + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "HFC-PCI irq %x %s", val, + test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags) ? + "locked" : "unlocked"); + val &= cs->hw.hfcpci.int_m1; + if (val & 0x40) { /* TE state machine irq */ + exval = Read_hfc(cs, HFCPCI_STATES) & 0xf; + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "ph_state chg %d->%d", cs->dc.hfcpci.ph_state, + exval); + cs->dc.hfcpci.ph_state = exval; + sched_event_D_pci(cs, D_L1STATECHANGE); + val &= ~0x40; + } + while (val) { + save_flags(flags); + cli(); + if (test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { + cs->hw.hfcpci.int_s1 |= val; + restore_flags(flags); + return; + } + if (cs->hw.hfcpci.int_s1 & 0x18) { + exval = val; + val = cs->hw.hfcpci.int_s1; + cs->hw.hfcpci.int_s1 = exval; + } + if (val & 0x08) { + if (!(bcs = Sel_BCS(cs, cs->hw.hfcpci.bswapped ? 1:0))) { + if (cs->debug) + debugl1(cs, "hfcpci spurious 0x08 IRQ"); + } else + main_rec_hfcpci(bcs); + } + if (val & 0x10) { + if (cs->logecho) + receive_emsg(cs); + else + if (!(bcs = Sel_BCS(cs, 1))) { + if (cs->debug) + debugl1(cs, "hfcpci spurious 0x10 IRQ"); + } else + main_rec_hfcpci(bcs); + } + if (val & 0x01) { + if (!(bcs = Sel_BCS(cs, cs->hw.hfcpci.bswapped ? 1:0))) { + if (cs->debug) + debugl1(cs, "hfcpci spurious 0x01 IRQ"); + } else { + if (bcs->tx_skb) { + if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { + hfcpci_fill_fifo(bcs); + test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); + } else + debugl1(cs, "fill_data %d blocked", bcs->channel); + } else { + if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { + if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { + hfcpci_fill_fifo(bcs); + test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); + } else + debugl1(cs, "fill_data %d blocked", bcs->channel); + } else { + hfcpci_sched_event(bcs, B_XMTBUFREADY); + } + } + } + } + if (val & 0x02) { + if (!(bcs = Sel_BCS(cs, 1))) { + if (cs->debug) + debugl1(cs, "hfcpci spurious 0x02 IRQ"); + } else { + if (bcs->tx_skb) { + if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { + hfcpci_fill_fifo(bcs); + test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); + } else + debugl1(cs, "fill_data %d blocked", bcs->channel); + } else { + if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { + if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { + hfcpci_fill_fifo(bcs); + test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); + } else + debugl1(cs, "fill_data %d blocked", bcs->channel); + } else { + hfcpci_sched_event(bcs, B_XMTBUFREADY); + } + } + } + } + if (val & 0x20) { /* receive dframe */ + receive_dmsg(cs); + } + if (val & 0x04) { /* dframe transmitted */ + if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) + del_timer(&cs->dbusytimer); + if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) + sched_event_D_pci(cs, D_CLEARBUSY); + if (cs->tx_skb) { + if (cs->tx_skb->len) { + if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { + hfcpci_fill_dfifo(cs); + test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); + } else { + debugl1(cs, "hfcpci_fill_dfifo irq blocked"); + } + goto afterXPR; + } else { + idev_kfree_skb(cs->tx_skb, FREE_WRITE); + cs->tx_cnt = 0; + cs->tx_skb = NULL; + } + } + if ((cs->tx_skb = skb_dequeue(&cs->sq))) { + cs->tx_cnt = 0; + if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { + hfcpci_fill_dfifo(cs); + test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); + } else { + debugl1(cs, "hfcpci_fill_dfifo irq blocked"); + } + } else + sched_event_D_pci(cs, D_XMTBUFREADY); + } + afterXPR: + if (cs->hw.hfcpci.int_s1 && count--) { + val = cs->hw.hfcpci.int_s1; + cs->hw.hfcpci.int_s1 = 0; + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "HFC-PCI irq %x loop %d", val, 15 - count); + } else + val = 0; + restore_flags(flags); + } +} + +/********************************************************************/ +/* timer callback for D-chan busy resolution. Currently no function */ +/********************************************************************/ +static void +hfcpci_dbusy_timer(struct IsdnCardState *cs) +{ +#if 0 + struct PStack *stptr; + if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { + if (cs->debug) + debugl1(cs, "D-Channel Busy"); + test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags); + stptr = cs->stlist; + + while (stptr != NULL) { + stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL); + stptr = stptr->next; + } + } +#endif +} + +/*************************************/ +/* Layer 1 D-channel hardware access */ +/*************************************/ +static void +HFCPCI_l1hw(struct PStack *st, int pr, void *arg) +{ + struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; + struct sk_buff *skb = arg; + + switch (pr) { + case (PH_DATA | REQUEST): + if (cs->debug & DEB_DLOG_HEX) + LogFrame(cs, skb->data, skb->len); + if (cs->debug & DEB_DLOG_VERBOSE) + dlogframe(cs, skb, 0); + if (cs->tx_skb) { + skb_queue_tail(&cs->sq, skb); +#ifdef L2FRAME_DEBUG /* psa */ + if (cs->debug & L1_DEB_LAPD) + Logl2Frame(cs, skb, "PH_DATA Queued", 0); +#endif + } else { + cs->tx_skb = skb; + cs->tx_cnt = 0; +#ifdef L2FRAME_DEBUG /* psa */ + if (cs->debug & L1_DEB_LAPD) + Logl2Frame(cs, skb, "PH_DATA", 0); +#endif + if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { + hfcpci_fill_dfifo(cs); + test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); + } else + debugl1(cs, "hfcpci_fill_dfifo blocked"); + + } + break; + case (PH_PULL | INDICATION): + if (cs->tx_skb) { + if (cs->debug & L1_DEB_WARN) + debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); + skb_queue_tail(&cs->sq, skb); + break; + } + if (cs->debug & DEB_DLOG_HEX) + LogFrame(cs, skb->data, skb->len); + if (cs->debug & DEB_DLOG_VERBOSE) + dlogframe(cs, skb, 0); + cs->tx_skb = skb; + cs->tx_cnt = 0; +#ifdef L2FRAME_DEBUG /* psa */ + if (cs->debug & L1_DEB_LAPD) + Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); +#endif + if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { + hfcpci_fill_dfifo(cs); + test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); + } else + debugl1(cs, "hfcpci_fill_dfifo blocked"); + break; + case (PH_PULL | REQUEST): +#ifdef L2FRAME_DEBUG /* psa */ + if (cs->debug & L1_DEB_LAPD) + debugl1(cs, "-> PH_REQUEST_PULL"); +#endif + if (!cs->tx_skb) { + test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); + st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); + } else + test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); + break; + case (HW_RESET | REQUEST): + Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 3); /* HFC ST 3 */ + udelay(6); + Write_hfc(cs, HFCPCI_STATES, 3); /* HFC ST 2 */ + cs->hw.hfcpci.mst_m |= HFCPCI_MASTER; + Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); + Write_hfc(cs, HFCPCI_STATES, HFCPCI_ACTIVATE | HFCPCI_DO_ACTION); + l1_msg(cs, HW_POWERUP | CONFIRM, NULL); + break; + case (HW_ENABLE | REQUEST): + Write_hfc(cs, HFCPCI_STATES, HFCPCI_ACTIVATE | HFCPCI_DO_ACTION); + break; + case (HW_DEACTIVATE | REQUEST): + cs->hw.hfcpci.mst_m &= ~HFCPCI_MASTER; + Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); + break; + case (HW_INFO3 | REQUEST): + cs->hw.hfcpci.mst_m |= HFCPCI_MASTER; + Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); + break; +#if 0 + case (HW_TESTLOOP | REQUEST): + u_char val = 0; + if (1 & (int) arg) + val |= 0x0c; + if (2 & (int) arg) + val |= 0x3; + if (test_bit(HW_IOM1, &cs->HW_Flags)) { + /* IOM 1 Mode */ + if (!val) { + cs->writeisac(cs, ISAC_SPCR, 0xa); + cs->writeisac(cs, ISAC_ADF1, 0x2); + } else { + cs->writeisac(cs, ISAC_SPCR, val); + cs->writeisac(cs, ISAC_ADF1, 0xa); + } + } else { + /* IOM 2 Mode */ + cs->writeisac(cs, ISAC_SPCR, val); + if (val) + cs->writeisac(cs, ISAC_ADF1, 0x8); + else + cs->writeisac(cs, ISAC_ADF1, 0x0); + } + break; +#endif + default: + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "hfcpci_l1hw unknown pr %4x", pr); + break; + } +} + +/***********************************************/ +/* called during init setting l1 stack pointer */ +/***********************************************/ +void +setstack_hfcpci(struct PStack *st, struct IsdnCardState *cs) +{ + st->l1.l1hw = HFCPCI_l1hw; +} + +/**************************************/ +/* send B-channel data if not blocked */ +/**************************************/ +static void +hfcpci_send_data(struct BCState *bcs) +{ + struct IsdnCardState *cs = bcs->cs; + + if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) { + hfcpci_fill_fifo(bcs); + test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); + } else + debugl1(cs, "send_data %d blocked", bcs->channel); +} + +/***************************************************************/ +/* activate/deactivate hardware for selected channels and mode */ +/***************************************************************/ +void +mode_hfcpci(struct BCState *bcs, int mode, int bc) +{ + struct IsdnCardState *cs = bcs->cs; + int flags; + + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "HFCPCI bchannel mode %d bchan %d/%d", + mode, bc, bcs->channel); + bcs->mode = mode; + bcs->channel = bc; + if (cs->chanlimit > 1) { + cs->hw.hfcpci.bswapped = 0; /* B1 and B2 normal mode */ + cs->hw.hfcpci.sctrl_e &= ~0x80; + } + else { + if (bc) { + cs->hw.hfcpci.bswapped = 1; /* B1 and B2 exchanged */ + cs->hw.hfcpci.sctrl_e |= 0x80; + bc = 0; /* B1 controller used */ + } + else { + cs->hw.hfcpci.bswapped = 0; /* B1 and B2 normal mode */ + cs->hw.hfcpci.sctrl_e &= ~0x80; + } + } + save_flags(flags); + cli(); + switch (mode) { + case (L1_MODE_NULL): + if (bc) { + cs->hw.hfcpci.sctrl &= ~SCTRL_B2_ENA; + cs->hw.hfcpci.sctrl_r &= ~SCTRL_B2_ENA; + cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2; + cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B2TRANS+HFCPCI_INTS_B2REC); + } else { + cs->hw.hfcpci.sctrl &= ~SCTRL_B1_ENA; + cs->hw.hfcpci.sctrl_r &= ~SCTRL_B1_ENA; + cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B1; + cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B1TRANS+HFCPCI_INTS_B1REC); + } + break; + case (L1_MODE_TRANS): + if (bc) { + cs->hw.hfcpci.ctmt |= 2; + cs->hw.hfcpci.conn &= ~0x18; + cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA; + cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA; + cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2; + cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS+HFCPCI_INTS_B2REC); + } else { + cs->hw.hfcpci.ctmt |= 1; + cs->hw.hfcpci.conn &= ~0x03; + cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA; + cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA; + cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B1; + cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS+HFCPCI_INTS_B1REC); + } + break; + case (L1_MODE_HDLC): + if (bc) { + cs->hw.hfcpci.ctmt &= ~2; + cs->hw.hfcpci.conn &= ~0x18; + cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA; + cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA; + cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2; + cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS+HFCPCI_INTS_B2REC); + } else { + cs->hw.hfcpci.ctmt &= ~1; + cs->hw.hfcpci.conn &= ~0x3; + cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA; + cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA; + cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B1; + cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS+HFCPCI_INTS_B1REC); + } + break; + case (L1_MODE_EXTRN): + if (bc) { + cs->hw.hfcpci.conn |= 0x10; + cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA; + cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA; + cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2; + cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B2TRANS+HFCPCI_INTS_B2REC); + } else { + cs->hw.hfcpci.conn |= 0x02; + cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA; + cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA; + cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B1; + cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B1TRANS+HFCPCI_INTS_B1REC); + } + break; + } + Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); + restore_flags(flags); + Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); + Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl); + Write_hfc(cs, HFCPCI_SCTRL_R, cs->hw.hfcpci.sctrl_r); + Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt); + Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); +} + +/******************************/ +/* Layer2 -> Layer 1 Transfer */ +/******************************/ +static void +hfcpci_l2l1(struct PStack *st, int pr, void *arg) +{ + struct sk_buff *skb = arg; + long flags; + + switch (pr) { + case (PH_DATA | REQUEST): + save_flags(flags); + cli(); + if (st->l1.bcs->tx_skb) { + skb_queue_tail(&st->l1.bcs->squeue, skb); + restore_flags(flags); + } else { + st->l1.bcs->tx_skb = skb; +/* test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); + */ st->l1.bcs->cs->BC_Send_Data(st->l1.bcs); + restore_flags(flags); + } + break; + case (PH_PULL | INDICATION): + if (st->l1.bcs->tx_skb) { + printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n"); + break; + } + save_flags(flags); + cli(); +/* test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); + */ st->l1.bcs->tx_skb = skb; + st->l1.bcs->cs->BC_Send_Data(st->l1.bcs); + restore_flags(flags); + break; + case (PH_PULL | REQUEST): + if (!st->l1.bcs->tx_skb) { + test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); + st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); + } else + test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); + break; + case (PH_ACTIVATE | REQUEST): + test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); + mode_hfcpci(st->l1.bcs, st->l1.mode, st->l1.bc); + l1_msg_b(st, pr, arg); + break; + case (PH_DEACTIVATE | REQUEST): + l1_msg_b(st, pr, arg); + break; + case (PH_DEACTIVATE | CONFIRM): + test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); + test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); + mode_hfcpci(st->l1.bcs, 0, st->l1.bc); + st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); + break; + } +} + +/******************************************/ +/* deactivate B-channel access and queues */ +/******************************************/ +static void +close_hfcpci(struct BCState *bcs) +{ + mode_hfcpci(bcs, 0, bcs->channel); + if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { + discard_queue(&bcs->rqueue); + discard_queue(&bcs->squeue); + if (bcs->tx_skb) { + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + bcs->tx_skb = NULL; + test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); + } + } +} + +/*************************************/ +/* init B-channel queues and control */ +/*************************************/ +static int +open_hfcpcistate(struct IsdnCardState *cs, struct BCState *bcs) +{ + if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { + skb_queue_head_init(&bcs->rqueue); + skb_queue_head_init(&bcs->squeue); + } + bcs->tx_skb = NULL; + test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); + bcs->event = 0; + bcs->tx_cnt = 0; + return (0); +} + +/*********************************/ +/* inits the stack for B-channel */ +/*********************************/ +static int +setstack_2b(struct PStack *st, struct BCState *bcs) +{ + bcs->channel = st->l1.bc; + if (open_hfcpcistate(st->l1.hardware, bcs)) + return (-1); + st->l1.bcs = bcs; + st->l2.l2l1 = hfcpci_l2l1; + setstack_manager(st); + bcs->st = st; + setstack_l1_B(st); + return (0); +} + +/***************************/ +/* handle L1 state changes */ +/***************************/ +static void +hfcpci_bh(struct IsdnCardState *cs) +{ +/* struct PStack *stptr; + */ + if (!cs) + return; +#if 0 + if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) { + if (cs->debug) + debugl1(cs, "D-Channel Busy cleared"); + stptr = cs->stlist; + while (stptr != NULL) { + stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL); + stptr = stptr->next; + } + } +#endif + if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) { + switch (cs->dc.hfcpci.ph_state) { + case (0): + l1_msg(cs, HW_RESET | INDICATION, NULL); + break; + case (3): + l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL); + break; + case (8): + l1_msg(cs, HW_RSYNC | INDICATION, NULL); + break; + case (6): + l1_msg(cs, HW_INFO2 | INDICATION, NULL); + break; + case (7): + l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL); + break; + default: + break; + } + } + if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) + DChannel_proc_rcv(cs); + if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) + DChannel_proc_xmt(cs); +} + + +/*************************************/ +/* Alloc memory send data for queues */ +/*************************************/ +__initfunc(unsigned int + *init_send_hfcpci(int cnt)) +{ + int i, *send; + + if (!(send = kmalloc(cnt * sizeof(unsigned int), GFP_ATOMIC))) { + printk(KERN_WARNING + "HiSax: No memory for hfcpci.send\n"); + return (NULL); + } + for (i = 0; i < cnt; i++) + send[i] = 0x1fff; + return (send); +} + +/********************************/ +/* called for card init message */ +/********************************/ +__initfunc(void + inithfcpci(struct IsdnCardState *cs)) +{ + cs->setstack_d = setstack_hfcpci; + cs->dbusytimer.function = (void *) hfcpci_dbusy_timer; + cs->dbusytimer.data = (long) cs; + init_timer(&cs->dbusytimer); + cs->tqueue.routine = (void *) (void *) hfcpci_bh; +#if 0 + if (!cs->hw.hfcpci.send) + cs->hw.hfcpci.send = init_send_hfcpci(16); +#endif + if (!cs->bcs[0].hw.hfc.send) + cs->bcs[0].hw.hfc.send = init_send_hfcpci(32); + if (!cs->bcs[1].hw.hfc.send) + cs->bcs[1].hw.hfc.send = init_send_hfcpci(32); + cs->BC_Send_Data = &hfcpci_send_data; + cs->bcs[0].BC_SetStack = setstack_2b; + cs->bcs[1].BC_SetStack = setstack_2b; + cs->bcs[0].BC_Close = close_hfcpci; + cs->bcs[1].BC_Close = close_hfcpci; + mode_hfcpci(cs->bcs, 0, 0); + mode_hfcpci(cs->bcs + 1, 0, 1); +} + + + +/*******************************************/ +/* handle card messages from control layer */ +/*******************************************/ +static int +hfcpci_card_msg(struct IsdnCardState *cs, int mt, void *arg) +{ + long flags; + + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "HFCPCI: card_msg %x", mt); + switch (mt) { + case CARD_RESET: + reset_hfcpci(cs); + return (0); + case CARD_RELEASE: + release_io_hfcpci(cs); + return (0); + case CARD_INIT: + inithfcpci(cs); + save_flags(flags); + sti(); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((80 * HZ) / 1000); /* Timeout 80ms */ + /* now switch timer interrupt off */ + cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER; + Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); + /* reinit mode reg */ + Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); + restore_flags(flags); + return (0); + case CARD_TEST: + return (0); + } + return (0); +} + + +/* this variable is used as card index when more than one cards are present */ +#ifdef COMPAT_HAS_NEW_PCI +static struct pci_dev *dev_hfcpci __initdata = NULL; +#else +static int pci_index __initdata = 0; +#endif + +#endif /* CONFIG_PCI */ + +__initfunc(int + setup_hfcpci(struct IsdnCard *card)) +{ + struct IsdnCardState *cs = card->cs; + char tmp[64]; + int i; +#ifdef COMPAT_HAS_NEW_PCI + struct pci_dev *tmp_hfcpci = NULL; +#endif + + strcpy(tmp, hfcpci_revision); + printk(KERN_INFO "HiSax: HFC-PCI driver Rev. %s\n", HiSax_getrev(tmp)); +#if CONFIG_PCI + cs->hw.hfcpci.int_s1 = 0; +#if 0 + cs->hw.hfcpci.send = NULL; +#endif + cs->bcs[0].hw.hfc.send = NULL; + cs->bcs[1].hw.hfc.send = NULL; + cs->dc.hfcpci.ph_state = 0; + cs->hw.hfcpci.fifo = 255; + if (cs->typ == ISDN_CTYPE_HFC_PCI) { +#ifdef COMPAT_HAS_NEW_PCI + if (!pci_present()) { + printk(KERN_ERR "HFC-PCI: no PCI bus present\n"); + return (0); + } + i = 0; + while (CCD_VENDOR_IDS[i]) { + tmp_hfcpci = pci_find_device(CCD_VENDOR_IDS[i], + CCD_DEVICE_IDS[i], + dev_hfcpci); + if (tmp_hfcpci) break; + i++; + } + + if (tmp_hfcpci) { + dev_hfcpci = tmp_hfcpci; /* old device */ + cs->hw.hfcpci.pci_bus = dev_hfcpci->bus->number; + cs->hw.hfcpci.pci_device_fn = dev_hfcpci->devfn; + cs->irq = dev_hfcpci->irq; + if (!cs->irq) { + printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); + return (0); + } + cs->hw.hfcpci.pci_io = (char *) get_pcibase(dev_hfcpci, 1); + } else { + printk(KERN_WARNING "HFC-PCI: No PCI card found\n"); + return (0); + } +#else + for (; pci_index < 255; pci_index++) { + unsigned char irq; + + i = 0; + while (CCD_VENDOR_IDS[i]) { + if (pcibios_find_device(CCD_VENDOR_IDS[i], + CCD_DEVICE_IDS[i], pci_index, + &cs->hw.hfcpci.pci_bus, &cs->hw.hfcpci.pci_device_fn) == 0) + break; + i++; + } + if (!CCD_VENDOR_IDS[i]) + continue; + + pcibios_read_config_byte(cs->hw.hfcpci.pci_bus, cs->hw.hfcpci.pci_device_fn, + PCI_INTERRUPT_LINE, &irq); + cs->irq = irq; + + pcibios_read_config_dword(cs->hw.hfcpci.pci_bus, + cs->hw.hfcpci.pci_device_fn, PCI_BASE_ADDRESS_1, + (void *) &cs->hw.hfcpci.pci_io); + break; + } + if (pci_index == 255) { + printk(KERN_WARNING "HFC-PCI: No card found\n"); + return (0); + } + pci_index++; +#endif /* COMPAT_HAS_NEW_PCI */ + if (!cs->hw.hfcpci.pci_io) { + printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n"); + return (0); + } + /* Allocate memory for FIFOS */ + /* Because the HFC-PCI needs a 32K physical alignment, we */ + /* need to allocate the double mem and align the address */ + if (!((void *) cs->hw.hfcpci.share_start = kmalloc(65536, GFP_KERNEL))) { + printk(KERN_WARNING "HFC-PCI: Error allocating memory for FIFO!\n"); + return 0; + } + (ulong) cs->hw.hfcpci.fifos = + (((ulong) cs->hw.hfcpci.share_start) & ~0x7FFF) + 0x8000; + pcibios_write_config_dword(cs->hw.hfcpci.pci_bus, + cs->hw.hfcpci.pci_device_fn, 0x80, + (u_int) virt_to_bus(cs->hw.hfcpci.fifos)); + cs->hw.hfcpci.pci_io = ioremap((ulong) cs->hw.hfcpci.pci_io, 256); + printk(KERN_INFO + "HFC-PCI: defined at mem %#x fifo %#x(%#x) IRQ %d HZ %d\n", + (u_int) cs->hw.hfcpci.pci_io, + (u_int) cs->hw.hfcpci.fifos, + (u_int) virt_to_bus(cs->hw.hfcpci.fifos), + cs->irq, HZ); + pcibios_write_config_word(cs->hw.hfcpci.pci_bus, cs->hw.hfcpci.pci_device_fn, PCI_COMMAND, PCI_ENA_MEMIO); /* enable memory mapped ports, disable busmaster */ + cs->hw.hfcpci.int_m2 = 0; /* disable alle interrupts */ + cs->hw.hfcpci.int_m1 = 0; + Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); + Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); + /* At this point the needed PCI config is done */ + /* fifos are still not enabled */ + } else + return (0); /* no valid card type */ + + + cs->readisac = NULL; + cs->writeisac = NULL; + cs->readisacfifo = NULL; + cs->writeisacfifo = NULL; + cs->BC_Read_Reg = NULL; + cs->BC_Write_Reg = NULL; + cs->irq_func = &hfcpci_interrupt; + cs->irq_flags |= SA_SHIRQ; + + cs->hw.hfcpci.timer.function = (void *) hfcpci_Timer; + cs->hw.hfcpci.timer.data = (long) cs; + init_timer(&cs->hw.hfcpci.timer); + + reset_hfcpci(cs); + cs->cardmsg = &hfcpci_card_msg; + return (1); +#else + printk(KERN_WARNING "HFC-PCI: NO_PCI_BIOS\n"); + return (0); +#endif /* CONFIG_PCI */ +} diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/hfc_pci.h linux/drivers/isdn/hisax/hfc_pci.h --- v2.3.13/linux/drivers/isdn/hisax/hfc_pci.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/hisax/hfc_pci.h Thu Aug 12 09:42:33 1999 @@ -0,0 +1,252 @@ +/* $Id: hfc_pci.h,v 1.5 1999/08/09 19:13:34 werner Exp $ + + * specific defines for CCD's HFC 2BDS0 PCI chips + * + * Author Werner Cornelius (werner@isdn4linux.de) + * + * Copyright 1999 by Werner Cornelius (werner@isdn4linux.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Log: hfc_pci.h,v $ + * Revision 1.5 1999/08/09 19:13:34 werner + * moved constant pci ids to pci id table + * + * Revision 1.4 1999/08/08 10:17:33 werner + * added new PCI vendor and card ids for Manufacturer 0x1043 + * + * Revision 1.3 1999/07/14 12:39:34 werner + * Added changes for echo handling. + * + * Revision 1.2 1999/07/01 08:07:52 keil + * Initial version + * + * + * + */ + + +/* defines for PCI config */ + +#define PCI_ENA_MEMIO 0x02 +#define PCI_ENA_MASTER 0x04 + + +/* GCI/IOM bus monitor registers */ + +#define HCFPCI_C_I 0x08 +#define HFCPCI_TRxR 0x0C +#define HFCPCI_MON1_D 0x28 +#define HFCPCI_MON2_D 0x2C + + +/* GCI/IOM bus timeslot registers */ + +#define HFCPCI_B1_SSL 0x80 +#define HFCPCI_B2_SSL 0x84 +#define HFCPCI_AUX1_SSL 0x88 +#define HFCPCI_AUX2_SSL 0x8C +#define HFCPCI_B1_RSL 0x90 +#define HFCPCI_B2_RSL 0x94 +#define HFCPCI_AUX1_RSL 0x98 +#define HFCPCI_AUX2_RSL 0x9C + +/* GCI/IOM bus data registers */ + +#define HFCPCI_B1_D 0xA0 +#define HFCPCI_B2_D 0xA4 +#define HFCPCI_AUX1_D 0xA8 +#define HFCPCI_AUX2_D 0xAC + +/* GCI/IOM bus configuration registers */ + +#define HFCPCI_MST_EMOD 0xB4 +#define HFCPCI_MST_MODE 0xB8 +#define HFCPCI_CONNECT 0xBC + + +/* Interrupt and status registers */ + +#define HFCPCI_FIFO_EN 0x44 +#define HFCPCI_TRM 0x48 +#define HFCPCI_B_MODE 0x4C +#define HFCPCI_CHIP_ID 0x58 +#define HFCPCI_CIRM 0x60 +#define HFCPCI_CTMT 0x64 +#define HFCPCI_INT_M1 0x68 +#define HFCPCI_INT_M2 0x6C +#define HFCPCI_INT_S1 0x78 +#define HFCPCI_INT_S2 0x7C +#define HFCPCI_STATUS 0x70 + +/* S/T section registers */ + +#define HFCPCI_STATES 0xC0 +#define HFCPCI_SCTRL 0xC4 +#define HFCPCI_SCTRL_E 0xC8 +#define HFCPCI_SCTRL_R 0xCC +#define HFCPCI_SQ 0xD0 +#define HFCPCI_CLKDEL 0xDC +#define HFCPCI_B1_REC 0xF0 +#define HFCPCI_B1_SEND 0xF0 +#define HFCPCI_B2_REC 0xF4 +#define HFCPCI_B2_SEND 0xF4 +#define HFCPCI_D_REC 0xF8 +#define HFCPCI_D_SEND 0xF8 +#define HFCPCI_E_REC 0xFC + + +/* bits in status register (READ) */ +#define HFCPCI_PCI_PROC 0x02 +#define HFCPCI_NBUSY 0x04 +#define HFCPCI_TIMER_ELAP 0x10 +#define HFCPCI_STATINT 0x20 +#define HFCPCI_FRAMEINT 0x40 +#define HFCPCI_ANYINT 0x80 + +/* bits in CTMT (Write) */ +#define HFCPCI_CLTIMER 0x80 +#define HFCPCI_TIM3_125 0x00 +#define HFCPCI_TIM25 0x10 +#define HFCPCI_TIM50 0x14 +#define HFCPCI_TIM400 0x18 +#define HFCPCI_TIM800 0x1C +#define HFCPCI_AUTO_TIMER 0x20 +#define HFCPCI_TRANSB2 0x02 +#define HFCPCI_TRANSB1 0x01 + +/* bits in CIRM (Write) */ +#define HFCPCI_AUX_MSK 0x07 +#define HFCPCI_RESET 0x08 +#define HFCPCI_B1_REV 0x40 +#define HFCPCI_B2_REV 0x80 + +/* bits in INT_M1 and INT_S1 */ +#define HFCPCI_INTS_B1TRANS 0x01 +#define HFCPCI_INTS_B2TRANS 0x02 +#define HFCPCI_INTS_DTRANS 0x04 +#define HFCPCI_INTS_B1REC 0x08 +#define HFCPCI_INTS_B2REC 0x10 +#define HFCPCI_INTS_DREC 0x20 +#define HFCPCI_INTS_L1STATE 0x40 +#define HFCPCI_INTS_TIMER 0x80 + +/* bits in INT_M2 */ +#define HFCPCI_PROC_TRANS 0x01 +#define HFCPCI_GCI_I_CHG 0x02 +#define HFCPCI_GCI_MON_REC 0x04 +#define HFCPCI_IRQ_ENABLE 0x08 +#define HFCPCI_PMESEL 0x80 + +/* bits in STATES */ +#define HFCPCI_STATE_MSK 0x0F +#define HFCPCI_LOAD_STATE 0x10 +#define HFCPCI_ACTIVATE 0x20 +#define HFCPCI_DO_ACTION 0x40 +#define HFCPCI_NT_G2_G3 0x80 + +/* bits in HFCD_MST_MODE */ +#define HFCPCI_MASTER 0x01 +#define HFCPCI_SLAVE 0x00 +/* remaining bits are for codecs control */ + +/* bits in HFCD_SCTRL */ +#define SCTRL_B1_ENA 0x01 +#define SCTRL_B2_ENA 0x02 +#define SCTRL_MODE_TE 0x00 +#define SCTRL_MODE_NT 0x04 +#define SCTRL_LOW_PRIO 0x08 +#define SCTRL_SQ_ENA 0x10 +#define SCTRL_TEST 0x20 +#define SCTRL_NONE_CAP 0x40 +#define SCTRL_PWR_DOWN 0x80 + +/* bits in SCTRL_E */ +#define HFCPCI_AUTO_AWAKE 0x01 +#define HFCPCI_DBIT_1 0x04 +#define HFCPCI_IGNORE_COL 0x08 +#define HFCPCI_CHG_B1_B2 0x80 + +/****************************/ +/* bits in FIFO_EN register */ +/****************************/ +#define HFCPCI_FIFOEN_B1 0x03 +#define HFCPCI_FIFOEN_B2 0x0C +#define HFCPCI_FIFOEN_DTX 0x10 +#define HFCPCI_FIFOEN_B2RX 0x08 + + +/***********************************/ +/* definitions of fifo memory area */ +/***********************************/ +#define MAX_D_FRAMES 15 +#define MAX_B_FRAMES 31 +#define B_SUB_VAL 0x200 +#define B_FIFO_SIZE (0x2000 - B_SUB_VAL) +#define D_FIFO_SIZE 512 +#define D_FREG_MASK 0xF + +typedef struct { + unsigned short z1; /* Z1 pointer 16 Bit */ + unsigned short z2; /* Z2 pointer 16 Bit */ + } z_type; + +typedef struct { + u_char data[D_FIFO_SIZE]; /* FIFO data space */ + u_char fill1[0x20A0-D_FIFO_SIZE]; /* reserved, do not use */ + u_char f1,f2; /* f pointers */ + u_char fill2[0x20C0-0x20A2]; /* reserved, do not use */ + z_type za[MAX_D_FRAMES+1]; /* mask index with D_FREG_MASK for access */ + u_char fill3[0x4000-0x2100]; /* align 16K */ + } dfifo_type; + +typedef struct { + z_type za[MAX_B_FRAMES+1]; /* only range 0x0..0x1F allowed */ + u_char f1,f2; /* f pointers */ + u_char fill[0x2100-0x2082]; /* alignment */ + } bzfifo_type; + + +typedef union { + struct { + dfifo_type d_tx; /* D-send channel */ + dfifo_type d_rx; /* D-receive channel */ + } d_chan; + struct { + u_char fill1[0x200]; + u_char txdat_b1[B_FIFO_SIZE]; + bzfifo_type txbz_b1; + + bzfifo_type txbz_b2; + u_char txdat_b2[B_FIFO_SIZE]; + + u_char fill2[D_FIFO_SIZE]; + + u_char rxdat_b1[B_FIFO_SIZE]; + bzfifo_type rxbz_b1; + + bzfifo_type rxbz_b2; + u_char rxdat_b2[B_FIFO_SIZE]; + } b_chans; + u_char fill[32768]; + } fifo_area; + + +#define Write_hfc(a,b,c) (*(((u_char *)a->hw.hfcpci.pci_io)+b) = c) +#define Read_hfc(a,b) (*(((u_char *)a->hw.hfcpci.pci_io)+b)) + +extern void main_irq_hcpci(struct BCState *bcs); +extern void inithfcpci(struct IsdnCardState *cs); +extern void releasehfcpci(struct IsdnCardState *cs); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/hfcscard.c linux/drivers/isdn/hisax/hfcscard.c --- v2.3.13/linux/drivers/isdn/hisax/hfcscard.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/hisax/hfcscard.c Thu Aug 12 09:42:33 1999 @@ -0,0 +1,206 @@ +/* $Id: hfcscard.c,v 1.4 1999/08/09 18:59:59 keil Exp $ + + * hfcscard.c low level stuff for hfcs based cards (Teles3c, ACER P10) + * + * Author Karsten Keil (keil@isdn4linux.de) + * + * + * $Log: hfcscard.c,v $ + * Revision 1.4 1999/08/09 18:59:59 keil + * Fix S0 init - Thanks to Stefan Gybas + * + * Revision 1.3 1999/07/12 21:05:12 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 1.2 1999/07/01 08:16:03 keil + * teles3c ---> hfcscard + * + * + * + */ + +#define __NO_VERSION__ +#include "hisax.h" +#include "hfc_2bds0.h" +#include "isdnl1.h" + +extern const char *CardType[]; + +static const char *hfcs_revision = "$Revision: 1.4 $"; + +static void +hfcs_interrupt(int intno, void *dev_id, struct pt_regs *regs) +{ + struct IsdnCardState *cs = dev_id; + u_char val, stat; + + if (!cs) { + printk(KERN_WARNING "HFCS: Spurious interrupt!\n"); + return; + } + if ((HFCD_ANYINT | HFCD_BUSY_NBUSY) & + (stat = cs->BC_Read_Reg(cs, HFCD_DATA, HFCD_STAT))) { + val = cs->BC_Read_Reg(cs, HFCD_DATA, HFCD_INT_S1); + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "HFCS: stat(%02x) s1(%02x)", stat, val); + hfc2bds0_interrupt(cs, val); + } else { + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "HFCS: irq_no_irq stat(%02x)", stat); + } +} + +static void +hfcs_Timer(struct IsdnCardState *cs) +{ + cs->hw.hfcD.timer.expires = jiffies + 75; + /* WD RESET */ +/* WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt | 0x80); + add_timer(&cs->hw.hfcD.timer); +*/ +} + +void +release_io_hfcs(struct IsdnCardState *cs) +{ + release2bds0(cs); + del_timer(&cs->hw.hfcD.timer); + if (cs->hw.hfcD.addr) + release_region(cs->hw.hfcD.addr, 2); +} + +static void +reset_hfcs(struct IsdnCardState *cs) +{ + long flags; + + printk(KERN_INFO "HFCS: resetting card\n"); + cs->hw.hfcD.cirm = HFCD_RESET; + if (cs->typ == ISDN_CTYPE_TELES3C) + cs->hw.hfcD.cirm |= HFCD_MEM8K; + cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CIRM, cs->hw.hfcD.cirm); /* Reset On */ + save_flags(flags); + sti(); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((30*HZ)/1000); + cs->hw.hfcD.cirm = 0; + if (cs->typ == ISDN_CTYPE_TELES3C) + cs->hw.hfcD.cirm |= HFCD_MEM8K; + cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CIRM, cs->hw.hfcD.cirm); /* Reset Off */ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((10*HZ)/1000); + if (cs->typ == ISDN_CTYPE_TELES3C) + cs->hw.hfcD.cirm |= HFCD_INTB; + else if (cs->typ == ISDN_CTYPE_ACERP10) + cs->hw.hfcD.cirm |= HFCD_INTA; + cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CIRM, cs->hw.hfcD.cirm); + cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CLKDEL, 0x0e); + cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_TEST, HFCD_AUTO_AWAKE); /* S/T Auto awake */ + cs->hw.hfcD.ctmt = HFCD_TIM25 | HFCD_AUTO_TIMER; + cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt); + cs->hw.hfcD.int_m2 = HFCD_IRQ_ENABLE; + cs->hw.hfcD.int_m1 = HFCD_INTS_B1TRANS | HFCD_INTS_B2TRANS | + HFCD_INTS_DTRANS | HFCD_INTS_B1REC | HFCD_INTS_B2REC | + HFCD_INTS_DREC | HFCD_INTS_L1STATE; + cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_INT_M1, cs->hw.hfcD.int_m1); + cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_INT_M2, cs->hw.hfcD.int_m2); + cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_STATES, HFCD_LOAD_STATE | 2); /* HFC ST 2 */ + udelay(10); + cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_STATES, 2); /* HFC ST 2 */ + cs->hw.hfcD.mst_m = HFCD_MASTER; + cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_MST_MODE, cs->hw.hfcD.mst_m); /* HFC Master */ + cs->hw.hfcD.sctrl = 0; + cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_SCTRL, cs->hw.hfcD.sctrl); + restore_flags(flags); +} + +static int +hfcs_card_msg(struct IsdnCardState *cs, int mt, void *arg) +{ + long flags; + + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "HFCS: card_msg %x", mt); + switch (mt) { + case CARD_RESET: + reset_hfcs(cs); + return(0); + case CARD_RELEASE: + release_io_hfcs(cs); + return(0); + case CARD_INIT: + cs->hw.hfcD.timer.expires = jiffies + 75; + add_timer(&cs->hw.hfcD.timer); + init2bds0(cs); + save_flags(flags); + sti(); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((80*HZ)/1000); + cs->hw.hfcD.ctmt |= HFCD_TIM800; + cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt); + cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_MST_MODE, cs->hw.hfcD.mst_m); + restore_flags(flags); + return(0); + case CARD_TEST: + return(0); + } + return(0); +} + +__initfunc(int +setup_hfcs(struct IsdnCard *card)) +{ + struct IsdnCardState *cs = card->cs; + char tmp[64]; + + strcpy(tmp, hfcs_revision); + printk(KERN_INFO "HiSax: HFC-S driver Rev. %s\n", HiSax_getrev(tmp)); + cs->hw.hfcD.addr = card->para[1] & 0xfffe; + cs->irq = card->para[0]; + cs->hw.hfcD.cip = 0; + cs->hw.hfcD.int_s1 = 0; + cs->hw.hfcD.send = NULL; + cs->bcs[0].hw.hfc.send = NULL; + cs->bcs[1].hw.hfc.send = NULL; + cs->hw.hfcD.dfifosize = 512; + cs->dc.hfcd.ph_state = 0; + cs->hw.hfcD.fifo = 255; + if (cs->typ == ISDN_CTYPE_TELES3C) { + cs->hw.hfcD.bfifosize = 1024 + 512; + } else if (cs->typ == ISDN_CTYPE_ACERP10) { + cs->hw.hfcD.bfifosize = 7*1024 + 512; + } else + return (0); + if (check_region((cs->hw.hfcD.addr), 2)) { + printk(KERN_WARNING + "HiSax: %s config port %x-%x already in use\n", + CardType[card->typ], + cs->hw.hfcD.addr, + cs->hw.hfcD.addr + 2); + return (0); + } else { + request_region(cs->hw.hfcD.addr, 2, "HFCS isdn"); + } + printk(KERN_INFO + "HFCS: defined at 0x%x IRQ %d HZ %d\n", + cs->hw.hfcD.addr, + cs->irq, HZ); + if (cs->typ == ISDN_CTYPE_TELES3C) { + /* Teles 16.3c IO ADR is 0x200 | YY0U (YY Bit 15/14 address) */ + outb(0x00, cs->hw.hfcD.addr); + outb(0x56, cs->hw.hfcD.addr | 1); + } else if (cs->typ == ISDN_CTYPE_ACERP10) { + /* Acer P10 IO ADR is 0x300 */ + outb(0x00, cs->hw.hfcD.addr); + outb(0x57, cs->hw.hfcD.addr | 1); + } + set_cs_func(cs); + cs->hw.hfcD.timer.function = (void *) hfcs_Timer; + cs->hw.hfcD.timer.data = (long) cs; + init_timer(&cs->hw.hfcD.timer); + reset_hfcs(cs); + cs->cardmsg = &hfcs_card_msg; + cs->irq_func = &hfcs_interrupt; + return (1); +} diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/hisax.h linux/drivers/isdn/hisax/hisax.h --- v2.3.13/linux/drivers/isdn/hisax/hisax.h Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/hisax.h Thu Aug 12 09:42:33 1999 @@ -1,8 +1,28 @@ -/* $Id: hisax.h,v 2.26 1998/11/15 23:54:45 keil Exp $ +/* $Id: hisax.h,v 2.33 1999/08/05 20:43:16 keil Exp $ * Basic declarations, defines and prototypes * * $Log: hisax.h,v $ + * Revision 2.33 1999/08/05 20:43:16 keil + * ISAR analog modem support + * + * Revision 2.31 1999/07/21 14:46:11 keil + * changes from EICON certification + * + * Revision 2.30 1999/07/14 12:38:38 werner + * Added changes for echo channel handling + * + * Revision 2.29 1999/07/12 21:05:14 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 2.28 1999/07/05 23:51:46 werner + * Allow limiting of available HiSax B-chans per card. Controlled by hisaxctrl + * hisaxctrl id 10 + * + * Revision 2.27 1999/07/01 08:11:38 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 2.26 1998/11/15 23:54:45 keil * changes from 2.0 * @@ -111,8 +131,7 @@ #include #include #include -#include -#include +#include #define REQUEST 0 #define CONFIRM 1 @@ -131,7 +150,6 @@ #define HW_RSYNC 0x0060 #define HW_TESTLOOP 0x0070 #define CARD_RESET 0x00F0 -#define CARD_SETIRQ 0x00F1 #define CARD_INIT 0x00F2 #define CARD_RELEASE 0x00F3 #define CARD_TEST 0x00F4 @@ -168,16 +186,21 @@ #define CC_SETUP_COMPL 0x0330 #define CC_PROCEEDING 0x0340 #define CC_ALERTING 0x0344 +#define CC_PROGRESS 0x0348 #define CC_CONNECT 0x0350 #define CC_CHARGE 0x0354 +#define CC_NOTIFY 0x0358 #define CC_DISCONNECT 0x0360 #define CC_RELEASE 0x0368 #define CC_SUSPEND 0x0370 +#define CC_PROCEED_SEND 0x0374 +#define CC_REDIR 0x0378 #define CC_T303 0x0383 #define CC_T304 0x0384 #define CC_T305 0x0385 #define CC_T308_1 0x0388 -#define CC_T308_2 0x0389 +#define CC_T308_2 0x038A +#define CC_T309 0x0309 #define CC_T310 0x0390 #define CC_T313 0x0393 #define CC_T318 0x0398 @@ -188,12 +211,22 @@ #define CC_RESUME_ERR 0x03E3 #define CC_CONNECT_ERR 0x03E4 #define CC_RELEASE_ERR 0x03E5 -#define CC_DLRL 0x03F0 #define CC_RESTART 0x03F4 +#define CC_TDSS1_IO 0x13F4 /* DSS1 IO user timer */ + +/* define maximum number of possible waiting incoming calls */ +#define MAX_WAITING_CALLS 2 #ifdef __KERNEL__ +/* include only l3dss1 specific process structures, but no other defines */ +#ifdef CONFIG_HISAX_EURO + #define l3dss1_process + #include "l3dss1.h" + #undef l3dss1_process +#endif CONFIG_HISAX_EURO + #define MAX_DFRAME_LEN 260 #define MAX_DFRAME_LEN_L1 300 #define HSCX_BUFMAX 4096 @@ -294,16 +327,17 @@ #define FLG_ESTAB_PEND 13 #define FLG_PTP 14 #define FLG_FIXED_TEI 15 +#define FLG_L2BLOCK 16 struct Layer2 { int tei; int sap; int maxlen; unsigned int flag; - int vs, va, vr; + unsigned int vs, va, vr; int rc; - int window; - int sow; + unsigned int window; + unsigned int sow; struct sk_buff *windowar[MAX_WINDOW]; struct sk_buff_head i_queue; struct sk_buff_head ui_queue; @@ -319,8 +353,10 @@ struct Layer3 { void (*l3l4) (struct PStack *, int, void *); + void (*l3ml3) (struct PStack *, int, void *); void (*l3l2) (struct PStack *, int, void *); struct FsmInst l3m; + struct FsmTimer l3m_timer; struct sk_buff_head squeue; struct l3_process *proc; struct l3_process *global; @@ -331,6 +367,7 @@ struct LLInterface { void (*l4l3) (struct PStack *, int, void *); + int (*l4l3_proto) (struct PStack *, isdn_ctrl *); void *userdata; void (*l1writewakeup) (struct PStack *, int); void (*l2writewakeup) (struct PStack *, int); @@ -345,16 +382,17 @@ void (*layer) (struct PStack *, int, void *); }; +#define NO_CAUSE 254 struct Param { - int cause; - int loc; + u_char cause; + u_char loc; + u_char diag[6]; int bchannel; - setup_parm setup; /* from isdnif.h numbers and Serviceindicator */ - int chargeinfo; /* Charge Info - only for 1tr6 in - * the moment - */ + int chargeinfo; int spv; /* SPV Flag */ + setup_parm setup; /* from isdnif.h numbers and Serviceindicator */ + u_char moderate; /* transfer mode and rate (bearer octet 4) */ }; @@ -366,6 +404,14 @@ struct LLInterface lli; struct Management ma; int protocol; /* EDSS1 or 1TR6 */ + + /* protocol specific data fields */ + union + { u_char uuuu; /* only as dummy */ +#ifdef CONFIG_HISAX_EURO + dss1_stk_priv dss1; /* private dss1 data */ +#endif CONFIG_HISAX_EURO + } prot; }; struct l3_process { @@ -378,6 +424,15 @@ struct Channel *chan; struct PStack *st; struct l3_process *next; + ulong redir_result; + + /* protocol specific data fields */ + union + { u_char uuuu; /* only when euro not defined, avoiding empty union */ +#ifdef CONFIG_HISAX_EURO + dss1_proc_priv dss1; /* private dss1 data */ +#endif CONFIG_HISAX_EURO + } prot; }; struct hscx_hw { @@ -385,6 +440,8 @@ int rcvidx; int count; /* Current skb sent count */ u_char *rcvbuf; /* B-Channel receive Buffer */ + u_char tsaxr0; + u_char tsaxr1; }; struct isar_reg { @@ -402,6 +459,7 @@ int txcnt; int mml; u_char *rcvbuf; /* B-Channel receive Buffer */ + u_char conmsg[16]; struct isar_reg *reg; }; @@ -469,11 +527,15 @@ #define BC_FLG_NOFRAME 4 #define BC_FLG_HALF 5 #define BC_FLG_EMPTY 6 +#define BC_FLG_ORIG 7 #define L1_MODE_NULL 0 #define L1_MODE_TRANS 1 #define L1_MODE_HDLC 2 +#define L1_MODE_EXTRN 3 #define L1_MODE_MODEM 7 +#define L1_MODE_V32 8 +#define L1_MODE_FAX 9 struct BCState { int channel; @@ -486,6 +548,7 @@ struct sk_buff_head squeue; /* B-Channel send Queue */ struct PStack *st; u_char *blog; + u_char *conmsg; struct timer_list transbusy; struct tq_struct tqueue; int event; @@ -578,7 +641,8 @@ }; struct diva_hw { - unsigned int cfg_reg; + unsigned long cfg_reg; + unsigned long pci_cfg; unsigned int ctrl; unsigned int isac_adr; unsigned int isac; @@ -647,6 +711,31 @@ unsigned char last_is0; }; +struct hfcPCI_hw { + unsigned char cirm; + unsigned char ctmt; + unsigned char conn; + unsigned char mst_m; + unsigned char int_m1; + unsigned char int_m2; + unsigned char int_s1; + unsigned char sctrl; + unsigned char sctrl_r; + unsigned char sctrl_e; + unsigned char trm; + unsigned char stat; + unsigned char fifo; + unsigned char fifo_en; + unsigned char bswapped; + /* unsigned int *send; */ + unsigned char pci_bus; + unsigned char pci_device_fn; + unsigned char *pci_io; /* start of PCI IO memory */ + void *share_start; /* shared memory for Fifos start */ + void *fifos; /* FIFO memory */ + struct timer_list timer; +}; + struct hfcD_hw { unsigned int addr; unsigned int bfifosize; @@ -668,25 +757,118 @@ struct timer_list timer; }; -#define HW_IOM1 0 -#define HW_IPAC 1 -#define HW_ISAR 2 -#define FLG_TWO_DCHAN 4 -#define FLG_L1_DBUSY 5 -#define FLG_DBUSY_TIMER 6 -#define FLG_LOCK_ATOMIC 7 -#define HW_MON0_RX_END 8 -#define HW_MON1_RX_END 9 -#define HW_MON0_TX_END 10 -#define HW_MON1_TX_END 11 +struct isurf_hw { + unsigned int reset; + unsigned int isac; + unsigned int isar; + struct isar_reg isar_r; +}; + +struct saphir_hw { + unsigned int cfg_reg; + unsigned int ale; + unsigned int isac; + unsigned int hscx; + struct timer_list timer; +}; + +struct bkm_hw { + unsigned int base; + /* A4T stuff */ + unsigned int isac_adr; + unsigned int isac_ale; + unsigned int jade_adr; + unsigned int jade_ale; + /* Scitel Quadro stuff */ + unsigned int plx_adr; + unsigned int data_adr; +}; + +struct gazel_hw { + unsigned int cfg_reg; + unsigned int pciaddr[2]; + signed int ipac; + signed int isac; + signed int hscx[2]; + signed int isacfifo; + signed int hscxfifo[2]; + unsigned char timeslot; + unsigned char iom2; +}; + +#ifdef CONFIG_HISAX_TESTEMU +struct te_hw { + unsigned char *sfifo; + unsigned char *sfifo_w; + unsigned char *sfifo_r; + unsigned char *sfifo_e; + int sfifo_cnt; + unsigned int stat; +#ifdef COMPAT_HAS_NEW_WAITQ + wait_queue_head_t rwaitq; + wait_queue_head_t swaitq; +#else + struct wait_queue *rwaitq; + struct wait_queue *swaitq; +#endif +}; +#endif + +struct arcofi_msg { + struct arcofi_msg *next; + u_char receive; + u_char len; + u_char msg[10]; +}; + +struct isac_chip { + int ph_state; + u_char *mon_tx; + u_char *mon_rx; + int mon_txp; + int mon_txc; + int mon_rxp; + struct arcofi_msg *arcofi_list; + struct timer_list arcofitimer; +#ifdef COMPAT_HAS_NEW_WAITQ + wait_queue_head_t arcofi_wait; +#else + struct wait_queue *arcofi_wait; +#endif + u_char arcofi_bc; + u_char arcofi_state; + u_char mocr; + u_char adf2; +}; + +struct hfcd_chip { + int ph_state; +}; + +struct hfcpci_chip { + int ph_state; +}; + +#define HW_IOM1 0 +#define HW_IPAC 1 +#define HW_ISAR 2 +#define FLG_TWO_DCHAN 4 +#define FLG_L1_DBUSY 5 +#define FLG_DBUSY_TIMER 6 +#define FLG_LOCK_ATOMIC 7 +#define FLG_ARCOFI_TIMER 8 +#define FLG_ARCOFI_ERROR 9 struct IsdnCardState { unsigned char typ; unsigned char subtyp; int protocol; unsigned int irq; + unsigned long irq_flags; int HW_Flags; int *busy_flag; + int chanlimit; /* limited number of B-chans to use */ + int logecho; /* log echo if supported by card */ union { struct elsa_hw elsa; struct teles0_hw teles0; @@ -701,7 +883,15 @@ struct mic_hw mic; struct njet_hw njet; struct hfcD_hw hfcD; + struct hfcPCI_hw hfcpci; struct ix1_hw niccy; + struct isurf_hw isurf; + struct saphir_hw saphir; +#ifdef CONFIG_HISAX_TESTEMU + struct te_hw te; +#endif + struct bkm_hw ax; + struct gazel_hw gazel; } hw; int myid; isdn_if iif; @@ -717,9 +907,21 @@ void (*BC_Write_Reg) (struct IsdnCardState *, int, u_char, u_char); void (*BC_Send_Data) (struct BCState *); int (*cardmsg) (struct IsdnCardState *, int, void *); - struct Channel channel[2]; - struct BCState bcs[2]; + void (*setstack_d) (struct PStack *, struct IsdnCardState *); + void (*DC_Close) (struct IsdnCardState *); + void (*irq_func) (int, void *, struct pt_regs *); + struct Channel channel[2+MAX_WAITING_CALLS]; + struct BCState bcs[2+MAX_WAITING_CALLS]; struct PStack *stlist; + struct sk_buff_head rq, sq; /* D-channel queues */ + int cardnr; + char *dlog; + int debug; + union { + struct isac_chip isac; + struct hfcd_chip hfcd; + struct hfcpci_chip hfcpci; + } dc; u_char *rcvbuf; int rcvidx; struct sk_buff *tx_skb; @@ -727,18 +929,6 @@ int event; struct tq_struct tqueue; struct timer_list dbusytimer; - struct sk_buff_head rq, sq; /* D-channel queues */ - int ph_state; - int cardnr; - char *dlog; - int debug; - u_char *mon_tx; - u_char *mon_rx; - int mon_txp; - int mon_txc; - int mon_rxp; - u_char mocr; - void (*setstack_d) (struct PStack *, struct IsdnCardState *); }; #define MON0_RX 1 @@ -776,18 +966,33 @@ #define ISDN_CTYPE_A1_PCMCIA 26 #define ISDN_CTYPE_FRITZPCI 27 #define ISDN_CTYPE_SEDLBAUER_FAX 28 +#define ISDN_CTYPE_ISURF 29 +#define ISDN_CTYPE_ACERP10 30 +#define ISDN_CTYPE_HSTSAPHIR 31 +#define ISDN_CTYPE_BKM_A4T 32 +#define ISDN_CTYPE_SCT_QUADRO 33 +#define ISDN_CTYPE_GAZEL 34 +#define ISDN_CTYPE_HFC_PCI 35 +#define ISDN_CTYPE_COUNT 35 -#define ISDN_CTYPE_COUNT 28 #ifdef ISDN_CHIP_ISAC #undef ISDN_CHIP_ISAC #endif +#ifndef __initfunc +#define __initfunc(__arginit) __arginit +#endif + +#ifndef __initdata +#define __initdata +#endif + #define HISAX_INITFUNC(__arginit) __initfunc(__arginit) #define HISAX_INITDATA __initdata #ifdef CONFIG_HISAX_16_0 -#define CARD_TELES0 (1<< ISDN_CTYPE_16_0) | (1<< ISDN_CTYPE_8_0) +#define CARD_TELES0 1 #ifndef ISDN_CHIP_ISAC #define ISDN_CHIP_ISAC 1 #endif @@ -796,8 +1001,7 @@ #endif #ifdef CONFIG_HISAX_16_3 -#define CARD_TELES3 (1<< ISDN_CTYPE_16_3) | (1<< ISDN_CTYPE_PNP) | \ - (1<< ISDN_CTYPE_TELESPCMCIA) | (1<< ISDN_CTYPE_COMPAQ_ISA) +#define CARD_TELES3 1 #ifndef ISDN_CHIP_ISAC #define ISDN_CHIP_ISAC 1 #endif @@ -806,7 +1010,7 @@ #endif #ifdef CONFIG_HISAX_TELESPCI -#define CARD_TELESPCI (1<< ISDN_CTYPE_TELESPCI) +#define CARD_TELESPCI 1 #ifndef ISDN_CHIP_ISAC #define ISDN_CHIP_ISAC 1 #endif @@ -815,7 +1019,7 @@ #endif #ifdef CONFIG_HISAX_AVM_A1 -#define CARD_AVM_A1 (1<< ISDN_CTYPE_A1) +#define CARD_AVM_A1 1 #ifndef ISDN_CHIP_ISAC #define ISDN_CHIP_ISAC 1 #endif @@ -824,7 +1028,7 @@ #endif #ifdef CONFIG_HISAX_AVM_A1_PCMCIA -#define CARD_AVM_A1_PCMCIA (1<< ISDN_CTYPE_A1_PCMCIA) +#define CARD_AVM_A1_PCMCIA 1 #ifndef ISDN_CHIP_ISAC #define ISDN_CHIP_ISAC 1 #endif @@ -833,7 +1037,7 @@ #endif #ifdef CONFIG_HISAX_FRITZPCI -#define CARD_FRITZPCI (1<< ISDN_CTYPE_FRITZPCI) +#define CARD_FRITZPCI 1 #ifndef ISDN_CHIP_ISAC #define ISDN_CHIP_ISAC 1 #endif @@ -842,8 +1046,7 @@ #endif #ifdef CONFIG_HISAX_ELSA -#define CARD_ELSA (1<< ISDN_CTYPE_ELSA) | (1<< ISDN_CTYPE_ELSA_PNP) | \ - (1<< ISDN_CTYPE_ELSA_PCMCIA) | (1<< ISDN_CTYPE_ELSA_PCI) +#define CARD_ELSA 1 #ifndef ISDN_CHIP_ISAC #define ISDN_CHIP_ISAC 1 #endif @@ -855,9 +1058,8 @@ #define CARD_ELSA 0 #endif - #ifdef CONFIG_HISAX_IX1MICROR2 -#define CARD_IX1MICROR2 (1 << ISDN_CTYPE_IX1MICROR2) +#define CARD_IX1MICROR2 1 #ifndef ISDN_CHIP_ISAC #define ISDN_CHIP_ISAC 1 #endif @@ -866,7 +1068,7 @@ #endif #ifdef CONFIG_HISAX_DIEHLDIVA -#define CARD_DIEHLDIVA (1 << ISDN_CTYPE_DIEHLDIVA) +#define CARD_DIEHLDIVA 1 #ifndef ISDN_CHIP_ISAC #define ISDN_CHIP_ISAC 1 #endif @@ -875,7 +1077,7 @@ #endif #ifdef CONFIG_HISAX_ASUSCOM -#define CARD_ASUSCOM (1 << ISDN_CTYPE_ASUSCOM) +#define CARD_ASUSCOM 1 #ifndef ISDN_CHIP_ISAC #define ISDN_CHIP_ISAC 1 #endif @@ -884,7 +1086,7 @@ #endif #ifdef CONFIG_HISAX_TELEINT -#define CARD_TELEINT (1 << ISDN_CTYPE_TELEINT) +#define CARD_TELEINT 1 #ifndef ISDN_CHIP_ISAC #define ISDN_CHIP_ISAC 1 #endif @@ -893,7 +1095,7 @@ #endif #ifdef CONFIG_HISAX_SEDLBAUER -#define CARD_SEDLBAUER (1 << ISDN_CTYPE_SEDLBAUER) | (1 << ISDN_CTYPE_SEDLBAUER_PCMCIA) | ( 1 << ISDN_CTYPE_SEDLBAUER_FAX) +#define CARD_SEDLBAUER 1 #ifndef ISDN_CHIP_ISAC #define ISDN_CHIP_ISAC 1 #endif @@ -902,7 +1104,7 @@ #endif #ifdef CONFIG_HISAX_SPORTSTER -#define CARD_SPORTSTER (1 << ISDN_CTYPE_SPORTSTER) +#define CARD_SPORTSTER 1 #ifndef ISDN_CHIP_ISAC #define ISDN_CHIP_ISAC 1 #endif @@ -911,7 +1113,7 @@ #endif #ifdef CONFIG_HISAX_MIC -#define CARD_MIC (1 << ISDN_CTYPE_MIC) +#define CARD_MIC 1 #ifndef ISDN_CHIP_ISAC #define ISDN_CHIP_ISAC 1 #endif @@ -920,7 +1122,7 @@ #endif #ifdef CONFIG_HISAX_NETJET -#define CARD_NETJET (1 << ISDN_CTYPE_NETJET) +#define CARD_NETJET 1 #ifndef ISDN_CHIP_ISAC #define ISDN_CHIP_ISAC 1 #endif @@ -928,20 +1130,27 @@ #define CARD_NETJET 0 #endif -#ifdef CONFIG_HISAX_TELES3C -#define CARD_TELES3C (1<< ISDN_CTYPE_TELES3C) +#ifdef CONFIG_HISAX_HFCS +#define CARD_HFCS 1 +#else +#define CARD_HFCS 0 +#endif + +#ifdef CONFIG_HISAX_HFC_PCI +#define CARD_HFC_PCI 1 +extern int hfcpci_set_echo(struct IsdnCardState *, int); #else -#define CARD_TELES3C 0 +#define CARD_HFC_PCI 0 #endif #ifdef CONFIG_HISAX_AMD7930 -#define CARD_AMD7930 (1 << ISDN_CTYPE_AMD7930) +#define CARD_AMD7930 1 #else #define CARD_AMD7930 0 #endif #ifdef CONFIG_HISAX_NICCY -#define CARD_NICCY (1 << ISDN_CTYPE_NICCY) +#define CARD_NICCY 1 #ifndef ISDN_CHIP_ISAC #define ISDN_CHIP_ISAC 1 #endif @@ -949,8 +1158,17 @@ #define CARD_NICCY 0 #endif +#ifdef CONFIG_HISAX_ISURF +#define CARD_ISURF 1 +#ifndef ISDN_CHIP_ISAC +#define ISDN_CHIP_ISAC 1 +#endif +#else +#define CARD_ISURF 0 +#endif + #ifdef CONFIG_HISAX_S0BOX -#define CARD_S0BOX (1 << ISDN_CTYPE_S0BOX) +#define CARD_S0BOX 1 #ifndef ISDN_CHIP_ISAC #define ISDN_CHIP_ISAC 1 #endif @@ -958,12 +1176,50 @@ #define CARD_S0BOX 0 #endif -#define SUPORTED_CARDS (CARD_TELES0 | CARD_TELES3 | CARD_AVM_A1 | CARD_ELSA \ - | CARD_IX1MICROR2 | CARD_DIEHLDIVA | CARD_ASUSCOM \ - | CARD_TELEINT | CARD_SEDLBAUER | CARD_SPORTSTER \ - | CARD_MIC | CARD_NETJET | CARD_TELES3C | CARD_AMD7930 \ - | CARD_AVM_A1_PCMCIA | CARD_FRITZPCI\ - | CARD_NICCY | CARD_S0BOX | CARD_TELESPCI) +#ifdef CONFIG_HISAX_HSTSAPHIR +#define CARD_HSTSAPHIR 1 +#ifndef ISDN_CHIP_ISAC +#define ISDN_CHIP_ISAC 1 +#endif +#else +#define CARD_HSTSAPHIR 0 +#endif + +#ifdef CONFIG_HISAX_TESTEMU +#define CARD_TESTEMU 1 +#define ISDN_CTYPE_TESTEMU 99 +#undef ISDN_CTYPE_COUNT +#define ISDN_CTYPE_COUNT ISDN_CTYPE_TESTEMU +#else +#define CARD_TESTEMU 0 +#endif + +#ifdef CONFIG_HISAX_BKM_A4T +#define CARD_BKM_A4T 1 +#ifndef ISDN_CHIP_ISAC +#define ISDN_CHIP_ISAC 1 +#endif +#else +#define CARD_BKM_A4T 0 +#endif + +#ifdef CONFIG_HISAX_SCT_QUADRO +#define CARD_SCT_QUADRO 1 +#ifndef ISDN_CHIP_ISAC +#define ISDN_CHIP_ISAC 1 +#endif +#else +#define CARD_SCT_QUADRO 0 +#endif + +#ifdef CONFIG_HISAX_GAZEL +#define CARD_GAZEL 1 +#ifndef ISDN_CHIP_ISAC +#define ISDN_CHIP_ISAC 1 +#endif +#else +#define CARD_GAZEL 0 +#endif #define TEI_PER_CARD 0 diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/hscx.c linux/drivers/isdn/hisax/hscx.c --- v2.3.13/linux/drivers/isdn/hisax/hscx.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/hscx.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: hscx.c,v 1.16 1998/11/15 23:54:48 keil Exp $ +/* $Id: hscx.c,v 1.17 1999/07/01 08:11:41 keil Exp $ * hscx.c HSCX specific routines * @@ -6,6 +6,9 @@ * * * $Log: hscx.c,v $ + * Revision 1.17 1999/07/01 08:11:41 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.16 1998/11/15 23:54:48 keil * changes from 2.0 * @@ -110,12 +113,12 @@ if (bc == 0) { cs->BC_Write_Reg(cs, hscx, HSCX_TSAX, - test_bit(HW_IOM1, &cs->HW_Flags) ? 0x7 : 0x2f); + test_bit(HW_IOM1, &cs->HW_Flags) ? 0x7 : bcs->hw.hscx.tsaxr0); cs->BC_Write_Reg(cs, hscx, HSCX_TSAR, - test_bit(HW_IOM1, &cs->HW_Flags) ? 0x7 : 0x2f); + test_bit(HW_IOM1, &cs->HW_Flags) ? 0x7 : bcs->hw.hscx.tsaxr0); } else { - cs->BC_Write_Reg(cs, hscx, HSCX_TSAX, 0x3); - cs->BC_Write_Reg(cs, hscx, HSCX_TSAR, 0x3); + cs->BC_Write_Reg(cs, hscx, HSCX_TSAX, bcs->hw.hscx.tsaxr1); + cs->BC_Write_Reg(cs, hscx, HSCX_TSAR, bcs->hw.hscx.tsaxr1); } switch (mode) { case (L1_MODE_NULL): @@ -216,7 +219,7 @@ discard_queue(&bcs->rqueue); discard_queue(&bcs->squeue); if (bcs->tx_skb) { - dev_kfree_skb(bcs->tx_skb); + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); } @@ -301,6 +304,10 @@ cs->bcs[1].BC_Close = close_hscxstate; cs->bcs[0].hw.hscx.hscx = 0; cs->bcs[1].hw.hscx.hscx = 1; + cs->bcs[0].hw.hscx.tsaxr0 = 0x2f; + cs->bcs[0].hw.hscx.tsaxr1 = 3; + cs->bcs[1].hw.hscx.tsaxr0 = 0x2f; + cs->bcs[1].hw.hscx.tsaxr1 = 3; modehscx(cs->bcs, 0, 0); modehscx(cs->bcs + 1, 0, 0); } diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/hscx_irq.c linux/drivers/isdn/hisax/hscx_irq.c --- v2.3.13/linux/drivers/isdn/hisax/hscx_irq.c Tue Jun 1 23:25:48 1999 +++ linux/drivers/isdn/hisax/hscx_irq.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: hscx_irq.c,v 1.11 1998/11/15 23:54:49 keil Exp $ +/* $Id: hscx_irq.c,v 1.12 1999/07/01 08:11:42 keil Exp $ * hscx_irq.c low level b-channel stuff for Siemens HSCX * @@ -7,6 +7,9 @@ * This is an include file for fast inline IRQ stuff * * $Log: hscx_irq.c,v $ + * Revision 1.12 1999/07/01 08:11:42 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.11 1998/11/15 23:54:49 keil * changes from 2.0 * @@ -42,8 +45,6 @@ * */ -#include - static inline void waitforCEC(struct IsdnCardState *cs, int hscx) @@ -203,6 +204,7 @@ if (!(skb = dev_alloc_skb(count))) printk(KERN_WARNING "HSCX: receive out of memory\n"); else { + SET_SKB_FREE(skb); memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count); skb_queue_tail(&bcs->rqueue, skb); } @@ -218,6 +220,7 @@ if (!(skb = dev_alloc_skb(fifo_size))) printk(KERN_WARNING "HiSax: receive out of memory\n"); else { + SET_SKB_FREE(skb); memcpy(skb_put(skb, fifo_size), bcs->hw.hscx.rcvbuf, fifo_size); skb_queue_tail(&bcs->rqueue, skb); } @@ -234,7 +237,7 @@ if (bcs->st->lli.l1writewakeup && (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count); - dev_kfree_skb(bcs->tx_skb); + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); bcs->hw.hscx.count = 0; bcs->tx_skb = NULL; } diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/isac.c linux/drivers/isdn/hisax/isac.c --- v2.3.13/linux/drivers/isdn/hisax/isac.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/isac.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: isac.c,v 1.18 1998/11/15 23:54:51 keil Exp $ +/* $Id: isac.c,v 1.22 1999/08/09 19:04:40 keil Exp $ * isac.c ISAC specific routines * @@ -9,6 +9,19 @@ * ../../../Documentation/isdn/HiSax.cert * * $Log: isac.c,v $ + * Revision 1.22 1999/08/09 19:04:40 keil + * Fix race condition - Thanks to Christer Weinigel + * + * Revision 1.21 1999/07/12 21:05:17 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 1.20 1999/07/09 08:23:06 keil + * Fix ISAC lost TX IRQ handling + * + * Revision 1.19 1999/07/01 08:11:43 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.18 1998/11/15 23:54:51 keil * changes from 2.0 * @@ -69,6 +82,7 @@ #define __NO_VERSION__ #include "hisax.h" #include "isac.h" +#include "arcofi.h" #include "isdnl1.h" #include @@ -100,7 +114,7 @@ static void isac_new_ph(struct IsdnCardState *cs) { - switch (cs->ph_state) { + switch (cs->dc.isac.ph_state) { case (ISAC_IND_RS): case (ISAC_IND_EI): ph_command(cs, ISAC_CMD_DUI); @@ -154,14 +168,10 @@ DChannel_proc_rcv(cs); if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) DChannel_proc_xmt(cs); - if (test_and_clear_bit(D_RX_MON0, &cs->event)) - test_and_set_bit(HW_MON0_RX_END, &cs->HW_Flags); if (test_and_clear_bit(D_RX_MON1, &cs->event)) - test_and_set_bit(HW_MON1_RX_END, &cs->HW_Flags); - if (test_and_clear_bit(D_TX_MON0, &cs->event)) - test_and_set_bit(HW_MON0_TX_END, &cs->HW_Flags); + arcofi_fsm(cs, ARCOFI_RX_END, NULL); if (test_and_clear_bit(D_TX_MON1, &cs->event)) - test_and_set_bit(HW_MON1_TX_END, &cs->HW_Flags); + arcofi_fsm(cs, ARCOFI_TX_END, NULL); } void @@ -226,7 +236,6 @@ cs->tx_cnt += count; cs->writeisacfifo(cs, ptr, count); cs->writeisac(cs, ISAC_CMDR, more ? 0x8 : 0xa); - restore_flags(flags); if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { debugl1(cs, "isac_fill_fifo dbusytimer running"); del_timer(&cs->dbusytimer); @@ -234,6 +243,7 @@ init_timer(&cs->dbusytimer); cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000); add_timer(&cs->dbusytimer); + restore_flags(flags); if (cs->debug & L1_DEB_ISAC_FIFO) { char *t = cs->dlog; @@ -283,6 +293,7 @@ if (!(skb = alloc_skb(count, GFP_ATOMIC))) printk(KERN_WARNING "HiSax: D receive out of memory\n"); else { + SET_SKB_FREE(skb); memcpy(skb_put(skb, count), cs->rcvbuf, count); skb_queue_tail(&cs->rq, skb); } @@ -310,7 +321,7 @@ isac_fill_fifo(cs); goto afterXPR; } else { - dev_kfree_skb(cs->tx_skb); + idev_kfree_skb(cs->tx_skb, FREE_WRITE); cs->tx_cnt = 0; cs->tx_skb = NULL; } @@ -327,9 +338,9 @@ if (cs->debug & L1_DEB_ISAC) debugl1(cs, "ISAC CIR0 %02X", exval ); if (exval & 2) { - cs->ph_state = (exval >> 2) & 0xf; + cs->dc.isac.ph_state = (exval >> 2) & 0xf; if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "ph_state change %x", cs->ph_state); + debugl1(cs, "ph_state change %x", cs->dc.isac.ph_state); isac_sched_event(cs, D_L1STATECHANGE); } if (exval & 1) { @@ -347,127 +358,147 @@ exval = cs->readisac(cs, ISAC_EXIR); if (cs->debug & L1_DEB_WARN) debugl1(cs, "ISAC EXIR %02x", exval); - if (exval & 0x04) { + if (exval & 0x80) { /* XMR */ + debugl1(cs, "ISAC XMR"); + printk(KERN_WARNING "HiSax: ISAC XMR\n"); + } + if (exval & 0x40) { /* XDU */ + debugl1(cs, "ISAC XDU"); + printk(KERN_WARNING "HiSax: ISAC XDU\n"); + if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) + del_timer(&cs->dbusytimer); + if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) + isac_sched_event(cs, D_CLEARBUSY); + if (cs->tx_skb) { /* Restart frame */ + skb_push(cs->tx_skb, cs->tx_cnt); + cs->tx_cnt = 0; + isac_fill_fifo(cs); + } else { + printk(KERN_WARNING "HiSax: ISAC XDU no skb\n"); + debugl1(cs, "ISAC XDU no skb"); + } + } + if (exval & 0x04) { /* MOS */ v1 = cs->readisac(cs, ISAC_MOSR); if (cs->debug & L1_DEB_MONITOR) debugl1(cs, "ISAC MOSR %02x", v1); #if ARCOFI_USE if (v1 & 0x08) { - if (!cs->mon_rx) { - if (!(cs->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) { + if (!cs->dc.isac.mon_rx) { + if (!(cs->dc.isac.mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "ISAC MON RX out of memory!"); - cs->mocr &= 0xf0; - cs->mocr |= 0x0a; - cs->writeisac(cs, ISAC_MOCR, cs->mocr); + cs->dc.isac.mocr &= 0xf0; + cs->dc.isac.mocr |= 0x0a; + cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); goto afterMONR0; } else - cs->mon_rxp = 0; + cs->dc.isac.mon_rxp = 0; } - if (cs->mon_rxp >= MAX_MON_FRAME) { - cs->mocr &= 0xf0; - cs->mocr |= 0x0a; - cs->writeisac(cs, ISAC_MOCR, cs->mocr); - cs->mon_rxp = 0; + if (cs->dc.isac.mon_rxp >= MAX_MON_FRAME) { + cs->dc.isac.mocr &= 0xf0; + cs->dc.isac.mocr |= 0x0a; + cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); + cs->dc.isac.mon_rxp = 0; if (cs->debug & L1_DEB_WARN) debugl1(cs, "ISAC MON RX overflow!"); goto afterMONR0; } - cs->mon_rx[cs->mon_rxp++] = cs->readisac(cs, ISAC_MOR0); + cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp++] = cs->readisac(cs, ISAC_MOR0); if (cs->debug & L1_DEB_MONITOR) - debugl1(cs, "ISAC MOR0 %02x", cs->mon_rx[cs->mon_rxp -1]); - if (cs->mon_rxp == 1) { - cs->mocr |= 0x04; - cs->writeisac(cs, ISAC_MOCR, cs->mocr); + debugl1(cs, "ISAC MOR0 %02x", cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp -1]); + if (cs->dc.isac.mon_rxp == 1) { + cs->dc.isac.mocr |= 0x04; + cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); } } afterMONR0: if (v1 & 0x80) { - if (!cs->mon_rx) { - if (!(cs->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) { + if (!cs->dc.isac.mon_rx) { + if (!(cs->dc.isac.mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "ISAC MON RX out of memory!"); - cs->mocr &= 0x0f; - cs->mocr |= 0xa0; - cs->writeisac(cs, ISAC_MOCR, cs->mocr); + cs->dc.isac.mocr &= 0x0f; + cs->dc.isac.mocr |= 0xa0; + cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); goto afterMONR1; } else - cs->mon_rxp = 0; + cs->dc.isac.mon_rxp = 0; } - if (cs->mon_rxp >= MAX_MON_FRAME) { - cs->mocr &= 0x0f; - cs->mocr |= 0xa0; - cs->writeisac(cs, ISAC_MOCR, cs->mocr); - cs->mon_rxp = 0; + if (cs->dc.isac.mon_rxp >= MAX_MON_FRAME) { + cs->dc.isac.mocr &= 0x0f; + cs->dc.isac.mocr |= 0xa0; + cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); + cs->dc.isac.mon_rxp = 0; if (cs->debug & L1_DEB_WARN) debugl1(cs, "ISAC MON RX overflow!"); goto afterMONR1; } - cs->mon_rx[cs->mon_rxp++] = cs->readisac(cs, ISAC_MOR1); + cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp++] = cs->readisac(cs, ISAC_MOR1); if (cs->debug & L1_DEB_MONITOR) - debugl1(cs, "ISAC MOR1 %02x", cs->mon_rx[cs->mon_rxp -1]); - cs->mocr |= 0x40; - cs->writeisac(cs, ISAC_MOCR, cs->mocr); + debugl1(cs, "ISAC MOR1 %02x", cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp -1]); + cs->dc.isac.mocr |= 0x40; + cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); } afterMONR1: if (v1 & 0x04) { - cs->mocr &= 0xf0; - cs->writeisac(cs, ISAC_MOCR, cs->mocr); - cs->mocr |= 0x0a; - cs->writeisac(cs, ISAC_MOCR, cs->mocr); - test_and_set_bit(HW_MON0_RX_END, &cs->HW_Flags); + cs->dc.isac.mocr &= 0xf0; + cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); + cs->dc.isac.mocr |= 0x0a; + cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); + isac_sched_event(cs, D_RX_MON0); } if (v1 & 0x40) { - cs->mocr &= 0x0f; - cs->writeisac(cs, ISAC_MOCR, cs->mocr); - cs->mocr |= 0xa0; - cs->writeisac(cs, ISAC_MOCR, cs->mocr); - test_and_set_bit(HW_MON1_RX_END, &cs->HW_Flags); + cs->dc.isac.mocr &= 0x0f; + cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); + cs->dc.isac.mocr |= 0xa0; + cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); + isac_sched_event(cs, D_RX_MON1); } if (v1 & 0x02) { - if ((!cs->mon_tx) || (cs->mon_txc && - (cs->mon_txp >= cs->mon_txc) && + if ((!cs->dc.isac.mon_tx) || (cs->dc.isac.mon_txc && + (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc) && !(v1 & 0x08))) { - cs->mocr &= 0xf0; - cs->writeisac(cs, ISAC_MOCR, cs->mocr); - cs->mocr |= 0x0a; - cs->writeisac(cs, ISAC_MOCR, cs->mocr); - if (cs->mon_txc && - (cs->mon_txp >= cs->mon_txc)) - test_and_set_bit(HW_MON0_TX_END, &cs->HW_Flags); + cs->dc.isac.mocr &= 0xf0; + cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); + cs->dc.isac.mocr |= 0x0a; + cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); + if (cs->dc.isac.mon_txc && + (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc)) + isac_sched_event(cs, D_TX_MON0); goto AfterMOX0; } - if (cs->mon_txc && (cs->mon_txp >= cs->mon_txc)) { - test_and_set_bit(HW_MON0_TX_END, &cs->HW_Flags); + if (cs->dc.isac.mon_txc && (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc)) { + isac_sched_event(cs, D_TX_MON0); goto AfterMOX0; } cs->writeisac(cs, ISAC_MOX0, - cs->mon_tx[cs->mon_txp++]); + cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]); if (cs->debug & L1_DEB_MONITOR) - debugl1(cs, "ISAC %02x -> MOX0", cs->mon_tx[cs->mon_txp -1]); + debugl1(cs, "ISAC %02x -> MOX0", cs->dc.isac.mon_tx[cs->dc.isac.mon_txp -1]); } AfterMOX0: if (v1 & 0x20) { - if ((!cs->mon_tx) || (cs->mon_txc && - (cs->mon_txp >= cs->mon_txc) && + if ((!cs->dc.isac.mon_tx) || (cs->dc.isac.mon_txc && + (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc) && !(v1 & 0x80))) { - cs->mocr &= 0x0f; - cs->writeisac(cs, ISAC_MOCR, cs->mocr); - cs->mocr |= 0xa0; - cs->writeisac(cs, ISAC_MOCR, cs->mocr); - if (cs->mon_txc && - (cs->mon_txp >= cs->mon_txc)) - test_and_set_bit(HW_MON1_TX_END, &cs->HW_Flags); + cs->dc.isac.mocr &= 0x0f; + cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); + cs->dc.isac.mocr |= 0xa0; + cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr); + if (cs->dc.isac.mon_txc && + (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc)) + isac_sched_event(cs, D_TX_MON1); goto AfterMOX1; } - if (cs->mon_txc && (cs->mon_txp >= cs->mon_txc)) { - test_and_set_bit(HW_MON1_TX_END, &cs->HW_Flags); + if (cs->dc.isac.mon_txc && (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc)) { + isac_sched_event(cs, D_TX_MON1); goto AfterMOX1; } cs->writeisac(cs, ISAC_MOX1, - cs->mon_tx[cs->mon_txp++]); + cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]); if (cs->debug & L1_DEB_MONITOR) - debugl1(cs, "ISAC %02x -> MOX1", cs->mon_tx[cs->mon_txp -1]); + debugl1(cs, "ISAC %02x -> MOX1", cs->dc.isac.mon_tx[cs->dc.isac.mon_txp -1]); } AfterMOX1: #endif @@ -535,9 +566,9 @@ test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); break; case (HW_RESET | REQUEST): - if ((cs->ph_state == ISAC_IND_EI) || - (cs->ph_state == ISAC_IND_DR) || - (cs->ph_state == ISAC_IND_RS)) + if ((cs->dc.isac.ph_state == ISAC_IND_EI) || + (cs->dc.isac.ph_state == ISAC_IND_DR) || + (cs->dc.isac.ph_state == ISAC_IND_RS)) ph_command(cs, ISAC_CMD_TIM); else ph_command(cs, ISAC_CMD_RS); @@ -576,7 +607,7 @@ discard_queue(&cs->rq); discard_queue(&cs->sq); if (cs->tx_skb) { - dev_kfree_skb(cs->tx_skb); + idev_kfree_skb(cs->tx_skb, FREE_WRITE); cs->tx_skb = NULL; } if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) @@ -597,27 +628,50 @@ st->l1.l1hw = ISAC_l1hw; } +void +DC_Close_isac(struct IsdnCardState *cs) { + if (cs->dc.isac.mon_rx) { + kfree(cs->dc.isac.mon_rx); + cs->dc.isac.mon_rx = NULL; + } + if (cs->dc.isac.mon_tx) { + kfree(cs->dc.isac.mon_tx); + cs->dc.isac.mon_tx = NULL; + } +} + static void dbusy_timer_handler(struct IsdnCardState *cs) { struct PStack *stptr; - int val; + int rbch, star; if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { - if (cs->debug) { - debugl1(cs, "D-Channel Busy"); - val = cs->readisac(cs, ISAC_RBCH); - if (val & ISAC_RBCH_XAC) - debugl1(cs, "ISAC XAC"); - else - debugl1(cs, "ISAC No XAC"); - } - test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags); - stptr = cs->stlist; - - while (stptr != NULL) { - stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL); - stptr = stptr->next; + rbch = cs->readisac(cs, ISAC_RBCH); + star = cs->readisac(cs, ISAC_STAR); + if (cs->debug) + debugl1(cs, "D-Channel Busy RBCH %02x STAR %02x", + rbch, star); + if (rbch & ISAC_RBCH_XAC) { /* D-Channel Busy */ + test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags); + stptr = cs->stlist; + while (stptr != NULL) { + stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL); + stptr = stptr->next; + } + } else { + /* discard frame; reset transceiver */ + test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags); + if (cs->tx_skb) { + idev_kfree_skb(cs->tx_skb, FREE_WRITE); + cs->tx_cnt = 0; + cs->tx_skb = NULL; + } else { + printk(KERN_WARNING "HiSax: ISAC D-Channel Busy no skb\n"); + debugl1(cs, "D-Channel Busy no skb"); + } + cs->writeisac(cs, ISAC_CMDR, 0x01); /* Transmitter reset */ + cs->irq_func(cs->irq, cs, NULL); } } } @@ -627,11 +681,14 @@ { cs->tqueue.routine = (void *) (void *) isac_bh; cs->setstack_d = setstack_isac; + cs->DC_Close = DC_Close_isac; + cs->dc.isac.mon_tx = NULL; + cs->dc.isac.mon_rx = NULL; cs->dbusytimer.function = (void *) dbusy_timer_handler; cs->dbusytimer.data = (long) cs; init_timer(&cs->dbusytimer); cs->writeisac(cs, ISAC_MASK, 0xff); - cs->mocr = 0xaa; + cs->dc.isac.mocr = 0xaa; if (test_bit(HW_IOM1, &cs->HW_Flags)) { /* IOM 1 Mode */ cs->writeisac(cs, ISAC_ADF2, 0x0); @@ -641,7 +698,9 @@ cs->writeisac(cs, ISAC_MODE, 0xc9); } else { /* IOM 2 Mode */ - cs->writeisac(cs, ISAC_ADF2, 0x80); + if (!cs->dc.isac.adf2) + cs->dc.isac.adf2 = 0x80; + cs->writeisac(cs, ISAC_ADF2, cs->dc.isac.adf2); cs->writeisac(cs, ISAC_SQXR, 0x2f); cs->writeisac(cs, ISAC_SPCR, 0x00); cs->writeisac(cs, ISAC_STCR, 0x70); @@ -672,7 +731,7 @@ } val = cs->readisac(cs, ISAC_CIR0); debugl1(cs, "ISAC CIR0 %x", val); - cs->ph_state = (val >> 2) & 0xf; + cs->dc.isac.ph_state = (val >> 2) & 0xf; isac_sched_event(cs, D_L1STATECHANGE); /* Disable all IRQ */ cs->writeisac(cs, ISAC_MASK, 0xFF); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/isar.c linux/drivers/isdn/hisax/isar.c --- v2.3.13/linux/drivers/isdn/hisax/isar.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/isar.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: isar.c,v 1.2 1998/11/15 23:54:53 keil Exp $ +/* $Id: isar.c,v 1.4 1999/08/05 20:43:18 keil Exp $ * isar.c ISAR (Siemens PSB 7110) specific routines * @@ -6,6 +6,12 @@ * * * $Log: isar.c,v $ + * Revision 1.4 1999/08/05 20:43:18 keil + * ISAR analog modem support + * + * Revision 1.3 1999/07/01 08:11:45 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.2 1998/11/15 23:54:53 keil * changes from 2.0 * @@ -425,7 +431,9 @@ cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); break; case L1_MODE_TRANS: + case L1_MODE_V32: if ((skb = dev_alloc_skb(ireg->clsb))) { + SET_SKB_FREE(skb); rcv_mbox(cs, ireg, (u_char *)skb_put(skb, ireg->clsb)); skb_queue_tail(&bcs->rqueue, skb); isar_sched_event(bcs, B_RCVBUFREADY); @@ -459,6 +467,7 @@ } else if (!(skb = dev_alloc_skb(bcs->hw.isar.rcvidx-2))) printk(KERN_WARNING "ISAR: receive out of memory\n"); else { + SET_SKB_FREE(skb); memcpy(skb_put(skb, bcs->hw.isar.rcvidx-2), bcs->hw.isar.rcvbuf, bcs->hw.isar.rcvidx-2); skb_queue_tail(&bcs->rqueue, skb); @@ -512,6 +521,7 @@ printk(KERN_ERR"isar_fill_fifo wrong mode 0\n"); break; case L1_MODE_TRANS: + case L1_MODE_V32: if (!sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA, 0, count, ptr)) { if (cs->debug) @@ -557,7 +567,7 @@ if (bcs->st->lli.l1writewakeup && (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.isar.txcnt); - dev_kfree_skb(bcs->tx_skb); + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); bcs->hw.isar.txcnt = 0; bcs->tx_skb = NULL; } @@ -593,6 +603,136 @@ } } +const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200", "NODEF4", + "300", "600", "1200", "2400", "4800", "7200", + "9600nt", "9600t", "12000", "14400", "WRONG"}; +const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21", + "Bell103", "V23", "Bell202", "V17", "V29", "V27ter"}; + +static void +isar_pump_status_rsp(struct BCState *bcs, struct isar_reg *ireg) { + struct IsdnCardState *cs = bcs->cs; + u_char ril = ireg->par[0]; + u_char rim; + + if (!test_and_clear_bit(ISAR_RATE_REQ, &bcs->hw.isar.reg->Flags)) + return; + if (ril > 14) { + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "wrong pstrsp ril=%d",ril); + ril = 15; + } + switch(ireg->par[1]) { + case 0: + rim = 0; + break; + case 0x20: + rim = 2; + break; + case 0x40: + rim = 3; + break; + case 0x41: + rim = 4; + break; + case 0x51: + rim = 5; + break; + case 0x61: + rim = 6; + break; + case 0x71: + rim = 7; + break; + case 0x82: + rim = 8; + break; + case 0x92: + rim = 9; + break; + case 0xa2: + rim = 10; + break; + default: + rim = 1; + break; + } + sprintf(bcs->hw.isar.conmsg,"%s %s", dmril[ril], dmrim[rim]); + bcs->conmsg = bcs->hw.isar.conmsg; + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "pump strsp %s", bcs->conmsg); +} + +static void +isar_pump_status_ev(struct BCState *bcs, u_char devt) { + struct IsdnCardState *cs = bcs->cs; + u_char dps = SET_DPS(bcs->hw.isar.dpath); + + switch(devt) { + case PSEV_10MS_TIMER: + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "pump stev TIMER"); + break; + case PSEV_CON_ON: + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "pump stev CONNECT"); + l1_msg_b(bcs->st, PH_ACTIVATE | REQUEST, NULL); + break; + case PSEV_CON_OFF: + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "pump stev NO CONNECT"); + sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL); + l1_msg_b(bcs->st, PH_DEACTIVATE | REQUEST, NULL); + break; + case PSEV_V24_OFF: + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "pump stev V24 OFF"); + break; + case PSEV_CTS_ON: + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "pump stev CTS ON"); + break; + case PSEV_CTS_OFF: + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "pump stev CTS OFF"); + break; + case PSEV_DCD_ON: + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "pump stev CARRIER ON"); + test_and_set_bit(ISAR_RATE_REQ, &bcs->hw.isar.reg->Flags); + sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL); + break; + case PSEV_DCD_OFF: + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "pump stev CARRIER OFF"); + break; + case PSEV_DSR_ON: + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "pump stev DSR ON"); +// sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, 0xCF, 0, NULL); + break; + case PSEV_DSR_OFF: + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "pump stev DSR_OFF"); + break; + case PSEV_REM_RET: + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "pump stev REMOTE RETRAIN"); + break; + case PSEV_REM_REN: + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "pump stev REMOTE RENEGOTIATE"); + break; + case PSEV_GSTN_CLR: + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "pump stev GSTN CLEAR", devt); + break; + default: + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "unknown pump stev %x", devt); + break; + } +} static char debbuf[64]; @@ -628,10 +768,31 @@ if (cs->debug & L1_DEB_WARN) debugl1(cs, "Buffer STEV dpath%d msb(%x)", ireg->iis>>6, ireg->cmsb); + case ISAR_IIS_PSTEV: + if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) { + rcv_mbox(cs, ireg, (u_char *)ireg->par); + isar_pump_status_ev(bcs, ireg->cmsb); + } else { + debugl1(cs, "isar spurious IIS_PSTEV %x/%x/%x", + ireg->iis, ireg->cmsb, ireg->clsb); + printk(KERN_WARNING"isar spurious IIS_PSTEV %x/%x/%x\n", + ireg->iis, ireg->cmsb, ireg->clsb); + cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); + } break; - case ISAR_IIS_DIAG: case ISAR_IIS_PSTRSP: - case ISAR_IIS_PSTEV: + if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) { + rcv_mbox(cs, ireg, (u_char *)ireg->par); + isar_pump_status_rsp(bcs, ireg); + } else { + debugl1(cs, "isar spurious IIS_PSTRSP %x/%x/%x", + ireg->iis, ireg->cmsb, ireg->clsb); + printk(KERN_WARNING"isar spurious IIS_PSTRSP %x/%x/%x\n", + ireg->iis, ireg->cmsb, ireg->clsb); + cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); + } + break; + case ISAR_IIS_DIAG: case ISAR_IIS_BSTRSP: case ISAR_IIS_IOM2RSP: rcv_mbox(cs, ireg, (u_char *)ireg->par); @@ -659,7 +820,8 @@ setup_pump(struct BCState *bcs) { struct IsdnCardState *cs = bcs->cs; u_char dps = SET_DPS(bcs->hw.isar.dpath); - + u_char ctrl, param[6]; + switch (bcs->mode) { case L1_MODE_NULL: case L1_MODE_TRANS: @@ -670,6 +832,44 @@ bcs->hw.isar.dpath); } break; + case L1_MODE_V32: + ctrl = PMOD_DATAMODEM; + if (test_bit(BC_FLG_ORIG, &bcs->Flag)) { + ctrl |= PCTRL_ORIG; + param[5] = PV32P6_CTN; + } else { + param[5] = PV32P6_ATN; + } + param[0] = 11; /* 11 db */ +// param[1] = PV32P2_V22A | PV32P2_V22B | PV32P2_V21; + param[1] = PV32P2_V22A; +// param[2] = PV32P3_AMOD | PV32P3_V32B; + param[2] = PV32P3_AMOD; + param[3] = PV32P4_48; + param[4] = PV32P5_48; +// param[3] = PV32P4_UT144; +// param[4] = PV32P5_UT144; + if (!sendmsg(cs, dps | ISAR_HIS_PUMPCFG, ctrl, 6, param)) { + if (cs->debug) + debugl1(cs, "isar pump datamodem cfg dp%d failed", + bcs->hw.isar.dpath); + } + break; + case L1_MODE_FAX: + ctrl = PMOD_FAX; + if (test_bit(BC_FLG_ORIG, &bcs->Flag)) { + ctrl |= PCTRL_ORIG; + param[1] = PFAXP2_CTN; + } else { + param[1] = PFAXP2_ATN; + } + param[0] = 8; /* 8 db */ + if (!sendmsg(cs, dps | ISAR_HIS_PUMPCFG, ctrl, 2, param)) { + if (cs->debug) + debugl1(cs, "isar pump faxmodem cfg dp%d failed", + bcs->hw.isar.dpath); + } + break; } if (!sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL)) { if (cs->debug) @@ -682,6 +882,7 @@ setup_sart(struct BCState *bcs) { struct IsdnCardState *cs = bcs->cs; u_char dps = SET_DPS(bcs->hw.isar.dpath); + u_char ctrl, param[2]; switch (bcs->mode) { case L1_MODE_NULL: @@ -701,7 +902,17 @@ case L1_MODE_HDLC: if (!sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_HDLC, 1, "\0")) { if (cs->debug) - debugl1(cs, "isar sart binary dp%d failed", + debugl1(cs, "isar sart hdlc dp%d failed", + bcs->hw.isar.dpath); + } + break; + case L1_MODE_V32: + ctrl = SMODE_V14 | SCTRL_HDMC_BOTH; + param[0] = S_P1_CHS_8; + param[1] = S_P2_BFT_DEF; + if (!sendmsg(cs, dps | ISAR_HIS_SARTCFG, ctrl, 2, param)) { + if (cs->debug) + debugl1(cs, "isar sart v14 dp%d failed", bcs->hw.isar.dpath); } break; @@ -717,18 +928,22 @@ setup_iom2(struct BCState *bcs) { struct IsdnCardState *cs = bcs->cs; u_char dps = SET_DPS(bcs->hw.isar.dpath); - u_char cmsb = 0, msg[5] = {0x10,0,0,0,0}; + u_char cmsb = IOM_CTRL_ENA, msg[5] = {IOM_P1_TXD,0,0,0,0}; + if (bcs->channel) + msg[1] = msg[3] = 1; switch (bcs->mode) { case L1_MODE_NULL: + cmsb = 0; /* dummy slot */ msg[1] = msg[3] = bcs->hw.isar.dpath + 2; break; case L1_MODE_TRANS: case L1_MODE_HDLC: - cmsb = 0x80; - if (bcs->channel) - msg[1] = msg[3] = 1; + break; + case L1_MODE_V32: + case L1_MODE_FAX: + cmsb |= IOM_CTRL_ALAW | IOM_CTRL_RCV; break; } if (!sendmsg(cs, dps | ISAR_HIS_IOM2CFG, cmsb, 5, msg)) { @@ -763,7 +978,18 @@ &bcs->hw.isar.reg->Flags)) bcs->hw.isar.dpath = 1; else { - printk(KERN_ERR"isar modeisar both pathes in use\n"); + printk(KERN_WARNING"isar modeisar both pathes in use\n"); + return(1); + } + break; + case L1_MODE_V32: + /* only datapath 1 */ + if (!test_and_set_bit(ISAR_DP1_USE, + &bcs->hw.isar.reg->Flags)) + bcs->hw.isar.dpath = 1; + else { + printk(KERN_WARNING"isar modeisar analog funktions only with DP1\n"); + debugl1(cs, "isar modeisar analog funktions only with DP1"); return(1); } break; @@ -774,8 +1000,8 @@ bcs->hw.isar.dpath, bcs->mode, mode, bc); bcs->mode = mode; setup_pump(bcs); - setup_sart(bcs); setup_iom2(bcs); + setup_sart(bcs); if (bcs->mode == L1_MODE_NULL) { /* Clear resources */ if (bcs->hw.isar.dpath == 1) @@ -853,8 +1079,24 @@ break; case (PH_ACTIVATE | REQUEST): test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); - modeisar(st->l1.bcs, st->l1.mode, st->l1.bc); - l1_msg_b(st, pr, arg); + st->l1.bcs->hw.isar.conmsg[0] = 0; + if (test_bit(FLG_ORIG, &st->l2.flag)) + test_and_set_bit(BC_FLG_ORIG, &st->l1.bcs->Flag); + else + test_and_clear_bit(BC_FLG_ORIG, &st->l1.bcs->Flag); + switch(st->l1.mode) { + case L1_MODE_TRANS: + case L1_MODE_HDLC: + if (modeisar(st->l1.bcs, st->l1.mode, st->l1.bc)) + l1_msg_b(st, PH_DEACTIVATE | REQUEST, arg); + else + l1_msg_b(st, PH_ACTIVATE | REQUEST, arg); + break; + case L1_MODE_V32: + if (modeisar(st->l1.bcs, st->l1.mode, st->l1.bc)) + l1_msg_b(st, PH_DEACTIVATE | REQUEST, arg); + break; + } break; case (PH_DEACTIVATE | REQUEST): l1_msg_b(st, pr, arg); @@ -882,7 +1124,7 @@ discard_queue(&bcs->rqueue); discard_queue(&bcs->squeue); if (bcs->tx_skb) { - dev_kfree_skb(bcs->tx_skb); + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); if (bcs->cs->debug & L1_DEB_HSCX) diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/isar.h linux/drivers/isdn/hisax/isar.h --- v2.3.13/linux/drivers/isdn/hisax/isar.h Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/isar.h Thu Aug 12 09:42:33 1999 @@ -1,10 +1,16 @@ -/* $Id: isar.h,v 1.2 1998/11/15 23:54:54 keil Exp $ +/* $Id: isar.h,v 1.4 1999/08/05 20:43:20 keil Exp $ * isar.h ISAR (Siemens PSB 7110) specific defines * * Author Karsten Keil (keil@isdn4linux.de) * * * $Log: isar.h,v $ + * Revision 1.4 1999/08/05 20:43:20 keil + * ISAR analog modem support + * + * Revision 1.3 1999/07/01 08:11:46 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.2 1998/11/15 23:54:54 keil * changes from 2.0 * @@ -36,8 +42,10 @@ #define ISAR_HIS_P12CFG 0x24 #define ISAR_HIS_SARTCFG 0x25 #define ISAR_HIS_PUMPCFG 0x26 +#define ISAR_HIS_PUMPCTRL 0x2a #define ISAR_HIS_IOM2CFG 0x27 #define ISAR_HIS_IOM2REQ 0x07 +#define ISAR_HIS_IOM2CTRL 0x2b #define ISAR_HIS_BSTREQ 0x0c #define ISAR_HIS_PSTREQ 0x0e #define ISAR_HIS_SDATA 0x20 @@ -66,12 +74,97 @@ #define ISAR_DP1_USE 1 #define ISAR_DP2_USE 2 +#define ISAR_RATE_REQ 3 +#define PMOD_DISABLE 0 +#define PMOD_FAX 1 +#define PMOD_DATAMODEM 2 +#define PMOD_HALFDUPLEX 3 +#define PMOD_V110 4 +#define PMOD_DTMF 5 +#define PMOD_DTMF_TRANS 6 #define PMOD_BYPASS 7 +#define PCTRL_ORIG 0x80 +#define PV32P2_V23R 0x40 +#define PV32P2_V22A 0x20 +#define PV32P2_V22B 0x10 +#define PV32P2_V22C 0x08 +#define PV32P2_V21 0x02 +#define PV32P2_BEL 0x01 + +#define PV32P3_AMOD 0x80 +#define PV32P3_V32B 0x02 +#define PV32P4_48 0x05 +#define PV32P5_48 0x11 +#define PV32P4_UT48 0x0d +#define PV32P5_UT48 0x11 +#define PV32P4_96 0x03 +#define PV32P5_96 0x11 +#define PV32P4_UT96 0x0f +#define PV32P5_UT96 0x11 +#define PV32P4_B96 0x0b +#define PV32P5_B96 0x91 +#define PV32P4_UTB96 0x0f +#define PV32P5_UTB96 0xd1 +#define PV32P4_120 0x09 +#define PV32P5_120 0xb1 +#define PV32P4_UT120 0x0f +#define PV32P5_UT120 0xf1 +#define PV32P4_144 0x09 +#define PV32P5_144 0x99 +#define PV32P4_UT144 0x0f +#define PV32P5_UT144 0xf9 +#define PV32P6_CTN 0x01 +#define PV32P6_ATN 0x02 +#define PFAXP2_CTN 0x01 +#define PFAXP2_ATN 0x04 + +#define PSEV_10MS_TIMER 0x02 +#define PSEV_CON_ON 0x18 +#define PSEV_CON_OFF 0x19 +#define PSEV_V24_OFF 0x20 +#define PSEV_CTS_ON 0x21 +#define PSEV_CTS_OFF 0x22 +#define PSEV_DCD_ON 0x23 +#define PSEV_DCD_OFF 0x24 +#define PSEV_DSR_ON 0x25 +#define PSEV_DSR_OFF 0x26 +#define PSEV_REM_RET 0xcc +#define PSEV_REM_REN 0xcd +#define PSEV_GSTN_CLR 0xd4 + +#define PCTRL_LOC_RET 0xcf +#define PCTRL_LOC_REN 0xce + #define SMODE_DISABLE 0 +#define SMODE_V14 2 #define SMODE_HDLC 3 #define SMODE_BINARY 4 +#define SMODE_FSK_V14 5 + +#define SCTRL_HDMC_BOTH 0x00 +#define SCTRL_HDMC_DTX 0x80 +#define SCTRL_HDMC_DRX 0x40 +#define S_P1_OVSP 0x40 +#define S_P1_SNP 0x20 +#define S_P1_EOP 0x10 +#define S_P1_EDP 0x08 +#define S_P1_NSB 0x04 +#define S_P1_CHS_8 0x03 +#define S_P1_CHS_7 0x02 +#define S_P1_CHS_6 0x01 +#define S_P1_CHS_5 0x00 + +#define S_P2_BFT_DEF 30 + +#define IOM_CTRL_ENA 0x80 +#define IOM_CTRL_NOPCM 0x00 +#define IOM_CTRL_ALAW 0x02 +#define IOM_CTRL_ULAW 0x04 +#define IOM_CTRL_RCV 0x01 + +#define IOM_P1_TXD 0x10 #define HDLC_FED 0x40 #define HDLC_FSD 0x20 diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/isdnl1.c linux/drivers/isdn/hisax/isdnl1.c --- v2.3.13/linux/drivers/isdn/hisax/isdnl1.c Wed May 26 16:55:40 1999 +++ linux/drivers/isdn/hisax/isdnl1.c Sun Aug 15 11:49:08 1999 @@ -1,4 +1,4 @@ -/* $Id: isdnl1.c,v 2.31 1998/11/15 23:54:56 keil Exp $ +/* $Id: isdnl1.c,v 2.34 1999/07/09 13:50:15 keil Exp $ * isdnl1.c common low level stuff for Siemens Chipsetbased isdn cards * based on the teles driver from Jan den Ouden @@ -15,6 +15,15 @@ * * * $Log: isdnl1.c,v $ + * Revision 2.34 1999/07/09 13:50:15 keil + * remove unused variable + * + * Revision 2.33 1999/07/09 13:34:33 keil + * remove debug code + * + * Revision 2.32 1999/07/01 08:11:47 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 2.31 1998/11/15 23:54:56 keil * changes from 2.0 * @@ -120,7 +129,7 @@ * */ -const char *l1_revision = "$Revision: 2.31 $"; +const char *l1_revision = "$Revision: 2.34 $"; #define __NO_VERSION__ #include "hisax.h" @@ -298,9 +307,18 @@ Logl2Frame(cs, skb, "PH_DATA", 1); #endif stptr = cs->stlist; + if (skb->len<3) { + debugl1(cs, "D-channel frame too short(%d)",skb->len); + idev_kfree_skb(skb, FREE_READ); + return; + } + if ((skb->data[0] & 1) || !(skb->data[1] &1)) { + debugl1(cs, "D-channel frame wrong EA0/EA1"); + idev_kfree_skb(skb, FREE_READ); + return; + } sapi = skb->data[0] >> 2; tei = skb->data[1] >> 1; - if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len); if (cs->debug & DEB_DLOG_VERBOSE) @@ -323,7 +341,7 @@ stptr = stptr->next; } } - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); } else if (sapi == CTRL_SAPI) { /* sapi 0 */ found = 0; while (stptr != NULL) @@ -334,7 +352,7 @@ } else stptr = stptr->next; if (!found) - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); } } } diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/isdnl2.c linux/drivers/isdn/hisax/isdnl2.c --- v2.3.13/linux/drivers/isdn/hisax/isdnl2.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/isdnl2.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: isdnl2.c,v 2.16 1998/11/15 23:55:01 keil Exp $ +/* $Id: isdnl2.c,v 2.19 1999/08/05 20:40:26 keil Exp $ * Author Karsten Keil (keil@isdn4linux.de) * based on the teles driver from Jan den Ouden @@ -11,6 +11,15 @@ * Fritz Elfert * * $Log: isdnl2.c,v $ + * Revision 2.19 1999/08/05 20:40:26 keil + * Fix interlayer communication + * + * Revision 2.18 1999/07/21 14:46:16 keil + * changes from EICON certification + * + * Revision 2.17 1999/07/01 08:11:50 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 2.16 1998/11/15 23:55:01 keil * changes from 2.0 * @@ -71,7 +80,7 @@ #include "hisax.h" #include "isdnl2.h" -const char *l2_revision = "$Revision: 2.16 $"; +const char *l2_revision = "$Revision: 2.19 $"; static void l2m_debug(struct FsmInst *fi, char *fmt, ...); @@ -106,7 +115,7 @@ enum { EV_L2_UI, - EV_L2_SABMX, + EV_L2_SABME, EV_L2_DISC, EV_L2_DM, EV_L2_UA, @@ -116,22 +125,25 @@ EV_L2_DL_DATA, EV_L2_ACK_PULL, EV_L2_DL_UNIT_DATA, - EV_L2_DL_ESTABLISH, - EV_L2_DL_RELEASE, + EV_L2_DL_ESTABLISH_REQ, + EV_L2_DL_RELEASE_REQ, EV_L2_MDL_ASSIGN, EV_L2_MDL_REMOVE, EV_L2_MDL_ERROR, EV_L1_DEACTIVATE, EV_L2_T200, EV_L2_T203, + EV_L2_SET_OWN_BUSY, + EV_L2_CLEAR_OWN_BUSY, + EV_L2_FRAME_ERROR, }; -#define L2_EVENT_COUNT (EV_L2_T203+1) +#define L2_EVENT_COUNT (EV_L2_FRAME_ERROR+1) static char *strL2Event[] = { "EV_L2_UI", - "EV_L2_SABMX", + "EV_L2_SABME", "EV_L2_DISC", "EV_L2_DM", "EV_L2_UA", @@ -141,19 +153,35 @@ "EV_L2_DL_DATA", "EV_L2_ACK_PULL", "EV_L2_DL_UNIT_DATA", - "EV_L2_DL_ESTABLISH", - "EV_L2_DL_RELEASE", + "EV_L2_DL_ESTABLISH_REQ", + "EV_L2_DL_RELEASE_REQ", "EV_L2_MDL_ASSIGN", "EV_L2_MDL_REMOVE", "EV_L2_MDL_ERROR", "EV_L1_DEACTIVATE", "EV_L2_T200", "EV_L2_T203", + "EV_L2_SET_OWN_BUSY", + "EV_L2_CLEAR_OWN_BUSY", + "EV_L2_FRAME_ERROR", }; static int l2addrsize(struct Layer2 *l2); static void +set_peer_busy(struct Layer2 *l2) { + test_and_set_bit(FLG_PEER_BUSY, &l2->flag); + if (skb_queue_len(&l2->i_queue) || skb_queue_len(&l2->ui_queue)) + test_and_set_bit(FLG_L2BLOCK, &l2->flag); +} + +static void +clear_peer_busy(struct Layer2 *l2) { + if (test_and_clear_bit(FLG_PEER_BUSY, &l2->flag)) + test_and_clear_bit(FLG_L2BLOCK, &l2->flag); +} + +static void InitWin(struct Layer2 *l2) { int i; @@ -162,30 +190,45 @@ l2->windowar[i] = NULL; } -static void -ReleaseWin(struct Layer2 *l2) +static int +freewin1(struct Layer2 *l2) { int i, cnt = 0; for (i = 0; i < MAX_WINDOW; i++) { if (l2->windowar[i]) { cnt++; - dev_kfree_skb(l2->windowar[i]); + idev_kfree_skb(l2->windowar[i], FREE_WRITE); l2->windowar[i] = NULL; } } - if (cnt) + return cnt; +} + +inline void +freewin(struct PStack *st) +{ + freewin1(&st->l2); +} + +static void +ReleaseWin(struct Layer2 *l2) +{ + int cnt; + + if((cnt = freewin1(l2))) printk(KERN_WARNING "isdl2 freed %d skbuffs in release\n", cnt); } -inline int +inline unsigned int cansend(struct PStack *st) { - int p1; + unsigned int p1; - p1 = st->l2.vs - st->l2.va; - if (p1 < 0) - p1 += (test_bit(FLG_MOD128, &st->l2.flag) ? 128 : 8); + if(test_bit(FLG_MOD128, &st->l2.flag)) + p1 = (st->l2.vs - st->l2.va) % 128; + else + p1 = (st->l2.vs - st->l2.va) % 8; return ((p1 < st->l2.window) && !test_bit(FLG_PEER_BUSY, &st->l2.flag)); } @@ -195,7 +238,7 @@ test_and_clear_bit(FLG_ACK_PEND, &l2->flag); test_and_clear_bit(FLG_REJEXC, &l2->flag); test_and_clear_bit(FLG_OWN_BUSY, &l2->flag); - test_and_clear_bit(FLG_PEER_BUSY, &l2->flag); + clear_peer_busy(l2); } inline int @@ -244,98 +287,197 @@ #define enqueue_ui(a, b) enqueue_super(a, b) inline int -IsUI(u_char * data, int ext) +IsUI(u_char * data) { return ((data[0] & 0xef) == UI); } inline int -IsUA(u_char * data, int ext) +IsUA(u_char * data) { return ((data[0] & 0xef) == UA); } inline int -IsDM(u_char * data, int ext) +IsDM(u_char * data) { return ((data[0] & 0xef) == DM); } inline int -IsDISC(u_char * data, int ext) +IsDISC(u_char * data) { return ((data[0] & 0xef) == DISC); } inline int -IsRR(u_char * data, int ext) +IsRR(u_char * data, struct PStack *st) { - if (ext) + if (test_bit(FLG_MOD128, &st->l2.flag)) return (data[0] == RR); else return ((data[0] & 0xf) == 1); } inline int -IsSFrame(u_char * data, int ext) +IsSFrame(u_char * data, struct PStack *st) { register u_char d = *data; - if (!ext) + if (!test_bit(FLG_MOD128, &st->l2.flag)) d &= 0xf; return(((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c)); } inline int -IsSABMX(u_char * data, int ext) +IsSABME(u_char * data, struct PStack *st) { u_char d = data[0] & ~0x10; - return (ext ? d == SABME : d == SABM); + return (test_bit(FLG_MOD128, &st->l2.flag) ? d == SABME : d == SABM); } inline int -IsREJ(u_char * data, int ext) +IsREJ(u_char * data, struct PStack *st) { - return (ext ? data[0] == REJ : (data[0] & 0xf) == REJ); + return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == REJ : (data[0] & 0xf) == REJ); } inline int -IsFRMR(u_char * data, int ext) +IsFRMR(u_char * data) { return ((data[0] & 0xef) == FRMR); } inline int -IsRNR(u_char * data, int ext) +IsRNR(u_char * data, struct PStack *st) { - return (ext ? data[0] == RNR : (data[0] & 0xf) == RNR); + return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == RNR : (data[0] & 0xf) == RNR); } -static int -legalnr(struct PStack *st, int nr) +int +iframe_error(struct PStack *st, struct sk_buff *skb) { - struct Layer2 *l2 = &st->l2; - int lnr, lvs; + int i = l2addrsize(&st->l2) + (test_bit(FLG_MOD128, &st->l2.flag) ? 1 : 0); + int rsp = *skb->data & 0x2; + + if (test_bit(FLG_ORIG, &st->l2.flag)) + rsp = !rsp; + + if (rsp) + return 'L'; + + + if (skb->len <= i) + return 'N'; + + if ((skb->len - i) > st->l2.maxlen) + return 'O'; - lvs = (l2->vs >= l2->va) ? l2->vs : - (l2->vs + (test_bit(FLG_MOD128, &l2->flag) ? 128 : 8)); - lnr = (nr >= l2->va) ? nr : (test_bit(FLG_MOD128, &l2->flag) ? 128 : 8); - return (lnr <= lvs); + + return 0; +} + +int +super_error(struct PStack *st, struct sk_buff *skb) +{ + if (skb->len != l2addrsize(&st->l2) + + (test_bit(FLG_MOD128, &st->l2.flag) ? 2 : 1)) + return 'N'; + + return 0; +} + +int +unnum_error(struct PStack *st, struct sk_buff *skb, int wantrsp) +{ + int rsp = (*skb->data & 0x2) >> 1; + if (test_bit(FLG_ORIG, &st->l2.flag)) + rsp = !rsp; + + if (rsp != wantrsp) + return 'L'; + + if (skb->len != l2addrsize(&st->l2) + 1) + return 'N'; + + return 0; +} + +int +UI_error(struct PStack *st, struct sk_buff *skb) +{ + int rsp = *skb->data & 0x2; + if (test_bit(FLG_ORIG, &st->l2.flag)) + rsp = !rsp; + + if (rsp) + return 'L'; + + if (skb->len > st->l2.maxlen + l2addrsize(&st->l2) + 1) + return 'O'; + + return 0; +} + +int +FRMR_error(struct PStack *st, struct sk_buff *skb) +{ + int headers = l2addrsize(&st->l2) + 1; + u_char *datap = skb->data + headers; + int rsp = *skb->data & 0x2; + + if (test_bit(FLG_ORIG, &st->l2.flag)) + rsp = !rsp; + + if (!rsp) + return 'L'; + + if (test_bit(FLG_MOD128, &st->l2.flag)) { + if (skb->len < headers + 5) + return 'N'; + else + l2m_debug(&st->l2.l2m, "FRMR information %2x %2x %2x %2x %2x", + datap[0], datap[1], datap[2], + datap[3], datap[4]); + } else { + if (skb->len < headers + 3) + return 'N'; + else + l2m_debug(&st->l2.l2m, "FRMR information %2x %2x %2x", + datap[0], datap[1], datap[2]); + } + + return 0; +} + +static unsigned int +legalnr(struct PStack *st, unsigned int nr) +{ + struct Layer2 *l2 = &st->l2; + + if(test_bit(FLG_MOD128, &l2->flag)) + return ((nr - l2->va) % 128) <= ((l2->vs - l2->va) % 128); + else + return ((nr - l2->va) % 8) <= ((l2->vs - l2->va) % 8); } static void -setva(struct PStack *st, int nr) +setva(struct PStack *st, unsigned int nr) { struct Layer2 *l2 = &st->l2; int len; while (l2->va != nr) { - l2->va = (l2->va + 1) % (test_bit(FLG_MOD128, &l2->flag) ? 128 : 8); + (l2->va)++; + if(test_bit(FLG_MOD128, &l2->flag)) + l2->va %= 128; + else + l2->va %= 8; len = l2->windowar[l2->sow]->len; if (PACKET_NOACK == l2->windowar[l2->sow]->pkt_type) len = -1; - dev_kfree_skb(l2->windowar[l2->sow]); + idev_kfree_skb(l2->windowar[l2->sow], FREE_WRITE); l2->windowar[l2->sow] = NULL; l2->sow = (l2->sow + 1) % l2->window; if (st->lli.l2writewakeup && (len >=0)) @@ -356,6 +498,7 @@ printk(KERN_WARNING "isdl2 can't alloc sbbuff for send_uframe\n"); return; } + SET_SKB_FREE(skb); memcpy(skb_put(skb, i), tmp, i); enqueue_super(st, skb); } @@ -369,7 +512,7 @@ inline void FreeSkb(struct sk_buff *skb) { - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); } @@ -383,6 +526,48 @@ return (PF); } +inline void +start_t200(struct PStack *st, int i) +{ + FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i); + test_and_set_bit(FLG_T200_RUN, &st->l2.flag); +} + +inline void +restart_t200(struct PStack *st, int i) +{ + FsmRestartTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i); + test_and_set_bit(FLG_T200_RUN, &st->l2.flag); +} + +inline void +stop_t200(struct PStack *st, int i) +{ + if(test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) + FsmDelTimer(&st->l2.t200, i); +} + +inline void +st5_dl_release_l2l3(struct PStack *st) +{ + int pr; + + if(test_and_clear_bit(FLG_PEND_REL, &st->l2.flag)) + pr = DL_RELEASE | CONFIRM; + else + pr = DL_RELEASE | INDICATION; + + st->l2.l2l3(st, pr, NULL); +} + +inline void +lapb_dl_release_l2l3(struct PStack *st, int f) +{ + if (test_bit(FLG_LAPB, &st->l2.flag)) + st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); + st->l2.l2l3(st, DL_RELEASE | f, NULL); +} + static void establishlink(struct FsmInst *fi) { @@ -394,56 +579,91 @@ cmd = (test_bit(FLG_MOD128, &st->l2.flag) ? SABME : SABM) | 0x10; send_uframe(st, cmd, CMD); FsmDelTimer(&st->l2.t203, 1); - FsmRestartTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 1); - test_and_set_bit(FLG_T200_RUN, &st->l2.flag); + restart_t200(st, 1); + test_and_clear_bit(FLG_PEND_REL, &st->l2.flag); + freewin(st); FsmChangeState(fi, ST_L2_5); } static void -l2_mdl_error(struct FsmInst *fi, int event, void *arg) +l2_mdl_error_ua(struct FsmInst *fi, int event, void *arg) { struct sk_buff *skb = arg; struct PStack *st = fi->userdata; - switch (event) { - case EV_L2_UA: - if (get_PollFlagFree(st, skb)) - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'C'); - else - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'D'); - break; - case EV_L2_DM: - if (get_PollFlagFree(st, skb)) - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'B'); - else { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'E'); - establishlink(fi); - test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); - } - break; - } + if (get_PollFlagFree(st, skb)) + st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'C'); + else + st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'D'); } static void -l2_dl_establish(struct FsmInst *fi, int event, void *arg) +l2_mdl_error_dm(struct FsmInst *fi, int event, void *arg) { + struct sk_buff *skb = arg; struct PStack *st = fi->userdata; - int state = fi->state; - - if (test_bit(FLG_FIXED_TEI, &st->l2.flag)) { - FsmChangeState(fi, ST_L2_4); + if (get_PollFlagFree(st, skb)) + st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'B'); + else { + st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'E'); establishlink(fi); - test_and_set_bit(FLG_L3_INIT, &st->l2.flag); - } else { - FsmChangeState(fi, ST_L2_3); - if (state == ST_L2_1) - st->l2.l2tei(st, MDL_ASSIGN | INDICATION, NULL); + test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); + } +} + +static void +l2_st8_mdl_error_dm(struct FsmInst *fi, int event, void *arg) +{ + struct sk_buff *skb = arg; + struct PStack *st = fi->userdata; + + if (get_PollFlagFree(st, skb)) + st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'B'); + else { + st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'E'); } + establishlink(fi); + test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); +} + +static void +l2_go_st3(struct FsmInst *fi, int event, void *arg) +{ + FsmChangeState(fi, ST_L2_3); +} + +static void +l2_mdl_assign(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + FsmChangeState(fi, ST_L2_3); + st->l2.l2tei(st, MDL_ASSIGN | INDICATION, NULL); +} + +static void +l2_queue_ui_assign(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + struct sk_buff *skb = arg; + + skb_queue_tail(&st->l2.ui_queue, skb); + FsmChangeState(fi, ST_L2_2); + st->l2.l2tei(st, MDL_ASSIGN | INDICATION, NULL); +} + +static void +l2_queue_ui(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + struct sk_buff *skb = arg; + + skb_queue_tail(&st->l2.ui_queue, skb); } static void -l2_send_ui(struct PStack *st) +tx_ui(struct PStack *st) { struct sk_buff *skb; u_char header[MAX_HEADER_LEN]; @@ -458,18 +678,13 @@ } static void -l2_put_ui(struct FsmInst *fi, int event, void *arg) +l2_send_ui(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; struct sk_buff *skb = arg; skb_queue_tail(&st->l2.ui_queue, skb); - if (fi->state == ST_L2_1) { - FsmChangeState(fi, ST_L2_2); - st->l2.l2tei(st, MDL_ASSIGN | INDICATION, NULL); - } - if (fi->state > ST_L2_3) - l2_send_ui(st); + tx_ui(st); } static void @@ -479,11 +694,12 @@ struct sk_buff *skb = arg; skb_pull(skb, l2headersize(&st->l2, 1)); - if (skb->len > st->l2.maxlen) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'O'); - FreeSkb(skb); - } else - st->l2.l2l3(st, DL_UNIT_DATA | INDICATION, skb); + st->l2.l2l3(st, DL_UNIT_DATA | INDICATION, skb); +/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * in states 1-3 for broadcast + */ + + } static void @@ -491,277 +707,244 @@ { struct PStack *st = fi->userdata; - if (fi->state != ST_L2_4) - discard_queue(&st->l2.i_queue); - if (fi->state != ST_L2_5) - establishlink(fi); + establishlink(fi); test_and_set_bit(FLG_L3_INIT, &st->l2.flag); } static void -l2_dl_release(struct FsmInst *fi, int event, void *arg) +l2_discard_i_setl3(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + discard_queue(&st->l2.i_queue); + test_and_set_bit(FLG_L3_INIT, &st->l2.flag); + test_and_clear_bit(FLG_PEND_REL, &st->l2.flag); +} + +static void +l2_l3_reestablish(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; - if (fi->state == ST_L2_4) { - st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL); - return; - } else if (fi->state == ST_L2_5) { - test_and_set_bit(FLG_PEND_REL, &st->l2.flag); - return; - } discard_queue(&st->l2.i_queue); + establishlink(fi); + test_and_set_bit(FLG_L3_INIT, &st->l2.flag); +} + +static void +l2_release(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL); +} + +static void +l2_pend_rel(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + test_and_set_bit(FLG_PEND_REL, &st->l2.flag); +} + +static void +l2_disconnect(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + discard_queue(&st->l2.i_queue); + freewin(st); FsmChangeState(fi, ST_L2_6); st->l2.rc = 0; send_uframe(st, DISC | 0x10, CMD); FsmDelTimer(&st->l2.t203, 1); - FsmRestartTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 2); - test_and_set_bit(FLG_T200_RUN, &st->l2.flag); + restart_t200(st, 2); +} + +static void +l2_start_multi(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + struct sk_buff *skb = arg; + + send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); + + clear_exception(&st->l2); + st->l2.vs = 0; + st->l2.va = 0; + st->l2.vr = 0; + st->l2.sow = 0; + FsmChangeState(fi, ST_L2_7); + FsmAddTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 3); + + st->l2.l2l3(st, DL_ESTABLISH | INDICATION, NULL); } static void -l2_got_SABMX(struct FsmInst *fi, int event, void *arg) +l2_send_UA(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; struct sk_buff *skb = arg; - int est = 1, state, rsp; - u_char PollFlag; + + send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); +} + +static void +l2_send_DM(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + struct sk_buff *skb = arg; + + send_uframe(st, DM | get_PollFlagFree(st, skb), RSP); +} + +static void +l2_restart_multi(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + struct sk_buff *skb = arg; + int est = 0, state; state = fi->state; - rsp = *skb->data & 0x2; - if (test_bit(FLG_ORIG, &st->l2.flag)) - rsp = !rsp; - if (rsp) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'L'); - FreeSkb(skb); - if ((state == ST_L2_7) || (state == ST_L2_8)) - establishlink(fi); - return; - } - if (skb->len != (l2addrsize(&st->l2) + 1)) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); - FreeSkb(skb); - if ((state == ST_L2_7) || (state == ST_L2_8)) - establishlink(fi); - return; - } - PollFlag = get_PollFlagFree(st, skb); - if (ST_L2_6 == state) { - send_uframe(st, DM | PollFlag, RSP); - return; - } else - send_uframe(st, UA | PollFlag, RSP); - if (ST_L2_5 == state) - return; - if (ST_L2_4 != state) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'F'); - if (st->l2.vs != st->l2.va) { - discard_queue(&st->l2.i_queue); - est = 1; - } else - est = 0; + + send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); + + st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'F'); + + if (st->l2.vs != st->l2.va) { + discard_queue(&st->l2.i_queue); + est = 1; } + clear_exception(&st->l2); st->l2.vs = 0; st->l2.va = 0; st->l2.vr = 0; st->l2.sow = 0; FsmChangeState(fi, ST_L2_7); - if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) - FsmDelTimer(&st->l2.t200, 2); + stop_t200(st, 3); FsmRestartTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 3); if (est) st->l2.l2l3(st, DL_ESTABLISH | INDICATION, NULL); - if (ST_L2_8 == state) - if (skb_queue_len(&st->l2.i_queue) && cansend(st)) - st->l2.l2l1(st, PH_PULL | REQUEST, NULL); + if ((ST_L2_7==state) || (ST_L2_8 == state)) + if (skb_queue_len(&st->l2.i_queue) && cansend(st)) + st->l2.l2l1(st, PH_PULL | REQUEST, NULL); +} + +static void +l2_stop_multi(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + struct sk_buff *skb = arg; + + FsmChangeState(fi, ST_L2_4); + FsmDelTimer(&st->l2.t203, 3); + stop_t200(st, 4); + + send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); + + discard_queue(&st->l2.i_queue); + freewin(st); + lapb_dl_release_l2l3(st, INDICATION); +} + +static void +l2_connected(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + struct sk_buff *skb = arg; + int pr=-1; + + if (!get_PollFlag(st, skb)) { + l2_mdl_error_ua(fi, event, arg); + return; + } + FreeSkb(skb); + + if (test_and_clear_bit(FLG_PEND_REL, &st->l2.flag)) + l2_disconnect(fi, event, arg); + + if (test_and_clear_bit(FLG_L3_INIT, &st->l2.flag)) { + pr = DL_ESTABLISH | CONFIRM; + } else if (st->l2.vs != st->l2.va) { + discard_queue(&st->l2.i_queue); + pr = DL_ESTABLISH | INDICATION; + } + + stop_t200(st, 5); + + st->l2.vr = 0; + st->l2.vs = 0; + st->l2.va = 0; + st->l2.sow = 0; + FsmChangeState(fi, ST_L2_7); + FsmAddTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 4); + + if (pr != -1) + st->l2.l2l3(st, pr, NULL); + + if (skb_queue_len(&st->l2.i_queue) && cansend(st)) + st->l2.l2l1(st, PH_PULL | REQUEST, NULL); +} + +static void +l2_released(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + struct sk_buff *skb = arg; + + if (!get_PollFlag(st, skb)) { + l2_mdl_error_ua(fi, event, arg); + return; + } + FreeSkb(skb); + + stop_t200(st, 6); + lapb_dl_release_l2l3(st, CONFIRM); + FsmChangeState(fi, ST_L2_4); } static void -l2_got_disconn(struct FsmInst *fi, int event, void *arg) +l2_reestablish(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; struct sk_buff *skb = arg; - u_char PollFlag, cmd = UA; - int state, rel = 1, cst = 1, rsp; - - state = fi->state; - rsp = *skb->data & 0x2; - if (test_bit(FLG_ORIG, &st->l2.flag)) - rsp = !rsp; - if (rsp) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'L'); - FreeSkb(skb); - if ((state == ST_L2_7) || (state == ST_L2_8)) - establishlink(fi); - return; - } - if (skb->len != (l2addrsize(&st->l2) + 1)) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); - FreeSkb(skb); - if ((state == ST_L2_7) || (state == ST_L2_8)) - establishlink(fi); - return; - } - PollFlag = get_PollFlagFree(st, skb); - if ((state == ST_L2_4) || (state == ST_L2_5)) { - rel = 0; - cst = 0; - cmd = DM; - } else if (state == ST_L2_6) { - rel = 0; - cst = 0; - } - if (cst) { - FsmChangeState(fi, ST_L2_4); - FsmDelTimer(&st->l2.t203, 3); - if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) - FsmDelTimer(&st->l2.t200, 2); - } - send_uframe(st, cmd | PollFlag, RSP); - if (rel) { - if (test_bit(FLG_LAPB, &st->l2.flag)) - st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); - st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); + if (!get_PollFlagFree(st, skb)) { + establishlink(fi); + test_and_set_bit(FLG_L3_INIT, &st->l2.flag); } } - static void -l2_got_ua(struct FsmInst *fi, int event, void *arg) +l2_st5_dm_release(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; struct sk_buff *skb = arg; - int pr=-1; - u_char PollFlag; - int state,rsp; - - state = fi->state; - rsp = *skb->data & 0x2; - if (test_bit(FLG_ORIG, &st->l2.flag)) - rsp = !rsp; - - if (!rsp) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'L'); - FreeSkb(skb); - if ((state == ST_L2_7) || (state == ST_L2_8)) - establishlink(fi); - return; - } - if (skb->len != (l2addrsize(&st->l2) + 1)) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); - FreeSkb(skb); - if ((fi->state == ST_L2_7) || (fi->state == ST_L2_8)) - establishlink(fi); - return; - } - PollFlag = get_PollFlag(st, skb); - if (!PollFlag) { - l2_mdl_error(fi, event, arg); - return; - } - FreeSkb(skb); - if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) - FsmDelTimer(&st->l2.t200, 2); - if (fi->state == ST_L2_5) { - if (test_and_clear_bit(FLG_PEND_REL, &st->l2.flag)) { + if (get_PollFlagFree(st, skb)) { + stop_t200(st, 7); + if (!test_bit(FLG_L3_INIT, &st->l2.flag)) discard_queue(&st->l2.i_queue); - st->l2.rc = 0; - send_uframe(st, DISC | 0x10, CMD); - FsmChangeState(fi, ST_L2_6); - FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 4); - test_and_set_bit(FLG_T200_RUN, &st->l2.flag); - } else { - if (test_and_clear_bit(FLG_L3_INIT, &st->l2.flag)) { - pr = DL_ESTABLISH | CONFIRM; - } else if (st->l2.vs != st->l2.va) { - discard_queue(&st->l2.i_queue); - pr = DL_ESTABLISH | INDICATION; - } - st->l2.vs = 0; - st->l2.va = 0; - st->l2.vr = 0; - st->l2.sow = 0; - FsmChangeState(fi, ST_L2_7); - if (pr > -1) - st->l2.l2l3(st, pr, NULL); - } - } else { /* ST_L2_6 */ if (test_bit(FLG_LAPB, &st->l2.flag)) st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); - st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL); + st5_dl_release_l2l3(st); FsmChangeState(fi, ST_L2_4); } } static void -l2_got_dm(struct FsmInst *fi, int event, void *arg) +l2_st6_dm_release(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; struct sk_buff *skb = arg; - u_char PollFlag; - int state,rsp; - - state = fi->state; - rsp = *skb->data & 0x2; - if (test_bit(FLG_ORIG, &st->l2.flag)) - rsp = !rsp; - if (!rsp) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'L'); - FreeSkb(skb); - if ((state == ST_L2_7) || (state == ST_L2_8)) - establishlink(fi); - return; - } - if (skb->len != (l2addrsize(&st->l2) + 1)) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); - FreeSkb(skb); - if ((fi->state == ST_L2_7) || (fi->state == ST_L2_8)) - establishlink(fi); - return; - } - PollFlag = get_PollFlagFree(st, skb); - if (!PollFlag) { - if (fi->state == ST_L2_4) { - establishlink(fi); - test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); - FsmChangeState(fi, ST_L2_5); - } else if ((fi->state == ST_L2_7) || (fi->state == ST_L2_8)) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'E'); - establishlink(fi); - } - } else { - switch (fi->state) { - case ST_L2_8: - establishlink(fi); - case ST_L2_7: - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'B'); - break; - case ST_L2_4: - break; - case ST_L2_5: - if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) - FsmDelTimer(&st->l2.t200, 2); - discard_queue(&st->l2.i_queue); - if (test_bit(FLG_LAPB, &st->l2.flag)) - st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); - st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); - FsmChangeState(fi, ST_L2_4); - break; - case ST_L2_6: - if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) - FsmDelTimer(&st->l2.t200, 2); - if (test_bit(FLG_LAPB, &st->l2.flag)) - st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); - st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL); - FsmChangeState(fi, ST_L2_4); - break; - } + if (get_PollFlagFree(st, skb)) { + stop_t200(st, 8); + lapb_dl_release_l2l3(st, CONFIRM); + FsmChangeState(fi, ST_L2_4); } } @@ -784,6 +967,7 @@ printk(KERN_WARNING "isdl2 can't alloc sbbuff for enquiry_cr\n"); return; } + SET_SKB_FREE(skb); memcpy(skb_put(skb, i), tmp, i); enqueue_super(st, skb); } @@ -806,8 +990,7 @@ else enquiry_cr(st, RR, CMD, 1); test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); - FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 12); - test_and_set_bit(FLG_T200_RUN, &st->l2.flag); + start_t200(st, 9); } @@ -818,42 +1001,42 @@ st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'J'); establishlink(fi); + test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); } static void -invoke_retransmission(struct PStack *st, int nr) +invoke_retransmission(struct PStack *st, unsigned int nr) { struct Layer2 *l2 = &st->l2; - int p1; - long flags; + unsigned int p1; if (l2->vs != nr) { - save_flags(flags); - cli(); while (l2->vs != nr) { - l2->vs = l2->vs - 1; - if (l2->vs < 0) - l2->vs += (test_bit(FLG_MOD128, &l2->flag) ? 128 : 8); - p1 = l2->vs - l2->va; - if (p1 < 0) - p1 += (test_bit(FLG_MOD128, &l2->flag) ? 128 : 8); + (l2->vs)--; + if(test_bit(FLG_MOD128, &l2->flag)) { + l2->vs %= 128; + p1 = (l2->vs - l2->va) % 128; + } else { + l2->vs %= 8; + p1 = (l2->vs - l2->va) % 8; + } p1 = (p1 + l2->sow) % l2->window; if (test_bit(FLG_LAPB, &l2->flag)) st->l1.bcs->tx_cnt += l2->windowar[p1]->len + l2headersize(l2, 0); skb_queue_head(&l2->i_queue, l2->windowar[p1]); l2->windowar[p1] = NULL; } - restore_flags(flags); st->l2.l2l1(st, PH_PULL | REQUEST, NULL); } } static void -l2_got_st7_super(struct FsmInst *fi, int event, void *arg) +l2_st7_got_super(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; struct sk_buff *skb = arg; - int PollFlag, nr, rsp, typ = RR; + int PollFlag, rsp, typ = RR; + unsigned int nr; struct Layer2 *l2 = &st->l2; rsp = *skb->data & 0x2; @@ -861,72 +1044,77 @@ rsp = !rsp; skb_pull(skb, l2addrsize(l2)); - if (IsRNR(skb->data, test_bit(FLG_MOD128, &l2->flag))) { - test_and_set_bit(FLG_PEER_BUSY, &l2->flag); + if (IsRNR(skb->data, st)) { + set_peer_busy(l2); typ = RNR; } else - test_and_clear_bit(FLG_PEER_BUSY, &l2->flag); - if (IsREJ(skb->data, test_bit(FLG_MOD128, &l2->flag))) + clear_peer_busy(l2); + if (IsREJ(skb->data, st)) typ = REJ; + if (test_bit(FLG_MOD128, &l2->flag)) { - if (skb->len == 2) { - PollFlag = (skb->data[1] & 0x1) == 0x1; - nr = skb->data[1] >> 1; - } else { - if (skb->len >2) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); - establishlink(fi); - } - FreeSkb(skb); - return; - } + PollFlag = (skb->data[1] & 0x1) == 0x1; + nr = skb->data[1] >> 1; } else { - if (skb->len == 1) { - PollFlag = (skb->data[0] & 0x10); - nr = (skb->data[0] >> 5) & 0x7; - } else { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); - FreeSkb(skb); - establishlink(fi); - return; - } + PollFlag = (skb->data[0] & 0x10); + nr = (skb->data[0] >> 5) & 0x7; } FreeSkb(skb); - if ((!rsp) && PollFlag) - enquiry_response(st); - if (rsp && PollFlag) - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'A'); + if (PollFlag) { + if (rsp) + st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'A'); + else + enquiry_response(st); + } if (legalnr(st, nr)) { if (typ == REJ) { setva(st, nr); invoke_retransmission(st, nr); - if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) - FsmDelTimer(&st->l2.t200, 9); + stop_t200(st, 10); if (FsmAddTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 6)) l2m_debug(&st->l2.l2m, "Restart T203 ST7 REJ"); } else if ((nr == l2->vs) && (typ == RR)) { setva(st, nr); - if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) - FsmDelTimer(&st->l2.t200, 9); + stop_t200(st, 11); FsmRestartTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 7); } else if ((l2->va != nr) || (typ == RNR)) { setva(st, nr); - FsmDelTimer(&st->l2.t203, 9); - FsmRestartTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 6); - test_and_set_bit(FLG_T200_RUN, &st->l2.flag); + if(typ != RR) FsmDelTimer(&st->l2.t203, 9); + restart_t200(st, 12); } if (skb_queue_len(&st->l2.i_queue) && (typ == RR)) st->l2.l2l1(st, PH_PULL | REQUEST, NULL); } else nrerrorrecovery(fi); +} - if ((fi->userint & LC_FLUSH_WAIT) && rsp && !(skb_queue_len(&st->l2.i_queue))) { - fi->userint &= ~LC_FLUSH_WAIT; - st->l2.l2l3(st, DL_FLUSH | INDICATION, NULL); - } +static void +l2_feed_i_if_reest(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + struct sk_buff *skb = arg; + + if (test_bit(FLG_LAPB, &st->l2.flag)) + st->l1.bcs->tx_cnt += skb->len + l2headersize(&st->l2, 0); + if (!test_bit(FLG_L3_INIT, &st->l2.flag)) + skb_queue_tail(&st->l2.i_queue, skb); + else + FreeSkb(skb); +} + +static void +l2_feed_i_pull(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + struct sk_buff *skb = arg; + + if (test_bit(FLG_LAPB, &st->l2.flag)) + st->l1.bcs->tx_cnt += skb->len + l2headersize(&st->l2, 0); + skb_queue_tail(&st->l2.i_queue, skb); + st->l2.l2l1(st, PH_PULL | REQUEST, NULL); } static void @@ -937,10 +1125,7 @@ if (test_bit(FLG_LAPB, &st->l2.flag)) st->l1.bcs->tx_cnt += skb->len + l2headersize(&st->l2, 0); - if (!((fi->state == ST_L2_5) && test_bit(FLG_L3_INIT, &st->l2.flag))) - skb_queue_tail(&st->l2.i_queue, skb); - if (fi->state == ST_L2_7) - st->l2.l2l1(st, PH_PULL | REQUEST, NULL); + skb_queue_tail(&st->l2.i_queue, skb); } static void @@ -949,54 +1134,30 @@ struct PStack *st = fi->userdata; struct sk_buff *skb = arg; struct Layer2 *l2 = &(st->l2); - int PollFlag, ns, nr, i, rsp; - - rsp = *skb->data & 0x2; - if (test_bit(FLG_ORIG, &l2->flag)) - rsp = !rsp; + int PollFlag, ns, i; + unsigned int nr; - if (rsp) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'L'); - FreeSkb(skb); - establishlink(fi); - return; - } i = l2addrsize(l2); if (test_bit(FLG_MOD128, &l2->flag)) { - if (skb->len <= (i + 1)) { - FreeSkb(skb); - return; - } else if ((skb->len - i - 1) > l2->maxlen) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'O'); - FreeSkb(skb); - establishlink(fi); - return; - } PollFlag = ((skb->data[i + 1] & 0x1) == 0x1); ns = skb->data[i] >> 1; nr = (skb->data[i + 1] >> 1) & 0x7f; } else { - if (skb->len <= i) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); - FreeSkb(skb); - establishlink(fi); - return; - } else if ((skb->len - i) > l2->maxlen) { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'O'); - FreeSkb(skb); - establishlink(fi); - return; - } PollFlag = (skb->data[i] & 0x10); ns = (skb->data[i] >> 1) & 0x7; nr = (skb->data[i] >> 5) & 0x7; } if (test_bit(FLG_OWN_BUSY, &l2->flag)) { FreeSkb(skb); - enquiry_response(st); + if(PollFlag) enquiry_response(st); } else if (l2->vr == ns) { - l2->vr = (l2->vr + 1) % (test_bit(FLG_MOD128, &l2->flag) ? 128 : 8); + (l2->vr)++; + if(test_bit(FLG_MOD128, &l2->flag)) + l2->vr %= 128; + else + l2->vr %= 8; test_and_clear_bit(FLG_REJEXC, &l2->flag); + if (PollFlag) enquiry_response(st); else @@ -1016,19 +1177,15 @@ } if (legalnr(st, nr)) { - setva(st, nr); if (!test_bit(FLG_PEER_BUSY, &st->l2.flag) && (fi->state == ST_L2_7)) { if (nr == st->l2.vs) { - if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) - FsmDelTimer(&st->l2.t200, 10); + stop_t200(st, 13); FsmRestartTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 7); - } else if (nr != st->l2.va) { - FsmRestartTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, - NULL, 8); - test_and_set_bit(FLG_T200_RUN, &st->l2.flag); - } + } else if (nr != st->l2.va) + restart_t200(st, 14); } + setva(st, nr); } else { nrerrorrecovery(fi); return; @@ -1053,7 +1210,7 @@ } else FsmChangeState(fi, ST_L2_4); if (skb_queue_len(&st->l2.ui_queue)) - l2_send_ui(st); + tx_ui(st); } static void @@ -1071,7 +1228,7 @@ st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'G'); if (test_bit(FLG_LAPB, &st->l2.flag)) st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); - st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); + st5_dl_release_l2l3(st); } else { st->l2.rc++; FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); @@ -1090,10 +1247,9 @@ FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); } else if (st->l2.rc == st->l2.N200) { FsmChangeState(fi, ST_L2_4); + test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'H'); - if (test_bit(FLG_LAPB, &st->l2.flag)) - st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); - st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); + lapb_dl_release_l2l3(st, CONFIRM); } else { st->l2.rc++; FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, @@ -1103,7 +1259,7 @@ } static void -l2_st78_tout_200(struct FsmInst *fi, int event, void *arg) +l2_st7_tout_200(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; @@ -1113,12 +1269,28 @@ return; } test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); - if (fi->state == ST_L2_7) { - st->l2.rc = 0; - FsmChangeState(fi, ST_L2_8); + st->l2.rc = 0; + FsmChangeState(fi, ST_L2_8); + + transmit_enquiry(st); + st->l2.rc++; +} + +static void +l2_st8_tout_200(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + if (test_bit(FLG_LAPD, &st->l2.flag) && + test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { + FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); + return; } + test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); if (st->l2.rc == st->l2.N200) { + st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'I'); establishlink(fi); + test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); } else { transmit_enquiry(st); st->l2.rc++; @@ -1147,7 +1319,9 @@ struct sk_buff *skb, *oskb; struct Layer2 *l2 = &st->l2; u_char header[MAX_HEADER_LEN]; - int p1, i; + int i; + int unsigned p1; + long flags; if (!cansend(st)) return; @@ -1156,14 +1330,17 @@ if (!skb) return; - p1 = l2->vs - l2->va; - if (p1 < 0) - p1 += test_bit(FLG_MOD128, &l2->flag) ? 128 : 8; + save_flags(flags); + cli(); + if(test_bit(FLG_MOD128, &l2->flag)) + p1 = (l2->vs - l2->va) % 128; + else + p1 = (l2->vs - l2->va) % 8; p1 = (p1 + l2->sow) % l2->window; if (l2->windowar[p1]) { printk(KERN_WARNING "isdnl2 try overwrite ack queue entry %d\n", p1); - dev_kfree_skb(l2->windowar[p1]); + idev_kfree_skb(l2->windowar[p1], FREE_WRITE); } l2->windowar[p1] = skb_clone(skb, GFP_ATOMIC); @@ -1177,6 +1354,8 @@ header[i++] = (l2->vr << 5) | (l2->vs << 1); l2->vs = (l2->vs + 1) % 8; } + restore_flags(flags); + p1 = skb->data - skb->head; if (p1 >= i) memcpy(skb_push(skb, i), header, i); @@ -1185,6 +1364,7 @@ "isdl2 pull_iqueue skb header(%d/%d) too short\n", i, p1); oskb = skb; skb = alloc_skb(oskb->len + i, GFP_ATOMIC); + SET_SKB_FREE(skb); memcpy(skb_put(skb, i), header, i); memcpy(skb_put(skb, oskb->len), oskb->data, oskb->len); FreeSkb(oskb); @@ -1200,74 +1380,58 @@ } static void -l2_got_st8_super(struct FsmInst *fi, int event, void *arg) +l2_st8_got_super(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; struct sk_buff *skb = arg; - int PollFlag, nr, rsp, rnr = 0; + int PollFlag, rsp, rnr = 0; + unsigned int nr; struct Layer2 *l2 = &st->l2; rsp = *skb->data & 0x2; if (test_bit(FLG_ORIG, &l2->flag)) rsp = !rsp; + skb_pull(skb, l2addrsize(l2)); - if (IsRNR(skb->data, test_bit(FLG_MOD128, &l2->flag))) { - test_and_set_bit(FLG_PEER_BUSY, &l2->flag); + if (IsRNR(skb->data, st)) { + set_peer_busy(l2); rnr = 1; } else - test_and_clear_bit(FLG_PEER_BUSY, &l2->flag); + clear_peer_busy(l2); + if (test_bit(FLG_MOD128, &l2->flag)) { - if (skb->len == 2) { - PollFlag = (skb->data[1] & 0x1) == 0x1; - nr = skb->data[1] >> 1; - } else { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); - FreeSkb(skb); - establishlink(fi); - return; - } + PollFlag = (skb->data[1] & 0x1) == 0x1; + nr = skb->data[1] >> 1; } else { - if (skb->len == 1) { - PollFlag = (skb->data[0] & 0x10); - nr = (skb->data[0] >> 5) & 0x7; - } else { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); - FreeSkb(skb); - establishlink(fi); - return; - } + PollFlag = (skb->data[0] & 0x10); + nr = (skb->data[0] >> 5) & 0x7; } FreeSkb(skb); if (rsp && PollFlag) { if (legalnr(st, nr)) { - setva(st, nr); - if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) - FsmDelTimer(&st->l2.t200, 7); - FsmDelTimer(&l2->t203, 8); if (rnr) { - FsmRestartTimer(&l2->t200, l2->T200, - EV_L2_T200, NULL, 14); - test_and_set_bit(FLG_T200_RUN, &st->l2.flag); - } else + restart_t200(st, 15); + } else { + stop_t200(st, 16); FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 5); + setva(st, nr); + } invoke_retransmission(st, nr); FsmChangeState(fi, ST_L2_7); if (skb_queue_len(&l2->i_queue) && cansend(st)) st->l2.l2l1(st, PH_PULL | REQUEST, NULL); - else if (fi->userint & LC_FLUSH_WAIT) { - fi->userint &= ~LC_FLUSH_WAIT; - st->l2.l2l3(st, DL_FLUSH | INDICATION, NULL); - } - } + } else + nrerrorrecovery(fi); } else { if (!rsp && PollFlag) enquiry_response(st); if (legalnr(st, nr)) { setva(st, nr); - } + } else + nrerrorrecovery(fi); } } @@ -1278,22 +1442,9 @@ struct sk_buff *skb = arg; skb_pull(skb, l2addrsize(&st->l2) + 1); - if (test_bit(FLG_MOD128, &st->l2.flag)) { - if (skb->len < 5) - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); - else - l2m_debug(&st->l2.l2m, "FRMR information %2x %2x %2x %2x %2x", - skb->data[0], skb->data[1], skb->data[2], - skb->data[3], skb->data[4]); - } else { - if (skb->len < 3) - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); - else - l2m_debug(&st->l2.l2m, "FRMR information %2x %2x %2x", - skb->data[0], skb->data[1], skb->data[2]); - } + if (!(skb->data[0] & 1) || ((skb->data[0] & 3) == 1) || /* I or S */ - (IsUA(skb->data, 0) && (fi->state == ST_L2_7))) { + (IsUA(skb->data) && (fi->state == ST_L2_7))) { st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'K'); establishlink(fi); test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); @@ -1302,115 +1453,209 @@ } static void +l2_st24_tei_remove(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + discard_queue(&st->l2.ui_queue); + st->l2.tei = -1; + FsmChangeState(fi, ST_L2_1); +} + +static void +l2_st3_tei_remove(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + discard_queue(&st->l2.ui_queue); + st->l2.tei = -1; + st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); + FsmChangeState(fi, ST_L2_1); +} + +static void +l2_st5_tei_remove(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + discard_queue(&st->l2.i_queue); + discard_queue(&st->l2.ui_queue); + freewin(st); + st->l2.tei = -1; + stop_t200(st, 17); + st5_dl_release_l2l3(st); + FsmChangeState(fi, ST_L2_1); +} + +static void +l2_st6_tei_remove(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + discard_queue(&st->l2.ui_queue); + st->l2.tei = -1; + stop_t200(st, 18); + st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL); + FsmChangeState(fi, ST_L2_1); +} + +static void l2_tei_remove(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; discard_queue(&st->l2.i_queue); discard_queue(&st->l2.ui_queue); + freewin(st); st->l2.tei = -1; - if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) - FsmDelTimer(&st->l2.t200, 18); + stop_t200(st, 17); FsmDelTimer(&st->l2.t203, 19); - if (fi->state != ST_L2_4) - st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); + st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); FsmChangeState(fi, ST_L2_1); } static void -l2_persistant_da(struct FsmInst *fi, int event, void *arg) +l2_st14_persistant_da(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; - int rel = DL_RELEASE | INDICATION; - discard_queue(&st->l2.i_queue); discard_queue(&st->l2.ui_queue); - if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) - FsmDelTimer(&st->l2.t200, 18); + if (test_and_clear_bit(FLG_ESTAB_PEND, &st->l2.flag)) + st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); +} + +static void +l2_st5_persistant_da(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + discard_queue(&st->l2.i_queue); + discard_queue(&st->l2.ui_queue); + freewin(st); + stop_t200(st, 19); + st5_dl_release_l2l3(st); + FsmChangeState(fi, ST_L2_4); +} + +static void +l2_st6_persistant_da(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + discard_queue(&st->l2.ui_queue); + stop_t200(st, 20); + st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL); + FsmChangeState(fi, ST_L2_4); +} + +static void +l2_persistant_da(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + discard_queue(&st->l2.i_queue); + discard_queue(&st->l2.ui_queue); + freewin(st); + stop_t200(st, 19); FsmDelTimer(&st->l2.t203, 19); - clear_exception(&st->l2); - switch (fi->state) { - case ST_L2_1: - if (!test_and_clear_bit(FLG_ESTAB_PEND, &st->l2.flag)) - break; - case ST_L2_3: - st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); - case ST_L2_2: - FsmChangeState(fi, ST_L2_1); - break; - case ST_L2_6: - rel = DL_RELEASE | CONFIRM; - case ST_L2_5: - if (test_and_clear_bit(FLG_PEND_REL, &st->l2.flag)) - rel = DL_RELEASE | CONFIRM; - case ST_L2_7: - case ST_L2_8: - st->l2.l2l3(st, rel, NULL); - FsmChangeState(fi, ST_L2_4); - break; - case ST_L2_4: - if (test_and_clear_bit(FLG_ESTAB_PEND, &st->l2.flag)) - st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); - break; + st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); + FsmChangeState(fi, ST_L2_4); +} + +static void +l2_set_own_busy(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + if(!test_and_set_bit(FLG_OWN_BUSY, &st->l2.flag)) { + enquiry_cr(st, RNR, RSP, 0); + test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); } - test_and_clear_bit(FLG_PEND_REL, &st->l2.flag); - test_and_clear_bit(FLG_L1_ACTIV, &st->l2.flag); +} + +static void +l2_clear_own_busy(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + if(!test_and_clear_bit(FLG_OWN_BUSY, &st->l2.flag)) { + enquiry_cr(st, RR, RSP, 0); + test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); + } +} + +static void +l2_frame_error(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + st->ma.layer(st, MDL_ERROR | INDICATION, arg); +} + +static void +l2_frame_error_reest(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + st->ma.layer(st, MDL_ERROR | INDICATION, arg); + establishlink(fi); + test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); } static struct FsmNode L2FnList[] HISAX_INITDATA = { - {ST_L2_1, EV_L2_DL_ESTABLISH, l2_dl_establish}, - {ST_L2_2, EV_L2_DL_ESTABLISH, l2_dl_establish}, - {ST_L2_4, EV_L2_DL_ESTABLISH, l2_establish}, - {ST_L2_5, EV_L2_DL_ESTABLISH, l2_establish}, - {ST_L2_7, EV_L2_DL_ESTABLISH, l2_establish}, - {ST_L2_8, EV_L2_DL_ESTABLISH, l2_establish}, - {ST_L2_4, EV_L2_DL_RELEASE, l2_dl_release}, - {ST_L2_5, EV_L2_DL_RELEASE, l2_dl_release}, - {ST_L2_7, EV_L2_DL_RELEASE, l2_dl_release}, - {ST_L2_8, EV_L2_DL_RELEASE, l2_dl_release}, - {ST_L2_5, EV_L2_DL_DATA, l2_feed_iqueue}, - {ST_L2_7, EV_L2_DL_DATA, l2_feed_iqueue}, + {ST_L2_1, EV_L2_DL_ESTABLISH_REQ, l2_mdl_assign}, + {ST_L2_2, EV_L2_DL_ESTABLISH_REQ, l2_go_st3}, + {ST_L2_4, EV_L2_DL_ESTABLISH_REQ, l2_establish}, + {ST_L2_5, EV_L2_DL_ESTABLISH_REQ, l2_discard_i_setl3}, + {ST_L2_7, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish}, + {ST_L2_8, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish}, + {ST_L2_4, EV_L2_DL_RELEASE_REQ, l2_release}, + {ST_L2_5, EV_L2_DL_RELEASE_REQ, l2_pend_rel}, + {ST_L2_7, EV_L2_DL_RELEASE_REQ, l2_disconnect}, + {ST_L2_8, EV_L2_DL_RELEASE_REQ, l2_disconnect}, + {ST_L2_5, EV_L2_DL_DATA, l2_feed_i_if_reest}, + {ST_L2_7, EV_L2_DL_DATA, l2_feed_i_pull}, {ST_L2_8, EV_L2_DL_DATA, l2_feed_iqueue}, - {ST_L2_1, EV_L2_DL_UNIT_DATA, l2_put_ui}, - {ST_L2_2, EV_L2_DL_UNIT_DATA, l2_put_ui}, - {ST_L2_3, EV_L2_DL_UNIT_DATA, l2_put_ui}, - {ST_L2_4, EV_L2_DL_UNIT_DATA, l2_put_ui}, - {ST_L2_5, EV_L2_DL_UNIT_DATA, l2_put_ui}, - {ST_L2_6, EV_L2_DL_UNIT_DATA, l2_put_ui}, - {ST_L2_7, EV_L2_DL_UNIT_DATA, l2_put_ui}, - {ST_L2_8, EV_L2_DL_UNIT_DATA, l2_put_ui}, + {ST_L2_1, EV_L2_DL_UNIT_DATA, l2_queue_ui_assign}, + {ST_L2_2, EV_L2_DL_UNIT_DATA, l2_queue_ui}, + {ST_L2_3, EV_L2_DL_UNIT_DATA, l2_queue_ui}, + {ST_L2_4, EV_L2_DL_UNIT_DATA, l2_send_ui}, + {ST_L2_5, EV_L2_DL_UNIT_DATA, l2_send_ui}, + {ST_L2_6, EV_L2_DL_UNIT_DATA, l2_send_ui}, + {ST_L2_7, EV_L2_DL_UNIT_DATA, l2_send_ui}, + {ST_L2_8, EV_L2_DL_UNIT_DATA, l2_send_ui}, {ST_L2_1, EV_L2_MDL_ASSIGN, l2_got_tei}, {ST_L2_2, EV_L2_MDL_ASSIGN, l2_got_tei}, {ST_L2_3, EV_L2_MDL_ASSIGN, l2_got_tei}, - {ST_L2_2, EV_L2_MDL_ERROR, l2_tei_remove}, - {ST_L2_3, EV_L2_MDL_ERROR, l2_tei_remove}, - {ST_L2_4, EV_L2_MDL_REMOVE, l2_tei_remove}, - {ST_L2_5, EV_L2_MDL_REMOVE, l2_tei_remove}, - {ST_L2_6, EV_L2_MDL_REMOVE, l2_tei_remove}, + {ST_L2_2, EV_L2_MDL_ERROR, l2_st24_tei_remove}, + {ST_L2_3, EV_L2_MDL_ERROR, l2_st3_tei_remove}, + {ST_L2_4, EV_L2_MDL_REMOVE, l2_st24_tei_remove}, + {ST_L2_5, EV_L2_MDL_REMOVE, l2_st5_tei_remove}, + {ST_L2_6, EV_L2_MDL_REMOVE, l2_st6_tei_remove}, {ST_L2_7, EV_L2_MDL_REMOVE, l2_tei_remove}, {ST_L2_8, EV_L2_MDL_REMOVE, l2_tei_remove}, - {ST_L2_4, EV_L2_SABMX, l2_got_SABMX}, - {ST_L2_5, EV_L2_SABMX, l2_got_SABMX}, - {ST_L2_6, EV_L2_SABMX, l2_got_SABMX}, - {ST_L2_7, EV_L2_SABMX, l2_got_SABMX}, - {ST_L2_8, EV_L2_SABMX, l2_got_SABMX}, - {ST_L2_4, EV_L2_DISC, l2_got_disconn}, - {ST_L2_5, EV_L2_DISC, l2_got_disconn}, - {ST_L2_6, EV_L2_DISC, l2_got_disconn}, - {ST_L2_7, EV_L2_DISC, l2_got_disconn}, - {ST_L2_8, EV_L2_DISC, l2_got_disconn}, - {ST_L2_4, EV_L2_UA, l2_mdl_error}, - {ST_L2_5, EV_L2_UA, l2_got_ua}, - {ST_L2_6, EV_L2_UA, l2_got_ua}, - {ST_L2_7, EV_L2_UA, l2_mdl_error}, - {ST_L2_8, EV_L2_UA, l2_mdl_error}, - {ST_L2_4, EV_L2_DM, l2_got_dm}, - {ST_L2_5, EV_L2_DM, l2_got_dm}, - {ST_L2_6, EV_L2_DM, l2_got_dm}, - {ST_L2_7, EV_L2_DM, l2_got_dm}, - {ST_L2_8, EV_L2_DM, l2_got_dm}, + {ST_L2_4, EV_L2_SABME, l2_start_multi}, + {ST_L2_5, EV_L2_SABME, l2_send_UA}, + {ST_L2_6, EV_L2_SABME, l2_send_DM}, + {ST_L2_7, EV_L2_SABME, l2_restart_multi}, + {ST_L2_8, EV_L2_SABME, l2_restart_multi}, + {ST_L2_4, EV_L2_DISC, l2_send_DM}, + {ST_L2_5, EV_L2_DISC, l2_send_DM}, + {ST_L2_6, EV_L2_DISC, l2_send_UA}, + {ST_L2_7, EV_L2_DISC, l2_stop_multi}, + {ST_L2_8, EV_L2_DISC, l2_stop_multi}, + {ST_L2_4, EV_L2_UA, l2_mdl_error_ua}, + {ST_L2_5, EV_L2_UA, l2_connected}, + {ST_L2_6, EV_L2_UA, l2_released}, + {ST_L2_7, EV_L2_UA, l2_mdl_error_ua}, + {ST_L2_8, EV_L2_UA, l2_mdl_error_ua}, + {ST_L2_4, EV_L2_DM, l2_reestablish}, + {ST_L2_5, EV_L2_DM, l2_st5_dm_release}, + {ST_L2_6, EV_L2_DM, l2_st6_dm_release}, + {ST_L2_7, EV_L2_DM, l2_mdl_error_dm}, + {ST_L2_8, EV_L2_DM, l2_st8_mdl_error_dm}, {ST_L2_1, EV_L2_UI, l2_got_ui}, {ST_L2_2, EV_L2_UI, l2_got_ui}, {ST_L2_3, EV_L2_UI, l2_got_ui}, @@ -1421,22 +1666,31 @@ {ST_L2_8, EV_L2_UI, l2_got_ui}, {ST_L2_7, EV_L2_FRMR, l2_got_FRMR}, {ST_L2_8, EV_L2_FRMR, l2_got_FRMR}, - {ST_L2_7, EV_L2_SUPER, l2_got_st7_super}, - {ST_L2_8, EV_L2_SUPER, l2_got_st8_super}, + {ST_L2_7, EV_L2_SUPER, l2_st7_got_super}, + {ST_L2_8, EV_L2_SUPER, l2_st8_got_super}, {ST_L2_7, EV_L2_I, l2_got_iframe}, {ST_L2_8, EV_L2_I, l2_got_iframe}, {ST_L2_5, EV_L2_T200, l2_st5_tout_200}, {ST_L2_6, EV_L2_T200, l2_st6_tout_200}, - {ST_L2_7, EV_L2_T200, l2_st78_tout_200}, - {ST_L2_8, EV_L2_T200, l2_st78_tout_200}, + {ST_L2_7, EV_L2_T200, l2_st7_tout_200}, + {ST_L2_8, EV_L2_T200, l2_st8_tout_200}, {ST_L2_7, EV_L2_T203, l2_st7_tout_203}, {ST_L2_7, EV_L2_ACK_PULL, l2_pull_iqueue}, - {ST_L2_1, EV_L1_DEACTIVATE, l2_persistant_da}, - {ST_L2_2, EV_L1_DEACTIVATE, l2_persistant_da}, - {ST_L2_3, EV_L1_DEACTIVATE, l2_persistant_da}, - {ST_L2_4, EV_L1_DEACTIVATE, l2_persistant_da}, - {ST_L2_5, EV_L1_DEACTIVATE, l2_persistant_da}, - {ST_L2_6, EV_L1_DEACTIVATE, l2_persistant_da}, + {ST_L2_7, EV_L2_SET_OWN_BUSY, l2_set_own_busy}, + {ST_L2_8, EV_L2_SET_OWN_BUSY, l2_set_own_busy}, + {ST_L2_7, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy}, + {ST_L2_8, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy}, + {ST_L2_4, EV_L2_FRAME_ERROR, l2_frame_error}, + {ST_L2_5, EV_L2_FRAME_ERROR, l2_frame_error}, + {ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error}, + {ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest}, + {ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest}, + {ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistant_da}, + {ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove}, + {ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove}, + {ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistant_da}, + {ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistant_da}, + {ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistant_da}, {ST_L2_7, EV_L1_DEACTIVATE, l2_persistant_da}, {ST_L2_8, EV_L1_DEACTIVATE, l2_persistant_da}, }; @@ -1449,6 +1703,7 @@ struct sk_buff *skb = arg; u_char *datap; int ret = 1, len; + int c = 0; switch (pr) { case (PH_DATA | INDICATION): @@ -1457,36 +1712,46 @@ if (skb->len > len) datap += len; else { - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N'); + FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'N'); FreeSkb(skb); return; } - if (!(*datap & 1)) /* I-Frame */ - ret = FsmEvent(&st->l2.l2m, EV_L2_I, skb); - else if (IsSFrame(datap, test_bit(FLG_MOD128, &st->l2.flag))) - ret = FsmEvent(&st->l2.l2m, EV_L2_SUPER, skb); - else if (IsUI(datap, test_bit(FLG_MOD128, &st->l2.flag))) - ret = FsmEvent(&st->l2.l2m, EV_L2_UI, skb); - else if (IsSABMX(datap, test_bit(FLG_MOD128, &st->l2.flag))) - ret = FsmEvent(&st->l2.l2m, EV_L2_SABMX, skb); - else if (IsUA(datap, test_bit(FLG_MOD128, &st->l2.flag))) - ret = FsmEvent(&st->l2.l2m, EV_L2_UA, skb); - else if (IsDISC(datap, test_bit(FLG_MOD128, &st->l2.flag))) - ret = FsmEvent(&st->l2.l2m, EV_L2_DISC, skb); - else if (IsDM(datap, test_bit(FLG_MOD128, &st->l2.flag))) - ret = FsmEvent(&st->l2.l2m, EV_L2_DM, skb); - else if (IsFRMR(datap, test_bit(FLG_MOD128, &st->l2.flag))) - ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, skb); - else { - ret = 1; - if ((st->l2.l2m.state == ST_L2_7) || - (st->l2.l2m.state == ST_L2_8)) - establishlink(&st->l2.l2m); - st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'L'); + if (!(*datap & 1)) { /* I-Frame */ + if(!(c = iframe_error(st, skb))) + ret = FsmEvent(&st->l2.l2m, EV_L2_I, skb); + } else if (IsSFrame(datap, st)) { /* S-Frame */ + if(!(c = super_error(st, skb))) + ret = FsmEvent(&st->l2.l2m, EV_L2_SUPER, skb); + } else if (IsUI(datap)) { + if(!(c = UI_error(st, skb))) + ret = FsmEvent(&st->l2.l2m, EV_L2_UI, skb); + } else if (IsSABME(datap, st)) { + if(!(c = unnum_error(st, skb, CMD))) + ret = FsmEvent(&st->l2.l2m, EV_L2_SABME, skb); + } else if (IsUA(datap)) { + if(!(c = unnum_error(st, skb, RSP))) + ret = FsmEvent(&st->l2.l2m, EV_L2_UA, skb); + } else if (IsDISC(datap)) { + if(!(c = unnum_error(st, skb, CMD))) + ret = FsmEvent(&st->l2.l2m, EV_L2_DISC, skb); + } else if (IsDM(datap)) { + if(!(c = unnum_error(st, skb, RSP))) + ret = FsmEvent(&st->l2.l2m, EV_L2_DM, skb); + } else if (IsFRMR(datap)) { + if(!(c = FRMR_error(st,skb))) + ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, skb); + } else { + FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'L'); + FreeSkb(skb); + ret = 0; } - if (ret) { + if(c) { FreeSkb(skb); + FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) c); + ret = 0; } + if (ret) + FreeSkb(skb); break; case (PH_PULL | CONFIRM): FsmEvent(&st->l2.l2m, EV_L2_ACK_PULL, arg); @@ -1501,7 +1766,7 @@ case (PH_ACTIVATE | INDICATION): test_and_set_bit(FLG_L1_ACTIV, &st->l2.flag); if (test_and_clear_bit(FLG_ESTAB_PEND, &st->l2.flag)) - FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH, arg); + FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH_REQ, arg); break; case (PH_DEACTIVATE | INDICATION): case (PH_DEACTIVATE | CONFIRM): @@ -1520,19 +1785,19 @@ switch (pr) { case (DL_DATA | REQUEST): if (FsmEvent(&st->l2.l2m, EV_L2_DL_DATA, arg)) { - dev_kfree_skb((struct sk_buff *) arg); + idev_kfree_skb((struct sk_buff *) arg, FREE_READ); } break; case (DL_UNIT_DATA | REQUEST): if (FsmEvent(&st->l2.l2m, EV_L2_DL_UNIT_DATA, arg)) { - dev_kfree_skb((struct sk_buff *) arg); + idev_kfree_skb((struct sk_buff *) arg, FREE_READ); } break; case (DL_ESTABLISH | REQUEST): if (test_bit(FLG_L1_ACTIV, &st->l2.flag)) { if (test_bit(FLG_LAPD, &st->l2.flag) || test_bit(FLG_ORIG, &st->l2.flag)) { - FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH, arg); + FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH_REQ, arg); } } else { if (test_bit(FLG_LAPD, &st->l2.flag) || @@ -1546,10 +1811,7 @@ if (test_bit(FLG_LAPB, &st->l2.flag)) { st->l2.l2l1(st, PH_DEACTIVATE, NULL); } - FsmEvent(&st->l2.l2m, EV_L2_DL_RELEASE, arg); - break; - case (DL_FLUSH | REQUEST): - (&st->l2.l2m)->userint |= LC_FLUSH_WAIT; + FsmEvent(&st->l2.l2m, EV_L2_DL_RELEASE_REQ, arg); break; case (MDL_ASSIGN | REQUEST): FsmEvent(&st->l2.l2m, EV_L2_MDL_ASSIGN, arg); @@ -1566,7 +1828,7 @@ void releasestack_isdnl2(struct PStack *st) { - FsmDelTimer(&st->l2.t200, 15); + FsmDelTimer(&st->l2.t200, 21); FsmDelTimer(&st->l2.t203, 16); discard_queue(&st->l2.i_queue); discard_queue(&st->l2.ui_queue); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/isdnl3.c linux/drivers/isdn/hisax/isdnl3.c --- v2.3.13/linux/drivers/isdn/hisax/isdnl3.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/isdnl3.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: isdnl3.c,v 2.8 1998/11/15 23:55:04 keil Exp $ +/* $Id: isdnl3.c,v 2.10 1999/07/21 14:46:19 keil Exp $ * Author Karsten Keil (keil@isdn4linux.de) * based on the teles driver from Jan den Ouden @@ -11,6 +11,12 @@ * Fritz Elfert * * $Log: isdnl3.c,v $ + * Revision 2.10 1999/07/21 14:46:19 keil + * changes from EICON certification + * + * Revision 2.9 1999/07/01 08:11:53 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 2.8 1998/11/15 23:55:04 keil * changes from 2.0 * @@ -62,7 +68,7 @@ #include "isdnl3.h" #include -const char *l3_revision = "$Revision: 2.8 $"; +const char *l3_revision = "$Revision: 2.10 $"; static struct Fsm l3fsm = @@ -71,6 +77,7 @@ enum { ST_L3_LC_REL, ST_L3_LC_ESTAB_WAIT, + ST_L3_LC_REL_DELAY, ST_L3_LC_REL_WAIT, ST_L3_LC_ESTAB, }; @@ -81,6 +88,7 @@ { "ST_L3_LC_REL", "ST_L3_LC_ESTAB_WAIT", + "ST_L3_LC_REL_DELAY", "ST_L3_LC_REL_WAIT", "ST_L3_LC_ESTAB", }; @@ -92,9 +100,10 @@ EV_RELEASE_REQ, EV_RELEASE_CNF, EV_RELEASE_IND, + EV_TIMEOUT, }; -#define L3_EVENT_COUNT (EV_RELEASE_IND+1) +#define L3_EVENT_COUNT (EV_TIMEOUT+1) static char *strL3Event[] = { @@ -104,6 +113,7 @@ "EV_RELEASE_REQ", "EV_RELEASE_CNF", "EV_RELEASE_IND", + "EV_TIMEOUT", }; static void @@ -142,7 +152,14 @@ else { if (codeset == wanted_set) { if (*p == ie) - return (p); + { /* improved length check (Werner Cornelius) */ + if ((pend - p) < 2) + return(NULL); + if (*(p+1) > (pend - (p+2))) + return(NULL); + return (p); + } + if (*p > ie) return (NULL); } @@ -158,15 +175,15 @@ int getcallref(u_char * p) { - int l, m = 1, cr = 0; + int l, cr = 0; + p++; /* prot discr */ + if (*p & 0xfe) /* wrong callref BRI only 1 octet*/ + return(-2); l = 0xf & *p++; /* callref length */ if (!l) /* dummy CallRef */ return(-1); - while (l--) { - cr += m * (*p++); - m *= 8; - } + cr = *p++; return (cr); } @@ -186,8 +203,9 @@ newl3state(struct l3_process *pc, int state) { if (pc->debug & L3_DEB_STATE) - l3_debug(pc->st, "newstate cr %d %d --> %d", pc->callref, - pc->state, state); + l3_debug(pc->st, "newstate cr %d %d --> %d", + pc->callref & 0x7F, + pc->state, state); pc->state = state; } @@ -242,6 +260,7 @@ printk(KERN_WARNING "HiSax: No skb for D-channel\n"); return (NULL); } + SET_SKB_FREE(skb); skb_reserve(skb, MAX_HEADER_LEN); return (skb); } @@ -253,10 +272,17 @@ HiSax_putstatus(st->l1.hardware, "L3", "no D protocol"); if (skb) { - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); } } +static int +no_l3_proto_spec(struct PStack *st, isdn_ctrl *ic) +{ + printk(KERN_WARNING "HiSax: no specific protocol handler for proto %lu\n",ic->arg & 0xFF); + return(-1); +} + #ifdef CONFIG_HISAX_EURO extern void setstack_dss1(struct PStack *st); #endif @@ -300,7 +326,7 @@ np->next = p; } p->next = NULL; - p->debug = L3_DEB_WARN; + p->debug = st->l3.debug; p->callref = cr; p->state = 0; p->chan = NULL; @@ -323,8 +349,19 @@ StopAllL3Timer(p); if (pp) pp->next = np->next; - else - p->st->l3.proc = np->next; + else if (!(p->st->l3.proc = np->next) && + !test_bit(FLG_PTP, &p->st->l2.flag)) { + if (p->debug) + l3_debug(p->st, "release_l3_process: last process"); + if (!skb_queue_len(&p->st->l3.squeue)) { + if (p->debug) + l3_debug(p->st, "release_l3_process: release link"); + FsmEvent(&p->st->l3.l3m, EV_RELEASE_REQ, NULL); + } else { + if (p->debug) + l3_debug(p->st, "release_l3_process: not release link"); + } + } kfree(p); return; } @@ -335,6 +372,17 @@ l3_debug(p->st, "HiSax internal L3 error CR(%d) not in list", p->callref); }; +static void +l3ml3p(struct PStack *st, int pr) +{ + struct l3_process *p = st->l3.proc; + + while (p) { + st->l3.l3ml3(st, pr, p); + p = p->next; + } +} + void setstack_l3dc(struct PStack *st, struct Channel *chanp) { @@ -349,7 +397,9 @@ st->l3.l3m.userdata = st; st->l3.l3m.userint = 0; st->l3.l3m.printdebug = l3m_debug; + FsmInitTimer(&st->l3.l3m, &st->l3.l3m_timer); strcpy(st->l3.debug_id, "L3DC "); + st->lli.l4l3_proto = no_l3_proto_spec; #ifdef CONFIG_HISAX_EURO if (st->protocol == ISDN_PTYPE_EURO) { @@ -369,10 +419,12 @@ if (st->protocol == ISDN_PTYPE_LEASED) { st->lli.l4l3 = no_l3_proto; st->l2.l2l3 = no_l3_proto; + st->l3.l3ml3 = no_l3_proto; printk(KERN_INFO "HiSax: Leased line mode\n"); } else { st->lli.l4l3 = no_l3_proto; st->l2.l2l3 = no_l3_proto; + st->l3.l3ml3 = no_l3_proto; sprintf(tmp, "protocol %s not supported", (st->protocol == ISDN_PTYPE_1TR6) ? "1tr6" : (st->protocol == ISDN_PTYPE_EURO) ? "euro" : @@ -398,6 +450,7 @@ kfree(st->l3.global); st->l3.global = NULL; } + FsmDelTimer(&st->l3.l3m_timer, 54); discard_queue(&st->l3.squeue); } @@ -418,6 +471,8 @@ st->lli.l4l3 = isdnl3_trans; } +#define DREL_TIMER_VALUE 40000 + static void lc_activate(struct FsmInst *fi, int event, void *arg) { @@ -432,12 +487,49 @@ { struct PStack *st = fi->userdata; struct sk_buff *skb = arg; + int dequeued = 0; FsmChangeState(fi, ST_L3_LC_ESTAB); while ((skb = skb_dequeue(&st->l3.squeue))) { st->l3.l3l2(st, DL_DATA | REQUEST, skb); + dequeued++; } - st->l3.l3l4(st, DL_ESTABLISH | INDICATION, NULL); + if ((!st->l3.proc) && dequeued) { + if (st->l3.debug) + l3_debug(st, "lc_connect: release link"); + FsmEvent(&st->l3.l3m, EV_RELEASE_REQ, NULL); + } else + l3ml3p(st, DL_ESTABLISH | INDICATION); +} + +static void +lc_connected(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + struct sk_buff *skb = arg; + int dequeued = 0; + + FsmDelTimer(&st->l3.l3m_timer, 51); + FsmChangeState(fi, ST_L3_LC_ESTAB); + while ((skb = skb_dequeue(&st->l3.squeue))) { + st->l3.l3l2(st, DL_DATA | REQUEST, skb); + dequeued++; + } + if ((!st->l3.proc) && dequeued) { + if (st->l3.debug) + l3_debug(st, "lc_connected: release link"); + FsmEvent(&st->l3.l3m, EV_RELEASE_REQ, NULL); + } else + l3ml3p(st, DL_ESTABLISH | CONFIRM); +} + +static void +lc_start_delay(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + FsmChangeState(fi, ST_L3_LC_REL_DELAY); + FsmAddTimer(&st->l3.l3m_timer, DREL_TIMER_VALUE, EV_TIMEOUT, NULL, 50); } static void @@ -445,11 +537,15 @@ { struct PStack *st = fi->userdata; - if (fi->state == ST_L3_LC_ESTAB_WAIT) - FsmChangeState(fi, ST_L3_LC_REL); - else + if (test_bit(FLG_L2BLOCK, &st->l2.flag)) { + if (st->l3.debug) + l3_debug(st, "lc_release_req: l2 blocked"); + /* restart release timer */ + FsmAddTimer(&st->l3.l3m_timer, DREL_TIMER_VALUE, EV_TIMEOUT, NULL, 51); + } else { FsmChangeState(fi, ST_L3_LC_REL_WAIT); - st->l3.l3l2(st, DL_RELEASE | REQUEST, NULL); + st->l3.l3l2(st, DL_RELEASE | REQUEST, NULL); + } } static void @@ -457,23 +553,38 @@ { struct PStack *st = fi->userdata; + FsmDelTimer(&st->l3.l3m_timer, 52); FsmChangeState(fi, ST_L3_LC_REL); discard_queue(&st->l3.squeue); - st->l3.l3l4(st, DL_RELEASE | INDICATION, NULL); + l3ml3p(st, DL_RELEASE | INDICATION); } +static void +lc_release_cnf(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *st = fi->userdata; + + FsmChangeState(fi, ST_L3_LC_REL); + discard_queue(&st->l3.squeue); + l3ml3p(st, DL_RELEASE | CONFIRM); +} + + /* *INDENT-OFF* */ static struct FsmNode L3FnList[] HISAX_INITDATA = { {ST_L3_LC_REL, EV_ESTABLISH_REQ, lc_activate}, {ST_L3_LC_REL, EV_ESTABLISH_IND, lc_connect}, {ST_L3_LC_REL, EV_ESTABLISH_CNF, lc_connect}, - {ST_L3_LC_ESTAB_WAIT, EV_ESTABLISH_CNF, lc_connect}, - {ST_L3_LC_ESTAB_WAIT, EV_RELEASE_REQ, lc_release_req}, + {ST_L3_LC_ESTAB_WAIT, EV_ESTABLISH_CNF, lc_connected}, + {ST_L3_LC_ESTAB_WAIT, EV_RELEASE_REQ, lc_start_delay}, {ST_L3_LC_ESTAB_WAIT, EV_RELEASE_IND, lc_release_ind}, {ST_L3_LC_ESTAB, EV_RELEASE_IND, lc_release_ind}, - {ST_L3_LC_ESTAB, EV_RELEASE_REQ, lc_release_req}, - {ST_L3_LC_REL_WAIT, EV_RELEASE_CNF, lc_release_ind}, + {ST_L3_LC_ESTAB, EV_RELEASE_REQ, lc_start_delay}, + {ST_L3_LC_REL_DELAY, EV_RELEASE_IND, lc_release_ind}, + {ST_L3_LC_REL_DELAY, EV_ESTABLISH_REQ, lc_connected}, + {ST_L3_LC_REL_DELAY, EV_TIMEOUT, lc_release_req}, + {ST_L3_LC_REL_WAIT, EV_RELEASE_CNF, lc_release_cnf}, {ST_L3_LC_REL_WAIT, EV_ESTABLISH_REQ, lc_activate}, }; /* *INDENT-ON* */ diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/isdnl3.h linux/drivers/isdn/hisax/isdnl3.h --- v2.3.13/linux/drivers/isdn/hisax/isdnl3.h Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/isdnl3.h Thu Aug 12 09:42:33 1999 @@ -1,6 +1,12 @@ -/* $Id: isdnl3.h,v 2.3 1998/11/15 23:55:06 keil Exp $ +/* $Id: isdnl3.h,v 2.5 1999/07/25 16:18:32 keil Exp $ * $Log: isdnl3.h,v $ + * Revision 2.5 1999/07/25 16:18:32 keil + * Fix Suspend/Resume + * + * Revision 2.4 1999/07/01 08:11:54 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 2.3 1998/11/15 23:55:06 keil * changes from 2.0 * @@ -31,14 +37,16 @@ */ #define SBIT(state) (1<hw.isurf.isac + offset)); +} + +static void +WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) +{ + writeb(value, cs->hw.isurf.isac + offset); mb(); +} + +static void +ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size) +{ + register int i; + for (i = 0; i < size; i++) + data[i] = readb(cs->hw.isurf.isac); +} + +static void +WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size) +{ + register int i; + for (i = 0; i < size; i++){ + writeb(data[i], cs->hw.isurf.isac);mb(); + } +} + +/* ISAR access routines + * mode = 0 access with IRQ on + * mode = 1 access with IRQ off + * mode = 2 access with IRQ off and using last offset + */ + +static u_char +ReadISAR(struct IsdnCardState *cs, int mode, u_char offset) +{ + return(readb(cs->hw.isurf.isar + offset)); +} + +static void +WriteISAR(struct IsdnCardState *cs, int mode, u_char offset, u_char value) +{ + writeb(value, cs->hw.isurf.isar + offset);mb(); +} + +static void +isurf_interrupt(int intno, void *dev_id, struct pt_regs *regs) +{ + struct IsdnCardState *cs = dev_id; + u_char val; + int cnt = 5; + + if (!cs) { + printk(KERN_WARNING "ISurf: Spurious interrupt!\n"); + return; + } + + val = readb(cs->hw.isurf.isar + ISAR_IRQBIT); + Start_ISAR: + if (val & ISAR_IRQSTA) + isar_int_main(cs); + val = readb(cs->hw.isurf.isac + ISAC_ISTA); + Start_ISAC: + if (val) + isac_interrupt(cs, val); + val = readb(cs->hw.isurf.isar + ISAR_IRQBIT); + if ((val & ISAR_IRQSTA) && --cnt) { + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "ISAR IntStat after IntRoutine"); + goto Start_ISAR; + } + val = readb(cs->hw.isurf.isac + ISAC_ISTA); + if (val && --cnt) { + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "ISAC IntStat after IntRoutine"); + goto Start_ISAC; + } + if (!cnt) + printk(KERN_WARNING "ISurf IRQ LOOP\n"); + + writeb(0, cs->hw.isurf.isar + ISAR_IRQBIT); mb(); + writeb(0xFF, cs->hw.isurf.isac + ISAC_MASK);mb(); + writeb(0, cs->hw.isurf.isac + ISAC_MASK);mb(); + writeb(ISAR_IRQMSK, cs->hw.isurf.isar + ISAR_IRQBIT); mb(); +} + +void +release_io_isurf(struct IsdnCardState *cs) +{ + release_region(cs->hw.isurf.reset, 1); +} + +static void +reset_isurf(struct IsdnCardState *cs, u_char chips) +{ + long flags; + + printk(KERN_INFO "ISurf: resetting card\n"); + + byteout(cs->hw.isurf.reset, chips); /* Reset On */ + save_flags(flags); + sti(); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((10*HZ)/1000); + byteout(cs->hw.isurf.reset, ISURF_ISAR_EA); /* Reset Off */ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((10*HZ)/1000); + restore_flags(flags); +} + +static int +ISurf_card_msg(struct IsdnCardState *cs, int mt, void *arg) +{ + switch (mt) { + case CARD_RESET: + reset_isurf(cs, ISURF_RESET); + return(0); + case CARD_RELEASE: + release_io_isurf(cs); + return(0); + case CARD_INIT: + clear_pending_isac_ints(cs); + writeb(0, cs->hw.isurf.isar+ISAR_IRQBIT);mb(); + initisac(cs); + initisar(cs); + /* Reenable ISAC IRQ */ + cs->writeisac(cs, ISAC_MASK, 0); + /* RESET Receiver and Transmitter */ + cs->writeisac(cs, ISAC_CMDR, 0x41); + return(0); + case CARD_TEST: + return(0); + case CARD_LOAD_FIRM: + if (isar_load_firmware(cs, arg)) + return(1); + ll_run(cs); + reset_isurf(cs, ISURF_ISAR_EA | ISURF_ISAC_RESET | + ISURF_ARCOFI_RESET); + initisac(cs); + cs->writeisac(cs, ISAC_MASK, 0); + cs->writeisac(cs, ISAC_CMDR, 0x41); + return(0); + } + return(0); +} + +__initfunc(int +setup_isurf(struct IsdnCard *card)) +{ + int ver; + struct IsdnCardState *cs = card->cs; + char tmp[64]; + + strcpy(tmp, ISurf_revision); + printk(KERN_INFO "HiSax: ISurf driver Rev. %s\n", HiSax_getrev(tmp)); + + if (cs->typ != ISDN_CTYPE_ISURF) + return(0); + if (card->para[1] && card->para[2]) { + cs->hw.isurf.reset = card->para[1]; + cs->hw.isurf.isar = card->para[2] + ISURF_ISAR_OFFSET; + cs->hw.isurf.isac = card->para[2] + ISURF_ISAC_OFFSET; + cs->irq = card->para[0]; + } else { + printk(KERN_WARNING "HiSax: %s port/mem not set\n", + CardType[card->typ]); + return (0); + } + if (check_region(cs->hw.isurf.reset, 1)) { + printk(KERN_WARNING + "HiSax: %s config port %x already in use\n", + CardType[card->typ], + cs->hw.isurf.reset); + return (0); + } else { + request_region(cs->hw.isurf.reset, 1, "isurf isdn"); + } + + printk(KERN_INFO + "ISurf: defined at 0x%x 0x%x IRQ %d\n", + cs->hw.isurf.reset, + cs->hw.isurf.isar, + cs->irq); + + cs->cardmsg = &ISurf_card_msg; + cs->irq_func = &isurf_interrupt; + cs->readisac = &ReadISAC; + cs->writeisac = &WriteISAC; + cs->readisacfifo = &ReadISACfifo; + cs->writeisacfifo = &WriteISACfifo; + cs->bcs[0].hw.isar.reg = &cs->hw.isurf.isar_r; + cs->bcs[1].hw.isar.reg = &cs->hw.isurf.isar_r; + reset_isurf(cs, ISURF_RESET); + test_and_set_bit(HW_ISAR, &cs->HW_Flags); + ISACVersion(cs, "ISurf:"); + cs->BC_Read_Reg = &ReadISAR; + cs->BC_Write_Reg = &WriteISAR; + cs->BC_Send_Data = &isar_fill_fifo; + ver = ISARVersion(cs, "ISurf:"); + if (ver < 0) { + printk(KERN_WARNING + "ISurf: wrong ISAR version (ret = %d)\n", ver); + release_io_isurf(cs); + return (0); + } + return (1); +} diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/ix1_micro.c linux/drivers/isdn/hisax/ix1_micro.c --- v2.3.13/linux/drivers/isdn/hisax/ix1_micro.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/isdn/hisax/ix1_micro.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: ix1_micro.c,v 2.7 1998/04/15 16:44:31 keil Exp $ +/* $Id: ix1_micro.c,v 2.8 1999/07/12 21:05:19 keil Exp $ * ix1_micro.c low level stuff for ITK ix1-micro Rev.2 isdn cards * derived from the original file teles3.c from Karsten Keil @@ -11,6 +11,10 @@ * Beat Doebeli * * $Log: ix1_micro.c,v $ + * Revision 2.8 1999/07/12 21:05:19 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * * Revision 2.7 1998/04/15 16:44:31 keil * new init code * @@ -84,7 +88,7 @@ #include "isdnl1.h" extern const char *CardType[]; -const char *ix1_revision = "$Revision: 2.7 $"; +const char *ix1_revision = "$Revision: 2.8 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -199,7 +203,7 @@ ix1micro_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; - u_char val, stat = 0; + u_char val; if (!cs) { printk(KERN_WARNING "IX1: Spurious interrupt!\n"); @@ -207,16 +211,12 @@ } val = readreg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_ISTA + 0x40); Start_HSCX: - if (val) { + if (val) hscx_int_main(cs, val); - stat |= 1; - } val = readreg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_ISTA); Start_ISAC: - if (val) { + if (val) isac_interrupt(cs, val); - stat |= 2; - } val = readreg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_ISTA + 0x40); if (val) { if (cs->debug & L1_DEB_HSCX) @@ -229,16 +229,12 @@ debugl1(cs, "ISAC IntStat after IntRoutine"); goto Start_ISAC; } - if (stat & 1) { - writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK, 0xFF); - writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK + 0x40, 0xFF); - writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK, 0); - writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK + 0x40, 0); - } - if (stat & 2) { - writereg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_MASK, 0); - } + writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK, 0xFF); + writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK + 0x40, 0xFF); + writereg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_MASK, 0xFF); + writereg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_MASK, 0); + writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK, 0); + writereg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_MASK + 0x40, 0); } void @@ -276,9 +272,6 @@ case CARD_RELEASE: release_io_ix1micro(cs); return(0); - case CARD_SETIRQ: - return(request_irq(cs->irq, &ix1micro_interrupt, - I4L_IRQ_FLAG, "HiSax", cs)); case CARD_INIT: inithscxisac(cs, 3); return(0); @@ -289,8 +282,8 @@ } -int __init -setup_ix1micro(struct IsdnCard *card) +__initfunc(int +setup_ix1micro(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; @@ -331,6 +324,7 @@ cs->BC_Write_Reg = &WriteHSCX; cs->BC_Send_Data = &hscx_fill_fifo; cs->cardmsg = &ix1_card_msg; + cs->irq_func = &ix1micro_interrupt; ISACVersion(cs, "ix1-Micro:"); if (HscxVersion(cs, "ix1-Micro:")) { printk(KERN_WARNING diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/jade.c linux/drivers/isdn/hisax/jade.c --- v2.3.13/linux/drivers/isdn/hisax/jade.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/hisax/jade.c Thu Aug 12 09:42:33 1999 @@ -0,0 +1,326 @@ +/* $Id: jade.c,v 1.2 1999/07/01 08:07:57 keil Exp $ + * + * jade.c JADE stuff (derived from original hscx.c) + * + * Author Roland Klabunde (R.Klabunde@Berkom.de) + * + * $Log: jade.c,v $ + * Revision 1.2 1999/07/01 08:07:57 keil + * Initial version + * + * + */ + + +#define __NO_VERSION__ +#include "hisax.h" +#include "hscx.h" +#include "jade.h" +#include "isdnl1.h" +#include + + +HISAX_INITFUNC(int +JadeVersion(struct IsdnCardState *cs, char *s)) +{ + int ver,i; + int to = 50; + cs->BC_Write_Reg(cs, -1, 0x50, 0x19); + i=0; + while (to) { + udelay(1); + ver = cs->BC_Read_Reg(cs, -1, 0x60); + to--; + if (ver) + break; + if (!to) { + printk(KERN_INFO "%s JADE version not obtainable\n", s); + return (0); + } + } + /* Wait for the JADE */ + udelay(10); + /* Read version */ + ver = cs->BC_Read_Reg(cs, -1, 0x60); + printk(KERN_INFO "%s JADE version: %d\n", s, ver); + return (1); +} + +/* Write to indirect accessible jade register set */ +static void +jade_write_indirect(struct IsdnCardState *cs, u_char reg, u_char value) +{ + int to = 50; + long flags; + u_char ret; + save_flags(flags); + cli(); + /* Write the data */ + cs->BC_Write_Reg(cs, -1, COMM_JADE+1, value); + /* Say JADE we wanna write indirect reg 'reg' */ + cs->BC_Write_Reg(cs, -1, COMM_JADE, reg); + to = 50; + /* Wait for RDY goes high */ + while (to) { + udelay(1); + ret = cs->BC_Read_Reg(cs, -1, COMM_JADE); + to--; + if (ret & 1) + /* Got acknowledge */ + break; + if (!to) { + restore_flags(flags); + printk(KERN_INFO "Can not see ready bit from JADE DSP (reg=0x%X, value=0x%X)\n", reg, value); + return; + } + } + restore_flags(flags); +} + + + +void +modejade(struct BCState *bcs, int mode, int bc) +{ + struct IsdnCardState *cs = bcs->cs; + int jade = bcs->hw.hscx.hscx; + + if (cs->debug & L1_DEB_HSCX) { + char tmp[40]; + sprintf(tmp, "jade %c mode %d ichan %d", + 'A' + jade, mode, bc); + debugl1(cs, tmp); + } + bcs->mode = mode; + bcs->channel = bc; + + cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (mode == L1_MODE_TRANS ? jadeMODE_TMO:0x00)); + cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR0, (jadeCCR0_PU|jadeCCR0_ITF)); + cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR1, 0x00); + + jade_write_indirect(cs, jade_HDLC1SERRXPATH, 0x08); + jade_write_indirect(cs, jade_HDLC2SERRXPATH, 0x08); + jade_write_indirect(cs, jade_HDLC1SERTXPATH, 0x00); + jade_write_indirect(cs, jade_HDLC2SERTXPATH, 0x00); + + cs->BC_Write_Reg(cs, jade, jade_HDLC_XCCR, 0x07); + cs->BC_Write_Reg(cs, jade, jade_HDLC_RCCR, 0x07); + + if (bc == 0) { + cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x00); + cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x00); + } else { + cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x04); + cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x04); + } + switch (mode) { + case (L1_MODE_NULL): + cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, jadeMODE_TMO); + break; + case (L1_MODE_TRANS): + cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_TMO|jadeMODE_RAC|jadeMODE_XAC)); + break; + case (L1_MODE_HDLC): + cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_RAC|jadeMODE_XAC)); + break; + } + if (mode) { + cs->BC_Write_Reg(cs, jade, jade_HDLC_RCMD, (jadeRCMD_RRES|jadeRCMD_RMC)); + cs->BC_Write_Reg(cs, jade, jade_HDLC_XCMD, jadeXCMD_XRES); + /* Unmask ints */ + cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0xF8); + } + else + /* Mask ints */ + cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0x00); +} + +void +jade_sched_event(struct BCState *bcs, int event) +{ + bcs->event |= 1 << event; + queue_task(&bcs->tqueue, &tq_immediate); + mark_bh(IMMEDIATE_BH); +} + +static void +jade_l2l1(struct PStack *st, int pr, void *arg) +{ + struct sk_buff *skb = arg; + long flags; + + switch (pr) { + case (PH_DATA | REQUEST): + save_flags(flags); + cli(); + if (st->l1.bcs->tx_skb) { + skb_queue_tail(&st->l1.bcs->squeue, skb); + restore_flags(flags); + } else { + st->l1.bcs->tx_skb = skb; + test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); + st->l1.bcs->hw.hscx.count = 0; + restore_flags(flags); + st->l1.bcs->cs->BC_Send_Data(st->l1.bcs); + } + break; + case (PH_PULL | INDICATION): + if (st->l1.bcs->tx_skb) { + printk(KERN_WARNING "jade_l2l1: this shouldn't happen\n"); + break; + } + test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); + st->l1.bcs->tx_skb = skb; + st->l1.bcs->hw.hscx.count = 0; + st->l1.bcs->cs->BC_Send_Data(st->l1.bcs); + break; + case (PH_PULL | REQUEST): + if (!st->l1.bcs->tx_skb) { + test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); + st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); + } else + test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); + break; + case (PH_ACTIVATE | REQUEST): + test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); + modejade(st->l1.bcs, st->l1.mode, st->l1.bc); + l1_msg_b(st, pr, arg); + break; + case (PH_DEACTIVATE | REQUEST): + l1_msg_b(st, pr, arg); + break; + case (PH_DEACTIVATE | CONFIRM): + test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); + test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); + modejade(st->l1.bcs, 0, st->l1.bc); + st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); + break; + } +} + +void +close_jadestate(struct BCState *bcs) +{ + modejade(bcs, 0, bcs->channel); + if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { + if (bcs->hw.hscx.rcvbuf) { + kfree(bcs->hw.hscx.rcvbuf); + bcs->hw.hscx.rcvbuf = NULL; + } + if (bcs->blog) { + kfree(bcs->blog); + bcs->blog = NULL; + } + discard_queue(&bcs->rqueue); + discard_queue(&bcs->squeue); + if (bcs->tx_skb) { + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + bcs->tx_skb = NULL; + test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); + } + } +} + +static int +open_jadestate(struct IsdnCardState *cs, struct BCState *bcs) +{ + if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { + if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) { + printk(KERN_WARNING + "HiSax: No memory for hscx.rcvbuf\n"); + test_and_clear_bit(BC_FLG_INIT, &bcs->Flag); + return (1); + } + if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) { + printk(KERN_WARNING + "HiSax: No memory for bcs->blog\n"); + test_and_clear_bit(BC_FLG_INIT, &bcs->Flag); + kfree(bcs->hw.hscx.rcvbuf); + bcs->hw.hscx.rcvbuf = NULL; + return (2); + } + skb_queue_head_init(&bcs->rqueue); + skb_queue_head_init(&bcs->squeue); + } + bcs->tx_skb = NULL; + test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); + bcs->event = 0; + bcs->hw.hscx.rcvidx = 0; + bcs->tx_cnt = 0; + return (0); +} + + +int +setstack_jade(struct PStack *st, struct BCState *bcs) +{ + bcs->channel = st->l1.bc; + if (open_jadestate(st->l1.hardware, bcs)) + return (-1); + st->l1.bcs = bcs; + st->l2.l2l1 = jade_l2l1; + setstack_manager(st); + bcs->st = st; + setstack_l1_B(st); + return (0); +} + +HISAX_INITFUNC(void +clear_pending_jade_ints(struct IsdnCardState *cs)) +{ + int val; + char tmp[64]; + + cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0x00); + cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0x00); + + val = cs->BC_Read_Reg(cs, 1, jade_HDLC_ISR); + sprintf(tmp, "jade B ISTA %x", val); + debugl1(cs, tmp); + val = cs->BC_Read_Reg(cs, 0, jade_HDLC_ISR); + sprintf(tmp, "jade A ISTA %x", val); + debugl1(cs, tmp); + val = cs->BC_Read_Reg(cs, 1, jade_HDLC_STAR); + sprintf(tmp, "jade B STAR %x", val); + debugl1(cs, tmp); + val = cs->BC_Read_Reg(cs, 0, jade_HDLC_STAR); + sprintf(tmp, "jade A STAR %x", val); + debugl1(cs, tmp); + /* Unmask ints */ + cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0xF8); + cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0xF8); +} + +HISAX_INITFUNC(void +initjade(struct IsdnCardState *cs)) +{ + cs->bcs[0].BC_SetStack = setstack_jade; + cs->bcs[1].BC_SetStack = setstack_jade; + cs->bcs[0].BC_Close = close_jadestate; + cs->bcs[1].BC_Close = close_jadestate; + cs->bcs[0].hw.hscx.hscx = 0; + cs->bcs[1].hw.hscx.hscx = 1; + + /* Stop DSP audio tx/rx */ + jade_write_indirect(cs, 0x11, 0x0f); + jade_write_indirect(cs, 0x17, 0x2f); + + /* Transparent Mode, RxTx inactive, No Test, No RFS/TFS */ + cs->BC_Write_Reg(cs, 0, jade_HDLC_MODE, jadeMODE_TMO); + cs->BC_Write_Reg(cs, 1, jade_HDLC_MODE, jadeMODE_TMO); + /* Power down, 1-Idle, RxTx least significant bit first */ + cs->BC_Write_Reg(cs, 0, jade_HDLC_CCR0, 0x00); + cs->BC_Write_Reg(cs, 1, jade_HDLC_CCR0, 0x00); + /* Mask all interrupts */ + cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0x00); + cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0x00); + /* Setup host access to hdlc controller */ + jade_write_indirect(cs, jade_HDLCCNTRACCESS, (jadeINDIRECT_HAH1|jadeINDIRECT_HAH2)); + /* Unmask HDLC int (donŽt forget DSP int later on)*/ + cs->BC_Write_Reg(cs, -1,jade_INT, (jadeINT_HDLC1|jadeINT_HDLC2)); + + /* once again TRANSPARENT */ + modejade(cs->bcs, 0, 0); + modejade(cs->bcs + 1, 0, 0); +} + diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/jade.h linux/drivers/isdn/hisax/jade.h --- v2.3.13/linux/drivers/isdn/hisax/jade.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/hisax/jade.h Thu Aug 12 09:42:33 1999 @@ -0,0 +1,137 @@ +/* $Id: jade.h,v 1.2 1999/07/01 08:07:58 keil Exp $ + * jade.h JADE specific defines + * + * Author Roland Klabunde (R.Klabunde@Berkom.de) + * + * + * $Log: jade.h,v $ + * Revision 1.2 1999/07/01 08:07:58 keil + * Initial version + * + * + */ + +/* All Registers original Siemens Spec */ +#ifndef __JADE_H__ +#define __JADE_H__ + +/* Special registers for access to indirect accessible JADE regs */ +#define DIRECT_IO_JADE 0x0000 /* Jade direct io access area */ +#define COMM_JADE 0x0040 /* Jade communication area */ + +/********************************************************************/ +/* JADE-HDLC registers */ +/********************************************************************/ +#define jade_HDLC_RFIFO 0x00 /* R */ +#define jade_HDLC_XFIFO 0x00 /* W */ + +#define jade_HDLC_STAR 0x20 /* R */ + #define jadeSTAR_XDOV 0x80 + #define jadeSTAR_XFW 0x40 /* Does not work*/ + #define jadeSTAR_XCEC 0x20 + #define jadeSTAR_RCEC 0x10 + #define jadeSTAR_BSY 0x08 + #define jadeSTAR_RNA 0x04 + #define jadeSTAR_STR 0x02 + #define jadeSTAR_STX 0x01 + +#define jade_HDLC_XCMD 0x20 /* W */ + #define jadeXCMD_XF 0x80 + #define jadeXCMD_XME 0x40 + #define jadeXCMD_XRES 0x20 + #define jadeXCMD_STX 0x01 + +#define jade_HDLC_RSTA 0x21 /* R */ + #define jadeRSTA_VFR 0x80 + #define jadeRSTA_RDO 0x40 + #define jadeRSTA_CRC 0x20 + #define jadeRSTA_RAB 0x10 + #define jadeRSTA_MASK 0xF0 + +#define jade_HDLC_MODE 0x22 /* RW*/ + #define jadeMODE_TMO 0x80 + #define jadeMODE_RAC 0x40 + #define jadeMODE_XAC 0x20 + #define jadeMODE_TLP 0x10 + #define jadeMODE_ERFS 0x02 + #define jadeMODE_ETFS 0x01 + +#define jade_HDLC_RBCH 0x24 /* R */ + +#define jade_HDLC_RBCL 0x25 /* R */ +#define jade_HDLC_RCMD 0x25 /* W */ + #define jadeRCMD_RMC 0x80 + #define jadeRCMD_RRES 0x40 + #define jadeRCMD_RMD 0x20 + #define jadeRCMD_STR 0x02 + +#define jade_HDLC_CCR0 0x26 /* RW*/ + #define jadeCCR0_PU 0x80 + #define jadeCCR0_ITF 0x40 + #define jadeCCR0_C32 0x20 + #define jadeCCR0_CRL 0x10 + #define jadeCCR0_RCRC 0x08 + #define jadeCCR0_XCRC 0x04 + #define jadeCCR0_RMSB 0x02 + #define jadeCCR0_XMSB 0x01 + +#define jade_HDLC_CCR1 0x27 /* RW*/ + #define jadeCCR1_RCS0 0x80 + #define jadeCCR1_RCONT 0x40 + #define jadeCCR1_RFDIS 0x20 + #define jadeCCR1_XCS0 0x10 + #define jadeCCR1_XCONT 0x08 + #define jadeCCR1_XFDIS 0x04 + +#define jade_HDLC_TSAR 0x28 /* RW*/ +#define jade_HDLC_TSAX 0x29 /* RW*/ +#define jade_HDLC_RCCR 0x2A /* RW*/ +#define jade_HDLC_XCCR 0x2B /* RW*/ + +#define jade_HDLC_ISR 0x2C /* R */ +#define jade_HDLC_IMR 0x2C /* W */ + #define jadeISR_RME 0x80 + #define jadeISR_RPF 0x40 + #define jadeISR_RFO 0x20 + #define jadeISR_XPR 0x10 + #define jadeISR_XDU 0x08 + #define jadeISR_ALLS 0x04 + +#define jade_INT 0x75 + #define jadeINT_HDLC1 0x02 + #define jadeINT_HDLC2 0x01 + #define jadeINT_DSP 0x04 +#define jade_INTR 0x70 + +/********************************************************************/ +/* Indirect accessible JADE registers of common interest */ +/********************************************************************/ +#define jade_CHIPVERSIONNR 0x00 /* Does not work*/ + +#define jade_HDLCCNTRACCESS 0x10 + #define jadeINDIRECT_HAH1 0x02 + #define jadeINDIRECT_HAH2 0x01 + +#define jade_HDLC1SERRXPATH 0x1D +#define jade_HDLC1SERTXPATH 0x1E +#define jade_HDLC2SERRXPATH 0x1F +#define jade_HDLC2SERTXPATH 0x20 + #define jadeINDIRECT_SLIN1 0x10 + #define jadeINDIRECT_SLIN0 0x08 + #define jadeINDIRECT_LMOD1 0x04 + #define jadeINDIRECT_LMOD0 0x02 + #define jadeINDIRECT_HHR 0x01 + #define jadeINDIRECT_HHX 0x01 + +#define jade_RXAUDIOCH1CFG 0x11 +#define jade_RXAUDIOCH2CFG 0x14 +#define jade_TXAUDIOCH1CFG 0x17 +#define jade_TXAUDIOCH2CFG 0x1A + +extern int JadeVersion(struct IsdnCardState *cs, char *s); +extern void jade_sched_event(struct BCState *bcs, int event); +extern void modejade(struct BCState *bcs, int mode, int bc); +extern void clear_pending_jade_ints(struct IsdnCardState *cs); +extern void initjade(struct IsdnCardState *cs); + +#endif /* __JADE_H__ */ diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/jade_irq.c linux/drivers/isdn/hisax/jade_irq.c --- v2.3.13/linux/drivers/isdn/hisax/jade_irq.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/hisax/jade_irq.c Thu Aug 12 09:42:33 1999 @@ -0,0 +1,247 @@ +/* $Id: jade_irq.c,v 1.2 1999/07/01 08:07:59 keil Exp $ + * + * jade_irq.c Low level JADE IRQ stuff (derived from original hscx_irq.c) + * + * Author Roland Klabunde (R.Klabunde@Berkom.de) + * + * $Log: jade_irq.c,v $ + * Revision 1.2 1999/07/01 08:07:59 keil + * Initial version + * + * + */ + +static inline void +waitforCEC(struct IsdnCardState *cs, int jade, int reg) +{ + int to = 50; + int mask = (reg == jade_HDLC_XCMD ? jadeSTAR_XCEC : jadeSTAR_RCEC); + while ((READJADE(cs, jade, jade_HDLC_STAR) & mask) && to) { + udelay(1); + to--; + } + if (!to) + printk(KERN_WARNING "HiSax: waitforCEC (jade) timeout\n"); +} + + +static inline void +waitforXFW(struct IsdnCardState *cs, int jade) +{ + /* Does not work on older jade versions, don't care */ +} + +static inline void +WriteJADECMDR(struct IsdnCardState *cs, int jade, int reg, u_char data) +{ + long flags; + + save_flags(flags); + cli(); + waitforCEC(cs, jade, reg); + WRITEJADE(cs, jade, reg, data); + restore_flags(flags); +} + + + +static void +jade_empty_fifo(struct BCState *bcs, int count) +{ + u_char *ptr; + struct IsdnCardState *cs = bcs->cs; + long flags; + + if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) + debugl1(cs, "jade_empty_fifo"); + + if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) { + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "jade_empty_fifo: incoming packet too large"); + WriteJADECMDR(cs, bcs->hw.hscx.hscx, jade_HDLC_RCMD, jadeRCMD_RMC); + bcs->hw.hscx.rcvidx = 0; + return; + } + ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; + bcs->hw.hscx.rcvidx += count; + save_flags(flags); + cli(); + READJADEFIFO(cs, bcs->hw.hscx.hscx, ptr, count); + WriteJADECMDR(cs, bcs->hw.hscx.hscx, jade_HDLC_RCMD, jadeRCMD_RMC); + restore_flags(flags); + if (cs->debug & L1_DEB_HSCX_FIFO) { + char *t = bcs->blog; + + t += sprintf(t, "jade_empty_fifo %c cnt %d", + bcs->hw.hscx.hscx ? 'B' : 'A', count); + QuickHex(t, ptr, count); + debugl1(cs, bcs->blog); + } +} + +static void +jade_fill_fifo(struct BCState *bcs) +{ + struct IsdnCardState *cs = bcs->cs; + int more, count; + int fifo_size = 32; + u_char *ptr; + long flags; + + if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) + debugl1(cs, "jade_fill_fifo"); + + if (!bcs->tx_skb) + return; + if (bcs->tx_skb->len <= 0) + return; + + more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0; + if (bcs->tx_skb->len > fifo_size) { + more = !0; + count = fifo_size; + } else + count = bcs->tx_skb->len; + + waitforXFW(cs, bcs->hw.hscx.hscx); + save_flags(flags); + cli(); + ptr = bcs->tx_skb->data; + skb_pull(bcs->tx_skb, count); + bcs->tx_cnt -= count; + bcs->hw.hscx.count += count; + WRITEJADEFIFO(cs, bcs->hw.hscx.hscx, ptr, count); + WriteJADECMDR(cs, bcs->hw.hscx.hscx, jade_HDLC_XCMD, more ? jadeXCMD_XF : (jadeXCMD_XF|jadeXCMD_XME)); + restore_flags(flags); + if (cs->debug & L1_DEB_HSCX_FIFO) { + char *t = bcs->blog; + + t += sprintf(t, "jade_fill_fifo %c cnt %d", + bcs->hw.hscx.hscx ? 'B' : 'A', count); + QuickHex(t, ptr, count); + debugl1(cs, bcs->blog); + } +} + + +static inline void +jade_interrupt(struct IsdnCardState *cs, u_char val, u_char jade) +{ + u_char r; + struct BCState *bcs = cs->bcs + jade; + struct sk_buff *skb; + int fifo_size = 32; + int count; + int i_jade = (int) jade; /* To satisfy the compiler */ + + if (!test_bit(BC_FLG_INIT, &bcs->Flag)) + return; + + if (val & 0x80) { /* RME */ + r = READJADE(cs, i_jade, jade_HDLC_RSTA); + if ((r & 0xf0) != 0xa0) { + if (!(r & 0x80)) + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "JADE %s invalid frame", (jade ? "B":"A")); + if ((r & 0x40) && bcs->mode) + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "JADE %c RDO mode=%d", 'A'+jade, bcs->mode); + if (!(r & 0x20)) + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "JADE %c CRC error", 'A'+jade); + WriteJADECMDR(cs, jade, jade_HDLC_RCMD, jadeRCMD_RMC); + } else { + count = READJADE(cs, i_jade, jade_HDLC_RBCL) & 0x1F; + if (count == 0) + count = fifo_size; + jade_empty_fifo(bcs, count); + if ((count = bcs->hw.hscx.rcvidx - 1) > 0) { + if (cs->debug & L1_DEB_HSCX_FIFO) + debugl1(cs, "HX Frame %d", count); + if (!(skb = dev_alloc_skb(count))) + printk(KERN_WARNING "JADE %s receive out of memory\n", (jade ? "B":"A")); + else { + SET_SKB_FREE(skb); + memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count); + skb_queue_tail(&bcs->rqueue, skb); + } + } + } + bcs->hw.hscx.rcvidx = 0; + jade_sched_event(bcs, B_RCVBUFREADY); + } + if (val & 0x40) { /* RPF */ + jade_empty_fifo(bcs, fifo_size); + if (bcs->mode == L1_MODE_TRANS) { + /* receive audio data */ + if (!(skb = dev_alloc_skb(fifo_size))) + printk(KERN_WARNING "HiSax: receive out of memory\n"); + else { + SET_SKB_FREE(skb); + memcpy(skb_put(skb, fifo_size), bcs->hw.hscx.rcvbuf, fifo_size); + skb_queue_tail(&bcs->rqueue, skb); + } + bcs->hw.hscx.rcvidx = 0; + jade_sched_event(bcs, B_RCVBUFREADY); + } + } + if (val & 0x10) { /* XPR */ + if (bcs->tx_skb) { + if (bcs->tx_skb->len) { + jade_fill_fifo(bcs); + return; + } else { + if (bcs->st->lli.l1writewakeup && + (PACKET_NOACK != bcs->tx_skb->pkt_type)) + bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count); + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + bcs->hw.hscx.count = 0; + bcs->tx_skb = NULL; + } + } + if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { + bcs->hw.hscx.count = 0; + test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); + jade_fill_fifo(bcs); + } else { + test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); + jade_sched_event(bcs, B_XMTBUFREADY); + } + } +} + +static inline void +jade_int_main(struct IsdnCardState *cs, u_char val, int jade) +{ + struct BCState *bcs; + bcs = cs->bcs + jade; + + if (val & jadeISR_RFO) { + /* handled with RDO */ + val &= ~jadeISR_RFO; + } + if (val & jadeISR_XDU) { + /* relevant in HDLC mode only */ + /* don't reset XPR here */ + if (bcs->mode == 1) + jade_fill_fifo(bcs); + else { + /* Here we lost an TX interrupt, so + * restart transmitting the whole frame. + */ + if (bcs->tx_skb) { + skb_push(bcs->tx_skb, bcs->hw.hscx.count); + bcs->tx_cnt += bcs->hw.hscx.count; + bcs->hw.hscx.count = 0; + } + WriteJADECMDR(cs, bcs->hw.hscx.hscx, jade_HDLC_XCMD, jadeXCMD_XRES); + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "JADE %c EXIR %x Lost TX", 'A'+jade, val); + } + } + if (val & (jadeISR_RME|jadeISR_RPF|jadeISR_XPR)) { + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "JADE %c interrupt %x", 'A'+jade, val); + jade_interrupt(cs, val, jade); + } +} diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/l3_1tr6.c linux/drivers/isdn/hisax/l3_1tr6.c --- v2.3.13/linux/drivers/isdn/hisax/l3_1tr6.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/l3_1tr6.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: l3_1tr6.c,v 2.8 1998/11/15 23:55:08 keil Exp $ +/* $Id: l3_1tr6.c,v 2.9 1999/07/01 08:11:55 keil Exp $ * German 1TR6 D-channel protocol * @@ -10,6 +10,9 @@ * * * $Log: l3_1tr6.c,v $ + * Revision 2.9 1999/07/01 08:11:55 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 2.8 1998/11/15 23:55:08 keil * changes from 2.0 * @@ -56,7 +59,7 @@ #include extern char *HiSax_getrev(const char *revision); -const char *l3_1tr6_revision = "$Revision: 2.8 $"; +const char *l3_1tr6_revision = "$Revision: 2.9 $"; #define MsgHead(ptr, cref, mty, dis) \ *ptr++ = dis; \ @@ -91,14 +94,14 @@ { struct sk_buff *skb = arg; - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); l3_1tr6_release_req(pc, 0, NULL); } static void l3_1tr6_error(struct l3_process *pc, u_char *msg, struct sk_buff *skb) { - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); if (pc->st->l3.debug & L3_DEB_WARN) l3_debug(pc->st, msg); l3_1tr6_release_req(pc, 0, NULL); @@ -248,7 +251,7 @@ if ((FAC_SPV == p[3]) || (FAC_Activate == p[3])) pc->para.spv = 1; } - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); /* Signal all services, linklevel takes care of Service-Indicator */ if (bcfound) { @@ -287,7 +290,7 @@ l3_1tr6_error(pc, "missing setup_ack WE0_chanID", skb); return; } - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); L3AddTimer(&pc->timer, T304, CC_T304); pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc); } @@ -318,7 +321,7 @@ l3_1tr6_error(pc, "missing call sent WE0_chanID", skb); return; } - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); L3AddTimer(&pc->timer, T310, CC_T310); newl3state(pc, 3); pc->st->l3.l3l4(pc->st, CC_PROCEEDING | INDICATION, pc); @@ -329,7 +332,7 @@ { struct sk_buff *skb = arg; - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); L3DelTimer(&pc->timer); /* T304 */ newl3state(pc, 4); pc->st->l3.l3l4(pc->st, CC_ALERTING | INDICATION, pc); @@ -360,7 +363,7 @@ } } else if (pc->st->l3.debug & L3_DEB_CHARGE) l3_debug(pc->st, "charging info not found"); - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); } @@ -369,7 +372,7 @@ { struct sk_buff *skb = arg; - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); } static void @@ -383,7 +386,7 @@ return; } newl3state(pc, 10); - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); pc->para.chargeinfo = 0; pc->st->l3.l3l4(pc->st, CC_SETUP | CONFIRM, pc); } @@ -407,11 +410,11 @@ pc->para.loc = 0; } } else { - pc->para.cause = -1; + pc->para.cause = NO_CAUSE; l3_1tr6_error(pc, "missing REL cause", skb); return; } - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); StopAllL3Timer(pc); newl3state(pc, 0); l3_1TR6_message(pc, MT_N1_REL_ACK, PROTO_DIS_N1); @@ -424,10 +427,10 @@ { struct sk_buff *skb = arg; - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); StopAllL3Timer(pc); newl3state(pc, 0); - pc->para.cause = -1; + pc->para.cause = NO_CAUSE; pc->st->l3.l3l4(pc->st, CC_RELEASE | CONFIRM, pc); release_l3_process(pc); } @@ -475,13 +478,13 @@ } else { if (pc->st->l3.debug & L3_DEB_WARN) l3_debug(pc->st, "cause not found"); - pc->para.cause = -1; + pc->para.cause = NO_CAUSE; } if (!findie(skb->data, skb->len, WE6_date, 6)) { l3_1tr6_error(pc, "missing connack date", skb); return; } - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); newl3state(pc, 12); pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc); } @@ -496,7 +499,7 @@ l3_1tr6_error(pc, "missing connack date", skb); return; } - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); newl3state(pc, 10); pc->para.chargeinfo = 0; L3DelTimer(&pc->timer); @@ -567,6 +570,9 @@ case 0x10: clen = 0; break; + case 0x11: + cause = CAUSE_UserBusy; + break; case 0x15: cause = CAUSE_CallRejected; break; @@ -620,7 +626,7 @@ u_char clen = 1; L3DelTimer(&pc->timer); - if (pc->para.cause > 0) + if (pc->para.cause != NO_CAUSE) cause = pc->para.cause; /* Map DSS1 causes */ switch (cause & 0x7f) { @@ -679,6 +685,24 @@ pc->st->l3.l3l4(pc->st, CC_RELEASE_ERR, pc); release_l3_process(pc); } + +static void +l3_1tr6_dl_reset(struct l3_process *pc, u_char pr, void *arg) +{ + pc->para.cause = CAUSE_LocalProcErr; + l3_1tr6_disconnect_req(pc, pr, NULL); + pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc); +} + +static void +l3_1tr6_dl_release(struct l3_process *pc, u_char pr, void *arg) +{ + newl3state(pc, 0); + pc->para.cause = 0x1b; /* Destination out of order */ + pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); + release_l3_process(pc); +} + /* *INDENT-OFF* */ static struct stateentry downstl[] = { @@ -689,8 +713,6 @@ CC_DISCONNECT | REQUEST, l3_1tr6_disconnect_req}, {SBIT(12), CC_RELEASE | REQUEST, l3_1tr6_release_req}, - {ALL_STATES, - CC_DLRL | REQUEST, l3_1tr6_reset}, {SBIT(6), CC_IGNORE | REQUEST, l3_1tr6_reset}, {SBIT(6), @@ -751,11 +773,22 @@ {SBIT(19), MT_N1_REL_ACK, l3_1tr6_rel_ack} }; -/* *INDENT-ON* */ #define DATASTLN1_LEN \ (sizeof(datastln1) / sizeof(struct stateentry)) +static struct stateentry manstatelist[] = +{ + {SBIT(2), + DL_ESTABLISH | INDICATION, l3_1tr6_dl_reset}, + {ALL_STATES, + DL_RELEASE | INDICATION, l3_1tr6_dl_release}, +}; + +#define MANSLLEN \ + (sizeof(manstatelist) / sizeof(struct stateentry)) +/* *INDENT-ON* */ + static void up1tr6(struct PStack *st, int pr, void *arg) { @@ -778,20 +811,20 @@ } if (skb->len < 4) { if (st->l3.debug & L3_DEB_PROTERR) { - sprintf(tmp, "up1tr6 len only %ld", skb->len); + sprintf(tmp, "up1tr6 len only %d", skb->len); l3_debug(st, tmp); } - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); return; } if ((skb->data[0] & 0xfe) != PROTO_DIS_N0) { if (st->l3.debug & L3_DEB_PROTERR) { - sprintf(tmp, "up1tr6%sunexpected discriminator %x message len %ld", + sprintf(tmp, "up1tr6%sunexpected discriminator %x message len %d", (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", skb->data[0], skb->len); l3_debug(st, tmp); } - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); return; } if (skb->data[1] != 1) { @@ -799,13 +832,13 @@ sprintf(tmp, "up1tr6 CR len not 1"); l3_debug(st, tmp); } - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); return; } cr = skb->data[2]; mt = skb->data[3]; if (skb->data[0] == PROTO_DIS_N0) { - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); if (st->l3.debug & L3_DEB_STATE) { sprintf(tmp, "up1tr6%s N0 mt %x unhandled", (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", mt); @@ -820,11 +853,11 @@ sprintf(tmp, "up1tr6 no roc mem"); l3_debug(st, tmp); } - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); return; } } else { - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); return; } } else if ((mt == MT_N1_REL) || (mt == MT_N1_REL_ACK) || @@ -832,7 +865,7 @@ (mt == MT_N1_REG_ACK) || (mt == MT_N1_REG_REJ) || (mt == MT_N1_SUSP_ACK) || (mt == MT_N1_RES_REJ) || (mt == MT_N1_INFO)) { - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); return; } else { if (!(proc = new_l3_process(st, cr))) { @@ -840,7 +873,7 @@ sprintf(tmp, "up1tr6 no roc mem"); l3_debug(st, tmp); } - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); return; } mt = MT_N1_INVALID; @@ -851,7 +884,7 @@ ((1 << proc->state) & datastln1[i].state)) break; if (i == DATASTLN1_LEN) { - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); if (st->l3.debug & L3_DEB_STATE) { sprintf(tmp, "up1tr6%sstate %d mt %x unhandled", (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", @@ -879,7 +912,7 @@ struct Channel *chan; char tmp[80]; - if (((DL_ESTABLISH | REQUEST)== pr) || ((DL_RELEASE | REQUEST)== pr)) { + if ((DL_ESTABLISH | REQUEST)== pr) { l3_msg(st, pr, NULL); return; } else if ((CC_SETUP | REQUEST) == pr) { @@ -918,6 +951,34 @@ } } +static void +man1tr6(struct PStack *st, int pr, void *arg) +{ + int i; + struct l3_process *proc = arg; + + if (!proc) { + printk(KERN_ERR "HiSax man1tr6 without proc pr=%04x\n", pr); + return; + } + for (i = 0; i < MANSLLEN; i++) + if ((pr == manstatelist[i].primitive) && + ((1 << proc->state) & manstatelist[i].state)) + break; + if (i == MANSLLEN) { + if (st->l3.debug & L3_DEB_STATE) { + l3_debug(st, "cr %d man1tr6 state %d prim %d unhandled", + proc->callref & 0x7f, proc->state, pr); + } + } else { + if (st->l3.debug & L3_DEB_STATE) { + l3_debug(st, "cr %d man1tr6 state %d prim %d", + proc->callref & 0x7f, proc->state, pr); + } + manstatelist[i].rout(proc, pr, arg); + } +} + void setstack_1tr6(struct PStack *st) { @@ -925,6 +986,7 @@ st->lli.l4l3 = down1tr6; st->l2.l2l3 = up1tr6; + st->l3.l3ml3 = man1tr6; st->l3.N303 = 0; strcpy(tmp, l3_1tr6_revision); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/l3dss1.c linux/drivers/isdn/hisax/l3dss1.c --- v2.3.13/linux/drivers/isdn/hisax/l3dss1.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/l3dss1.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: l3dss1.c,v 2.12 1998/11/15 23:55:10 keil Exp $ +/* $Id: l3dss1.c,v 2.18 1999/08/11 20:54:39 keil Exp $ * EURO/DSS1 D-channel protocol * @@ -13,6 +13,21 @@ * Fritz Elfert * * $Log: l3dss1.c,v $ + * Revision 2.18 1999/08/11 20:54:39 keil + * High layer compatibility is valid in SETUP + * + * Revision 2.17 1999/07/25 16:18:25 keil + * Fix Suspend/Resume + * + * Revision 2.16 1999/07/21 14:46:23 keil + * changes from EICON certification + * + * Revision 2.14 1999/07/09 08:30:08 keil + * cosmetics + * + * Revision 2.13 1999/07/01 08:11:58 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 2.12 1998/11/15 23:55:10 keil * changes from 2.0 * @@ -72,29 +87,227 @@ #include extern char *HiSax_getrev(const char *revision); -const char *dss1_revision = "$Revision: 2.12 $"; +const char *dss1_revision = "$Revision: 2.18 $"; + +#define EXT_BEARER_CAPS 1 #define MsgHead(ptr, cref, mty) \ *ptr++ = 0x8; \ - *ptr++ = 0x1; \ - *ptr++ = cref^0x80; \ + if (cref == -1) { \ + *ptr++ = 0x0; \ + } else { \ + *ptr++ = 0x1; \ + *ptr++ = cref^0x80; \ + } \ *ptr++ = mty -#if HISAX_DE_AOC +/**********************************************/ +/* get a new invoke id for remote operations. */ +/* Only a return value != 0 is valid */ +/**********************************************/ +static unsigned char new_invoke_id(struct PStack *p) +{ + unsigned char retval; + int flags,i; + + i = 32; /* maximum search depth */ + + save_flags(flags); + cli(); + + retval = p->prot.dss1.last_invoke_id + 1; /* try new id */ + while ((i) && (p->prot.dss1.invoke_used[retval >> 3] == 0xFF)) { + p->prot.dss1.last_invoke_id = (retval & 0xF8) + 8; + i--; + } + if (i) { + while (p->prot.dss1.invoke_used[retval >> 3] & (1 << (retval & 7))) + retval++; + } else + retval = 0; + p->prot.dss1.last_invoke_id = retval; + p->prot.dss1.invoke_used[retval >> 3] |= (1 << (retval & 7)); + restore_flags(flags); + + return(retval); +} /* new_invoke_id */ + +/*************************/ +/* free a used invoke id */ +/*************************/ +static void free_invoke_id(struct PStack *p, unsigned char id) +{ int flags; + + if (!id) return; /* 0 = invalid value */ + + save_flags(flags); + cli(); + p->prot.dss1.invoke_used[id >> 3] &= ~(1 << (id & 7)); + restore_flags(flags); +} /* free_invoke_id */ + + +/**********************************************************/ +/* create a new l3 process and fill in dss1 specific data */ +/**********************************************************/ +static struct l3_process +*dss1_new_l3_process(struct PStack *st, int cr) +{ struct l3_process *proc; + + if (!(proc = new_l3_process(st, cr))) + return(NULL); + + proc->prot.dss1.invoke_id = 0; + proc->prot.dss1.remote_operation = 0; + proc->prot.dss1.uus1_data[0] = '\0'; + + return(proc); +} /* dss1_new_l3_process */ + +/************************************************/ +/* free a l3 process and all dss1 specific data */ +/************************************************/ +static void +dss1_release_l3_process(struct l3_process *p) +{ + free_invoke_id(p->st,p->prot.dss1.invoke_id); + release_l3_process(p); +} /* dss1_release_l3_process */ + +/********************************************************/ +/* search a process with invoke id id and dummy callref */ +/********************************************************/ +static struct l3_process * +l3dss1_search_dummy_proc(struct PStack *st, int id) +{ struct l3_process *pc = st->l3.proc; /* start of processes */ + + if (!id) return(NULL); + + while (pc) + { if ((pc->callref == -1) && (pc->prot.dss1.invoke_id == id)) + return(pc); + pc = pc->next; + } + return(NULL); +} /* l3dss1_search_dummy_proc */ + +/*******************************************************************/ +/* called when a facility message with a dummy callref is received */ +/* and a return result is delivered. id specifies the invoke id. */ +/*******************************************************************/ +static void +l3dss1_dummy_return_result(struct PStack *st, int id, u_char *p, u_char nlen) +{ isdn_ctrl ic; + struct IsdnCardState *cs; + struct l3_process *pc = NULL; + + if ((pc = l3dss1_search_dummy_proc(st, id))) + { L3DelTimer(&pc->timer); /* remove timer */ + + cs = pc->st->l1.hardware; + ic.driver = cs->myid; + ic.command = ISDN_STAT_PROT; + ic.arg = DSS1_STAT_INVOKE_RES; + ic.parm.dss1_io.hl_id = pc->prot.dss1.invoke_id; + ic.parm.dss1_io.ll_id = pc->prot.dss1.ll_id; + ic.parm.dss1_io.proc = pc->prot.dss1.proc; + ic.parm.dss1_io.timeout= 0; + ic.parm.dss1_io.datalen = nlen; + ic.parm.dss1_io.data = p; + free_invoke_id(pc->st, pc->prot.dss1.invoke_id); + pc->prot.dss1.invoke_id = 0; /* reset id */ + + cs->iif.statcallb(&ic); + dss1_release_l3_process(pc); + } + else + l3_debug(st, "dummy return result id=0x%x result len=%d",id,nlen); +} /* l3dss1_dummy_return_result */ + +/*******************************************************************/ +/* called when a facility message with a dummy callref is received */ +/* and a return error is delivered. id specifies the invoke id. */ +/*******************************************************************/ +static void +l3dss1_dummy_error_return(struct PStack *st, int id, ulong error) +{ isdn_ctrl ic; + struct IsdnCardState *cs; + struct l3_process *pc = NULL; + + if ((pc = l3dss1_search_dummy_proc(st, id))) + { L3DelTimer(&pc->timer); /* remove timer */ + + cs = pc->st->l1.hardware; + ic.driver = cs->myid; + ic.command = ISDN_STAT_PROT; + ic.arg = DSS1_STAT_INVOKE_ERR; + ic.parm.dss1_io.hl_id = pc->prot.dss1.invoke_id; + ic.parm.dss1_io.ll_id = pc->prot.dss1.ll_id; + ic.parm.dss1_io.proc = pc->prot.dss1.proc; + ic.parm.dss1_io.timeout= error; + ic.parm.dss1_io.datalen = 0; + ic.parm.dss1_io.data = NULL; + free_invoke_id(pc->st, pc->prot.dss1.invoke_id); + pc->prot.dss1.invoke_id = 0; /* reset id */ + + cs->iif.statcallb(&ic); + dss1_release_l3_process(pc); + } + else + l3_debug(st, "dummy return error id=0x%x error=0x%lx",id,error); +} /* l3dss1_error_return */ + +/*******************************************************************/ +/* called when a facility message with a dummy callref is received */ +/* and a invoke is delivered. id specifies the invoke id. */ +/*******************************************************************/ +static void +l3dss1_dummy_invoke(struct PStack *st, int cr, int id, + int ident, u_char *p, u_char nlen) +{ isdn_ctrl ic; + struct IsdnCardState *cs; + + l3_debug(st, "dummy invoke %s id=0x%x ident=0x%x datalen=%d", + (cr == -1) ? "local" : "broadcast",id,ident,nlen); + if (cr >= -1) return; /* ignore local data */ + + cs = st->l1.hardware; + ic.driver = cs->myid; + ic.command = ISDN_STAT_PROT; + ic.arg = DSS1_STAT_INVOKE_BRD; + ic.parm.dss1_io.hl_id = id; + ic.parm.dss1_io.ll_id = 0; + ic.parm.dss1_io.proc = ident; + ic.parm.dss1_io.timeout= 0; + ic.parm.dss1_io.datalen = nlen; + ic.parm.dss1_io.data = p; + + cs->iif.statcallb(&ic); +} /* l3dss1_dummy_invoke */ + static void -l3dss1_parse_facility(struct l3_process *pc, u_char * p) +l3dss1_parse_facility(struct PStack *st, struct l3_process *pc, + int cr, u_char * p) { int qd_len = 0; + unsigned char nlen = 0, ilen, cp_tag; + int ident, id; + ulong err_ret; + + if (pc) + st = pc->st; /* valid Stack */ + else + if ((!st) || (cr >= 0)) return; /* neither pc nor st specified */ p++; qd_len = *p++; if (qd_len == 0) { - l3_debug(pc->st, "qd_len == 0"); + l3_debug(st, "qd_len == 0"); return; } if ((*p & 0x1F) != 0x11) { /* Service discriminator, supplementary service */ - l3_debug(pc->st, "supplementary service != 0x11"); + l3_debug(st, "supplementary service != 0x11"); return; } while (qd_len > 0 && !(*p & 0x80)) { /* extension ? */ @@ -102,72 +315,92 @@ qd_len--; } if (qd_len < 2) { - l3_debug(pc->st, "qd_len < 2"); + l3_debug(st, "qd_len < 2"); return; } p++; qd_len--; if ((*p & 0xE0) != 0xA0) { /* class and form */ - l3_debug(pc->st, "class and form != 0xA0"); + l3_debug(st, "class and form != 0xA0"); return; } - switch (*p & 0x1F) { /* component tag */ - case 1: /* invoke */ - { - unsigned char nlen = 0, ilen; - int ident; - - p++; - qd_len--; - if (qd_len < 1) { - l3_debug(pc->st, "qd_len < 1"); - break; - } - if (*p & 0x80) { /* length format */ - l3_debug(pc->st, "*p & 0x80 length format"); - break; - } - nlen = *p++; - qd_len--; - if (qd_len < nlen) { - l3_debug(pc->st, "qd_len < nlen"); - return; - } - qd_len -= nlen; + + cp_tag = *p & 0x1F; /* remember tag value */ - if (nlen < 2) { - l3_debug(pc->st, "nlen < 2"); - return; - } - if (*p != 0x02) { /* invoke identifier tag */ - l3_debug(pc->st, "invoke identifier tag !=0x02"); - return; - } - p++; - nlen--; - if (*p & 0x80) { /* length format */ - l3_debug(pc->st, "*p & 0x80 length format 2"); - break; - } - ilen = *p++; - nlen--; - if (ilen > nlen || ilen == 0) { - l3_debug(pc->st, "ilen > nlen || ilen == 0"); - return; - } - nlen -= ilen; - ident = 0; - while (ilen > 0) { - ident = (ident << 8) | (*p++ & 0xFF); /* invoke identifier */ - ilen--; - } + p++; + qd_len--; + if (qd_len < 1) + { l3_debug(st, "qd_len < 1"); + return; + } + if (*p & 0x80) + { /* length format indefinite or limited */ + nlen = *p++ & 0x7F; /* number of len bytes or indefinite */ + if ((qd_len-- < ((!nlen) ? 3 : (1 + nlen))) || + (nlen > 1)) + { l3_debug(st, "length format error or not implemented"); + return; + } + if (nlen == 1) + { nlen = *p++; /* complete length */ + qd_len--; + } + else + { qd_len -= 2; /* trailing null bytes */ + if ((*(p+qd_len)) || (*(p+qd_len+1))) + { l3_debug(st,"length format indefinite error"); + return; + } + nlen = qd_len; + } + } + else + { nlen = *p++; + qd_len--; + } + if (qd_len < nlen) + { l3_debug(st, "qd_len < nlen"); + return; + } + qd_len -= nlen; + + if (nlen < 2) + { l3_debug(st, "nlen < 2"); + return; + } + if (*p != 0x02) + { /* invoke identifier tag */ + l3_debug(st, "invoke identifier tag !=0x02"); + return; + } + p++; + nlen--; + if (*p & 0x80) + { /* length format */ + l3_debug(st, "invoke id length format 2"); + return; + } + ilen = *p++; + nlen--; + if (ilen > nlen || ilen == 0) + { l3_debug(st, "ilen > nlen || ilen == 0"); + return; + } + nlen -= ilen; + id = 0; + while (ilen > 0) + { id = (id << 8) | (*p++ & 0xFF); /* invoke identifier */ + ilen--; + } + switch (cp_tag) { /* component tag */ + case 1: /* invoke */ if (nlen < 2) { - l3_debug(pc->st, "nlen < 2 22"); + l3_debug(st, "nlen < 2 22"); return; } if (*p != 0x02) { /* operation value */ - l3_debug(pc->st, "operation value !=0x02"); + l3_debug(st, "operation value !=0x02"); return; } p++; @@ -175,7 +408,7 @@ ilen = *p++; nlen--; if (ilen > nlen || ilen == 0) { - l3_debug(pc->st, "ilen > nlen || ilen == 0 22"); + l3_debug(st, "ilen > nlen || ilen == 0 22"); return; } nlen -= ilen; @@ -185,11 +418,18 @@ ilen--; } + if (!pc) + { l3dss1_dummy_invoke(st, cr, id, ident, p, nlen); + return; + } +#if HISAX_DE_AOC + { + #define FOO1(s,a,b) \ while(nlen > 1) { \ int ilen = p[1]; \ if(nlen < ilen+2) { \ - l3_debug(pc->st, "FOO1 nlen < ilen+2"); \ + l3_debug(st, "FOO1 nlen < ilen+2"); \ return; \ } \ nlen -= ilen+2; \ @@ -203,8 +443,6 @@ } switch (ident) { - default: - break; case 0x22: /* during */ FOO1("1A", 0x30, FOO1("1C", 0xA1, FOO1("1D", 0x30, FOO1("1E", 0x02, ( { ident = 0; @@ -215,14 +453,14 @@ } if (ident > pc->para.chargeinfo) { pc->para.chargeinfo = ident; - pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc); + st->l3.l3l4(st, CC_CHARGE | INDICATION, pc); } - if (pc->st->l3.debug & L3_DEB_CHARGE) { + if (st->l3.debug & L3_DEB_CHARGE) { if (*(p + 2) == 0) { - l3_debug(pc->st, "charging info during %d", pc->para.chargeinfo); + l3_debug(st, "charging info during %d", pc->para.chargeinfo); } else { - l3_debug(pc->st, "charging info final %d", pc->para.chargeinfo); + l3_debug(st, "charging info final %d", pc->para.chargeinfo); } } } @@ -238,113 +476,553 @@ } if (ident > pc->para.chargeinfo) { pc->para.chargeinfo = ident; - pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc); + st->l3.l3l4(st, CC_CHARGE | INDICATION, pc); } - if (pc->st->l3.debug & L3_DEB_CHARGE) { - l3_debug(pc->st, "charging info final %d", pc->para.chargeinfo); + if (st->l3.debug & L3_DEB_CHARGE) { + l3_debug(st, "charging info final %d", pc->para.chargeinfo); } } )))))) break; + default: + l3_debug(st, "invoke break invalid ident %02x",ident); + break; } #undef FOO1 } +#else not HISAX_DE_AOC + l3_debug(st, "invoke break"); +#endif not HISAX_DE_AOC break; case 2: /* return result */ - l3_debug(pc->st, "return result break"); + /* if no process available handle separately */ + if (!pc) + { if (cr == -1) + l3dss1_dummy_return_result(st, id, p, nlen); + return; + } + if ((pc->prot.dss1.invoke_id) && (pc->prot.dss1.invoke_id == id)) + { /* Diversion successfull */ + free_invoke_id(st,pc->prot.dss1.invoke_id); + pc->prot.dss1.remote_result = 0; /* success */ + pc->prot.dss1.invoke_id = 0; + pc->redir_result = pc->prot.dss1.remote_result; + st->l3.l3l4(st, CC_REDIR | INDICATION, pc); } /* Diversion successfull */ + else + l3_debug(st,"return error unknown identifier"); break; case 3: /* return error */ - l3_debug(pc->st, "return error break"); + err_ret = 0; + if (nlen < 2) + { l3_debug(st, "return error nlen < 2"); + return; + } + if (*p != 0x02) + { /* result tag */ + l3_debug(st, "invoke error tag !=0x02"); + return; + } + p++; + nlen--; + if (*p > 4) + { /* length format */ + l3_debug(st, "invoke return errlen > 4 "); + return; + } + ilen = *p++; + nlen--; + if (ilen > nlen || ilen == 0) + { l3_debug(st, "error return ilen > nlen || ilen == 0"); + return; + } + nlen -= ilen; + while (ilen > 0) + { err_ret = (err_ret << 8) | (*p++ & 0xFF); /* error value */ + ilen--; + } + /* if no process available handle separately */ + if (!pc) + { if (cr == -1) + l3dss1_dummy_error_return(st, id, err_ret); + return; + } + if ((pc->prot.dss1.invoke_id) && (pc->prot.dss1.invoke_id == id)) + { /* Deflection error */ + free_invoke_id(st,pc->prot.dss1.invoke_id); + pc->prot.dss1.remote_result = err_ret; /* result */ + pc->prot.dss1.invoke_id = 0; + pc->redir_result = pc->prot.dss1.remote_result; + st->l3.l3l4(st, CC_REDIR | INDICATION, pc); + } /* Deflection error */ + else + l3_debug(st,"return result unknown identifier"); break; default: - l3_debug(pc->st, "default break"); + l3_debug(st, "facility default break tag=0x%02x",cp_tag); break; } } + +static void +l3dss1_message(struct l3_process *pc, u_char mt) +{ + struct sk_buff *skb; + u_char *p; + + if (!(skb = l3_alloc_skb(4))) + return; + p = skb_put(skb, 4); + MsgHead(p, pc->callref, mt); + l3_msg(pc->st, DL_DATA | REQUEST, skb); +} + +static void +l3dss1_message_cause(struct l3_process *pc, u_char mt, u_char cause) +{ + struct sk_buff *skb; + u_char tmp[16]; + u_char *p = tmp; + int l; + + MsgHead(p, pc->callref, mt); + *p++ = IE_CAUSE; + *p++ = 0x2; + *p++ = 0x80; + *p++ = cause | 0x80; + + l = p - tmp; + if (!(skb = l3_alloc_skb(l))) + return; + memcpy(skb_put(skb, l), tmp, l); + l3_msg(pc->st, DL_DATA | REQUEST, skb); +} + +static void +l3dss1_status_send(struct l3_process *pc, u_char pr, void *arg) +{ + u_char tmp[16]; + u_char *p = tmp; + int l; + struct sk_buff *skb; + + MsgHead(p, pc->callref, MT_STATUS); + + *p++ = IE_CAUSE; + *p++ = 0x2; + *p++ = 0x80; + *p++ = pc->para.cause | 0x80; + + *p++ = IE_CALL_STATE; + *p++ = 0x1; + *p++ = pc->state & 0x3f; + + l = p - tmp; + if (!(skb = l3_alloc_skb(l))) + return; + memcpy(skb_put(skb, l), tmp, l); + l3_msg(pc->st, DL_DATA | REQUEST, skb); +} + +static void +l3dss1_msg_without_setup(struct l3_process *pc, u_char pr, void *arg) +{ + /* This routine is called if here was no SETUP made (checks in dss1up and in + * l3dss1_setup) and a RELEASE_COMPLETE have to be sent with an error code + * MT_STATUS_ENQUIRE in the NULL state is handled too + */ + u_char tmp[16]; + u_char *p = tmp; + int l; + struct sk_buff *skb; + + switch (pc->para.cause) { + case 81: /* invalid callreference */ + case 88: /* incomp destination */ + case 96: /* mandory IE missing */ + case 100: /* invalid IE contents */ + case 101: /* incompatible Callstate */ + MsgHead(p, pc->callref, MT_RELEASE_COMPLETE); + *p++ = IE_CAUSE; + *p++ = 0x2; + *p++ = 0x80; + *p++ = pc->para.cause | 0x80; + break; + default: + printk(KERN_ERR "HiSax l3dss1_msg_without_setup wrong cause %d\n", + pc->para.cause); + return; + } + l = p - tmp; + if (!(skb = l3_alloc_skb(l))) + return; + memcpy(skb_put(skb, l), tmp, l); + l3_msg(pc->st, DL_DATA | REQUEST, skb); + dss1_release_l3_process(pc); +} + +static int ie_ALERTING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1, + IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_HLC, IE_USER_USER, -1}; +static int ie_CALL_PROCEEDING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1, + IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_HLC, -1}; +static int ie_CONNECT[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1, + IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_DATE, IE_CONNECT_PN, + IE_CONNECT_SUB, IE_LLC, IE_HLC, IE_USER_USER, -1}; +static int ie_CONNECT_ACKNOWLEDGE[] = {IE_CHANNEL_ID, IE_DISPLAY, -1}; +static int ie_DISCONNECT[] = {IE_CAUSE | IE_MANDATORY, IE_FACILITY, + IE_PROGRESS, IE_DISPLAY, IE_USER_USER, -1}; +static int ie_INFORMATION[] = {IE_COMPLETE, IE_DISPLAY, IE_KEYPAD, + IE_CALLED_PN, -1}; +static int ie_NOTIFY[] = {IE_BEARER, IE_NOTIFY | IE_MANDATORY, IE_DISPLAY, -1}; +static int ie_PROGRESS[] = {IE_BEARER, IE_CAUSE, IE_FACILITY, IE_PROGRESS | + IE_MANDATORY, IE_DISPLAY, IE_HLC, IE_USER_USER, -1}; +static int ie_RELEASE[] = {IE_CAUSE | IE_MANDATORY_1, IE_FACILITY, IE_DISPLAY, IE_USER_USER, -1}; +/* a RELEASE_COMPLETE with errors don't require special actions +static int ie_RELEASE_COMPLETE[] = {IE_CAUSE | IE_MANDATORY_1, IE_DISPLAY, IE_USER_USER, -1}; +*/ +static int ie_RESUME_ACKNOWLEDGE[] = {IE_CHANNEL_ID| IE_MANDATORY, IE_FACILITY, + IE_DISPLAY, -1}; +static int ie_RESUME_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1}; +static int ie_SETUP[] = {IE_COMPLETE, IE_BEARER | IE_MANDATORY, + IE_CHANNEL_ID| IE_MANDATORY, IE_FACILITY, IE_PROGRESS, + IE_NET_FAC, IE_DISPLAY, IE_KEYPAD, IE_CALLING_PN, + IE_CALLING_SUB, IE_CALLED_PN, IE_CALLED_SUB, IE_LLC, IE_HLC, + IE_USER_USER, -1}; +static int ie_SETUP_ACKNOWLEDGE[] = {IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY, + IE_PROGRESS, IE_DISPLAY, -1}; +static int ie_STATUS[] = {IE_CAUSE | IE_MANDATORY, IE_CALL_STATE | + IE_MANDATORY, IE_DISPLAY, -1}; +static int ie_STATUS_ENQUIRY[] = {IE_DISPLAY, -1}; +static int ie_SUSPEND_ACKNOWLEDGE[] = {IE_DISPLAY, IE_FACILITY, -1}; +static int ie_SUSPEND_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1}; +/* not used + * static int ie_CONGESTION_CONTROL[] = {IE_CONGESTION | IE_MANDATORY, + * IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1}; + * static int ie_USER_INFORMATION[] = {IE_MORE_DATA, IE_USER_USER | IE_MANDATORY, -1}; + * static int ie_RESTART[] = {IE_CHANNEL_ID, IE_DISPLAY, IE_RESTART_IND | + * IE_MANDATORY, -1}; + */ +static int ie_FACILITY[] = {IE_FACILITY | IE_MANDATORY, IE_DISPLAY, -1}; +static int comp_required[] = {1,2,3,5,6,7,9,10,11,14,15,-1}; +static int l3_valid_states[] = {0,1,2,3,4,6,7,8,9,10,11,12,15,17,19,25,-1}; + +struct ie_len { + int ie; + int len; +}; + +static +struct ie_len max_ie_len[] = { + {IE_SEGMENT, 4}, + {IE_BEARER, 12}, + {IE_CAUSE, 32}, + {IE_CALL_ID, 10}, + {IE_CALL_STATE, 3}, + {IE_CHANNEL_ID, 34}, + {IE_FACILITY, 255}, + {IE_PROGRESS, 4}, + {IE_NET_FAC, 255}, + {IE_NOTIFY, 3}, + {IE_DISPLAY, 82}, + {IE_DATE, 8}, + {IE_KEYPAD, 34}, + {IE_SIGNAL, 3}, + {IE_INFORATE, 6}, + {IE_E2E_TDELAY, 11}, + {IE_TDELAY_SEL, 5}, + {IE_PACK_BINPARA, 3}, + {IE_PACK_WINSIZE, 4}, + {IE_PACK_SIZE, 4}, + {IE_CUG, 7}, + {IE_REV_CHARGE, 3}, + {IE_CALLING_PN, 24}, + {IE_CALLING_SUB, 23}, + {IE_CALLED_PN, 24}, + {IE_CALLED_SUB, 23}, + {IE_REDIR_NR, 255}, + {IE_TRANS_SEL, 255}, + {IE_RESTART_IND, 3}, + {IE_LLC, 18}, + {IE_HLC, 5}, + {IE_USER_USER, 131}, + {-1,0}, +}; + +static int +getmax_ie_len(u_char ie) { + int i = 0; + while (max_ie_len[i].ie != -1) { + if (max_ie_len[i].ie == ie) + return(max_ie_len[i].len); + i++; + } + return(255); +} + +static int +ie_in_set(struct l3_process *pc, u_char ie, int *checklist) { + int ret = 1; + + while (*checklist != -1) { +#if 0 + if (pc->debug & L3_DEB_CHECK) + l3_debug(pc->st, "ie_in_set ie(%x) cl(%x)", + ie, *checklist); #endif + if ((*checklist & 0xff) == ie) { + if (ie & 0x80) + return(-ret); + else + return(ret); + } + ret++; + checklist++; + } + return(0); +} + +static int +check_infoelements(struct l3_process *pc, struct sk_buff *skb, int *checklist) +{ + int *cl = checklist; + u_char mt; + u_char *p, ie; + int l, newpos, oldpos; + int err_seq = 0, err_len = 0, err_compr = 0, err_ureg = 0; + + p = skb->data; + /* skip cr */ + p++; + l = (*p++) & 0xf; + p += l; + mt = *p++; + oldpos = 0; +/* shift codeset procedure not implemented in the moment */ + while ((p - skb->data) < skb->len) { + if ((newpos = ie_in_set(pc, *p, cl))) { + if (newpos > 0) { + if (newpos < oldpos) + err_seq++; + else + oldpos = newpos; + } + } else { + if (ie_in_set(pc, *p, comp_required)) + err_compr++; + else + err_ureg++; + } + ie = *p++; + if (ie & 0x80) { + l = 1; + } else { + l = *p++; + p += l; + l += 2; + } + if (l > getmax_ie_len(ie)) + err_len++; + } + if (err_compr | err_ureg | err_len | err_seq) { + if (pc->debug & L3_DEB_CHECK) + l3_debug(pc->st, "check_infoelements mt %x %d/%d/%d/%d", + mt, err_compr, err_ureg, err_len, err_seq); + if (err_compr) + return(ERR_IE_COMPREHENSION); + if (err_ureg) + return(ERR_IE_UNRECOGNIZED); + if (err_len) + return(ERR_IE_LENGTH); + if (err_seq) + return(ERR_IE_SEQUENCE); + } + return(0); +} +/* verify if a message type exists and contain no IE error */ static int -l3dss1_check_messagetype_validity(int mt) +l3dss1_check_messagetype_validity(struct l3_process *pc, int mt, void *arg) { -/* verify if a message type exists */ switch (mt) { case MT_ALERTING: case MT_CALL_PROCEEDING: case MT_CONNECT: case MT_CONNECT_ACKNOWLEDGE: + case MT_DISCONNECT: + case MT_INFORMATION: + case MT_FACILITY: + case MT_NOTIFY: case MT_PROGRESS: + case MT_RELEASE: + case MT_RELEASE_COMPLETE: case MT_SETUP: case MT_SETUP_ACKNOWLEDGE: - case MT_RESUME: case MT_RESUME_ACKNOWLEDGE: case MT_RESUME_REJECT: - case MT_SUSPEND: case MT_SUSPEND_ACKNOWLEDGE: case MT_SUSPEND_REJECT: case MT_USER_INFORMATION: - case MT_DISCONNECT: - case MT_RELEASE: - case MT_RELEASE_COMPLETE: case MT_RESTART: case MT_RESTART_ACKNOWLEDGE: - case MT_SEGMENT: case MT_CONGESTION_CONTROL: - case MT_INFORMATION: - case MT_FACILITY: - case MT_NOTIFY: case MT_STATUS: case MT_STATUS_ENQUIRY: + if (pc->debug & L3_DEB_CHECK) + l3_debug(pc->st, "l3dss1_check_messagetype_validity mt(%x) OK", mt); + break; + case MT_RESUME: /* RESUME only in user->net */ + case MT_SUSPEND: /* SUSPEND only in user->net */ + default: + if (pc->debug & (L3_DEB_CHECK | L3_DEB_WARN)) + l3_debug(pc->st, "l3dss1_check_messagetype_validity mt(%x) fail", mt); + pc->para.cause = 97; + l3dss1_status_send(pc, 0, NULL); return(1); + } + return(0); +} + +static void +l3dss1_std_ie_err(struct l3_process *pc, int ret) { + + if (pc->debug & L3_DEB_CHECK) + l3_debug(pc->st, "check_infoelements ret %d", ret); + switch(ret) { + case 0: + break; + case ERR_IE_COMPREHENSION: + pc->para.cause = 96; + l3dss1_status_send(pc, 0, NULL); + break; + case ERR_IE_UNRECOGNIZED: + pc->para.cause = 99; + l3dss1_status_send(pc, 0, NULL); + break; + case ERR_IE_LENGTH: + pc->para.cause = 100; + l3dss1_status_send(pc, 0, NULL); + break; + case ERR_IE_SEQUENCE: default: - return(0); + break; } +} + +static int +l3dss1_get_channel_id(struct l3_process *pc, struct sk_buff *skb) { + u_char *p; + + p = skb->data; + if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) { + p++; + if (*p != 1) { /* len for BRI = 1 */ + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "wrong chid len %d", *p); + return (-2); + } + p++; + if (*p & 0x60) { /* only base rate interface */ + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "wrong chid %x", *p); + return (-3); + } + return(*p & 0x3); + } else + return(-1); +} + +static int +l3dss1_get_cause(struct l3_process *pc, struct sk_buff *skb) { + u_char l, i=0; + u_char *p; + + p = skb->data; + pc->para.cause = 31; + pc->para.loc = 0; + if ((p = findie(p, skb->len, IE_CAUSE, 0))) { + p++; + l = *p++; + if (l>30) + return(1); + if (l) { + pc->para.loc = *p++; + l--; + } else { + return(2); + } + if (l && !(pc->para.loc & 0x80)) { + l--; + p++; /* skip recommendation */ + } + if (l) { + pc->para.cause = *p++; + l--; + if (!(pc->para.cause & 0x80)) + return(3); + } else + return(4); + while (l && (i<6)) { + pc->para.diag[i++] = *p++; + l--; + } + } else + return(-1); return(0); } static void -l3dss1_message(struct l3_process *pc, u_char mt) +l3dss1_msg_with_uus(struct l3_process *pc, u_char cmd) { struct sk_buff *skb; - u_char *p; + u_char tmp[16+40]; + u_char *p = tmp; + int l; - if (!(skb = l3_alloc_skb(4))) + MsgHead(p, pc->callref, cmd); + + if (pc->prot.dss1.uus1_data[0]) + { *p++ = IE_USER_USER; /* UUS info element */ + *p++ = strlen(pc->prot.dss1.uus1_data) + 1; + *p++ = 0x04; /* IA5 chars */ + strcpy(p,pc->prot.dss1.uus1_data); + p += strlen(pc->prot.dss1.uus1_data); + pc->prot.dss1.uus1_data[0] = '\0'; + } + + l = p - tmp; + if (!(skb = l3_alloc_skb(l))) return; - p = skb_put(skb, 4); - MsgHead(p, pc->callref, mt); + memcpy(skb_put(skb, l), tmp, l); l3_msg(pc->st, DL_DATA | REQUEST, skb); -} +} /* l3dss1_msg_with_uus */ static void l3dss1_release_req(struct l3_process *pc, u_char pr, void *arg) { StopAllL3Timer(pc); newl3state(pc, 19); - l3dss1_message(pc, MT_RELEASE); + if (!pc->prot.dss1.uus1_data[0]) + l3dss1_message(pc, MT_RELEASE); + else + l3dss1_msg_with_uus(pc, MT_RELEASE); L3AddTimer(&pc->timer, T308, CC_T308_1); } static void l3dss1_release_cmpl(struct l3_process *pc, u_char pr, void *arg) { - u_char *p; struct sk_buff *skb = arg; - int cause = -1; + int ret; - p = skb->data; - pc->para.loc = 0; - if ((p = findie(p, skb->len, IE_CAUSE, 0))) { - p++; - if (*p++ == 2) - pc->para.loc = *p++; - cause = *p & 0x7f; - } - dev_kfree_skb(skb); + if ((ret = l3dss1_get_cause(pc, skb))>0) { + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "RELCMPL get_cause ret(%d)",ret); + } else if (ret < 0) + pc->para.cause = NO_CAUSE; StopAllL3Timer(pc); - pc->para.cause = cause; newl3state(pc, 0); pc->st->l3.l3l4(pc->st, CC_RELEASE | CONFIRM, pc); - release_l3_process(pc); + dss1_release_l3_process(pc); } #if EXT_BEARER_CAPS @@ -574,9 +1252,8 @@ break; case 0x08: // if (p[5] == 0x02) // sync. Bitratenadaption - - return DecodeSyncParams(176, p[5]); // V.120 - + if (p[1] > 3) + return DecodeSyncParams(176, p[5]); // V.120 break; } } @@ -594,6 +1271,7 @@ u_char tmp[128]; u_char *p = tmp; u_char channel = 0; + u_char send_keypad; u_char screen = 0x80; u_char *teln; u_char *msn; @@ -603,13 +1281,17 @@ MsgHead(p, pc->callref, MT_SETUP); + teln = pc->para.setup.phone; + send_keypad = (strchr(teln,'*') || strchr(teln,'#')) ? 1 : 0; /* * Set Bearer Capability, Map info from 1TR6-convention to EDSS1 */ #if HISAX_EURO_SENDCOMPLETE - *p++ = 0xa1; /* complete indicator */ + if (!send_keypad) + *p++ = 0xa1; /* complete indicator */ #endif - switch (pc->para.setup.si1) { + if (!send_keypad) + switch (pc->para.setup.si1) { case 1: /* Telephony */ *p++ = 0x4; /* BC-IE-code */ *p++ = 0x3; /* Length */ @@ -625,12 +1307,26 @@ *p++ = 0x88; /* Coding Std. CCITT, unrestr. dig. Inform. */ *p++ = 0x90; /* Circuit-Mode 64kbps */ break; - } + } + else { *p++ = 0x4; /* assumptions for bearer services with keypad */ + *p++ = 0x3; + *p++ = 0x80; + *p++ = 0x90; + *p++ = 0xa3; + *p++ = 0x18; /* no specific channel */ + *p++ = 0x01; + *p++ = 0x83; + *p++ = 0x2C; /* IE keypad */ + *p++ = strlen(teln); + while (*teln) + *p++ = (*teln++) & 0x7F; + } + + /* * What about info2? Mapping to High-Layer-Compatibility? */ - teln = pc->para.setup.phone; - if (*teln) { + if ((*teln) && (!send_keypad)) { /* parse number for special things */ if (!isdigit(*teln)) { switch (0x5f & *teln) { @@ -650,7 +1346,8 @@ case 'D': screen = 0x80; break; - default: + + default: if (pc->debug & L3_DEB_WARN) l3_debug(pc->st, "Wrong MSN Code"); break; @@ -703,24 +1400,33 @@ } else sp++; } - *p++ = 0x70; - *p++ = strlen(teln) + 1; - /* Classify as AnyPref. */ - *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */ - while (*teln) - *p++ = *teln++ & 0x7f; - - if (sub) { - *sub++ = '.'; - *p++ = 0x71; /* Called party subaddress */ - *p++ = strlen(sub) + 2; - *p++ = 0x80; /* NSAP coded */ - *p++ = 0x50; /* local IDI format */ - while (*sub) - *p++ = *sub++ & 0x7f; - } + + if (!send_keypad) { + *p++ = 0x70; + *p++ = strlen(teln) + 1; + /* Classify as AnyPref. */ + *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */ + while (*teln) + *p++ = *teln++ & 0x7f; + + if (sub) { + *sub++ = '.'; + *p++ = 0x71; /* Called party subaddress */ + *p++ = strlen(sub) + 2; + *p++ = 0x80; /* NSAP coded */ + *p++ = 0x50; /* local IDI format */ + while (*sub) + *p++ = *sub++ & 0x7f; + } + } #if EXT_BEARER_CAPS - if ((pc->para.setup.si2 >= 160) && (pc->para.setup.si2 <= 175)) { // sync. Bitratenadaption, V.110/X.30 + if (send_keypad) { /* special handling independant of si2 */ + *p++ = 0x7c; + *p++ = 0x03; + *p++ = 0x80; + *p++ = 0x90; + *p++ = 0xa3; + } else if ((pc->para.setup.si2 >= 160) && (pc->para.setup.si2 <= 175)) { // sync. Bitratenadaption, V.110/X.30 *p++ = 0x7c; *p++ = 0x04; @@ -767,74 +1473,136 @@ static void l3dss1_call_proc(struct l3_process *pc, u_char pr, void *arg) { - u_char *p; struct sk_buff *skb = arg; + int id, ret; + if ((id = l3dss1_get_channel_id(pc, skb)) >= 0) { + if ((0 == id) || ((3 == id) && (0x10 == pc->para.moderate))) { + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "setup answer with wrong chid %x", id); + pc->para.cause = 100; + l3dss1_status_send(pc, pr, NULL); + return; + } + pc->para.bchannel = id; + } else if (1 == pc->state) { + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "setup answer wrong chid (ret %d)", id); + if (id == -1) + pc->para.cause = 96; + else + pc->para.cause = 100; + l3dss1_status_send(pc, pr, NULL); + return; + } + /* Now we are on none mandatory IEs */ + ret = check_infoelements(pc, skb, ie_CALL_PROCEEDING); + if (ERR_IE_COMPREHENSION == ret) { + l3dss1_std_ie_err(pc, ret); + return; + } L3DelTimer(&pc->timer); - p = skb->data; - if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) { - pc->para.bchannel = p[2] & 0x3; - if ((!pc->para.bchannel) && (pc->debug & L3_DEB_WARN)) - l3_debug(pc->st, "setup answer without bchannel"); - } else if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup answer without bchannel"); - dev_kfree_skb(skb); newl3state(pc, 3); L3AddTimer(&pc->timer, T310, CC_T310); + if (ret) /* STATUS for none mandatory IE errors after actions are taken */ + l3dss1_std_ie_err(pc, ret); pc->st->l3.l3l4(pc->st, CC_PROCEEDING | INDICATION, pc); } static void l3dss1_setup_ack(struct l3_process *pc, u_char pr, void *arg) { - u_char *p; struct sk_buff *skb = arg; + int id, ret; + if ((id = l3dss1_get_channel_id(pc, skb)) >= 0) { + if ((0 == id) || ((3 == id) && (0x10 == pc->para.moderate))) { + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "setup answer with wrong chid %x", id); + pc->para.cause = 100; + l3dss1_status_send(pc, pr, NULL); + return; + } + pc->para.bchannel = id; + } else { + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "setup answer wrong chid (ret %d)", id); + if (id == -1) + pc->para.cause = 96; + else + pc->para.cause = 100; + l3dss1_status_send(pc, pr, NULL); + return; + } + /* Now we are on none mandatory IEs */ + ret = check_infoelements(pc, skb, ie_SETUP_ACKNOWLEDGE); + if (ERR_IE_COMPREHENSION == ret) { + l3dss1_std_ie_err(pc, ret); + return; + } L3DelTimer(&pc->timer); - p = skb->data; - if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) { - pc->para.bchannel = p[2] & 0x3; - if ((!pc->para.bchannel) && (pc->debug & L3_DEB_WARN)) - l3_debug(pc->st, "setup answer without bchannel"); - } else if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup answer without bchannel"); - dev_kfree_skb(skb); newl3state(pc, 2); L3AddTimer(&pc->timer, T304, CC_T304); + if (ret) /* STATUS for none mandatory IE errors after actions are taken */ + l3dss1_std_ie_err(pc, ret); pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc); } static void l3dss1_disconnect(struct l3_process *pc, u_char pr, void *arg) { - u_char *p; struct sk_buff *skb = arg; - int cause = -1; + u_char *p; + int ret; + u_char cause = 0; StopAllL3Timer(pc); - p = skb->data; - pc->para.loc = 0; - if ((p = findie(p, skb->len, IE_CAUSE, 0))) { - p++; - if (*p++ == 2) - pc->para.loc = *p++; - cause = *p & 0x7f; - } - dev_kfree_skb(skb); + if ((ret = l3dss1_get_cause(pc, skb))) { + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "DISC get_cause ret(%d)", ret); + if (ret < 0) + cause = 96; + else if (ret > 0) + cause = 100; + } + if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) + l3dss1_parse_facility(pc->st, pc, pc->callref, p); + ret = check_infoelements(pc, skb, ie_DISCONNECT); + if (ERR_IE_COMPREHENSION == ret) + cause = 96; + else if ((!cause) && (ERR_IE_UNRECOGNIZED == ret)) + cause = 99; + ret = pc->state; newl3state(pc, 12); - pc->para.cause = cause; - pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc); + if (cause) + newl3state(pc, 19); + if (11 != ret) + pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc); + else if (!cause) + l3dss1_release_req(pc, pr, NULL); + if (cause) { + l3dss1_message_cause(pc, MT_RELEASE, cause); + L3AddTimer(&pc->timer, T308, CC_T308_1); + } } static void l3dss1_connect(struct l3_process *pc, u_char pr, void *arg) { struct sk_buff *skb = arg; + int ret; - dev_kfree_skb(skb); + ret = check_infoelements(pc, skb, ie_CONNECT); + if (ERR_IE_COMPREHENSION == ret) { + l3dss1_std_ie_err(pc, ret); + return; + } L3DelTimer(&pc->timer); /* T310 */ newl3state(pc, 10); pc->para.chargeinfo = 0; + /* here should inserted COLP handling KKe */ + if (ret) + l3dss1_std_ie_err(pc, ret); pc->st->l3.l3l4(pc->st, CC_SETUP | CONFIRM, pc); } @@ -842,143 +1610,142 @@ l3dss1_alerting(struct l3_process *pc, u_char pr, void *arg) { struct sk_buff *skb = arg; + int ret; - dev_kfree_skb(skb); + ret = check_infoelements(pc, skb, ie_ALERTING); + if (ERR_IE_COMPREHENSION == ret) { + l3dss1_std_ie_err(pc, ret); + return; + } L3DelTimer(&pc->timer); /* T304 */ newl3state(pc, 4); + if (ret) + l3dss1_std_ie_err(pc, ret); pc->st->l3.l3l4(pc->st, CC_ALERTING | INDICATION, pc); } static void -l3dss1_msg_without_setup(struct l3_process *pc, u_char pr, void *arg) -{ - /* This routine is called if here was no SETUP made (checks in dss1up and in - * l3dss1_setup) and a RELEASE_COMPLETE have to be sent with an error code - * MT_STATUS_ENQUIRE in the NULL state is handled too - */ - u_char tmp[16]; - u_char *p = tmp; - int l; - struct sk_buff *skb; - - switch (pc->para.cause) { - case 81: /* 0x51 invalid callreference */ - case 88: /* 0x58 incomp destination */ - case 96: /* 0x60 mandory IE missing */ - case 101: /* 0x65 incompatible Callstate */ - MsgHead(p, pc->callref, MT_RELEASE_COMPLETE); - *p++ = IE_CAUSE; - *p++ = 0x2; - *p++ = 0x80; - *p++ = pc->para.cause | 0x80; - break; - default: - printk(KERN_ERR "HiSax internal error l3dss1_msg_without_setup\n"); - return; - } - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; - memcpy(skb_put(skb, l), tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); - release_l3_process(pc); -} - -static void l3dss1_setup(struct l3_process *pc, u_char pr, void *arg) { - u_char *p, *ptmp[8]; - int i; + u_char *p; int bcfound = 0; char tmp[80]; struct sk_buff *skb = arg; + int id; + int err = 0; - /* ETS 300-104 1.3.4 and 1.3.5 - * we need to detect unknown inform. element from 0 to 7 + /* + * Bearer Capabilities */ p = skb->data; - for (i = 0; i < 8; i++) - ptmp[i] = skb->data; - if (findie(ptmp[1], skb->len, 0x01, 0) - || findie(ptmp[2], skb->len, 0x02, 0) - || findie(ptmp[3], skb->len, 0x03, 0) - || findie(ptmp[5], skb->len, 0x05, 0) - || findie(ptmp[6], skb->len, 0x06, 0) - || findie(ptmp[7], skb->len, 0x07, 0)) { - /* if ie is < 8 and not 0 nor 4, send RELEASE_COMPLETE - * cause 0x60 - */ - pc->para.cause = 0x60; - dev_kfree_skb(skb); + /* only the first occurence 'll be detected ! */ + if ((p = findie(p, skb->len, 0x04, 0))) { + if ((p[1] < 2) || (p[1] > 11)) + err = 1; + else { + pc->para.setup.si2 = 0; + switch (p[2] & 0x7f) { + case 0x00: /* Speech */ + case 0x10: /* 3.1 Khz audio */ + pc->para.setup.si1 = 1; + break; + case 0x08: /* Unrestricted digital information */ + pc->para.setup.si1 = 7; +/* JIM, 05.11.97 I wanna set service indicator 2 */ +#if EXT_BEARER_CAPS + pc->para.setup.si2 = DecodeSI2(skb); +#endif + break; + case 0x09: /* Restricted digital information */ + pc->para.setup.si1 = 2; + break; + case 0x11: + /* Unrestr. digital information with + * tones/announcements ( or 7 kHz audio + */ + pc->para.setup.si1 = 3; + break; + case 0x18: /* Video */ + pc->para.setup.si1 = 4; + break; + default: + err = 2; + break; + } + switch (p[3] & 0x7f) { + case 0x40: /* packed mode */ + pc->para.setup.si1 = 8; + break; + case 0x10: /* 64 kbit */ + case 0x11: /* 2*64 kbit */ + case 0x13: /* 384 kbit */ + case 0x15: /* 1536 kbit */ + case 0x17: /* 1920 kbit */ + pc->para.moderate = p[3] & 0x7f; + break; + default: + err = 3; + break; + } + } + if (pc->debug & L3_DEB_SI) + l3_debug(pc->st, "SI=%d, AI=%d", + pc->para.setup.si1, pc->para.setup.si2); + if (err) { + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "setup with wrong bearer(l=%d:%x,%x)", + p[1], p[2], p[3]); + pc->para.cause = 100; + l3dss1_msg_without_setup(pc, pr, NULL); + return; + } + } else { + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "setup without bearer capabilities"); + /* ETS 300-104 1.3.3 */ + pc->para.cause = 96; l3dss1_msg_without_setup(pc, pr, NULL); return; } /* * Channel Identification */ - p = skb->data; - if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) { - pc->para.bchannel = p[2] & 0x3; - if (pc->para.bchannel) + if ((id = l3dss1_get_channel_id(pc, skb)) >= 0) { + if ((pc->para.bchannel = id)) { + if ((3 == id) && (0x10 == pc->para.moderate)) { + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "setup with wrong chid %x", + id); + pc->para.cause = 100; + l3dss1_msg_without_setup(pc, pr, NULL); + return; + } bcfound++; - else if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup without bchannel"); + } else + { if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "setup without bchannel, call waiting"); + bcfound++; + } } else { if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup without bchannel"); - pc->para.cause = 0x60; - dev_kfree_skb(skb); + l3_debug(pc->st, "setup with wrong chid ret %d", id); + if (id == -1) + pc->para.cause = 96; + else + pc->para.cause = 100; l3dss1_msg_without_setup(pc, pr, NULL); return; } - /* - * Bearer Capabilities - */ - p = skb->data; - if ((p = findie(p, skb->len, 0x04, 0))) { - pc->para.setup.si2 = 0; - switch (p[2] & 0x1f) { - case 0x00: - /* Speech */ - case 0x10: - /* 3.1 Khz audio */ - pc->para.setup.si1 = 1; - break; - case 0x08: - /* Unrestricted digital information */ - pc->para.setup.si1 = 7; -/* JIM, 05.11.97 I wanna set service indicator 2 */ -#if EXT_BEARER_CAPS - pc->para.setup.si2 = DecodeSI2(skb); - printk(KERN_DEBUG "HiSax: SI=%d, AI=%d\n", - pc->para.setup.si1, pc->para.setup.si2); -#endif - break; - case 0x09: - /* Restricted digital information */ - pc->para.setup.si1 = 2; - break; - case 0x11: - /* Unrestr. digital information with tones/announcements */ - pc->para.setup.si1 = 3; - break; - case 0x18: - /* Video */ - pc->para.setup.si1 = 4; - break; - default: - pc->para.setup.si1 = 0; - } - } else { - if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "setup without bearer capabilities"); - /* ETS 300-104 1.3.3 */ - pc->para.cause = 0x60; - dev_kfree_skb(skb); + /* Now we are on none mandatory IEs */ +#if 1 +/* !!!!!! this check seems to be a problem ? info bugfix to Karsten */ + err = check_infoelements(pc, skb, ie_SETUP); + if (ERR_IE_COMPREHENSION == err) { + pc->para.cause = 96; l3dss1_msg_without_setup(pc, pr, NULL); return; } - +#endif p = skb->data; if ((p = findie(p, skb->len, 0x70, 0))) iecpy(pc->para.setup.eazmsn, p, 1); @@ -1020,8 +1787,8 @@ } else if (pc->debug & L3_DEB_WARN) l3_debug(pc->st, "wrong calling subaddress"); } - dev_kfree_skb(skb); +#if 0 if (bcfound) { if ((pc->para.setup.si1 != 7) && (pc->debug & L3_DEB_WARN)) { l3_debug(pc->st, "non-digital call: %s -> %s", @@ -1029,53 +1796,38 @@ } if ((pc->para.setup.si1 != 7) && test_bit(FLG_PTP, &pc->st->l2.flag)) { - pc->para.cause = 0x58; + pc->para.cause = 88; /* incompatible destination */ l3dss1_msg_without_setup(pc, pr, NULL); return; } newl3state(pc, 6); pc->st->l3.l3l4(pc->st, CC_SETUP | INDICATION, pc); } else - release_l3_process(pc); -} - -static void -l3dss1_reset(struct l3_process *pc, u_char pr, void *arg) -{ - release_l3_process(pc); -} - -static void -l3dss1_setup_rsp(struct l3_process *pc, u_char pr, - void *arg) -{ - newl3state(pc, 8); - l3dss1_message(pc, MT_CONNECT); - L3DelTimer(&pc->timer); - L3AddTimer(&pc->timer, T313, CC_T313); + dss1_release_l3_process(pc); +#else + newl3state(pc, 6); + if (err) /* STATUS for none mandatory IE errors after actions are taken */ + l3dss1_std_ie_err(pc, err); + pc->st->l3.l3l4(pc->st, CC_SETUP | INDICATION, pc); +#endif } static void -l3dss1_connect_ack(struct l3_process *pc, u_char pr, void *arg) +l3dss1_reset(struct l3_process *pc, u_char pr, void *arg) { - struct sk_buff *skb = arg; - - dev_kfree_skb(skb); - newl3state(pc, 10); - L3DelTimer(&pc->timer); - pc->st->l3.l3l4(pc->st, CC_SETUP_COMPL | INDICATION, pc); + dss1_release_l3_process(pc); } static void l3dss1_disconnect_req(struct l3_process *pc, u_char pr, void *arg) { struct sk_buff *skb; - u_char tmp[16]; + u_char tmp[16+40]; u_char *p = tmp; int l; - u_char cause = 0x10; + u_char cause = 16; - if (pc->para.cause > 0) + if (pc->para.cause != NO_CAUSE) cause = pc->para.cause; StopAllL3Timer(pc); @@ -1087,6 +1839,15 @@ *p++ = 0x80; *p++ = cause | 0x80; + if (pc->prot.dss1.uus1_data[0]) + { *p++ = IE_USER_USER; /* UUS info element */ + *p++ = strlen(pc->prot.dss1.uus1_data) + 1; + *p++ = 0x04; /* IA5 chars */ + strcpy(p,pc->prot.dss1.uus1_data); + p += strlen(pc->prot.dss1.uus1_data); + pc->prot.dss1.uus1_data[0] = '\0'; + } + l = p - tmp; if (!(skb = l3_alloc_skb(l))) return; @@ -1097,15 +1858,49 @@ } static void +l3dss1_setup_rsp(struct l3_process *pc, u_char pr, + void *arg) +{ + if (!pc->para.bchannel) + { if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "D-chan connect for waiting call"); + l3dss1_disconnect_req(pc, pr, arg); + return; + } + newl3state(pc, 8); + l3dss1_message(pc, MT_CONNECT); + L3DelTimer(&pc->timer); + L3AddTimer(&pc->timer, T313, CC_T313); +} + +static void +l3dss1_connect_ack(struct l3_process *pc, u_char pr, void *arg) +{ + struct sk_buff *skb = arg; + int ret; + + ret = check_infoelements(pc, skb, ie_CONNECT_ACKNOWLEDGE); + if (ERR_IE_COMPREHENSION == ret) { + l3dss1_std_ie_err(pc, ret); + return; + } + newl3state(pc, 10); + L3DelTimer(&pc->timer); + if (ret) + l3dss1_std_ie_err(pc, ret); + pc->st->l3.l3l4(pc->st, CC_SETUP_COMPL | INDICATION, pc); +} + +static void l3dss1_reject_req(struct l3_process *pc, u_char pr, void *arg) { struct sk_buff *skb; u_char tmp[16]; u_char *p = tmp; int l; - u_char cause = 0x95; + u_char cause = 21; - if (pc->para.cause > 0) + if (pc->para.cause != NO_CAUSE) cause = pc->para.cause; MsgHead(p, pc->callref, MT_RELEASE_COMPLETE); @@ -1113,7 +1908,7 @@ *p++ = IE_CAUSE; *p++ = 0x2; *p++ = 0x80; - *p++ = cause; + *p++ = cause | 0x80; l = p - tmp; if (!(skb = l3_alloc_skb(l))) @@ -1122,38 +1917,41 @@ l3_msg(pc->st, DL_DATA | REQUEST, skb); pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); newl3state(pc, 0); - release_l3_process(pc); + dss1_release_l3_process(pc); } static void l3dss1_release(struct l3_process *pc, u_char pr, void *arg) { - u_char *p; struct sk_buff *skb = arg; - int cause = -1; + u_char *p; + int ret, cause=0; - p = skb->data; - if ((p = findie(p, skb->len, IE_CAUSE, 0))) { - p++; - if (*p++ == 2) - pc->para.loc = *p++; - cause = *p & 0x7f; - } - p = skb->data; - if ((p = findie(p, skb->len, IE_FACILITY, 0))) { -#if HISAX_DE_AOC - l3dss1_parse_facility(pc, p); -#else - p = NULL; -#endif - } - dev_kfree_skb(skb); StopAllL3Timer(pc); - pc->para.cause = cause; - l3dss1_message(pc, MT_RELEASE_COMPLETE); + if ((ret = l3dss1_get_cause(pc, skb))>0) { + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "REL get_cause ret(%d)", ret); + } else if (ret<0) + pc->para.cause = NO_CAUSE; + if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) { + l3dss1_parse_facility(pc->st, pc, pc->callref, p); + } + if ((ret<0) && (pc->state != 11)) + cause = 96; + else if (ret>0) + cause = 100; + ret = check_infoelements(pc, skb, ie_RELEASE); + if (ERR_IE_COMPREHENSION == ret) + cause = 96; + else if ((ERR_IE_UNRECOGNIZED == ret) && (!cause)) + cause = 99; + if (cause) + l3dss1_message_cause(pc, MT_RELEASE_COMPLETE, cause); + else + l3dss1_message(pc, MT_RELEASE_COMPLETE); pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); newl3state(pc, 0); - release_l3_process(pc); + dss1_release_l3_process(pc); } static void @@ -1161,66 +1959,360 @@ void *arg) { newl3state(pc, 7); - l3dss1_message(pc, MT_ALERTING); + if (!pc->prot.dss1.uus1_data[0]) + l3dss1_message(pc, MT_ALERTING); + else + l3dss1_msg_with_uus(pc, MT_ALERTING); } static void -l3dss1_status_enq(struct l3_process *pc, u_char pr, void *arg) +l3dss1_proceed_req(struct l3_process *pc, u_char pr, + void *arg) { - u_char tmp[16]; - u_char *p = tmp; - int l; - struct sk_buff *skb = arg; + newl3state(pc, 9); + l3dss1_message(pc, MT_CALL_PROCEEDING); + pc->st->l3.l3l4(pc->st, CC_PROCEED_SEND | INDICATION, pc); +} - dev_kfree_skb(skb); +/********************************************/ +/* deliver a incoming display message to HL */ +/********************************************/ +static void +l3dss1_deliver_display(struct l3_process *pc, int pr, u_char *infp) +{ u_char len; + isdn_ctrl ic; + struct IsdnCardState *cs; + char *p; - MsgHead(p, pc->callref, MT_STATUS); + if (*infp++ != IE_DISPLAY) return; + if ((len = *infp++) > 80) return; /* total length <= 82 */ + if (!pc->chan) return; - *p++ = IE_CAUSE; - *p++ = 0x2; - *p++ = 0x80; - *p++ = 0x9E; /* answer status enquire */ + p = ic.parm.display; + while (len--) + *p++ = *infp++; + *p = '\0'; + ic.command = ISDN_STAT_DISPLAY; + cs = pc->st->l1.hardware; + ic.driver = cs->myid; + ic.arg = pc->chan->chan; + cs->iif.statcallb(&ic); +} /* l3dss1_deliver_display */ - *p++ = 0x14; /* CallState */ - *p++ = 0x1; - *p++ = pc->state & 0x3f; - l = p - tmp; - if (!(skb = l3_alloc_skb(l))) +static void +l3dss1_progress(struct l3_process *pc, u_char pr, void *arg) +{ + struct sk_buff *skb = arg; + int err = 0; + u_char *p; + + if ((p = findie(skb->data, skb->len, IE_PROGRESS, 0))) { + if (p[1] != 2) { + err = 1; + pc->para.cause = 100; + } else if (p[2] & 0x60) { + switch (p[2]) { + case 0x80: + case 0x81: + case 0x82: + case 0x84: + case 0x85: + case 0x87: + case 0x8a: + switch (p[3]) { + case 0x81: + case 0x82: + case 0x83: + case 0x84: + case 0x88: + break; + default: + err = 2; + pc->para.cause = 100; + break; + } + break; + default: + err = 3; + pc->para.cause = 100; + break; + } + } + } else { + pc->para.cause = 96; + err = 4; + } + if (err) { + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "progress error %d", err); + l3dss1_status_send(pc, pr, NULL); return; - memcpy(skb_put(skb, l), tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); + } + /* Now we are on none mandatory IEs */ + err = check_infoelements(pc, skb, ie_PROGRESS); + if (err) + l3dss1_std_ie_err(pc, err); + if (ERR_IE_COMPREHENSION != err) + pc->st->l3.l3l4(pc->st, CC_PROGRESS | INDICATION, pc); } static void -l3dss1_status_req(struct l3_process *pc, u_char pr, void *arg) +l3dss1_notify(struct l3_process *pc, u_char pr, void *arg) { - /* ETS 300-104 7.4.1, 8.4.1, 10.3.1, 11.4.1, 12.4.1, 13.4.1, 14.4.1... - if setup has been made and a non expected message type is received, we must send MT_STATUS cause 0x62 */ - u_char tmp[16]; - u_char *p = tmp; - int l; + struct sk_buff *skb = arg; + int err = 0; + u_char *p; + + if ((p = findie(skb->data, skb->len, IE_NOTIFY, 0))) { + if (p[1] != 1) { + err = 1; + pc->para.cause = 100; + } else { + switch (p[2]) { + case 0x80: + case 0x81: + case 0x82: + break; + default: + pc->para.cause = 100; + err = 2; + break; + } + } + } else { + pc->para.cause = 96; + err = 3; + } + if (err) { + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "notify error %d", err); + l3dss1_status_send(pc, pr, NULL); + return; + } + /* Now we are on none mandatory IEs */ + err = check_infoelements(pc, skb, ie_NOTIFY); + if (err) + l3dss1_std_ie_err(pc, err); + if (ERR_IE_COMPREHENSION != err) + pc->st->l3.l3l4(pc->st, CC_NOTIFY | INDICATION, pc); +} + +static void +l3dss1_status_enq(struct l3_process *pc, u_char pr, void *arg) +{ + int ret; struct sk_buff *skb = arg; - dev_kfree_skb(skb); + ret = check_infoelements(pc, skb, ie_STATUS_ENQUIRY); + l3dss1_std_ie_err(pc, ret); +// KKe 19.7.99 test eicon +// idev_kfree_skb(skb, FREE_READ); + pc->para.cause = 30; /* response to STATUS_ENQUIRY */ + l3dss1_status_send(pc, pr, NULL); +} - MsgHead(p, pc->callref, MT_STATUS); +static void +l3dss1_information(struct l3_process *pc, u_char pr, void *arg) +{ + int ret; + struct sk_buff *skb = arg; - *p++ = IE_CAUSE; - *p++ = 0x2; - *p++ = 0x80; - *p++ = 0x62 | 0x80; /* status sending */ + ret = check_infoelements(pc, skb, ie_INFORMATION); + l3dss1_std_ie_err(pc, ret); +} - *p++ = 0x14; /* CallState */ - *p++ = 0x1; - *p++ = pc->state & 0x3f; +/******************************/ +/* handle deflection requests */ +/******************************/ +static void l3dss1_redir_req(struct l3_process *pc, u_char pr, void *arg) +{ + struct sk_buff *skb; + u_char tmp[128]; + u_char *p = tmp; + u_char *subp; + u_char len_phone = 0; + u_char len_sub = 0; + int l; + + + strcpy(pc->prot.dss1.uus1_data,pc->chan->setup.eazmsn); /* copy uus element if available */ + if (!pc->chan->setup.phone[0]) + { pc->para.cause = -1; + l3dss1_disconnect_req(pc,pr,arg); /* disconnect immediately */ + return; + } /* only uus */ + + if (pc->prot.dss1.invoke_id) + free_invoke_id(pc->st,pc->prot.dss1.invoke_id); + + if (!(pc->prot.dss1.invoke_id = new_invoke_id(pc->st))) + return; + + MsgHead(p, pc->callref, MT_FACILITY); + + for (subp = pc->chan->setup.phone; (*subp) && (*subp != '.'); subp++) len_phone++; /* len of phone number */ + if (*subp++ == '.') len_sub = strlen(subp) + 2; /* length including info subadress element */ + + *p++ = 0x1c; /* Facility info element */ + *p++ = len_phone + len_sub + 2 + 2 + 8 + 3 + 3; /* length of element */ + *p++ = 0x91; /* remote operations protocol */ + *p++ = 0xa1; /* invoke component */ + + *p++ = len_phone + len_sub + 2 + 2 + 8 + 3; /* length of data */ + *p++ = 0x02; /* invoke id tag, integer */ + *p++ = 0x01; /* length */ + *p++ = pc->prot.dss1.invoke_id; /* invoke id */ + *p++ = 0x02; /* operation value tag, integer */ + *p++ = 0x01; /* length */ + *p++ = 0x0D; /* Call Deflect */ + + *p++ = 0x30; /* sequence phone number */ + *p++ = len_phone + 2 + 2 + 3 + len_sub; /* length */ + + *p++ = 0x30; /* Deflected to UserNumber */ + *p++ = len_phone+2+len_sub; /* length */ + *p++ = 0x80; /* NumberDigits */ + *p++ = len_phone; /* length */ + for (l = 0; l < len_phone; l++) + *p++ = pc->chan->setup.phone[l]; + + if (len_sub) + { *p++ = 0x04; /* called party subadress */ + *p++ = len_sub - 2; + while (*subp) *p++ = *subp++; + } + + *p++ = 0x01; /* screening identifier */ + *p++ = 0x01; + *p++ = pc->chan->setup.screen; l = p - tmp; - if (!(skb = l3_alloc_skb(l))) - return; + if (!(skb = l3_alloc_skb(l))) return; memcpy(skb_put(skb, l), tmp, l); - l3_msg(pc->st, DL_DATA | REQUEST, skb); -} + + l3_msg(pc->st, DL_DATA | REQUEST, skb); +} /* l3dss1_redir_req */ + +/********************************************/ +/* handle deflection request in early state */ +/********************************************/ +static void l3dss1_redir_req_early(struct l3_process *pc, u_char pr, void *arg) +{ + l3dss1_proceed_req(pc,pr,arg); + l3dss1_redir_req(pc,pr,arg); +} /* l3dss1_redir_req_early */ + +/***********************************************/ +/* handle special commands for this protocol. */ +/* Examples are call independant services like */ +/* remote operations with dummy callref. */ +/***********************************************/ +static int l3dss1_cmd_global(struct PStack *st, isdn_ctrl *ic) +{ u_char id; + u_char temp[265]; + u_char *p = temp; + int i, l, proc_len; + struct sk_buff *skb; + struct l3_process *pc = NULL; + + switch (ic->arg) + { case DSS1_CMD_INVOKE: + if (ic->parm.dss1_io.datalen < 0) return(-2); /* invalid parameter */ + + for (proc_len = 1, i = ic->parm.dss1_io.proc >> 8; i; i++) + i = i >> 8; /* add one byte */ + l = ic->parm.dss1_io.datalen + proc_len + 8; /* length excluding ie header */ + if (l > 255) + return(-2); /* too long */ + + if (!(id = new_invoke_id(st))) + return(0); /* first get a invoke id -> return if no available */ + + i = -1; + MsgHead(p, i, MT_FACILITY); /* build message head */ + *p++ = 0x1C; /* Facility IE */ + *p++ = l; /* length of ie */ + *p++ = 0x91; /* remote operations */ + *p++ = 0xA1; /* invoke */ + *p++ = l - 3; /* length of invoke */ + *p++ = 0x02; /* invoke id tag */ + *p++ = 0x01; /* length is 1 */ + *p++ = id; /* invoke id */ + *p++ = 0x02; /* operation */ + *p++ = proc_len; /* length of operation */ + + for (i = proc_len; i; i--) + *p++ = (ic->parm.dss1_io.proc >> (i-1)) & 0xFF; + memcpy(p, ic->parm.dss1_io.data, ic->parm.dss1_io.datalen); /* copy data */ + l = (p - temp) + ic->parm.dss1_io.datalen; /* total length */ + + if (ic->parm.dss1_io.timeout > 0) + if (!(pc = dss1_new_l3_process(st, -1))) + { free_invoke_id(st, id); + return(-2); + } + pc->prot.dss1.ll_id = ic->parm.dss1_io.ll_id; /* remember id */ + pc->prot.dss1.proc = ic->parm.dss1_io.proc; /* and procedure */ + + if (!(skb = l3_alloc_skb(l))) + { free_invoke_id(st, id); + if (pc) dss1_release_l3_process(pc); + return(-2); + } + memcpy(skb_put(skb, l), temp, l); + + if (pc) + { pc->prot.dss1.invoke_id = id; /* remember id */ + L3AddTimer(&pc->timer, ic->parm.dss1_io.timeout, CC_TDSS1_IO | REQUEST); + } + + l3_msg(st, DL_DATA | REQUEST, skb); + ic->parm.dss1_io.hl_id = id; /* return id */ + return(0); + + case DSS1_CMD_INVOKE_ABORT: + if ((pc = l3dss1_search_dummy_proc(st, ic->parm.dss1_io.hl_id))) + { L3DelTimer(&pc->timer); /* remove timer */ + dss1_release_l3_process(pc); + return(0); + } + else + { l3_debug(st, "l3dss1_cmd_global abort unknown id"); + return(-2); + } + break; + + default: + l3_debug(st, "l3dss1_cmd_global unknown cmd 0x%lx", ic->arg); + return(-1); + } /* switch ic-> arg */ + return(-1); +} /* l3dss1_cmd_global */ + +static void +l3dss1_io_timer(struct l3_process *pc) +{ isdn_ctrl ic; + struct IsdnCardState *cs = pc->st->l1.hardware; + + L3DelTimer(&pc->timer); /* remove timer */ + + ic.driver = cs->myid; + ic.command = ISDN_STAT_PROT; + ic.arg = DSS1_STAT_INVOKE_ERR; + ic.parm.dss1_io.hl_id = pc->prot.dss1.invoke_id; + ic.parm.dss1_io.ll_id = pc->prot.dss1.ll_id; + ic.parm.dss1_io.proc = pc->prot.dss1.proc; + ic.parm.dss1_io.timeout= -1; + ic.parm.dss1_io.datalen = 0; + ic.parm.dss1_io.data = NULL; + free_invoke_id(pc->st, pc->prot.dss1.invoke_id); + pc->prot.dss1.invoke_id = 0; /* reset id */ + + cs->iif.statcallb(&ic); + + dss1_release_l3_process(pc); +} /* l3dss1_io_timer */ static void l3dss1_release_ind(struct l3_process *pc, u_char pr, void *arg) @@ -1241,13 +2333,18 @@ */ pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); newl3state(pc, 0); - release_l3_process(pc); + dss1_release_l3_process(pc); } else { pc->st->l3.l3l4(pc->st, CC_IGNORE | INDICATION, pc); } } static void +l3dss1_dummy(struct l3_process *pc, u_char pr, void *arg) +{ +} + +static void l3dss1_t303(struct l3_process *pc, u_char pr, void *arg) { if (pc->N303 > 0) { @@ -1256,8 +2353,9 @@ l3dss1_setup_req(pc, pr, arg); } else { L3DelTimer(&pc->timer); + l3dss1_message_cause(pc, MT_RELEASE_COMPLETE, 102); pc->st->l3.l3l4(pc->st, CC_NOSETUP_RSP, pc); - release_l3_process(pc); + dss1_release_l3_process(pc); } } @@ -1265,7 +2363,7 @@ l3dss1_t304(struct l3_process *pc, u_char pr, void *arg) { L3DelTimer(&pc->timer); - pc->para.cause = 0xE6; + pc->para.cause = 102; l3dss1_disconnect_req(pc, pr, NULL); pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc); @@ -1278,18 +2376,18 @@ u_char *p = tmp; int l; struct sk_buff *skb; - u_char cause = 0x90; + u_char cause = 16; L3DelTimer(&pc->timer); - if (pc->para.cause > 0) - cause = pc->para.cause | 0x80; + if (pc->para.cause != NO_CAUSE) + cause = pc->para.cause; MsgHead(p, pc->callref, MT_RELEASE); *p++ = IE_CAUSE; *p++ = 0x2; *p++ = 0x80; - *p++ = cause; + *p++ = cause | 0x80; l = p - tmp; if (!(skb = l3_alloc_skb(l))) @@ -1304,7 +2402,7 @@ l3dss1_t310(struct l3_process *pc, u_char pr, void *arg) { L3DelTimer(&pc->timer); - pc->para.cause = 0xE6; + pc->para.cause = 102; l3dss1_disconnect_req(pc, pr, NULL); pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc); } @@ -1313,7 +2411,7 @@ l3dss1_t313(struct l3_process *pc, u_char pr, void *arg) { L3DelTimer(&pc->timer); - pc->para.cause = 0xE6; + pc->para.cause = 102; l3dss1_disconnect_req(pc, pr, NULL); pc->st->l3.l3l4(pc->st, CC_CONNECT_ERR, pc); } @@ -1332,14 +2430,14 @@ { L3DelTimer(&pc->timer); pc->st->l3.l3l4(pc->st, CC_RELEASE_ERR, pc); - release_l3_process(pc); + dss1_release_l3_process(pc); } static void l3dss1_t318(struct l3_process *pc, u_char pr, void *arg) { L3DelTimer(&pc->timer); - pc->para.cause = 0x66; /* Timer expiry */ + pc->para.cause = 102; /* Timer expiry */ pc->para.loc = 0; /* local */ pc->st->l3.l3l4(pc->st, CC_RESUME_ERR, pc); newl3state(pc, 19); @@ -1351,7 +2449,7 @@ l3dss1_t319(struct l3_process *pc, u_char pr, void *arg) { L3DelTimer(&pc->timer); - pc->para.cause = 0x66; /* Timer expiry */ + pc->para.cause = 102; /* Timer expiry */ pc->para.loc = 0; /* local */ pc->st->l3.l3l4(pc->st, CC_SUSPEND_ERR, pc); newl3state(pc, 10); @@ -1361,69 +2459,80 @@ l3dss1_restart(struct l3_process *pc, u_char pr, void *arg) { L3DelTimer(&pc->timer); - pc->st->l3.l3l4(pc->st, CC_DLRL | INDICATION, pc); - release_l3_process(pc); + pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); + dss1_release_l3_process(pc); } static void l3dss1_status(struct l3_process *pc, u_char pr, void *arg) { u_char *p; - char tmp[64], *t; - int l; struct sk_buff *skb = arg; - int cause, callState; - - cause = callState = -1; - p = skb->data; - t = tmp; - if ((p = findie(p, skb->len, IE_CAUSE, 0))) { - p++; - l = *p++; - t += sprintf(t, "Status CR %x Cause:", pc->callref); - while (l--) { - cause = *p; - t += sprintf(t, " %2x", *p++); - } - } else - sprintf(t, "Status CR %x no Cause", pc->callref); - l3_debug(pc->st, tmp); - p = skb->data; - t = tmp; - t += sprintf(t, "Status state %x ", pc->state); - if ((p = findie(p, skb->len, IE_CALL_STATE, 0))) { + int ret; + u_char cause = 0, callState = 0; + + if ((ret = l3dss1_get_cause(pc, skb))) { + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "STATUS get_cause ret(%d)",ret); + if (ret < 0) + cause = 96; + else if (ret > 0) + cause = 100; + } + if ((p = findie(skb->data, skb->len, IE_CALL_STATE, 0))) { p++; if (1 == *p++) { callState = *p; - t += sprintf(t, "peer state %x", *p); + if (!ie_in_set(pc, *p, l3_valid_states)) + cause = 100; } else - t += sprintf(t, "peer state len error"); + cause = 100; } else - sprintf(t, "no peer state"); - l3_debug(pc->st, tmp); - if (((cause & 0x7f) == 0x6f) && (callState == 0)) { + cause = 96; + if (!cause) { /* no error before */ + ret = check_infoelements(pc, skb, ie_STATUS); + if (ERR_IE_COMPREHENSION == ret) + cause = 96; + else if (ERR_IE_UNRECOGNIZED == ret) + cause = 99; + } + if (cause) { + u_char tmp; + + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "STATUS error(%d/%d)",ret,cause); + tmp = pc->para.cause; + pc->para.cause = cause; + l3dss1_status_send(pc, 0, NULL); + if (cause == 99) + pc->para.cause = tmp; + else + return; + } + cause = pc->para.cause; + if (((cause & 0x7f) == 111) && (callState == 0)) { /* ETS 300-104 7.6.1, 8.6.1, 10.6.1... - * if received MT_STATUS with cause == 0x6f and call + * if received MT_STATUS with cause == 111 and call * state == 0, then we must set down layer 3 */ - l3dss1_release_ind(pc, pr, arg); - } else - dev_kfree_skb(skb); + pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); + newl3state(pc, 0); + dss1_release_l3_process(pc); + } } static void l3dss1_facility(struct l3_process *pc, u_char pr, void *arg) { - u_char *p; struct sk_buff *skb = arg; - - p = skb->data; - if ((p = findie(p, skb->len, IE_FACILITY, 0))) { -#if HISAX_DE_AOC - l3dss1_parse_facility(pc, p); -#else - p = NULL; -#endif + int ret; + + ret = check_infoelements(pc, skb, ie_FACILITY); + l3dss1_std_ie_err(pc, ret); + { + u_char *p; + if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) + l3dss1_parse_facility(pc->st, pc, pc->callref, p); } } @@ -1438,14 +2547,14 @@ MsgHead(p, pc->callref, MT_SUSPEND); - *p++ = IE_CALLID; + *p++ = IE_CALL_ID; l = *msg++; if (l && (l <= 10)) { /* Max length 10 octets */ *p++ = l; for (i = 0; i < l; i++) *p++ = *msg++; } else { - l3_debug(pc->st, "SUS wrong CALLID len %d", l); + l3_debug(pc->st, "SUS wrong CALL_ID len %d", l); return; } l = p - tmp; @@ -1461,34 +2570,45 @@ l3dss1_suspend_ack(struct l3_process *pc, u_char pr, void *arg) { struct sk_buff *skb = arg; + int ret; L3DelTimer(&pc->timer); newl3state(pc, 0); - dev_kfree_skb(skb); - pc->para.cause = -1; + pc->para.cause = NO_CAUSE; pc->st->l3.l3l4(pc->st, CC_SUSPEND | CONFIRM, pc); - release_l3_process(pc); + /* We don't handle suspend_ack for IE errors now */ + if ((ret = check_infoelements(pc, skb, ie_SUSPEND_ACKNOWLEDGE))) + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "SUSPACK check ie(%d)",ret); + dss1_release_l3_process(pc); } static void l3dss1_suspend_rej(struct l3_process *pc, u_char pr, void *arg) { - u_char *p; struct sk_buff *skb = arg; - int cause = -1; + int ret; - L3DelTimer(&pc->timer); - p = skb->data; - if ((p = findie(p, skb->len, IE_CAUSE, 0))) { - p++; - if (*p++ == 2) - pc->para.loc = *p++; - cause = *p & 0x7f; + if ((ret = l3dss1_get_cause(pc, skb))) { + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "SUSP_REJ get_cause ret(%d)",ret); + if (ret < 0) + pc->para.cause = 96; + else + pc->para.cause = 100; + l3dss1_status_send(pc, pr, NULL); + return; + } + ret = check_infoelements(pc, skb, ie_SUSPEND_REJECT); + if (ERR_IE_COMPREHENSION == ret) { + l3dss1_std_ie_err(pc, ret); + return; } - dev_kfree_skb(skb); - pc->para.cause = cause; + L3DelTimer(&pc->timer); pc->st->l3.l3l4(pc->st, CC_SUSPEND_ERR, pc); newl3state(pc, 10); + if (ret) /* STATUS for none mandatory IE errors after actions are taken */ + l3dss1_std_ie_err(pc, ret); } static void @@ -1502,14 +2622,14 @@ MsgHead(p, pc->callref, MT_RESUME); - *p++ = IE_CALLID; + *p++ = IE_CALL_ID; l = *msg++; if (l && (l <= 10)) { /* Max length 10 octets */ *p++ = l; for (i = 0; i < l; i++) *p++ = *msg++; } else { - l3_debug(pc->st, "RES wrong CALLID len %d", l); + l3_debug(pc->st, "RES wrong CALL_ID len %d", l); return; } l = p - tmp; @@ -1518,48 +2638,70 @@ memcpy(skb_put(skb, l), tmp, l); l3_msg(pc->st, DL_DATA | REQUEST, skb); newl3state(pc, 17); - L3AddTimer(&pc->timer, T319, CC_T319); + L3AddTimer(&pc->timer, T318, CC_T318); } static void l3dss1_resume_ack(struct l3_process *pc, u_char pr, void *arg) { - u_char *p; struct sk_buff *skb = arg; + int id, ret; + if ((id = l3dss1_get_channel_id(pc, skb)) > 0) { + if ((0 == id) || ((3 == id) && (0x10 == pc->para.moderate))) { + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "resume ack with wrong chid %x", id); + pc->para.cause = 100; + l3dss1_status_send(pc, pr, NULL); + return; + } + pc->para.bchannel = id; + } else if (1 == pc->state) { + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "resume ack without chid (ret %d)", id); + pc->para.cause = 96; + l3dss1_status_send(pc, pr, NULL); + return; + } + ret = check_infoelements(pc, skb, ie_RESUME_ACKNOWLEDGE); + if (ERR_IE_COMPREHENSION == ret) { + l3dss1_std_ie_err(pc, ret); + return; + } L3DelTimer(&pc->timer); - p = skb->data; - if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) { - pc->para.bchannel = p[2] & 0x3; - if ((!pc->para.bchannel) && (pc->debug & L3_DEB_WARN)) - l3_debug(pc->st, "resume ack without bchannel"); - } else if (pc->debug & L3_DEB_WARN) - l3_debug(pc->st, "resume ack without bchannel"); - dev_kfree_skb(skb); pc->st->l3.l3l4(pc->st, CC_RESUME | CONFIRM, pc); newl3state(pc, 10); + if (ret) /* STATUS for none mandatory IE errors after actions are taken */ + l3dss1_std_ie_err(pc, ret); } static void l3dss1_resume_rej(struct l3_process *pc, u_char pr, void *arg) { - u_char *p; struct sk_buff *skb = arg; - int cause = -1; + int ret; - L3DelTimer(&pc->timer); - p = skb->data; - if ((p = findie(p, skb->len, IE_CAUSE, 0))) { - p++; - if (*p++ == 2) - pc->para.loc = *p++; - cause = *p & 0x7f; + if ((ret = l3dss1_get_cause(pc, skb))) { + if (pc->debug & L3_DEB_WARN) + l3_debug(pc->st, "RES_REJ get_cause ret(%d)",ret); + if (ret < 0) + pc->para.cause = 96; + else + pc->para.cause = 100; + l3dss1_status_send(pc, pr, NULL); + return; } - dev_kfree_skb(skb); - pc->para.cause = cause; - newl3state(pc, 0); + ret = check_infoelements(pc, skb, ie_RESUME_REJECT); + if (ERR_IE_COMPREHENSION == ret) { + l3dss1_std_ie_err(pc, ret); + return; + } + L3DelTimer(&pc->timer); pc->st->l3.l3l4(pc->st, CC_RESUME_ERR, pc); - release_l3_process(pc); + newl3state(pc, 0); + if (ret) /* STATUS for none mandatory IE errors after actions are taken */ + l3dss1_std_ie_err(pc, ret); + dss1_release_l3_process(pc); } static void @@ -1589,7 +2731,6 @@ if (pc->st->l3.debug) l3_debug(pc->st, "Restart for channel %d", chan); } - dev_kfree_skb(skb); newl3state(pc, 2); up = pc->st->l3.proc; while (up) { @@ -1616,6 +2757,41 @@ newl3state(pc, 0); l3_msg(pc->st, DL_DATA | REQUEST, skb); } + +static void +l3dss1_dl_reset(struct l3_process *pc, u_char pr, void *arg) +{ + pc->para.cause = 0x29; /* Temporary failure */ + l3dss1_disconnect_req(pc, pr, NULL); + pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc); +} + +static void +l3dss1_dl_release(struct l3_process *pc, u_char pr, void *arg) +{ + newl3state(pc, 0); + pc->para.cause = 0x1b; /* Destination out of order */ + pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); + release_l3_process(pc); +} + +static void +l3dss1_dl_reestablish(struct l3_process *pc, u_char pr, void *arg) +{ + L3DelTimer(&pc->timer); + L3AddTimer(&pc->timer, T309, CC_T309); + l3_msg(pc->st, DL_ESTABLISH | REQUEST, NULL); +} + +static void +l3dss1_dl_reest_status(struct l3_process *pc, u_char pr, void *arg) +{ + L3DelTimer(&pc->timer); + + pc->para.cause = 0x1F; /* normal, unspecified */ + l3dss1_status_send(pc, 0, NULL); +} + /* *INDENT-OFF* */ static struct stateentry downstatelist[] = { @@ -1623,24 +2799,32 @@ CC_SETUP | REQUEST, l3dss1_setup_req}, {SBIT(0), CC_RESUME | REQUEST, l3dss1_resume_req}, - {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) | SBIT(10), + {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10), CC_DISCONNECT | REQUEST, l3dss1_disconnect_req}, {SBIT(12), CC_RELEASE | REQUEST, l3dss1_release_req}, {ALL_STATES, - CC_DLRL | REQUEST, l3dss1_reset}, - {ALL_STATES, CC_RESTART | REQUEST, l3dss1_restart}, {SBIT(6), CC_IGNORE | REQUEST, l3dss1_reset}, {SBIT(6), CC_REJECT | REQUEST, l3dss1_reject_req}, {SBIT(6), + CC_PROCEED_SEND | REQUEST, l3dss1_proceed_req}, + {SBIT(6) | SBIT(9), CC_ALERTING | REQUEST, l3dss1_alert_req}, - {SBIT(6) | SBIT(7), + {SBIT(6) | SBIT(7) | SBIT(9), CC_SETUP | RESPONSE, l3dss1_setup_rsp}, {SBIT(10), CC_SUSPEND | REQUEST, l3dss1_suspend_req}, + {SBIT(6), + CC_PROCEED_SEND | REQUEST, l3dss1_proceed_req}, + {SBIT(7) | SBIT(9), + CC_REDIR | REQUEST, l3dss1_redir_req}, + {SBIT(6), + CC_REDIR | REQUEST, l3dss1_redir_req_early}, + {SBIT(9) | SBIT(25), + CC_DISCONNECT | REQUEST, l3dss1_disconnect_req}, {SBIT(1), CC_T303, l3dss1_t303}, {SBIT(2), @@ -1659,6 +2843,8 @@ CC_T308_1, l3dss1_t308_1}, {SBIT(19), CC_T308_2, l3dss1_t308_2}, + {SBIT(10), + CC_T309, l3dss1_dl_release}, }; #define DOWNSLLEN \ @@ -1674,37 +2860,37 @@ MT_STATUS, l3dss1_release_ind}, {ALL_STATES, MT_STATUS, l3dss1_status}, - {SBIT(0) | SBIT(6), + {SBIT(0), MT_SETUP, l3dss1_setup}, + {SBIT(6) | SBIT(7), + MT_SETUP, l3dss1_dummy}, {SBIT(1) | SBIT(2), MT_CALL_PROCEEDING, l3dss1_call_proc}, - {SBIT(3) | SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19), - MT_CALL_PROCEEDING, l3dss1_status_req}, {SBIT(1), MT_SETUP_ACKNOWLEDGE, l3dss1_setup_ack}, - {SBIT(2) | SBIT(3) | SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19), - MT_SETUP_ACKNOWLEDGE, l3dss1_status_req}, - {SBIT(1) | SBIT(2) | SBIT(3), + {SBIT(2) | SBIT(3), MT_ALERTING, l3dss1_alerting}, - {SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19), - MT_ALERTING, l3dss1_status_req}, + {SBIT(2) | SBIT(3), + MT_PROGRESS, l3dss1_progress}, + {SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | + SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19) | SBIT(25), + MT_INFORMATION, l3dss1_information}, + {SBIT(10) | SBIT(11) | SBIT(15), + MT_NOTIFY, l3dss1_notify}, {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) | - SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19), + SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19) | SBIT(25), MT_RELEASE_COMPLETE, l3dss1_release_cmpl}, - {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) | - SBIT(11) | SBIT(12) | SBIT(15) /* | SBIT(17) | SBIT(19)*/, + {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(25), MT_RELEASE, l3dss1_release}, {SBIT(19), MT_RELEASE, l3dss1_release_ind}, - {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) | SBIT(15), + {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(11) | SBIT(15) | SBIT(17) | SBIT(25), MT_DISCONNECT, l3dss1_disconnect}, - {SBIT(11), - MT_DISCONNECT, l3dss1_release_req}, +// {SBIT(11), +// MT_DISCONNECT, l3dss1_release_req}, + {SBIT(19), + MT_DISCONNECT, l3dss1_dummy}, {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4), MT_CONNECT, l3dss1_connect}, - {SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19), - MT_CONNECT, l3dss1_status_req}, - {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(11) | SBIT(19), - MT_CONNECT_ACKNOWLEDGE, l3dss1_status_req}, {SBIT(8), MT_CONNECT_ACKNOWLEDGE, l3dss1_connect_ack}, {SBIT(15), @@ -1715,8 +2901,6 @@ MT_RESUME_ACKNOWLEDGE, l3dss1_resume_ack}, {SBIT(17), MT_RESUME_REJECT, l3dss1_resume_rej}, - {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(15) | SBIT(17) | SBIT(19), - MT_INVALID, l3dss1_status_req}, }; #define DATASLLEN \ @@ -1734,26 +2918,56 @@ }; #define GLOBALM_LEN \ (sizeof(globalmes_list) / sizeof(struct stateentry)) + +static struct stateentry manstatelist[] = +{ + {SBIT(2), + DL_ESTABLISH | INDICATION, l3dss1_dl_reset}, + {SBIT(10), + DL_ESTABLISH | CONFIRM, l3dss1_dl_reest_status}, + {SBIT(10), + DL_RELEASE | INDICATION, l3dss1_dl_reestablish}, + {ALL_STATES, + DL_RELEASE | INDICATION, l3dss1_dl_release}, +}; + +#define MANSLLEN \ + (sizeof(manstatelist) / sizeof(struct stateentry)) /* *INDENT-ON* */ static void global_handler(struct PStack *st, int mt, struct sk_buff *skb) { + u_char tmp[16]; + u_char *p = tmp; + int l; int i; struct l3_process *proc = st->l3.global; + proc->callref = skb->data[2]; /* cr flag */ for (i = 0; i < GLOBALM_LEN; i++) if ((mt == globalmes_list[i].primitive) && ((1 << proc->state) & globalmes_list[i].state)) break; if (i == GLOBALM_LEN) { - dev_kfree_skb(skb); if (st->l3.debug & L3_DEB_STATE) { l3_debug(st, "dss1 global state %d mt %x unhandled", proc->state, mt); } - return; + MsgHead(p, proc->callref, MT_STATUS); + *p++ = IE_CAUSE; + *p++ = 0x2; + *p++ = 0x80; + *p++ = 81 |0x80; /* invalid cr */ + *p++ = 0x14; /* CallState */ + *p++ = 0x1; + *p++ = proc->state & 0x3f; + l = p - tmp; + if (!(skb = l3_alloc_skb(l))) + return; + memcpy(skb_put(skb, l), tmp, l); + l3_msg(proc->st, DL_DATA | REQUEST, skb); } else { if (st->l3.debug & L3_DEB_STATE) { l3_debug(st, "dss1 global %d mt %x", @@ -1768,6 +2982,7 @@ { int i, mt, cr, cause, callState; char *ptr; + u_char *p; struct sk_buff *skb = arg; struct l3_process *proc; @@ -1782,23 +2997,57 @@ l3_msg(st, pr, arg); return; break; + default: + printk(KERN_ERR "HiSax dss1up unknown pr=%04x\n", pr); + return; + } + if (skb->len < 3) { + l3_debug(st, "dss1up frame too short(%d)", skb->len); + idev_kfree_skb(skb, FREE_READ); + return; } + if (skb->data[0] != PROTO_DIS_EURO) { if (st->l3.debug & L3_DEB_PROTERR) { l3_debug(st, "dss1up%sunexpected discriminator %x message len %d", (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", skb->data[0], skb->len); } - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); return; } cr = getcallref(skb->data); + if (skb->len < ((skb->data[1] & 0x0f) + 3)) { + l3_debug(st, "dss1up frame too short(%d)", skb->len); + idev_kfree_skb(skb, FREE_READ); + return; + } mt = skb->data[skb->data[1] + 2]; - if (!cr) { /* Global CallRef */ - global_handler(st, mt, skb); + if (st->l3.debug & L3_DEB_STATE) + l3_debug(st, "dss1up cr %d", cr); + if (cr == -2) { /* wrong Callref */ + if (st->l3.debug & L3_DEB_WARN) + l3_debug(st, "dss1up wrong Callref"); + idev_kfree_skb(skb, FREE_READ); return; } else if (cr == -1) { /* Dummy Callref */ - dev_kfree_skb(skb); + if (mt == MT_FACILITY) + if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) { + l3dss1_parse_facility(st, NULL, + (pr == (DL_DATA | INDICATION)) ? -1 : -2, p); + idev_kfree_skb(skb, FREE_READ); + return; + } + if (st->l3.debug & L3_DEB_WARN) + l3_debug(st, "dss1up dummy Callref (no facility msg or ie)"); + idev_kfree_skb(skb, FREE_READ); + return; + } else if ((((skb->data[1] & 0x0f) == 1) && (0==(cr & 0x7f))) || + (((skb->data[1] & 0x0f) == 2) && (0==(cr & 0x7fff)))) { /* Global CallRef */ + if (st->l3.debug & L3_DEB_STATE) + l3_debug(st, "dss1up Global CallRef"); + global_handler(st, mt, skb); + idev_kfree_skb(skb, FREE_READ); return; } else if (!(proc = getl3proc(st, cr))) { /* No transaction process exist, that means no call with @@ -1806,12 +3055,19 @@ */ if (mt == MT_SETUP) { /* Setup creates a new transaction process */ - if (!(proc = new_l3_process(st, cr))) { + if (skb->data[2] & 0x80) { + /* Setup with wrong CREF flag */ + if (st->l3.debug & L3_DEB_STATE) + l3_debug(st, "dss1up wrong CRef flag"); + idev_kfree_skb(skb, FREE_READ); + return; + } + if (!(proc = dss1_new_l3_process(st, cr))) { /* May be to answer with RELEASE_COMPLETE and * CAUSE 0x2f "Resource unavailable", but this * need a new_l3_process too ... arghh */ - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); return; } } else if (mt == MT_STATUS) { @@ -1829,62 +3085,60 @@ ptr++; callState = *ptr; } - if (callState == 0) { - /* ETS 300-104 part 2.4.1 - * if setup has not been made and a message type - * MT_STATUS is received with call state == 0, - * we must send nothing - */ - dev_kfree_skb(skb); - return; - } else { + /* ETS 300-104 part 2.4.1 + * if setup has not been made and a message type + * MT_STATUS is received with call state == 0, + * we must send nothing + */ + if (callState != 0) { /* ETS 300-104 part 2.4.2 * if setup has not been made and a message type * MT_STATUS is received with call state != 0, * we must send MT_RELEASE_COMPLETE cause 101 */ - dev_kfree_skb(skb); - if ((proc = new_l3_process(st, cr))) { - proc->para.cause = 0x65; /* 101 */ + if ((proc = dss1_new_l3_process(st, cr))) { + proc->para.cause = 101; l3dss1_msg_without_setup(proc, 0, NULL); } - return; } + idev_kfree_skb(skb, FREE_READ); + return; } else if (mt == MT_RELEASE_COMPLETE) { - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); return; } else { /* ETS 300-104 part 2 * if setup has not been made and a message type * (except MT_SETUP and RELEASE_COMPLETE) is received, * we must send MT_RELEASE_COMPLETE cause 81 */ - dev_kfree_skb(skb); - if ((proc = new_l3_process(st, cr))) { - proc->para.cause = 0x51; /* 81 */ + idev_kfree_skb(skb, FREE_READ); + if ((proc = dss1_new_l3_process(st, cr))) { + proc->para.cause = 81; l3dss1_msg_without_setup(proc, 0, NULL); } return; } - } else if (!l3dss1_check_messagetype_validity(mt)) { - /* ETS 300-104 7.4.2, 8.4.2, 10.3.2, 11.4.2, 12.4.2, 13.4.2, - * 14.4.2... - * if setup has been made and invalid message type is received, - * we must send MT_STATUS cause 0x62 - */ - mt = MT_INVALID; /* sorry, not clean, but do the right thing ;-) */ } + if (l3dss1_check_messagetype_validity(proc, mt, skb)) { + idev_kfree_skb(skb, FREE_READ); + return; + } + if ((p = findie(skb->data, skb->len, IE_DISPLAY, 0)) != NULL) + l3dss1_deliver_display(proc, pr, p); /* Display IE included */ for (i = 0; i < DATASLLEN; i++) if ((mt == datastatelist[i].primitive) && ((1 << proc->state) & datastatelist[i].state)) break; if (i == DATASLLEN) { - dev_kfree_skb(skb); if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "dss1up%sstate %d mt %x unhandled", + l3_debug(st, "dss1up%sstate %d mt %#x unhandled", (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", proc->state, mt); } - return; + if ((MT_RELEASE_COMPLETE != mt) && (MT_RELEASE != mt)) { + proc->para.cause = 101; + l3dss1_status_send(proc, pr, skb); + } } else { if (st->l3.debug & L3_DEB_STATE) { l3_debug(st, "dss1up%sstate %d mt %x", @@ -1893,6 +3147,8 @@ } datastatelist[i].rout(proc, pr, skb); } + idev_kfree_skb(skb, FREE_READ); + return; } static void @@ -1902,14 +3158,14 @@ struct l3_process *proc; struct Channel *chan; - if (((DL_ESTABLISH | REQUEST) == pr) || ((DL_RELEASE | REQUEST) == pr)) { + if ((DL_ESTABLISH | REQUEST) == pr) { l3_msg(st, pr, NULL); return; } else if (((CC_SETUP | REQUEST) == pr) || ((CC_RESUME | REQUEST) == pr)) { chan = arg; cr = newcallref(); cr |= 0x80; - if ((proc = new_l3_process(st, cr))) { + if ((proc = dss1_new_l3_process(st, cr))) { proc->chan = chan; chan->proc = proc; proc->para.setup = chan->setup; @@ -1922,32 +3178,75 @@ printk(KERN_ERR "HiSax dss1down without proc pr=%04x\n", pr); return; } + + if ( pr == (CC_TDSS1_IO | REQUEST)) { + l3dss1_io_timer(proc); /* timer expires */ + return; + } + for (i = 0; i < DOWNSLLEN; i++) if ((pr == downstatelist[i].primitive) && ((1 << proc->state) & downstatelist[i].state)) break; if (i == DOWNSLLEN) { if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "dss1down state %d prim %d unhandled", + l3_debug(st, "dss1down state %d prim %#x unhandled", proc->state, pr); } } else { if (st->l3.debug & L3_DEB_STATE) { - l3_debug(st, "dss1down state %d prim %d", + l3_debug(st, "dss1down state %d prim %#x", proc->state, pr); } downstatelist[i].rout(proc, pr, arg); } } +static void +dss1man(struct PStack *st, int pr, void *arg) +{ + int i; + struct l3_process *proc = arg; + + if (!proc) { + printk(KERN_ERR "HiSax dss1man without proc pr=%04x\n", pr); + return; + } + for (i = 0; i < MANSLLEN; i++) + if ((pr == manstatelist[i].primitive) && + ((1 << proc->state) & manstatelist[i].state)) + break; + if (i == MANSLLEN) { + if (st->l3.debug & L3_DEB_STATE) { + l3_debug(st, "cr %d dss1man state %d prim %#x unhandled", + proc->callref & 0x7f, proc->state, pr); + } + } else { + if (st->l3.debug & L3_DEB_STATE) { + l3_debug(st, "cr %d dss1man state %d prim %#x", + proc->callref & 0x7f, proc->state, pr); + } + manstatelist[i].rout(proc, pr, arg); + } +} + void setstack_dss1(struct PStack *st) { char tmp[64]; + int i; st->lli.l4l3 = dss1down; + st->lli.l4l3_proto = l3dss1_cmd_global; st->l2.l2l3 = dss1up; + st->l3.l3ml3 = dss1man; st->l3.N303 = 1; + st->prot.dss1.last_invoke_id = 0; + st->prot.dss1.invoke_used[0] = 1; /* Bit 0 must always be set to 1 */ + i = 1; + while (i < 32) + st->prot.dss1.invoke_used[i++] = 0; + if (!(st->l3.global = kmalloc(sizeof(struct l3_process), GFP_ATOMIC))) { printk(KERN_ERR "HiSax can't get memory for dss1 global CR\n"); } else { @@ -1957,6 +3256,8 @@ st->l3.global->debug = L3_DEB_WARN; st->l3.global->st = st; st->l3.global->N303 = 1; + st->l3.global->prot.dss1.invoke_id = 0; + L3InitTimer(st->l3.global, &st->l3.global->timer); } strcpy(tmp, dss1_revision); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/l3dss1.h linux/drivers/isdn/hisax/l3dss1.h --- v2.3.13/linux/drivers/isdn/hisax/l3dss1.h Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/l3dss1.h Thu Aug 12 09:42:33 1999 @@ -1,8 +1,11 @@ -/* $Id: l3dss1.h,v 1.6 1998/03/19 13:18:50 keil Exp $ +/* $Id: l3dss1.h,v 1.7 1999/07/01 08:12:02 keil Exp $ * * DSS1 (Euro) D-channel protocol defines * * $Log: l3dss1.h,v $ + * Revision 1.7 1999/07/01 08:12:02 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.6 1998/03/19 13:18:50 keil * Start of a CAPI like interface for supplementary Service * first service: SUSPEND @@ -25,10 +28,14 @@ * * */ + +#ifndef l3dss1_process + #define T303 4000 #define T304 30000 #define T305 30000 #define T308 4000 +#define T309 40000 #define T310 30000 #define T313 4000 #define T318 4000 @@ -38,39 +45,99 @@ * Message-Types */ -#define MT_ALERTING 0x01 -#define MT_CALL_PROCEEDING 0x02 -#define MT_CONNECT 0x07 -#define MT_CONNECT_ACKNOWLEDGE 0x0f -#define MT_PROGRESS 0x03 -#define MT_SETUP 0x05 -#define MT_SETUP_ACKNOWLEDGE 0x0d -#define MT_RESUME 0x26 -#define MT_RESUME_ACKNOWLEDGE 0x2e -#define MT_RESUME_REJECT 0x22 -#define MT_SUSPEND 0x25 -#define MT_SUSPEND_ACKNOWLEDGE 0x2d -#define MT_SUSPEND_REJECT 0x21 -#define MT_USER_INFORMATION 0x20 -#define MT_DISCONNECT 0x45 -#define MT_RELEASE 0x4d -#define MT_RELEASE_COMPLETE 0x5a -#define MT_RESTART 0x46 -#define MT_RESTART_ACKNOWLEDGE 0x4e -#define MT_SEGMENT 0x60 -#define MT_CONGESTION_CONTROL 0x79 -#define MT_INFORMATION 0x7b -#define MT_FACILITY 0x62 -#define MT_NOTIFY 0x6e -#define MT_STATUS 0x7d -#define MT_STATUS_ENQUIRY 0x75 - -#define MT_INVALID 0xff - -#define IE_BEARER 0x04 -#define IE_CAUSE 0x08 -#define IE_CALLID 0x10 -#define IE_FACILITY 0x1c -#define IE_CALL_STATE 0x14 -#define IE_CHANNEL_ID 0x18 -#define IE_RESTART_IND 0x79 +#define MT_ALERTING 0x01 +#define MT_CALL_PROCEEDING 0x02 +#define MT_CONNECT 0x07 +#define MT_CONNECT_ACKNOWLEDGE 0x0f +#define MT_PROGRESS 0x03 +#define MT_SETUP 0x05 +#define MT_SETUP_ACKNOWLEDGE 0x0d +#define MT_RESUME 0x26 +#define MT_RESUME_ACKNOWLEDGE 0x2e +#define MT_RESUME_REJECT 0x22 +#define MT_SUSPEND 0x25 +#define MT_SUSPEND_ACKNOWLEDGE 0x2d +#define MT_SUSPEND_REJECT 0x21 +#define MT_USER_INFORMATION 0x20 +#define MT_DISCONNECT 0x45 +#define MT_RELEASE 0x4d +#define MT_RELEASE_COMPLETE 0x5a +#define MT_RESTART 0x46 +#define MT_RESTART_ACKNOWLEDGE 0x4e +#define MT_SEGMENT 0x60 +#define MT_CONGESTION_CONTROL 0x79 +#define MT_INFORMATION 0x7b +#define MT_FACILITY 0x62 +#define MT_NOTIFY 0x6e +#define MT_STATUS 0x7d +#define MT_STATUS_ENQUIRY 0x75 + +#define IE_SEGMENT 0x00 +#define IE_BEARER 0x04 +#define IE_CAUSE 0x08 +#define IE_CALL_ID 0x10 +#define IE_CALL_STATE 0x14 +#define IE_CHANNEL_ID 0x18 +#define IE_FACILITY 0x1c +#define IE_PROGRESS 0x1e +#define IE_NET_FAC 0x20 +#define IE_NOTIFY 0x27 +#define IE_DISPLAY 0x28 +#define IE_DATE 0x29 +#define IE_KEYPAD 0x2c +#define IE_SIGNAL 0x34 +#define IE_INFORATE 0x40 +#define IE_E2E_TDELAY 0x42 +#define IE_TDELAY_SEL 0x43 +#define IE_PACK_BINPARA 0x44 +#define IE_PACK_WINSIZE 0x45 +#define IE_PACK_SIZE 0x46 +#define IE_CUG 0x47 +#define IE_REV_CHARGE 0x4a +#define IE_CONNECT_PN 0x4c +#define IE_CONNECT_SUB 0x4d +#define IE_CALLING_PN 0x6c +#define IE_CALLING_SUB 0x6d +#define IE_CALLED_PN 0x70 +#define IE_CALLED_SUB 0x71 +#define IE_REDIR_NR 0x74 +#define IE_TRANS_SEL 0x78 +#define IE_RESTART_IND 0x79 +#define IE_LLC 0x7c +#define IE_HLC 0x7d +#define IE_USER_USER 0x7e +#define IE_ESCAPE 0x7f +#define IE_SHIFT 0x90 +#define IE_MORE_DATA 0xa0 +#define IE_COMPLETE 0xa1 +#define IE_CONGESTION 0xb0 +#define IE_REPEAT 0xd0 + +#define IE_MANDATORY 0x0100 +/* mandatory not in every case */ +#define IE_MANDATORY_1 0x0200 + +#define ERR_IE_COMPREHENSION 1 +#define ERR_IE_UNRECOGNIZED -1 +#define ERR_IE_LENGTH -2 +#define ERR_IE_SEQUENCE -3 + +#else /* only l3dss1_process */ + +/* l3dss1 specific data in l3 process */ +typedef struct + { unsigned char invoke_id; /* used invoke id in remote ops, 0 = not active */ + ulong ll_id; /* remebered ll id */ + u_char remote_operation; /* handled remote operation, 0 = not active */ + int proc; /* rememered procedure */ + ulong remote_result; /* result of remote operation for statcallb */ + char uus1_data[35]; /* data send during alerting or disconnect */ + } dss1_proc_priv; + +/* l3dss1 specific data in protocol stack */ +typedef struct + { unsigned char last_invoke_id; /* last used value for invoking */ + unsigned char invoke_used[32]; /* 256 bits for 256 values */ + } dss1_stk_priv; + +#endif /* only l3dss1_process */ diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/lmgr.c linux/drivers/isdn/hisax/lmgr.c --- v2.3.13/linux/drivers/isdn/hisax/lmgr.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/lmgr.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: lmgr.c,v 1.5 1998/11/15 23:55:12 keil Exp $ +/* $Id: lmgr.c,v 1.6 1999/07/01 08:12:04 keil Exp $ * Author Karsten Keil (keil@isdn4linux.de) * @@ -6,6 +6,9 @@ * Layermanagement module * * $Log: lmgr.c,v $ + * Revision 1.6 1999/07/01 08:12:04 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.5 1998/11/15 23:55:12 keil * changes from 2.0 * @@ -50,7 +53,7 @@ case (MDL_ERROR | INDICATION): Code = (long) arg; HiSax_putstatus(st->l1.hardware, "manager: MDL_ERROR", - "%c %s\n", (char)Code, + " %c %s", (char)Code, test_bit(FLG_LAPD, &st->l2.flag) ? "D-channel" : "B-channel"); if (test_bit(FLG_LAPD, &st->l2.flag)) diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/md5sums.asc linux/drivers/isdn/hisax/md5sums.asc --- v2.3.13/linux/drivers/isdn/hisax/md5sums.asc Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/md5sums.asc Thu Aug 12 09:42:33 1999 @@ -2,28 +2,30 @@ # This are valid md5sums for certificated HiSax driver. # The certification is valid only if the md5sums of all files match. -# The certification is valid only for ELSA QuickStep cards in the moment. +# The certification is valid only for ELSA QuickStep cards and +# Eicon Technology Diva 2.01 PCI cards in the moment. # Read ../../../Documentation/isdn/HiSax.cert for more informations. # -a273c532aec063574273ee519975cd9a isac.c -27c5c5bfa2ceabf02e2e6d686b03abde isdnl1.c -8c89ac659d3188ab997fb575da22b566 isdnl2.c -d0fa912aa284b8fd19fed86b65999f6f isdnl3.c -1bce120740b615006286ad9b2d7fcdcb tei.c -8845f88dd17917d9b58badeff1605057 callc.c -f3ec2a634f06074d16167aaba02b6dc1 cert.c -71840ec8189f42b0db86fb38e5e5984c l3dss1.c -1882de8bea921b9ccd98fbe77267aa04 l3_1tr6.c -3bd7af3a11693d028300278744d0da09 elsa.c +d93f31e02c1b153ec04d16f69e5688b3 isac.c +e2a78c07f32c8ca7c88fc9f92a87dfab isdnl1.c +54490c4f46a998ff4ef34287bc262185 isdnl2.c +f4184a50e35e5b568608e6cb7a693319 isdnl3.c +ef70f4269fdc2ca15100f9b776afaa0d tei.c +cf3923304983e9d64cf35bc5a3533f6c callc.c +bf9605b36429898f7be6630034e83230 cert.c +309261e4c36d950db6978440e8bc8342 l3dss1.c +b674eee9314a7cc413971c84003cf1d2 l3_1tr6.c +8f86d92f43ecc42f6457773168cfc114 elsa.c +24cda374da44b57f6a1bb215424267b5 diva.c # end of md5sums -----BEGIN PGP SIGNATURE----- Version: 2.6.3i Charset: noconv -iQCVAwUBNrl5JDpxHvX/mS9tAQHm8wP+Nk64UJ2abdDG/igXZSrwcYhX/Kp7cxt9 -ccYp+aaur+pALA0lxwY3xcLt9u36fCYuTLHAVmQoiC9Vbemj37yzM2rUpz9nkw/7 -D6gLqZs2jxVpAwVVJgp0JwDONKXaRX6Lt2EPD9PTW6vxRWEu0HqGhM5hrtd/o4rV -mC1W7Wj13XM= -=LdhT +iQCVAwUBN7HnvDpxHvX/mS9tAQFANgP+LGuG98lvCv97vN2dc6T/6hZTxFW+WirJ +XMhU5NHoZ+8MISMOVKB7ugsGO9cJI0lUA0sOe8jtPCo5070nF1ZkNsxV/x7WK2dS +RwXfHy6+TAH7qIiBnkP9odB2lib+VFl/nnkkTwsXfVwRCD8bLaagMPv+nAveDoNE +uff0xxXEnJw= +=Wu2M -----END PGP SIGNATURE----- diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/mic.c linux/drivers/isdn/hisax/mic.c --- v2.3.13/linux/drivers/isdn/hisax/mic.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/isdn/hisax/mic.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: mic.c,v 1.7 1998/04/15 16:44:32 keil Exp $ +/* $Id: mic.c,v 1.8 1999/07/12 21:05:20 keil Exp $ * mic.c low level stuff for mic cards * @@ -8,6 +8,10 @@ * * * $Log: mic.c,v $ + * Revision 1.8 1999/07/12 21:05:20 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * * Revision 1.7 1998/04/15 16:44:32 keil * new init code * @@ -40,7 +44,7 @@ extern const char *CardType[]; -const char *mic_revision = "$Revision: 1.7 $"; +const char *mic_revision = "$Revision: 1.8 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -158,7 +162,7 @@ mic_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; - u_char val, stat = 0; + u_char val; if (!cs) { printk(KERN_WARNING "mic: Spurious interrupt!\n"); @@ -166,16 +170,12 @@ } val = readreg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_ISTA + 0x40); Start_HSCX: - if (val) { + if (val) hscx_int_main(cs, val); - stat |= 1; - } val = readreg(cs->hw.mic.adr, cs->hw.mic.isac, ISAC_ISTA); Start_ISAC: - if (val) { + if (val) isac_interrupt(cs, val); - stat |= 2; - } val = readreg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_ISTA + 0x40); if (val) { if (cs->debug & L1_DEB_HSCX) @@ -188,16 +188,12 @@ debugl1(cs, "ISAC IntStat after IntRoutine"); goto Start_ISAC; } - if (stat & 1) { - writereg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_MASK, 0xFF); - writereg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_MASK + 0x40, 0xFF); - writereg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_MASK, 0x0); - writereg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_MASK + 0x40, 0x0); - } - if (stat & 2) { - writereg(cs->hw.mic.adr, cs->hw.mic.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.mic.adr, cs->hw.mic.isac, ISAC_MASK, 0x0); - } + writereg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_MASK, 0xFF); + writereg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_MASK + 0x40, 0xFF); + writereg(cs->hw.mic.adr, cs->hw.mic.isac, ISAC_MASK, 0xFF); + writereg(cs->hw.mic.adr, cs->hw.mic.isac, ISAC_MASK, 0x0); + writereg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_MASK, 0x0); + writereg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_MASK + 0x40, 0x0); } void @@ -218,9 +214,6 @@ case CARD_RELEASE: release_io_mic(cs); return(0); - case CARD_SETIRQ: - return(request_irq(cs->irq, &mic_interrupt, - I4L_IRQ_FLAG, "HiSax", cs)); case CARD_INIT: inithscx(cs); /* /RTSA := ISAC RST */ inithscxisac(cs, 3); @@ -231,8 +224,8 @@ return(0); } -int __init -setup_mic(struct IsdnCard *card) +__initfunc(int +setup_mic(struct IsdnCard *card)) { int bytecnt; struct IsdnCardState *cs = card->cs; @@ -273,6 +266,7 @@ cs->BC_Write_Reg = &WriteHSCX; cs->BC_Send_Data = &hscx_fill_fifo; cs->cardmsg = &mic_card_msg; + cs->irq_func = &mic_interrupt; ISACVersion(cs, "mic:"); if (HscxVersion(cs, "mic:")) { printk(KERN_WARNING diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/netjet.c linux/drivers/isdn/hisax/netjet.c --- v2.3.13/linux/drivers/isdn/hisax/netjet.c Mon Aug 9 14:59:20 1999 +++ linux/drivers/isdn/hisax/netjet.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: netjet.c,v 1.8 1998/11/15 23:55:14 keil Exp $ +/* $Id: netjet.c,v 1.13 1999/08/11 21:01:31 keil Exp $ * netjet.c low level stuff for Traverse Technologie NETJet ISDN cards * @@ -6,8 +6,25 @@ * * Thanks to Traverse Technologie Australia for documents and informations * - * * $Log: netjet.c,v $ + * Revision 1.13 1999/08/11 21:01:31 keil + * new PCI codefix + * + * Revision 1.12 1999/08/10 16:02:00 calle + * struct pci_dev changed in 2.3.13. Made the necessary changes. + * + * Revision 1.11 1999/08/07 17:32:00 keil + * Asymetric buffers for improved ping times. Interframe spacing + * fix for NJ<->NJ thoughput. Matt Henderson - www.traverse.com.au + * + * + * Revision 1.10 1999/07/12 21:05:22 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 1.9 1999/07/01 08:12:05 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.8 1998/11/15 23:55:14 keil * changes from 2.0 * @@ -42,12 +59,23 @@ #include "hscx.h" #include "isdnl1.h" #include +#ifndef COMPAT_HAS_NEW_PCI +#include +#endif #include #include +#ifndef bus_to_virt +#define bus_to_virt (u_int *) +#endif + +#ifndef virt_to_bus +#define virt_to_bus (u_int) +#endif + extern const char *CardType[]; -const char *NETjet_revision = "$Revision: 1.8 $"; +const char *NETjet_revision = "$Revision: 1.13 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -83,7 +111,8 @@ #define NETJET_IRQM0_WRITE_1 0x01 #define NETJET_IRQM0_WRITE_2 0x02 -#define NETJET_DMA_SIZE 512 +#define NETJET_DMA_TXSIZE 512 +#define NETJET_DMA_RXSIZE 128 #define HDLC_ZERO_SEARCH 0 #define HDLC_FLAG_SEARCH 1 @@ -211,7 +240,7 @@ switch (mode) { case (L1_MODE_NULL): fill_mem(bcs, bcs->hw.tiger.send, - NETJET_DMA_SIZE, bc, 0xff); + NETJET_DMA_TXSIZE, bc, 0xff); if (cs->debug & L1_DEB_HSCX) debugl1(cs, "Tiger stat rec %d/%d send %d", bcs->hw.tiger.r_tot, bcs->hw.tiger.r_err, @@ -228,7 +257,7 @@ break; case (L1_MODE_HDLC): fill_mem(bcs, bcs->hw.tiger.send, - NETJET_DMA_SIZE, bc, 0xff); + NETJET_DMA_TXSIZE, bc, 0xff); bcs->hw.tiger.r_state = HDLC_ZERO_SEARCH; bcs->hw.tiger.r_tot = 0; bcs->hw.tiger.r_bitcnt = 0; @@ -237,14 +266,14 @@ bcs->hw.tiger.s_tot = 0; if (! cs->hw.njet.dmactrl) { fill_mem(bcs, bcs->hw.tiger.send, - NETJET_DMA_SIZE, !bc, 0xff); + NETJET_DMA_TXSIZE, !bc, 0xff); cs->hw.njet.dmactrl = 1; byteout(cs->hw.njet.base + NETJET_DMACTRL, cs->hw.njet.dmactrl); byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0x3f); } bcs->hw.tiger.sendp = bcs->hw.tiger.send; - bcs->hw.tiger.free = NETJET_DMA_SIZE; + bcs->hw.tiger.free = NETJET_DMA_TXSIZE; test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag); break; } @@ -363,6 +392,7 @@ s_val |= 0x80; } bcs->hw.tiger.sendbuf[s_cnt++] = s_val; + bcs->hw.tiger.sendbuf[s_cnt++] = 0xff; // NJ<->NJ thoughput bug fix } bcs->hw.tiger.sendcnt = s_cnt; bcs->tx_cnt -= bcs->tx_skb->len; @@ -376,6 +406,7 @@ if (!(skb = dev_alloc_skb(count))) printk(KERN_WARNING "TIGER: receive out of memory\n"); else { + SET_SKB_FREE(skb); memcpy(skb_put(skb, count), bcs->hw.tiger.rcvbuf, count); skb_queue_tail(&bcs->rqueue, skb); } @@ -393,7 +424,7 @@ int i; register u_char j; register u_char val; - u_int *pend = bcs->hw.tiger.rec +NETJET_DMA_SIZE -1; + u_int *pend = bcs->hw.tiger.rec +NETJET_DMA_RXSIZE -1; register u_char state = bcs->hw.tiger.r_state; register u_char r_one = bcs->hw.tiger.r_one; register u_char r_val = bcs->hw.tiger.r_val; @@ -548,7 +579,7 @@ static void read_tiger(struct IsdnCardState *cs) { u_int *p; - int cnt = NETJET_DMA_SIZE/2; + int cnt = NETJET_DMA_RXSIZE/2; if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_READ) { debugl1(cs,"tiger warn read double dma %x/%x", @@ -559,7 +590,7 @@ cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ); } if (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ_1) - p = cs->bcs[0].hw.tiger.rec + NETJET_DMA_SIZE - 1; + p = cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1; else p = cs->bcs[0].hw.tiger.rec + cnt - 1; if (cs->bcs[0].mode == L1_MODE_HDLC) @@ -616,12 +647,12 @@ cnt = bcs->hw.tiger.s_end - p; if (cnt < 2) { p = bcs->hw.tiger.send + 1; - cnt = NETJET_DMA_SIZE/2 - 2; + cnt = NETJET_DMA_TXSIZE/2 - 2; } else { p++; p++; - if (cnt <= (NETJET_DMA_SIZE/2)) - cnt += NETJET_DMA_SIZE/2; + if (cnt <= (NETJET_DMA_TXSIZE/2)) + cnt += NETJET_DMA_TXSIZE/2; cnt--; cnt--; } @@ -674,12 +705,12 @@ if (bcs->st->lli.l1writewakeup && (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->tx_skb->len); - dev_kfree_skb(bcs->tx_skb); + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); bcs->tx_skb = NULL; } test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); bcs->hw.tiger.free = cnt - s_cnt; - if (bcs->hw.tiger.free > (NETJET_DMA_SIZE/2)) + if (bcs->hw.tiger.free > (NETJET_DMA_TXSIZE/2)) test_and_set_bit(BC_FLG_HALF, &bcs->Flag); else { test_and_clear_bit(BC_FLG_HALF, &bcs->Flag); @@ -719,7 +750,7 @@ } static void write_tiger(struct IsdnCardState *cs) { - u_int *p, cnt = NETJET_DMA_SIZE/2; + u_int *p, cnt = NETJET_DMA_TXSIZE/2; if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_WRITE) { debugl1(cs,"tiger warn write double dma %x/%x", @@ -730,7 +761,7 @@ cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE); } if (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE_1) - p = cs->bcs[0].hw.tiger.send + NETJET_DMA_SIZE - 1; + p = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1; else p = cs->bcs[0].hw.tiger.send + cnt - 1; if (cs->bcs[0].mode == L1_MODE_HDLC) @@ -811,7 +842,7 @@ discard_queue(&bcs->rqueue); discard_queue(&bcs->squeue); if (bcs->tx_skb) { - dev_kfree_skb(bcs->tx_skb); + idev_kfree_skb(bcs->tx_skb, FREE_WRITE); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); } @@ -858,45 +889,45 @@ } -void __init -inittiger(struct IsdnCardState *cs) +__initfunc(void +inittiger(struct IsdnCardState *cs)) { - if (!(cs->bcs[0].hw.tiger.send = kmalloc(NETJET_DMA_SIZE * sizeof(unsigned int), + if (!(cs->bcs[0].hw.tiger.send = kmalloc(NETJET_DMA_TXSIZE * sizeof(unsigned int), GFP_KERNEL | GFP_DMA))) { printk(KERN_WARNING "HiSax: No memory for tiger.send\n"); return; } - cs->bcs[0].hw.tiger.s_irq = cs->bcs[0].hw.tiger.send + NETJET_DMA_SIZE/2 - 1; - cs->bcs[0].hw.tiger.s_end = cs->bcs[0].hw.tiger.send + NETJET_DMA_SIZE - 1; + cs->bcs[0].hw.tiger.s_irq = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE/2 - 1; + cs->bcs[0].hw.tiger.s_end = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1; cs->bcs[1].hw.tiger.send = cs->bcs[0].hw.tiger.send; cs->bcs[1].hw.tiger.s_irq = cs->bcs[0].hw.tiger.s_irq; cs->bcs[1].hw.tiger.s_end = cs->bcs[0].hw.tiger.s_end; - memset(cs->bcs[0].hw.tiger.send, 0xff, NETJET_DMA_SIZE * sizeof(unsigned int)); + memset(cs->bcs[0].hw.tiger.send, 0xff, NETJET_DMA_TXSIZE * sizeof(unsigned int)); debugl1(cs, "tiger: send buf %x - %x", (u_int)cs->bcs[0].hw.tiger.send, - (u_int)(cs->bcs[0].hw.tiger.send + NETJET_DMA_SIZE - 1)); + (u_int)(cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1)); outl(virt_to_bus(cs->bcs[0].hw.tiger.send), cs->hw.njet.base + NETJET_DMA_READ_START); outl(virt_to_bus(cs->bcs[0].hw.tiger.s_irq), cs->hw.njet.base + NETJET_DMA_READ_IRQ); outl(virt_to_bus(cs->bcs[0].hw.tiger.s_end), cs->hw.njet.base + NETJET_DMA_READ_END); - if (!(cs->bcs[0].hw.tiger.rec = kmalloc(NETJET_DMA_SIZE * sizeof(unsigned int), + if (!(cs->bcs[0].hw.tiger.rec = kmalloc(NETJET_DMA_RXSIZE * sizeof(unsigned int), GFP_KERNEL | GFP_DMA))) { printk(KERN_WARNING "HiSax: No memory for tiger.rec\n"); return; } debugl1(cs, "tiger: rec buf %x - %x", (u_int)cs->bcs[0].hw.tiger.rec, - (u_int)(cs->bcs[0].hw.tiger.rec + NETJET_DMA_SIZE - 1)); + (u_int)(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1)); cs->bcs[1].hw.tiger.rec = cs->bcs[0].hw.tiger.rec; - memset(cs->bcs[0].hw.tiger.rec, 0xff, NETJET_DMA_SIZE * sizeof(unsigned int)); + memset(cs->bcs[0].hw.tiger.rec, 0xff, NETJET_DMA_RXSIZE * sizeof(unsigned int)); outl(virt_to_bus(cs->bcs[0].hw.tiger.rec), cs->hw.njet.base + NETJET_DMA_WRITE_START); - outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_SIZE/2 - 1), + outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE/2 - 1), cs->hw.njet.base + NETJET_DMA_WRITE_IRQ); - outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_SIZE - 1), + outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1), cs->hw.njet.base + NETJET_DMA_WRITE_END); debugl1(cs, "tiger: dmacfg %x/%x pulse=%d", inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR), @@ -1030,9 +1061,6 @@ case CARD_RELEASE: release_io_netjet(cs); return(0); - case CARD_SETIRQ: - return(request_irq(cs->irq, &netjet_interrupt, - I4L_IRQ_FLAG | SA_SHIRQ, "HiSax", cs)); case CARD_INIT: inittiger(cs); clear_pending_isac_ints(cs); @@ -1046,23 +1074,31 @@ return(0); } - - +#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *dev_netjet __initdata = NULL; +#else +static int pci_index __initdata = 0; +#endif -int __init -setup_netjet(struct IsdnCard *card) +__initfunc(int +setup_netjet(struct IsdnCard *card)) { int bytecnt; struct IsdnCardState *cs = card->cs; char tmp[64]; - +#if CONFIG_PCI +#ifndef COMPAT_HAS_NEW_PCI + u_char pci_bus, pci_device_fn, pci_irq; + u_int pci_ioaddr, found; +#endif +#endif strcpy(tmp, NETjet_revision); printk(KERN_INFO "HiSax: Traverse Tech. NETjet driver Rev. %s\n", HiSax_getrev(tmp)); if (cs->typ != ISDN_CTYPE_NETJET) return(0); test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); #if CONFIG_PCI +#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_ERR "Netjet: no PCI bus present\n"); return(0); @@ -1071,22 +1107,57 @@ PCI_NETJET_ID, dev_netjet))) { cs->irq = dev_netjet->irq; if (!cs->irq) { + printk(KERN_WARNING "NETjet: No IRQ for PCI card found\n"); + return(0); + } + cs->hw.njet.base = get_pcibase(dev_netjet, 0) + & PCI_BASE_ADDRESS_IO_MASK; + if (!cs->hw.njet.base) { + printk(KERN_WARNING "NETjet: No IO-Adr for PCI card found\n"); + return(0); + } + } else { + printk(KERN_WARNING "NETjet: No PCI card found\n"); + return(0); + } +#else + found = 0; + for (; pci_index < 0xff; pci_index++) { + if (pcibios_find_device(PCI_VENDOR_TRAVERSE_TECH, + PCI_NETJET_ID, pci_index, &pci_bus, &pci_device_fn) + == PCIBIOS_SUCCESSFUL) + found = 1; + else + continue; + /* get IRQ */ + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_INTERRUPT_LINE, &pci_irq); + + /* get IO address */ + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_0, &pci_ioaddr); + if (found) + break; + } + if (!found) { + printk(KERN_WARNING "NETjet: No PCI card found\n"); + return(0); + } + pci_index++; + if (!pci_irq) { printk(KERN_WARNING "NETjet: No IRQ for PCI card found\n"); return(0); } - cs->hw.njet.base = dev_netjet->resource[0].start & - PCI_BASE_ADDRESS_IO_MASK; - if (!cs->hw.njet.base) { + if (!pci_ioaddr) { printk(KERN_WARNING "NETjet: No IO-Adr for PCI card found\n"); return(0); } - cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; - cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF; + cs->hw.njet.base = pci_ioaddr & PCI_BASE_ADDRESS_IO_MASK; + cs->irq = pci_irq; +#endif /* COMPAT_HAS_NEW_PCI */ + cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; + cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF; bytecnt = 256; - } else { - printk(KERN_WARNING "NETjet: No PCI card found\n"); - return(0); - } #else printk(KERN_WARNING "NETjet: NO_PCI_BIOS\n"); printk(KERN_WARNING "NETjet: unable to config NETJET PCI\n"); @@ -1114,6 +1185,8 @@ cs->BC_Write_Reg = &dummywr; cs->BC_Send_Data = &fill_dma; cs->cardmsg = &NETjet_card_msg; + cs->irq_func = &netjet_interrupt; + cs->irq_flags |= SA_SHIRQ; ISACVersion(cs, "NETjet:"); return (1); } diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/niccy.c linux/drivers/isdn/hisax/niccy.c --- v2.3.13/linux/drivers/isdn/hisax/niccy.c Mon Aug 9 14:59:20 1999 +++ linux/drivers/isdn/hisax/niccy.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: niccy.c,v 1.4 1998/04/16 19:16:48 keil Exp $ +/* $Id: niccy.c,v 1.8 1999/08/11 21:01:33 keil Exp $ * niccy.c low level stuff for Dr. Neuhaus NICCY PnP and NICCY PCI and * compatible (SAGEM cybermodem) @@ -8,6 +8,19 @@ * Thanks to Dr. Neuhaus and SAGEM for informations * * $Log: niccy.c,v $ + * Revision 1.8 1999/08/11 21:01:33 keil + * new PCI codefix + * + * Revision 1.7 1999/08/10 16:02:04 calle + * struct pci_dev changed in 2.3.13. Made the necessary changes. + * + * Revision 1.6 1999/07/12 21:05:23 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 1.5 1999/07/01 08:12:07 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.4 1998/04/16 19:16:48 keil * need config.h * @@ -27,9 +40,12 @@ #include "hscx.h" #include "isdnl1.h" #include +#ifndef COMPAT_HAS_NEW_PCI +#include +#endif extern const char *CardType[]; -const char *niccy_revision = "$Revision: 1.4 $"; +const char *niccy_revision = "$Revision: 1.8 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -154,7 +170,7 @@ niccy_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; - u_char val, stat = 0; + u_char val; if (!cs) { printk(KERN_WARNING "Niccy: Spurious interrupt!\n"); @@ -169,16 +185,12 @@ } val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_ISTA + 0x40); Start_HSCX: - if (val) { + if (val) hscx_int_main(cs, val); - stat |= 1; - } val = readreg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_ISTA); Start_ISAC: - if (val) { + if (val) isac_interrupt(cs, val); - stat |= 2; - } val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_ISTA + 0x40); if (val) { if (cs->debug & L1_DEB_HSCX) @@ -191,16 +203,12 @@ debugl1(cs, "ISAC IntStat after IntRoutine"); goto Start_ISAC; } - if (stat & 1) { - writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK, 0xFF); - writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40, 0xFF); - writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK, 0); - writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40, 0); - } - if (stat & 2) { - writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0); - } + writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK, 0xFF); + writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40, 0xFF); + writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0xFF); + writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0); + writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK, 0); + writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40, 0); } void @@ -235,8 +243,6 @@ static int niccy_card_msg(struct IsdnCardState *cs, int mt, void *arg) { - int imode; - switch (mt) { case CARD_RESET: niccy_reset(cs); @@ -244,14 +250,6 @@ case CARD_RELEASE: release_io_niccy(cs); return(0); - case CARD_SETIRQ: - if (cs->subtyp == NICCY_PCI) - imode = I4L_IRQ_FLAG | SA_SHIRQ; - else - imode = I4L_IRQ_FLAG; - return(request_irq(cs->irq, &niccy_interrupt, - imode, "HiSax", cs)); - break; case CARD_INIT: niccy_reset(cs); return(0); @@ -261,10 +259,14 @@ return(0); } +#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *niccy_dev __initdata = NULL; +#else +static int pci_index __initdata = 0; +#endif -int __init -setup_niccy(struct IsdnCard *card) +__initfunc(int +setup_niccy(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; @@ -304,40 +306,85 @@ } else { #if CONFIG_PCI u_int pci_ioaddr; - +#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_ERR "Niccy: no PCI bus present\n"); return(0); } - cs->subtyp = 0; if ((niccy_dev = pci_find_device(PCI_VENDOR_DR_NEUHAUS, PCI_NICCY_ID, niccy_dev))) { /* get IRQ */ if (!niccy_dev->irq) { printk(KERN_WARNING "Niccy: No IRQ for PCI card found\n"); + return(0); + } + cs->irq = niccy_dev->irq; + if (!get_pcibase(niccy_dev, 0)) { + printk(KERN_WARNING "Niccy: No IO-Adr for PCI cfg found\n"); + return(0); + } + cs->hw.niccy.cfg_reg = get_pcibase(niccy_dev, 0) & PCI_BASE_ADDRESS_IO_MASK; + if (!get_pcibase(niccy_dev, 1)) { + printk(KERN_WARNING "Niccy: No IO-Adr for PCI card found\n"); + return(0); + } + pci_ioaddr = get_pcibase(niccy_dev, 1) & PCI_BASE_ADDRESS_IO_MASK; + cs->subtyp = NICCY_PCI; + } else { + printk(KERN_WARNING "Niccy: No PCI card found\n"); return(0); } - cs->irq = niccy_dev->irq; - if (!niccy_dev->resource[0].start) { +#else + u_char pci_bus, pci_device_fn, pci_irq; + + cs->subtyp = 0; + for (; pci_index < 0xff; pci_index++) { + if (pcibios_find_device(PCI_VENDOR_DR_NEUHAUS, + PCI_NICCY_ID, pci_index, &pci_bus, &pci_device_fn) + == PCIBIOS_SUCCESSFUL) + cs->subtyp = NICCY_PCI; + else + continue; + /* get IRQ */ + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_INTERRUPT_LINE, &pci_irq); + + /* get IO pci AMCC address */ + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_0, &pci_ioaddr); + if (!pci_ioaddr) { printk(KERN_WARNING "Niccy: No IO-Adr for PCI cfg found\n"); + return(0); + } + cs->hw.niccy.cfg_reg = pci_ioaddr & ~3 ; + /* get IO address */ + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_1, &pci_ioaddr); + if (cs->subtyp) + break; + } + if (!cs->subtyp) { + printk(KERN_WARNING "Niccy: No PCI card found\n"); return(0); } - cs->hw.niccy.cfg_reg = niccy_dev->resource[0].start & PCI_BASE_ADDRESS_IO_MASK; - if (!niccy_dev->resource[1].start) { + pci_index++; + if (!pci_irq) { + printk(KERN_WARNING "Niccy: No IRQ for PCI card found\n"); + return(0); + } + if (!pci_ioaddr) { printk(KERN_WARNING "Niccy: No IO-Adr for PCI card found\n"); return(0); } - pci_ioaddr = niccy_dev->resource[1].start & PCI_BASE_ADDRESS_IO_MASK; + pci_ioaddr &= ~3; /* remove io/mem flag */ + cs->irq = pci_irq; +#endif /* COMPAT_HAS_NEW_PCI */ + cs->irq_flags |= SA_SHIRQ; cs->hw.niccy.isac = pci_ioaddr + ISAC_PCI_DATA; cs->hw.niccy.isac_ale = pci_ioaddr + ISAC_PCI_ADDR; cs->hw.niccy.hscx = pci_ioaddr + HSCX_PCI_DATA; cs->hw.niccy.hscx_ale = pci_ioaddr + HSCX_PCI_ADDR; - cs->subtyp = NICCY_PCI; - } else { - printk(KERN_WARNING "Niccy: No PCI card found\n"); - return(0); - } if (check_region((cs->hw.niccy.isac), 4)) { printk(KERN_WARNING "HiSax: %s data port %x-%x already in use\n", @@ -376,6 +423,7 @@ cs->BC_Write_Reg = &WriteHSCX; cs->BC_Send_Data = &hscx_fill_fifo; cs->cardmsg = &niccy_card_msg; + cs->irq_func = &niccy_interrupt; ISACVersion(cs, "Niccy:"); if (HscxVersion(cs, "Niccy:")) { printk(KERN_WARNING diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/s0box.c linux/drivers/isdn/hisax/s0box.c --- v2.3.13/linux/drivers/isdn/hisax/s0box.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/s0box.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: s0box.c,v 2.1 1998/04/15 16:38:24 keil Exp $ +/* $Id: s0box.c,v 2.2 1999/07/12 21:05:25 keil Exp $ * s0box.c low level stuff for Creatix S0BOX * @@ -13,7 +13,7 @@ #include "isdnl1.h" extern const char *CardType[]; -const char *s0box_revision = "$Revision: 2.1 $"; +const char *s0box_revision = "$Revision: 2.2 $"; static inline void writereg(unsigned int padr, signed int addr, u_char off, u_char val) { @@ -148,9 +148,9 @@ static void s0box_interrupt(int intno, void *dev_id, struct pt_regs *regs) { -#define MAXCOUNT 20 +#define MAXCOUNT 5 struct IsdnCardState *cs = dev_id; - u_char val, stat = 0; + u_char val; int count = 0; if (!cs) { @@ -159,16 +159,12 @@ } val = readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_ISTA); Start_HSCX: - if (val) { + if (val) hscx_int_main(cs, val); - stat |= 1; - } val = readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_ISTA); Start_ISAC: - if (val) { + if (val) isac_interrupt(cs, val); - stat |= 2; - } count++; val = readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_ISTA); if (val && count < MAXCOUNT) { @@ -184,16 +180,12 @@ } if (count >= MAXCOUNT) printk(KERN_WARNING "S0Box: more than %d loops in s0box_interrupt\n", count); - if (stat & 1) { - writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[0], HSCX_MASK, 0xFF); - writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_MASK, 0xFF); - writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[0], HSCX_MASK, 0x0); - writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_MASK, 0x0); - } - if (stat & 2) { - writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_MASK, 0x0); - } + writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[0], HSCX_MASK, 0xFF); + writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_MASK, 0xFF); + writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_MASK, 0xFF); + writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_MASK, 0x0); + writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[0], HSCX_MASK, 0x0); + writereg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_MASK, 0x0); } void @@ -211,9 +203,6 @@ case CARD_RELEASE: release_io_s0box(cs); break; - case CARD_SETIRQ: - return(request_irq(cs->irq, &s0box_interrupt, - I4L_IRQ_FLAG, "HiSax", cs)); case CARD_INIT: inithscxisac(cs, 3); break; @@ -266,6 +255,7 @@ cs->BC_Write_Reg = &WriteHSCX; cs->BC_Send_Data = &hscx_fill_fifo; cs->cardmsg = &S0Box_card_msg; + cs->irq_func = &s0box_interrupt; ISACVersion(cs, "S0Box:"); if (HscxVersion(cs, "S0Box:")) { printk(KERN_WARNING diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/saphir.c linux/drivers/isdn/hisax/saphir.c --- v2.3.13/linux/drivers/isdn/hisax/saphir.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/hisax/saphir.c Thu Aug 12 09:42:33 1999 @@ -0,0 +1,326 @@ +/* $Id: saphir.c,v 1.3 1999/07/12 21:05:26 keil Exp $ + + * saphir.c low level stuff for HST Saphir 1 + * + * Author Karsten Keil (keil@isdn4linux.de) + * + * Thanks to HST High Soft Tech GmbH + * + * + * $Log: saphir.c,v $ + * Revision 1.3 1999/07/12 21:05:26 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 1.2 1999/07/01 08:07:55 keil + * Initial version + * + * + */ + + +#define __NO_VERSION__ +#include "hisax.h" +#include "isac.h" +#include "hscx.h" +#include "isdnl1.h" + +extern const char *CardType[]; +static char *saphir_rev = "$Revision: 1.3 $"; + +#define byteout(addr,val) outb(val,addr) +#define bytein(addr) inb(addr) + +#define ISAC_DATA 0 +#define HSCX_DATA 1 +#define ADDRESS_REG 2 +#define IRQ_REG 3 +#define SPARE_REG 4 +#define RESET_REG 5 + +static inline u_char +readreg(unsigned int ale, unsigned int adr, u_char off) +{ + register u_char ret; + long flags; + + save_flags(flags); + cli(); + byteout(ale, off); + ret = bytein(adr); + restore_flags(flags); + return (ret); +} + +static inline void +readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size) +{ + /* fifo read without cli because it's allready done */ + + byteout(ale, off); + insb(adr, data, size); +} + + +static inline void +writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) +{ + long flags; + + save_flags(flags); + cli(); + byteout(ale, off); + byteout(adr, data); + restore_flags(flags); +} + +static inline void +writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size) +{ + /* fifo write without cli because it's allready done */ + byteout(ale, off); + outsb(adr, data, size); +} + +/* Interface functions */ + +static u_char +ReadISAC(struct IsdnCardState *cs, u_char offset) +{ + return (readreg(cs->hw.saphir.ale, cs->hw.saphir.isac, offset)); +} + +static void +WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) +{ + writereg(cs->hw.saphir.ale, cs->hw.saphir.isac, offset, value); +} + +static void +ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size) +{ + readfifo(cs->hw.saphir.ale, cs->hw.saphir.isac, 0, data, size); +} + +static void +WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size) +{ + writefifo(cs->hw.saphir.ale, cs->hw.saphir.isac, 0, data, size); +} + +static u_char +ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) +{ + return (readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx, + offset + (hscx ? 0x40 : 0))); +} + +static void +WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) +{ + writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, + offset + (hscx ? 0x40 : 0), value); +} + +#define READHSCX(cs, nr, reg) readreg(cs->hw.saphir.ale, \ + cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0)) +#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.saphir.ale, \ + cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0), data) + +#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.saphir.ale, \ + cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt) + +#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.saphir.ale, \ + cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt) + +#include "hscx_irq.c" + +static void +saphir_interrupt(int intno, void *dev_id, struct pt_regs *regs) +{ + struct IsdnCardState *cs = dev_id; + u_char val; + + if (!cs) { + printk(KERN_WARNING "saphir: Spurious interrupt!\n"); + return; + } + val = readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_ISTA + 0x40); + Start_HSCX: + if (val) + hscx_int_main(cs, val); + val = readreg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_ISTA); + Start_ISAC: + if (val) + isac_interrupt(cs, val); + val = readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_ISTA + 0x40); + if (val) { + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "HSCX IntStat after IntRoutine"); + goto Start_HSCX; + } + val = readreg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_ISTA); + if (val) { + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "ISAC IntStat after IntRoutine"); + goto Start_ISAC; + } + /* Watchdog */ + if (cs->hw.saphir.timer.function) { + del_timer(&cs->hw.saphir.timer); + cs->hw.saphir.timer.expires = jiffies + 1*HZ; + add_timer(&cs->hw.saphir.timer); + } else + printk(KERN_WARNING "saphir: Spurious timer!\n"); + writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK, 0xFF); + writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK + 0x40, 0xFF); + writereg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_MASK, 0xFF); + writereg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_MASK, 0); + writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK, 0); + writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK + 0x40, 0); +} + +static void +SaphirWatchDog(struct IsdnCardState *cs) +{ + /* 5 sec WatchDog, so read at least every 4 sec */ + cs->readisac(cs, ISAC_RBCH); + del_timer(&cs->hw.saphir.timer); + cs->hw.saphir.timer.expires = jiffies + 1*HZ; + add_timer(&cs->hw.saphir.timer); +} + +void +release_io_saphir(struct IsdnCardState *cs) +{ + long flags; + + save_flags(flags); + cli(); + byteout(cs->hw.saphir.cfg_reg + IRQ_REG, 0xff); + del_timer(&cs->hw.saphir.timer); + cs->hw.saphir.timer.function = NULL; + restore_flags(flags); + if (cs->hw.saphir.cfg_reg) + release_region(cs->hw.saphir.cfg_reg, 6); +} + +static int +saphir_reset(struct IsdnCardState *cs) +{ + long flags; + u_char irq_val; + + switch(cs->irq) { + case 5: irq_val = 0; + break; + case 3: irq_val = 1; + break; + case 11: + irq_val = 2; + break; + case 12: + irq_val = 3; + break; + case 15: + irq_val = 4; + break; + default: + printk(KERN_WARNING "HiSax: saphir wrong IRQ %d\n", + cs->irq); + return (1); + } + byteout(cs->hw.saphir.cfg_reg + IRQ_REG, irq_val); + save_flags(flags); + sti(); + byteout(cs->hw.saphir.cfg_reg + RESET_REG, 1); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((30*HZ)/1000); /* Timeout 30ms */ + byteout(cs->hw.saphir.cfg_reg + RESET_REG, 0); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((30*HZ)/1000); /* Timeout 30ms */ + restore_flags(flags); + byteout(cs->hw.saphir.cfg_reg + IRQ_REG, irq_val); + byteout(cs->hw.saphir.cfg_reg + SPARE_REG, 0x02); + return (0); +} + +static int +saphir_card_msg(struct IsdnCardState *cs, int mt, void *arg) +{ + switch (mt) { + case CARD_RESET: + saphir_reset(cs); + return(0); + case CARD_RELEASE: + release_io_saphir(cs); + return(0); + case CARD_INIT: + inithscxisac(cs, 3); + return(0); + case CARD_TEST: + return(0); + } + return(0); +} + + +__initfunc(int +setup_saphir(struct IsdnCard *card)) +{ + struct IsdnCardState *cs = card->cs; + char tmp[64]; + + strcpy(tmp, saphir_rev); + printk(KERN_INFO "HiSax: HST Saphir driver Rev. %s\n", HiSax_getrev(tmp)); + if (cs->typ != ISDN_CTYPE_HSTSAPHIR) + return (0); + + /* IO-Ports */ + cs->hw.saphir.cfg_reg = card->para[1]; + cs->hw.saphir.isac = card->para[1] + ISAC_DATA; + cs->hw.saphir.hscx = card->para[1] + HSCX_DATA; + cs->hw.saphir.ale = card->para[1] + ADDRESS_REG; + cs->irq = card->para[0]; + if (check_region((cs->hw.saphir.cfg_reg), 6)) { + printk(KERN_WARNING + "HiSax: %s config port %x-%x already in use\n", + CardType[card->typ], + cs->hw.saphir.cfg_reg, + cs->hw.saphir.cfg_reg + 5); + return (0); + } else + request_region(cs->hw.saphir.cfg_reg,6, "saphir"); + + printk(KERN_INFO + "HiSax: %s config irq:%d io:0x%X\n", + CardType[cs->typ], cs->irq, + cs->hw.saphir.cfg_reg); + + cs->hw.saphir.timer.function = (void *) SaphirWatchDog; + cs->hw.saphir.timer.data = (long) cs; + init_timer(&cs->hw.saphir.timer); + cs->hw.saphir.timer.expires = jiffies + 4*HZ; + add_timer(&cs->hw.saphir.timer); + if (saphir_reset(cs)) { + release_io_saphir(cs); + return (0); + } + cs->readisac = &ReadISAC; + cs->writeisac = &WriteISAC; + cs->readisacfifo = &ReadISACfifo; + cs->writeisacfifo = &WriteISACfifo; + cs->BC_Read_Reg = &ReadHSCX; + cs->BC_Write_Reg = &WriteHSCX; + cs->BC_Send_Data = &hscx_fill_fifo; + cs->cardmsg = &saphir_card_msg; + cs->irq_func = &saphir_interrupt; + ISACVersion(cs, "saphir:"); + if (HscxVersion(cs, "saphir:")) { + printk(KERN_WARNING + "saphir: wrong HSCX versions check IO address\n"); + release_io_saphir(cs); + return (0); + } + return (1); +} diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/sedlbauer.c linux/drivers/isdn/hisax/sedlbauer.c --- v2.3.13/linux/drivers/isdn/hisax/sedlbauer.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/isdn/hisax/sedlbauer.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: sedlbauer.c,v 1.9 1998/11/15 23:55:20 keil Exp $ +/* $Id: sedlbauer.c,v 1.14 1999/08/11 20:59:22 keil Exp $ * sedlbauer.c low level stuff for Sedlbauer cards * includes support for the Sedlbauer speed star (speed star II), @@ -17,6 +17,23 @@ * Edgar Toernig * * $Log: sedlbauer.c,v $ + * Revision 1.14 1999/08/11 20:59:22 keil + * new PCI codefix + * fix IRQ problem while unload + * + * Revision 1.13 1999/08/10 16:02:08 calle + * struct pci_dev changed in 2.3.13. Made the necessary changes. + * + * Revision 1.12 1999/08/05 20:43:22 keil + * ISAR analog modem support + * + * Revision 1.11 1999/07/12 21:05:27 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 1.10 1999/07/01 08:12:09 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.9 1998/11/15 23:55:20 keil * changes from 2.0 * @@ -76,10 +93,13 @@ #include "isar.h" #include "isdnl1.h" #include +#ifndef COMPAT_HAS_NEW_PCI +#include +#endif extern const char *CardType[]; -const char *Sedlbauer_revision = "$Revision: 1.9 $"; +const char *Sedlbauer_revision = "$Revision: 1.14 $"; const char *Sedlbauer_Types[] = {"None", "speed card/win", "speed star", "speed fax+", @@ -291,7 +311,7 @@ sedlbauer_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; - u_char val, stat = 0; + u_char val; if (!cs) { printk(KERN_WARNING "Sedlbauer: Spurious interrupt!\n"); @@ -307,16 +327,12 @@ val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_ISTA + 0x40); Start_HSCX: - if (val) { + if (val) hscx_int_main(cs, val); - stat |= 1; - } val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA); Start_ISAC: - if (val) { + if (val) isac_interrupt(cs, val); - stat |= 2; - } val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_ISTA + 0x40); if (val) { if (cs->debug & L1_DEB_HSCX) @@ -329,23 +345,19 @@ debugl1(cs, "ISAC IntStat after IntRoutine"); goto Start_ISAC; } - if (stat & 1) { - writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK, 0xFF); - writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK + 0x40, 0xFF); - writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK, 0x0); - writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK + 0x40, 0x0); - } - if (stat & 2) { - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0x0); - } + writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK, 0xFF); + writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK + 0x40, 0xFF); + writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0xFF); + writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_MASK, 0x0); + writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK, 0x0); + writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_MASK + 0x40, 0x0); } static void sedlbauer_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; - u_char ista, val, icnt = 20; + u_char ista, val, icnt = 5; if (!cs) { printk(KERN_WARNING "Sedlbauer: Spurious interrupt!\n"); @@ -392,7 +404,7 @@ { struct IsdnCardState *cs = dev_id; u_char val; - int cnt = 20; + int cnt = 5; if (!cs) { printk(KERN_WARNING "Sedlbauer: Spurious interrupt!\n"); @@ -431,9 +443,11 @@ void release_io_sedlbauer(struct IsdnCardState *cs) { - int bytecnt = (cs->subtyp == SEDL_SPEED_FAX) ? 16 : 8; + int bytecnt = 8; - if (cs->hw.sedl.bus == SEDL_BUS_PCI) { + if (cs->subtyp == SEDL_SPEED_FAX) { + bytecnt = 16; + } else if (cs->hw.sedl.bus == SEDL_BUS_PCI) { bytecnt = 256; } if (cs->hw.sedl.cfg_reg) @@ -454,10 +468,10 @@ save_flags(flags); sti(); current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout((10*HZ)/1000); writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_POTA2, 0x0); current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout((10*HZ)/1000); writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_CONF, 0x0); writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ACFG, 0xff); writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_AOE, 0x0); @@ -469,10 +483,10 @@ save_flags(flags); sti(); current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout((10*HZ)/1000); byteout(cs->hw.sedl.reset_off, 0); /* Reset Off */ current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout((10*HZ)/1000); restore_flags(flags); } } @@ -486,19 +500,19 @@ reset_sedlbauer(cs); return(0); case CARD_RELEASE: - release_io_sedlbauer(cs); - return(0); - case CARD_SETIRQ: if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) { - return(request_irq(cs->irq, &sedlbauer_interrupt_isar, - I4L_IRQ_FLAG, "HiSax", cs)); - } else if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) { - return(request_irq(cs->irq, &sedlbauer_interrupt_ipac, - I4L_IRQ_FLAG, "HiSax", cs)); - } else { - return(request_irq(cs->irq, &sedlbauer_interrupt, - I4L_IRQ_FLAG, "HiSax", cs)); + writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, + ISAR_IRQBIT, 0); + writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, + ISAC_MASK, 0xFF); + reset_sedlbauer(cs); + writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx, + ISAR_IRQBIT, 0); + writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, + ISAC_MASK, 0xFF); } + release_io_sedlbauer(cs); + return(0); case CARD_INIT: if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) { clear_pending_isac_ints(cs); @@ -530,11 +544,15 @@ #ifdef SEDLBAUER_PCI +#ifdef COMPAT_HAS_NEW_PCI +static struct pci_dev *dev_sedl __initdata = NULL; +#else static int pci_index __initdata = 0; #endif +#endif -int __init -setup_sedlbauer(struct IsdnCard *card) +__initfunc(int +setup_sedlbauer(struct IsdnCard *card)) { int bytecnt, ver, val; struct IsdnCardState *cs = card->cs; @@ -569,6 +587,25 @@ /* Probe for Sedlbauer speed pci */ #if SEDLBAUER_PCI #if CONFIG_PCI +#ifdef COMPAT_HAS_NEW_PCI + if (!pci_present()) { + printk(KERN_ERR "FritzPCI: no PCI bus present\n"); + return(0); + } + if ((dev_sedl = pci_find_device(PCI_VENDOR_SEDLBAUER, + PCI_SPEEDPCI_ID, dev_sedl))) { + cs->irq = dev_sedl->irq; + if (!cs->irq) { + printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n"); + return(0); + } + cs->hw.sedl.cfg_reg = get_pcibase(dev_sedl, 0) & + PCI_BASE_ADDRESS_IO_MASK; + } else { + printk(KERN_WARNING "Sedlbauer: No PCI card found\n"); + return(0); + } +#else for (; pci_index < 255; pci_index++) { unsigned char pci_bus, pci_device_fn; unsigned int ioaddr; @@ -589,14 +626,6 @@ printk(KERN_WARNING "Sedlbauer: No IO-Adr for PCI card found\n"); return(0); } - cs->hw.sedl.bus = SEDL_BUS_PCI; - cs->hw.sedl.chip = SEDL_CHIP_IPAC; - cs->subtyp = SEDL_SPEED_PCI; - bytecnt = 256; - byteout(cs->hw.sedl.cfg_reg, 0xff); - byteout(cs->hw.sedl.cfg_reg, 0x00); - byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd); - byteout(cs->hw.sedl.cfg_reg+ 5, 0x02); break; } if (pci_index == 255) { @@ -604,6 +633,16 @@ return(0); } pci_index++; +#endif /* COMPAT_HAS_NEW_PCI */ + cs->irq_flags |= SA_SHIRQ; + cs->hw.sedl.bus = SEDL_BUS_PCI; + cs->hw.sedl.chip = SEDL_CHIP_IPAC; + cs->subtyp = SEDL_SPEED_PCI; + bytecnt = 256; + byteout(cs->hw.sedl.cfg_reg, 0xff); + byteout(cs->hw.sedl.cfg_reg, 0x00); + byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd); + byteout(cs->hw.sedl.cfg_reg+ 5, 0x02); #else printk(KERN_WARNING "Sedlbauer: NO_PCI_BIOS\n"); return (0); @@ -683,6 +722,7 @@ cs->writeisac = &WriteISAC_IPAC; cs->readisacfifo = &ReadISACfifo_IPAC; cs->writeisacfifo = &WriteISACfifo_IPAC; + cs->irq_func = &sedlbauer_interrupt_ipac; val = readreg(cs->hw.sedl.adr,cs->hw.sedl.isac, IPAC_ID); printk(KERN_INFO "Sedlbauer: IPAC version %x\n", val); @@ -702,6 +742,7 @@ cs->bcs[0].hw.isar.reg = &cs->hw.sedl.isar; cs->bcs[1].hw.isar.reg = &cs->hw.sedl.isar; test_and_set_bit(HW_ISAR, &cs->HW_Flags); + cs->irq_func = &sedlbauer_interrupt_isar; ISACVersion(cs, "Sedlbauer:"); @@ -729,6 +770,7 @@ cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_ON; cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_OFF; } + cs->irq_func = &sedlbauer_interrupt; ISACVersion(cs, "Sedlbauer:"); if (HscxVersion(cs, "Sedlbauer:")) { diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/sportster.c linux/drivers/isdn/hisax/sportster.c --- v2.3.13/linux/drivers/isdn/hisax/sportster.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/isdn/hisax/sportster.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: sportster.c,v 1.7 1998/11/15 23:55:22 keil Exp $ +/* $Id: sportster.c,v 1.9 1999/07/12 21:05:29 keil Exp $ * sportster.c low level stuff for USR Sportster internal TA * @@ -7,6 +7,13 @@ * Thanks to Christian "naddy" Weisgerber (3Com, US Robotics) for documentation * * $Log: sportster.c,v $ + * Revision 1.9 1999/07/12 21:05:29 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 1.8 1999/07/01 08:12:10 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.7 1998/11/15 23:55:22 keil * changes from 2.0 * @@ -36,7 +43,7 @@ #include "isdnl1.h" extern const char *CardType[]; -const char *sportster_revision = "$Revision: 1.7 $"; +const char *sportster_revision = "$Revision: 1.9 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -171,11 +178,11 @@ save_flags(flags); sti(); current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout((10*HZ)/1000); cs->hw.spt.res_irq &= ~SPORTSTER_RESET; /* Reset Off */ byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq); current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout((10*HZ)/1000); restore_flags(flags); } @@ -189,9 +196,6 @@ case CARD_RELEASE: release_io_sportster(cs); return(0); - case CARD_SETIRQ: - return(request_irq(cs->irq, &sportster_interrupt, - I4L_IRQ_FLAG, "HiSax", cs)); case CARD_INIT: inithscxisac(cs, 1); cs->hw.spt.res_irq |= SPORTSTER_INTE; /* IRQ On */ @@ -204,8 +208,8 @@ return(0); } -int __init -get_io_range(struct IsdnCardState *cs) +__initfunc(int +get_io_range(struct IsdnCardState *cs)) { int i, j, adr; @@ -230,8 +234,8 @@ } } -int __init -setup_sportster(struct IsdnCard *card) +__initfunc(int +setup_sportster(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; @@ -282,6 +286,7 @@ cs->BC_Write_Reg = &WriteHSCX; cs->BC_Send_Data = &hscx_fill_fifo; cs->cardmsg = &Sportster_card_msg; + cs->irq_func = &sportster_interrupt; ISACVersion(cs, "Sportster:"); if (HscxVersion(cs, "Sportster:")) { printk(KERN_WARNING diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/tei.c linux/drivers/isdn/hisax/tei.c --- v2.3.13/linux/drivers/isdn/hisax/tei.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/hisax/tei.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: tei.c,v 2.11 1998/11/15 23:55:24 keil Exp $ +/* $Id: tei.c,v 2.13 1999/07/21 14:46:28 keil Exp $ * Author Karsten Keil (keil@isdn4linux.de) * based on the teles driver from Jan den Ouden @@ -11,6 +11,12 @@ * Fritz Elfert * * $Log: tei.c,v $ + * Revision 2.13 1999/07/21 14:46:28 keil + * changes from EICON certification + * + * Revision 2.12 1999/07/01 08:12:11 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 2.11 1998/11/15 23:55:24 keil * changes from 2.0 * @@ -72,7 +78,7 @@ #include "isdnl2.h" #include -const char *tei_revision = "$Revision: 2.11 $"; +const char *tei_revision = "$Revision: 2.13 $"; #define ID_REQUEST 1 #define ID_ASSIGNED 2 @@ -163,6 +169,7 @@ printk(KERN_WARNING "HiSax: No skb for TEI manager\n"); return; } + SET_SKB_FREE(skb); bp = skb_put(skb, 3); bp[0] = (TEI_SAPI << 2); bp[1] = (GROUP_TEI << 1) | 0x1; @@ -226,6 +233,25 @@ } static void +tei_id_test_dup(struct FsmInst *fi, int event, void *arg) +{ + struct PStack *ost, *st = fi->userdata; + struct sk_buff *skb = arg; + int tei, ri; + + ri = ((unsigned int) skb->data[1] << 8) + skb->data[2]; + tei = skb->data[4] >> 1; + if (st->ma.debug) + st->ma.tei_m.printdebug(&st->ma.tei_m, + "foreign identity assign ri %d tei %d", ri, tei); + if ((ost = findtei(st, tei))) { /* same tei is in use */ + st->ma.tei_m.printdebug(&st->ma.tei_m, + "possible duplicate assignment tei %d", tei); + FsmEvent(&ost->ma.tei_m, EV_VERIFY, NULL); + } +} + +static void tei_id_denied(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; @@ -345,7 +371,7 @@ int mt; if (test_bit(FLG_FIXED_TEI, &st->l2.flag)) { - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); return; } @@ -353,8 +379,8 @@ if (skb->len < 3) { st->ma.tei_m.printdebug(&st->ma.tei_m, "short mgr frame %ld/3", skb->len); - } else if (((skb->data[0] >> 2) != TEI_SAPI) || - ((skb->data[1] >> 1) != GROUP_TEI)) { + } else if ((skb->data[0] != ((TEI_SAPI << 2) | 2)) || + (skb->data[1] != ((GROUP_TEI << 1) | 1))) { st->ma.tei_m.printdebug(&st->ma.tei_m, "wrong mgr sapi/tei %x/%x", skb->data[0], skb->data[1]); @@ -391,7 +417,7 @@ st->ma.tei_m.printdebug(&st->ma.tei_m, "tei handler wrong pr %x\n", pr); } - dev_kfree_skb(skb); + idev_kfree_skb(skb, FREE_READ); } static void @@ -468,6 +494,7 @@ static struct FsmNode TeiFnList[] HISAX_INITDATA = { {ST_TEI_NOP, EV_IDREQ, tei_id_request}, + {ST_TEI_NOP, EV_ASSIGN, tei_id_test_dup}, {ST_TEI_NOP, EV_VERIFY, tei_id_verify}, {ST_TEI_NOP, EV_REMOVE, tei_id_remove}, {ST_TEI_NOP, EV_CHKREQ, tei_id_chk_req}, diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/teleint.c linux/drivers/isdn/hisax/teleint.c --- v2.3.13/linux/drivers/isdn/hisax/teleint.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/isdn/hisax/teleint.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: teleint.c,v 1.7 1998/11/15 23:55:26 keil Exp $ +/* $Id: teleint.c,v 1.9 1999/07/12 21:05:30 keil Exp $ * teleint.c low level stuff for TeleInt isdn cards * @@ -6,6 +6,13 @@ * * * $Log: teleint.c,v $ + * Revision 1.9 1999/07/12 21:05:30 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 1.8 1999/07/01 08:12:12 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 1.7 1998/11/15 23:55:26 keil * changes from 2.0 * @@ -38,7 +45,7 @@ extern const char *CardType[]; -const char *TeleInt_revision = "$Revision: 1.7 $"; +const char *TeleInt_revision = "$Revision: 1.9 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -191,7 +198,7 @@ TeleInt_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; - u_char val, stat = 0; + u_char val; if (!cs) { printk(KERN_WARNING "TeleInt: Spurious interrupt!\n"); @@ -199,20 +206,16 @@ } val = readreg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, ISAC_ISTA); Start_ISAC: - if (val) { + if (val) isac_interrupt(cs, val); - stat |= 2; - } val = readreg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, ISAC_ISTA); if (val) { if (cs->debug & L1_DEB_ISAC) debugl1(cs, "ISAC IntStat after IntRoutine"); goto Start_ISAC; } - if (stat & 2) { - writereg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, ISAC_MASK, 0xFF); - writereg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, ISAC_MASK, 0x0); - } + writereg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, ISAC_MASK, 0xFF); + writereg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, ISAC_MASK, 0x0); } static void @@ -252,11 +255,11 @@ save_flags(flags); sti(); current->state = TASK_INTERRUPTIBLE; - schedule_timeout(3); + schedule_timeout((30*HZ)/1000); cs->hw.hfc.cirm &= ~HFC_RESET; byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm); /* Reset Off */ current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout((10*HZ)/1000); restore_flags(flags); } @@ -270,9 +273,6 @@ case CARD_RELEASE: release_io_TeleInt(cs); return(0); - case CARD_SETIRQ: - return(request_irq(cs->irq, &TeleInt_interrupt, - I4L_IRQ_FLAG, "HiSax", cs)); case CARD_INIT: inithfc(cs); clear_pending_isac_ints(cs); @@ -289,8 +289,8 @@ return(0); } -int __init -setup_TeleInt(struct IsdnCard *card) +__initfunc(int +setup_TeleInt(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; @@ -365,6 +365,7 @@ cs->BC_Read_Reg = &ReadHFC; cs->BC_Write_Reg = &WriteHFC; cs->cardmsg = &TeleInt_card_msg; + cs->irq_func = &TeleInt_interrupt; ISACVersion(cs, "TeleInt:"); return (1); } diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/teles0.c linux/drivers/isdn/hisax/teles0.c --- v2.3.13/linux/drivers/isdn/hisax/teles0.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/isdn/hisax/teles0.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: teles0.c,v 2.8 1998/04/15 16:44:28 keil Exp $ +/* $Id: teles0.c,v 2.9 1999/07/12 21:05:31 keil Exp $ * teles0.c low level stuff for Teles Memory IO isdn cards * based on the teles driver from Jan den Ouden @@ -10,6 +10,10 @@ * Beat Doebeli * * $Log: teles0.c,v $ + * Revision 2.9 1999/07/12 21:05:31 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * * Revision 2.8 1998/04/15 16:44:28 keil * new init code * @@ -54,7 +58,7 @@ extern const char *CardType[]; -const char *teles0_revision = "$Revision: 2.8 $"; +const char *teles0_revision = "$Revision: 2.9 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -177,7 +181,7 @@ teles0_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; - u_char val, stat = 0; + u_char val; int count = 0; if (!cs) { @@ -186,39 +190,31 @@ } val = readhscx(cs->hw.teles0.membase, 1, HSCX_ISTA); Start_HSCX: - if (val) { + if (val) hscx_int_main(cs, val); - stat |= 1; - } val = readisac(cs->hw.teles0.membase, ISAC_ISTA); Start_ISAC: - if (val) { + if (val) isac_interrupt(cs, val); - stat |= 2; - } count++; val = readhscx(cs->hw.teles0.membase, 1, HSCX_ISTA); - if (val && count < 20) { + if (val && count < 5) { if (cs->debug & L1_DEB_HSCX) debugl1(cs, "HSCX IntStat after IntRoutine"); goto Start_HSCX; } val = readisac(cs->hw.teles0.membase, ISAC_ISTA); - if (val && count < 20) { + if (val && count < 5) { if (cs->debug & L1_DEB_ISAC) debugl1(cs, "ISAC IntStat after IntRoutine"); goto Start_ISAC; } - if (stat & 1) { - writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0xFF); - writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0xFF); - writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0x0); - writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0x0); - } - if (stat & 2) { - writeisac(cs->hw.teles0.membase, ISAC_MASK, 0xFF); - writeisac(cs->hw.teles0.membase, ISAC_MASK, 0x0); - } + writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0xFF); + writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0xFF); + writeisac(cs->hw.teles0.membase, ISAC_MASK, 0xFF); + writeisac(cs->hw.teles0.membase, ISAC_MASK, 0x0); + writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0x0); + writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0x0); } void @@ -290,9 +286,6 @@ case CARD_RELEASE: release_io_teles0(cs); return(0); - case CARD_SETIRQ: - return(request_irq(cs->irq, &teles0_interrupt, - I4L_IRQ_FLAG, "HiSax", cs)); case CARD_INIT: inithscxisac(cs, 3); return(0); @@ -302,8 +295,8 @@ return(0); } -int __init -setup_teles0(struct IsdnCard *card) +__initfunc(int +setup_teles0(struct IsdnCard *card)) { u_char val; struct IsdnCardState *cs = card->cs; @@ -382,6 +375,7 @@ cs->BC_Write_Reg = &WriteHSCX; cs->BC_Send_Data = &hscx_fill_fifo; cs->cardmsg = &Teles_card_msg; + cs->irq_func = &teles0_interrupt; ISACVersion(cs, "Teles0:"); if (HscxVersion(cs, "Teles0:")) { printk(KERN_WARNING diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/teles3.c linux/drivers/isdn/hisax/teles3.c --- v2.3.13/linux/drivers/isdn/hisax/teles3.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/isdn/hisax/teles3.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: teles3.c,v 2.10 1999/02/15 14:37:15 cpetig Exp $ +/* $Id: teles3.c,v 2.12 1999/07/12 21:05:32 keil Exp $ * teles3.c low level stuff for Teles 16.3 & PNP isdn cards * @@ -11,6 +11,13 @@ * Beat Doebeli * * $Log: teles3.c,v $ + * Revision 2.12 1999/07/12 21:05:32 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 2.11 1999/07/01 08:12:14 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 2.10 1999/02/15 14:37:15 cpetig * oops, missed something in last commit * @@ -78,7 +85,7 @@ #include "isdnl1.h" extern const char *CardType[]; -const char *teles3_revision = "$Revision: 2.10 $"; +const char *teles3_revision = "$Revision: 2.12 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -160,9 +167,9 @@ static void teles3_interrupt(int intno, void *dev_id, struct pt_regs *regs) { -#define MAXCOUNT 20 +#define MAXCOUNT 5 struct IsdnCardState *cs = dev_id; - u_char val, stat = 0; + u_char val; int count = 0; if (!cs) { @@ -171,16 +178,12 @@ } val = readreg(cs->hw.teles3.hscx[1], HSCX_ISTA); Start_HSCX: - if (val) { + if (val) hscx_int_main(cs, val); - stat |= 1; - } val = readreg(cs->hw.teles3.isac, ISAC_ISTA); Start_ISAC: - if (val) { + if (val) isac_interrupt(cs, val); - stat |= 2; - } count++; val = readreg(cs->hw.teles3.hscx[1], HSCX_ISTA); if (val && count < MAXCOUNT) { @@ -196,16 +199,12 @@ } if (count >= MAXCOUNT) printk(KERN_WARNING "Teles3: more than %d loops in teles3_interrupt\n", count); - if (stat & 1) { - writereg(cs->hw.teles3.hscx[0], HSCX_MASK, 0xFF); - writereg(cs->hw.teles3.hscx[1], HSCX_MASK, 0xFF); - writereg(cs->hw.teles3.hscx[0], HSCX_MASK, 0x0); - writereg(cs->hw.teles3.hscx[1], HSCX_MASK, 0x0); - } - if (stat & 2) { - writereg(cs->hw.teles3.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.teles3.isac, ISAC_MASK, 0x0); - } + writereg(cs->hw.teles3.hscx[0], HSCX_MASK, 0xFF); + writereg(cs->hw.teles3.hscx[1], HSCX_MASK, 0xFF); + writereg(cs->hw.teles3.isac, ISAC_MASK, 0xFF); + writereg(cs->hw.teles3.isac, ISAC_MASK, 0x0); + writereg(cs->hw.teles3.hscx[0], HSCX_MASK, 0x0); + writereg(cs->hw.teles3.hscx[1], HSCX_MASK, 0x0); } inline static void @@ -222,15 +221,16 @@ void release_io_teles3(struct IsdnCardState *cs) { - if (cs->typ == ISDN_CTYPE_TELESPCMCIA) + if (cs->typ == ISDN_CTYPE_TELESPCMCIA) { release_region(cs->hw.teles3.hscx[0], 97); - else { - if (cs->hw.teles3.cfg_reg) + } else { + if (cs->hw.teles3.cfg_reg) { if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { release_region(cs->hw.teles3.cfg_reg, 1); } else { release_region(cs->hw.teles3.cfg_reg, 8); } + } release_ioregs(cs, 0x7); } } @@ -309,9 +309,6 @@ case CARD_RELEASE: release_io_teles3(cs); return(0); - case CARD_SETIRQ: - return(request_irq(cs->irq, &teles3_interrupt, - I4L_IRQ_FLAG, "HiSax", cs)); case CARD_INIT: inithscxisac(cs, 3); return(0); @@ -321,8 +318,8 @@ return(0); } -int __init -setup_teles3(struct IsdnCard *card) +__initfunc(int +setup_teles3(struct IsdnCard *card)) { u_char val; struct IsdnCardState *cs = card->cs; @@ -405,12 +402,13 @@ CardType[cs->typ], cs->hw.teles3.isac + 32, cs->hw.teles3.isac + 64); - if (cs->hw.teles3.cfg_reg) + if (cs->hw.teles3.cfg_reg) { if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { release_region(cs->hw.teles3.cfg_reg, 1); } else { release_region(cs->hw.teles3.cfg_reg, 8); } + } return (0); } else request_region(cs->hw.teles3.isac + 32, 32, "HiSax isac"); @@ -420,12 +418,13 @@ CardType[cs->typ], cs->hw.teles3.hscx[0] + 32, cs->hw.teles3.hscx[0] + 64); - if (cs->hw.teles3.cfg_reg) + if (cs->hw.teles3.cfg_reg) { if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { release_region(cs->hw.teles3.cfg_reg, 1); } else { release_region(cs->hw.teles3.cfg_reg, 8); } + } release_ioregs(cs, 1); return (0); } else @@ -436,12 +435,13 @@ CardType[cs->typ], cs->hw.teles3.hscx[1] + 32, cs->hw.teles3.hscx[1] + 64); - if (cs->hw.teles3.cfg_reg) + if (cs->hw.teles3.cfg_reg) { if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { release_region(cs->hw.teles3.cfg_reg, 1); } else { release_region(cs->hw.teles3.cfg_reg, 8); } + } release_ioregs(cs, 3); return (0); } else @@ -494,6 +494,7 @@ cs->BC_Write_Reg = &WriteHSCX; cs->BC_Send_Data = &hscx_fill_fifo; cs->cardmsg = &Teles_card_msg; + cs->irq_func = &teles3_interrupt; ISACVersion(cs, "Teles3:"); if (HscxVersion(cs, "Teles3:")) { printk(KERN_WARNING diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/telespci.c linux/drivers/isdn/hisax/telespci.c --- v2.3.13/linux/drivers/isdn/hisax/telespci.c Tue Jun 1 23:25:48 1999 +++ linux/drivers/isdn/hisax/telespci.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: telespci.c,v 2.5 1998/11/15 23:55:28 keil Exp $ +/* $Id: telespci.c,v 2.9 1999/08/11 21:01:34 keil Exp $ * telespci.c low level stuff for Teles PCI isdn cards * @@ -7,6 +7,19 @@ * * * $Log: telespci.c,v $ + * Revision 2.9 1999/08/11 21:01:34 keil + * new PCI codefix + * + * Revision 2.8 1999/08/10 16:02:10 calle + * struct pci_dev changed in 2.3.13. Made the necessary changes. + * + * Revision 2.7 1999/07/12 21:05:34 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 2.6 1999/07/01 08:12:15 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 2.5 1998/11/15 23:55:28 keil * changes from 2.0 * @@ -24,16 +37,17 @@ */ #define __NO_VERSION__ #include -#include #include "hisax.h" #include "isac.h" #include "hscx.h" #include "isdnl1.h" #include +#ifndef COMPAT_HAS_NEW_PCI +#include +#endif extern const char *CardType[]; - -const char *telespci_revision = "$Revision: 2.5 $"; +const char *telespci_revision = "$Revision: 2.9 $"; #define ZORAN_PO_RQ_PEN 0x02000000 #define ZORAN_PO_WR 0x00800000 @@ -243,35 +257,27 @@ { #define MAXCOUNT 20 struct IsdnCardState *cs = dev_id; - u_char val, stat = 0; + u_char val; if (!cs) { printk(KERN_WARNING "TelesPCI: Spurious interrupt!\n"); return; } val = readhscx(cs->hw.teles0.membase, 1, HSCX_ISTA); - if (val) { + if (val) hscx_int_main(cs, val); - stat |= 1; - } val = readisac(cs->hw.teles0.membase, ISAC_ISTA); - if (val) { + if (val) isac_interrupt(cs, val); - stat |= 2; - } /* Clear interrupt register for Zoran PCI controller */ writel(0x70000000, cs->hw.teles0.membase + 0x3C); - if (stat & 1) { - writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0xFF); - writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0xFF); - writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0x0); - writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0x0); - } - if (stat & 2) { - writeisac(cs->hw.teles0.membase, ISAC_MASK, 0xFF); - writeisac(cs->hw.teles0.membase, ISAC_MASK, 0x0); - } + writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0xFF); + writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0xFF); + writeisac(cs->hw.teles0.membase, ISAC_MASK, 0xFF); + writeisac(cs->hw.teles0.membase, ISAC_MASK, 0x0); + writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0x0); + writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0x0); } void @@ -289,9 +295,6 @@ case CARD_RELEASE: release_io_telespci(cs); return(0); - case CARD_SETIRQ: - return(request_irq(cs->irq, &telespci_interrupt, - I4L_IRQ_FLAG | SA_SHIRQ, "HiSax", cs)); case CARD_INIT: inithscxisac(cs, 3); return(0); @@ -301,20 +304,29 @@ return(0); } +#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *dev_tel __initdata = NULL; +#else +static int pci_index __initdata = 0; +#endif __initfunc(int setup_telespci(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; +#ifndef COMPAT_HAS_NEW_PCI + u_char pci_bus, pci_device_fn, pci_irq; + u_int pci_memaddr; + u_char found = 0; +#endif strcpy(tmp, telespci_revision); printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", HiSax_getrev(tmp)); if (cs->typ != ISDN_CTYPE_TELESPCI) return (0); - #if CONFIG_PCI +#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_ERR "TelesPCI: no PCI bus present\n"); return(0); @@ -325,15 +337,41 @@ printk(KERN_WARNING "Teles: No IRQ for PCI card found\n"); return(0); } - cs->hw.teles0.membase = (u_int) ioremap(dev_tel->base_address[0], + cs->hw.teles0.membase = (u_int) ioremap(get_pcibase(dev_tel, 0), PAGE_SIZE); printk(KERN_INFO "Found: Zoran, base-address: 0x%lx, irq: 0x%x\n", - dev_tel->base_address[0], dev_tel->irq); + get_pcibase(dev_tel, 0), dev_tel->irq); } else { printk(KERN_WARNING "TelesPCI: No PCI card found\n"); return(0); } #else + for (; pci_index < 0xff; pci_index++) { + if (pcibios_find_device (0x11DE, 0x6120, + pci_index, &pci_bus, &pci_device_fn) + == PCIBIOS_SUCCESSFUL) { + found = 1; + } else { + break; + } + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_0, &pci_memaddr); + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_INTERRUPT_LINE, &pci_irq); + + printk(KERN_INFO "Found: Zoran, base-address: 0x%x," + " irq: 0x%x\n", pci_memaddr, pci_irq); + break; + } + if (!found) { + printk(KERN_WARNING "TelesPCI: No PCI card found\n"); + return(0); + } + pci_index++; + cs->irq = pci_irq; + cs->hw.teles0.membase = (u_int) vremap(pci_memaddr, PAGE_SIZE); +#endif /* COMPAT_HAS_NEW_PCI */ +#else printk(KERN_WARNING "HiSax: Teles/PCI and NO_PCI_BIOS\n"); printk(KERN_WARNING "HiSax: Teles/PCI unable to config\n"); return (0); @@ -361,6 +399,8 @@ cs->BC_Write_Reg = &WriteHSCX; cs->BC_Send_Data = &hscx_fill_fifo; cs->cardmsg = &TelesPCI_card_msg; + cs->irq_func = &telespci_interrupt; + cs->irq_flags |= SA_SHIRQ; ISACVersion(cs, "TelesPCI:"); if (HscxVersion(cs, "TelesPCI:")) { printk(KERN_WARNING diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/icn/icn.c linux/drivers/isdn/icn/icn.c --- v2.3.13/linux/drivers/isdn/icn/icn.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/icn/icn.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: icn.c,v 1.56 1999/04/12 13:15:07 fritz Exp $ +/* $Id: icn.c,v 1.57 1999/07/06 16:15:30 detabc Exp $ * ISDN low-level module for the ICN active ISDN-Card. * @@ -19,6 +19,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: icn.c,v $ + * Revision 1.57 1999/07/06 16:15:30 detabc + * remove unused messages + * * Revision 1.56 1999/04/12 13:15:07 fritz * Fixed a cast. * @@ -39,10 +42,6 @@ * Revision 1.51 1998/03/07 22:29:55 fritz * Adapted Detlef's chenges for 2.1. * - * Revision 1.50 1998/03/07 17:41:54 detabc - * add d-channel connect and disconnect support statcallback - * from icn low-level to link->level - * * Revision 1.49 1998/02/13 11:14:15 keil * change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb() * @@ -233,7 +232,7 @@ #undef MAP_DEBUG static char -*revision = "$Revision: 1.56 $"; +*revision = "$Revision: 1.57 $"; static int icn_addcard(int, char *, char *); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/isdn_audio.c linux/drivers/isdn/isdn_audio.c --- v2.3.13/linux/drivers/isdn/isdn_audio.c Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/isdn_audio.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_audio.c,v 1.13 1999/04/12 12:33:09 fritz Exp $ +/* $Id: isdn_audio.c,v 1.16 1999/08/06 12:47:35 calle Exp $ * Linux ISDN subsystem, audio conversion and compression (linklevel). * @@ -21,6 +21,27 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_audio.c,v $ + * Revision 1.16 1999/08/06 12:47:35 calle + * Using __GNUC__ == 2 && __GNUC_MINOR__ < 95 how to define + * ISDN_AUDIO_OPTIMIZE_ON_X386_WITH_ASM_IF_GCC_ALLOW_IT + * + * Revision 1.15 1999/08/06 12:02:52 calle + * egcs 2.95 complain about invalid asm statement: + * "fixed or forbidden register 2 (cx) was spilled for class CREG." + * Using ISDN_AUDIO_OPTIMIZE_ON_X386_WITH_ASM_IF_GCC_ALLOW_IT and not + * define it at the moment. + * + * Revision 1.14 1999/07/11 17:14:06 armin + * Added new layer 2 and 3 protocols for Fax and DSP functions. + * Moved "Add CPN to RING message" to new register S23, + * "Display message" is now correct on register S13 bit 7. + * New audio command AT+VDD implemented (deactivate DTMF decoder and + * activate possible existing hardware/DSP decoder). + * Moved some tty defines to .h file. + * Made whitespace possible in AT command line. + * Some AT-emulator output bugfixes. + * First Fax G3 implementations. + * * Revision 1.13 1999/04/12 12:33:09 fritz * Changes from 2.0 tree. * @@ -71,7 +92,7 @@ #include "isdn_audio.h" #include "isdn_common.h" -char *isdn_audio_revision = "$Revision: 1.13 $"; +char *isdn_audio_revision = "$Revision: 1.16 $"; /* * Misc. lookup-tables. @@ -268,7 +289,18 @@ {'*', '0', '#', 'D'} }; -#if ((CPU == 386) || (CPU == 486) || (CPU == 586)) + +/* + * egcs 2.95 complain about invalid asm statement: + * "fixed or forbidden register 2 (cx) was spilled for class CREG." + */ +#if ((CPU == 386) || (CPU == 486) || (CPU == 586)) || defined(__GNUC__) +#if __GNUC__ == 2 && __GNUC_MINOR__ < 95 +#define ISDN_AUDIO_OPTIMIZE_ON_X386_WITH_ASM_IF_GCC_ALLOW_IT +#endif +#endif + +#ifdef ISDN_AUDIO_OPTIMIZE_ON_X386_WITH_ASM_IF_GCC_ALLOW_IT static inline void isdn_audio_tlookup(const void *table, void *buff, unsigned long n) { @@ -711,16 +743,51 @@ } void -isdn_audio_eval_silence(modem_info * info) +isdn_audio_put_dle_code(modem_info * info, u_char code) { - silence_state *s = info->silence_state; struct sk_buff *skb; unsigned long flags; int di; int ch; - char what; char *p; + skb = dev_alloc_skb(2); + if (!skb) { + printk(KERN_WARNING + "isdn_audio: Could not alloc skb for ttyI%d\n", + info->line); + return; + } + p = (char *) skb_put(skb, 2); + p[0] = 0x10; + p[1] = code; + if (skb_headroom(skb) < sizeof(isdn_audio_skb)) { + printk(KERN_WARNING + "isdn_audio: insufficient skb_headroom, dropping\n"); + kfree_skb(skb); + return; + } + ISDN_AUDIO_SKB_DLECOUNT(skb) = 0; + ISDN_AUDIO_SKB_LOCK(skb) = 0; + save_flags(flags); + cli(); + di = info->isdn_driver; + ch = info->isdn_channel; + __skb_queue_tail(&dev->drv[di]->rpqueue[ch], skb); + dev->drv[di]->rcvcount[ch] += 2; + restore_flags(flags); + /* Schedule dequeuing */ + if ((dev->modempoll) && (info->rcvsched)) + isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); + wake_up_interruptible(&dev->drv[di]->rcv_waitq[ch]); +} + +void +isdn_audio_eval_silence(modem_info * info) +{ + silence_state *s = info->silence_state; + char what; + what = ' '; if (s->idx > (info->emu.vpar[2] * 800)) { @@ -734,28 +801,6 @@ if ((what == 's') || (what == 'q')) { printk(KERN_DEBUG "ttyI%d: %s\n", info->line, (what=='s') ? "silence":"quiet"); - skb = dev_alloc_skb(2); - p = (char *) skb_put(skb, 2); - p[0] = 0x10; - p[1] = what; - if (skb_headroom(skb) < sizeof(isdn_audio_skb)) { - printk(KERN_WARNING - "isdn_audio: insufficient skb_headroom, dropping\n"); - kfree_skb(skb); - return; - } - ISDN_AUDIO_SKB_DLECOUNT(skb) = 0; - ISDN_AUDIO_SKB_LOCK(skb) = 0; - save_flags(flags); - cli(); - di = info->isdn_driver; - ch = info->isdn_channel; - __skb_queue_tail(&dev->drv[di]->rpqueue[ch], skb); - dev->drv[di]->rcvcount[ch] += 2; - restore_flags(flags); - /* Schedule dequeuing */ - if ((dev->modempoll) && (info->rcvsched)) - isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); - wake_up_interruptible(&dev->drv[di]->rcv_waitq[ch]); + isdn_audio_put_dle_code(info, what); } } diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/isdn_audio.h linux/drivers/isdn/isdn_audio.h --- v2.3.13/linux/drivers/isdn/isdn_audio.h Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/isdn_audio.h Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_audio.h,v 1.7 1999/04/12 12:33:11 fritz Exp $ +/* $Id: isdn_audio.h,v 1.8 1999/07/11 17:14:07 armin Exp $ * Linux ISDN subsystem, audio conversion and compression (linklevel). * @@ -19,6 +19,17 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_audio.h,v $ + * Revision 1.8 1999/07/11 17:14:07 armin + * Added new layer 2 and 3 protocols for Fax and DSP functions. + * Moved "Add CPN to RING message" to new register S23, + * "Display message" is now correct on register S13 bit 7. + * New audio command AT+VDD implemented (deactivate DTMF decoder and + * activate possible existing hardware/DSP decoder). + * Moved some tty defines to .h file. + * Made whitespace possible in AT command line. + * Some AT-emulator output bugfixes. + * First Fax G3 implementations. + * * Revision 1.7 1999/04/12 12:33:11 fritz * Changes from 2.0 tree. * @@ -74,3 +85,4 @@ extern void isdn_audio_calc_silence(modem_info *, unsigned char *, int, int); extern void isdn_audio_eval_silence(modem_info *); silence_state *isdn_audio_silence_init(silence_state *); +extern void isdn_audio_put_dle_code(modem_info *, u_char); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/isdn_budget.c linux/drivers/isdn/isdn_budget.c --- v2.3.13/linux/drivers/isdn/isdn_budget.c Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/isdn_budget.c Wed Dec 31 16:00:00 1969 @@ -1,206 +0,0 @@ -/* $Id: isdn_budget.c,v 1.3 1998/10/23 10:18:39 paul Exp $ - * - * Linux ISDN subsystem, budget-accounting for network interfaces. - * - * Copyright 1997 by Christian Lademann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Log: isdn_budget.c,v $ - * Revision 1.3 1998/10/23 10:18:39 paul - * Implementation of "dialmode" (successor of "status") - * You also need current isdnctrl for this! - * - * Revision 1.2 1998/03/07 23:17:30 fritz - * Added RCS keywords - * Bugfix: Did not compile without isdn_dumppkt beeing enabled. - * - */ - -/* -30.06.97:cal:angelegt -04.11.97:cal:budget.period: int --> time_t -*/ - -#include -#define __NO_VERSION__ -#include -#include -#include "isdn_common.h" -#include "isdn_net.h" - -#ifdef CONFIG_ISDN_BUDGET - -#define VERBOSE_PRINTK(v, l, p...) { \ - if(dev->net_verbose >= (v)) { \ - printk(l ## p); \ - } else { ; } \ -} - - -int -isdn_net_budget(int type, struct device *ndev) { - isdn_net_local *lp = (isdn_net_local *)ndev->priv; - int i, ret = 0; - - switch(type) { - case ISDN_BUDGET_INIT: - for(i = 0; i < ISDN_BUDGET_NUM_BUDGET; i++) { - lp->budget [i] .amount = -1; - lp->budget [i] .used = 0; - lp->budget [i] .period = (time_t)0; - lp->budget [i] .period_started = (time_t)0; - lp->budget [i] .last_check = CURRENT_TIME; - lp->budget [i] .notified = 0; - } - - return(0); - break; - - case ISDN_BUDGET_CHECK_DIAL: - case ISDN_BUDGET_CHECK_CHARGE: - case ISDN_BUDGET_CHECK_ONLINE: - ret = 0; - - for(i = 0; i < ISDN_BUDGET_NUM_BUDGET; i++) { - if(lp->budget [i] .amount < 0) - continue; - - if(lp->budget [i] .period_started + lp->budget [i] .period < CURRENT_TIME) { - lp->budget [i] .used = 0; - lp->budget [i] .period_started = CURRENT_TIME; - lp->budget [i] .notified = 0; - } - - if(lp->budget [i] .used >= lp->budget [i] .amount) - ret |= (1 << i); - } - - switch(type) { - case ISDN_BUDGET_CHECK_DIAL: - if(! ret) { - lp->budget [ISDN_BUDGET_DIAL] .used++; - lp->budget [ISDN_BUDGET_DIAL] .last_check = CURRENT_TIME; - } - break; - - case ISDN_BUDGET_CHECK_CHARGE: - lp->budget [ISDN_BUDGET_CHARGE] .used++; - lp->budget [ISDN_BUDGET_CHARGE] .last_check = CURRENT_TIME; - break; - - case ISDN_BUDGET_CHECK_ONLINE: - if(lp->budget [ISDN_BUDGET_ONLINE] .last_check) { - lp->budget [ISDN_BUDGET_ONLINE] .used += (CURRENT_TIME - lp->budget [ISDN_BUDGET_ONLINE] .last_check); - } - - lp->budget [ISDN_BUDGET_ONLINE] .last_check = CURRENT_TIME; - break; - } - -/* - if(ret) - lp->flags |= ISDN_NET_DM_OFF; -*/ - for(i = 0; i < ISDN_BUDGET_NUM_BUDGET; i++) { - if(ret & (1 << i) && ! lp->budget [i] .notified) { - switch(i) { - case ISDN_BUDGET_DIAL: - printk(KERN_WARNING "isdn_budget: dial budget used up.\n"); - break; - - case ISDN_BUDGET_CHARGE: - printk(KERN_WARNING "isdn_budget: charge budget used up.\n"); - break; - - case ISDN_BUDGET_ONLINE: - printk(KERN_WARNING "isdn_budget: online budget used up.\n"); - break; - - default: - printk(KERN_WARNING "isdn_budget: budget #%d used up.\n", i); - break; - } - - lp->budget [i] .notified = 1; - } - } - - return(ret); - break; - - case ISDN_BUDGET_START_ONLINE: - lp->budget [ISDN_BUDGET_ONLINE] .last_check = CURRENT_TIME; - return(0); - - break; - } - - return(-1); -} - - -int -isdn_budget_ioctl(isdn_ioctl_budget *iocmd) { - isdn_net_dev *p = isdn_net_findif(iocmd->name); - - if(p) { - switch(iocmd->command) { - case ISDN_BUDGET_SET_BUDGET: - if(! suser()) - return(-EPERM); - - if(iocmd->budget < 0 || iocmd->budget > ISDN_BUDGET_NUM_BUDGET) - return(-EINVAL); - - if(iocmd->amount < 0) - iocmd->amount = -1; - - p->local->budget [iocmd->budget] .amount = iocmd->amount; - p->local->budget [iocmd->budget] .period = iocmd->period; - - if(iocmd->used <= 0) - p->local->budget [iocmd->budget] .used = 0; - else - p->local->budget [iocmd->budget] .used = iocmd->used; - - if(iocmd->period_started == (time_t)0) - p->local->budget [iocmd->budget] .period_started = CURRENT_TIME; - else - p->local->budget [iocmd->budget] .period_started = iocmd->period_started; - - return(0); - break; - - case ISDN_BUDGET_GET_BUDGET: - if(iocmd->budget < 0 || iocmd->budget > ISDN_BUDGET_NUM_BUDGET) - return(-EINVAL); - - iocmd->amount = p->local->budget [iocmd->budget] .amount; - iocmd->used = p->local->budget [iocmd->budget] .used; - iocmd->period = p->local->budget [iocmd->budget] .period; - iocmd->period_started = p->local->budget [iocmd->budget] .period_started; - - return(0); - break; - - default: - return(-EINVAL); - break; - } - } - return(-ENODEV); -} -#endif diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/isdn_cards.c linux/drivers/isdn/isdn_cards.c --- v2.3.13/linux/drivers/isdn/isdn_cards.c Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/isdn_cards.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_cards.c,v 1.9 1999/04/12 12:33:11 fritz Exp $ +/* $Id: isdn_cards.c,v 1.10 1999/07/20 06:41:28 calle Exp $ * Linux ISDN subsystem, initialization for non-modularized drivers. * @@ -19,6 +19,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_cards.c,v $ + * Revision 1.10 1999/07/20 06:41:28 calle + * Bugfix: After the redesign of the AVM B1 driver, the driver didn't even + * compile, if not selected as modules. + * * Revision 1.9 1999/04/12 12:33:11 fritz * Changes from 2.0 tree. * @@ -67,12 +71,9 @@ #endif #ifdef CONFIG_ISDN_DRV_AVMB1 -extern void avmb1_init(void); +extern void kcapi_init(void); extern void capi_init(void); extern void capidrv_init(void); -#ifdef CONFIG_PCI -extern int b1pci_init(void); -#endif #endif void @@ -88,10 +89,7 @@ pcbit_init(); #endif #ifdef CONFIG_ISDN_DRV_AVMB1 - avmb1_init(); -#ifdef CONFIG_PCI - b1pci_init(); -#endif + kcapi_init(); capi_init(); capidrv_init(); #endif diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c --- v2.3.13/linux/drivers/isdn/isdn_common.c Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/isdn_common.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_common.c,v 1.75 1999/04/18 14:06:47 fritz Exp $ +/* $Id: isdn_common.c,v 1.86 1999/07/31 12:59:42 armin Exp $ * Linux ISDN subsystem, common used functions (linklevel). * @@ -21,6 +21,51 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_common.c,v $ + * Revision 1.86 1999/07/31 12:59:42 armin + * Added tty fax capabilities. + * + * Revision 1.85 1999/07/29 16:58:35 armin + * Bugfix: DLE handling in isdn_readbchan() + * + * Revision 1.84 1999/07/25 16:21:10 keil + * fix number matching + * + * Revision 1.83 1999/07/13 21:02:05 werner + * Added limit possibilty of driver b_channel resources (ISDN_STAT_DISCH) + * + * Revision 1.82 1999/07/12 21:06:50 werner + * Fixed problem when loading more than one driver temporary + * + * Revision 1.81 1999/07/11 17:14:09 armin + * Added new layer 2 and 3 protocols for Fax and DSP functions. + * Moved "Add CPN to RING message" to new register S23, + * "Display message" is now correct on register S13 bit 7. + * New audio command AT+VDD implemented (deactivate DTMF decoder and + * activate possible existing hardware/DSP decoder). + * Moved some tty defines to .h file. + * Made whitespace possible in AT command line. + * Some AT-emulator output bugfixes. + * First Fax G3 implementations. + * + * Revision 1.80 1999/07/07 10:14:00 detabc + * remove unused messages + * + * Revision 1.79 1999/07/05 23:51:30 werner + * Allow limiting of available HiSax B-chans per card. Controlled by hisaxctrl + * hisaxctrl id 10 + * + * Revision 1.78 1999/07/05 20:21:15 werner + * changes to use diversion sources for all kernel versions. + * removed static device, only proc filesystem used + * + * Revision 1.77 1999/07/01 08:29:50 keil + * compatibility to 2.3 kernel + * + * Revision 1.76 1999/06/29 16:16:44 calle + * Let ISDN_CMD_UNLOAD work with open isdn devices without crash again. + * Also right unlocking (ISDN_CMD_UNLOCK) is done now. + * isdnlog should check returncode of read(2) calls. + * * Revision 1.75 1999/04/18 14:06:47 fritz * Removed TIMRU stuff. * @@ -65,16 +110,6 @@ * brute force fix to avoid Ugh's in isdn_tty_write() * cleaned up some dead code * - * Revision 1.65 1998/06/07 00:20:00 fritz - * abc cleanup. - * - * Revision 1.64 1998/06/02 12:10:03 detabc - * wegen einer einstweiliger verfuegung gegen DW ist zur zeit - * die abc-extension bis zur klaerung der rechtslage nicht verfuegbar - * - * Revision 1.63 1998/05/03 17:40:38 detabc - * Include abc-extension-support for >= 2.1.x Kernels in - * isdn_net.c and isdn_common.c. alpha-test OK and running ! * * Revision 1.62 1998/04/14 16:28:43 he * Fixed user space access with interrupts off and remaining @@ -335,6 +370,9 @@ #ifdef CONFIG_ISDN_AUDIO #include "isdn_audio.h" #endif +#ifdef CONFIG_ISDN_DIVERSION +#include +#endif CONFIG_ISDN_DIVERSION #include "isdn_v110.h" #include "isdn_cards.h" @@ -343,7 +381,7 @@ isdn_dev *dev = (isdn_dev *) 0; -static char *isdn_revision = "$Revision: 1.75 $"; +static char *isdn_revision = "$Revision: 1.86 $"; extern char *isdn_net_revision; extern char *isdn_tty_revision; @@ -359,6 +397,11 @@ #endif extern char *isdn_v110_revision; +#ifdef CONFIG_ISDN_DIVERSION +isdn_divert_if *divert_if = NULL; /* interface to diversion module */ +#endif CONFIG_ISDN_DIVERSION + + static int isdn_writebuf_stub(int, int, const u_char *, int, int); void @@ -449,6 +492,8 @@ register int reverse; register int nostar = 1; + if (!(*s) && !(*p)) + return(1); for (; *p; s++, p++) switch (*p) { case '\\': @@ -760,7 +805,7 @@ return 0; } /* Try to find a network-interface which will accept incoming call */ - r = isdn_net_find_icall(di, c->arg, i, c->parm.setup); + r = ((c->command == ISDN_STAT_ICALLW) ? 0 : isdn_net_find_icall(di, c->arg, i, c->parm.setup)); switch (r) { case 0: /* No network-device replies. @@ -768,7 +813,13 @@ * These return 0 on no match, 1 on match and * 3 on eventually match, if CID is longer. */ - retval = isdn_tty_find_icall(di, c->arg, c->parm.setup); + if (c->command == ISDN_STAT_ICALL) + if ((retval = isdn_tty_find_icall(di, c->arg, c->parm.setup))) return(retval); +#ifdef CONFIG_ISDN_DIVERSION + if (divert_if) + if ((retval = divert_if->stat_callback(c))) + return(retval); /* processed */ +#endif CONFIG_ISDN_DIVERSION if ((!retval) && (dev->drv[di]->flags & DRV_FLAG_REJBUS)) { /* No tty responding */ cmd.driver = di; @@ -831,6 +882,20 @@ printk(KERN_INFO "isdn: %s,ch%ld cause: %s\n", dev->drvid[di], c->arg, c->parm.num); isdn_tty_stat_callback(i, c); +#ifdef CONFIG_ISDN_DIVERSION + if (divert_if) + divert_if->stat_callback(c); +#endif CONFIG_ISDN_DIVERSION + break; + case ISDN_STAT_DISPLAY: +#ifdef ISDN_DEBUG_STATCALLB + printk(KERN_DEBUG "DISPLAY: %ld %s\n", c->arg, c->parm.display); +#endif + isdn_tty_stat_callback(i, c); +#ifdef CONFIG_ISDN_DIVERSION + if (divert_if) + divert_if->stat_callback(c); +#endif CONFIG_ISDN_DIVERSION break; case ISDN_STAT_DCONN: if (i < 0) @@ -869,6 +934,11 @@ isdn_v110_stat_callback(i, c); if (isdn_tty_stat_callback(i, c)) break; +#ifdef CONFIG_ISDN_DIVERSION + if (divert_if) + divert_if->stat_callback(c); +#endif CONFIG_ISDN_DIVERSION + break; break; case ISDN_STAT_BCONN: if (i < 0) @@ -924,7 +994,34 @@ return -1; isdn_info_update(); break; + case ISDN_STAT_DISCH: + save_flags(flags); + cli(); + for (i = 0; i < ISDN_MAX_CHANNELS; i++) + if ((dev->drvmap[i] == di) && + (dev->chanmap[i] == c->arg)) { + if (c->parm.num[0]) + dev->usage[i] &= ~ISDN_USAGE_DISABLED; + else + if (USG_NONE(dev->usage[i])) { + dev->usage[i] |= ISDN_USAGE_DISABLED; + } + else + retval = -1; + break; + } + restore_flags(flags); + isdn_info_update(); + break; case ISDN_STAT_UNLOAD: + while (dev->drv[di]->locks > 0) { + isdn_ctrl cmd; + cmd.driver = di; + cmd.arg = 0; + cmd.command = ISDN_CMD_UNLOCK; + isdn_command(&cmd); + dev->drv[di]->locks--; + } save_flags(flags); cli(); isdn_tty_stat_callback(i, c); @@ -932,6 +1029,7 @@ if (dev->drvmap[i] == di) { dev->drvmap[i] = -1; dev->chanmap[i] = -1; + dev->usage[i] &= ~ISDN_USAGE_DISABLED; } dev->drivers--; dev->channels -= dev->drv[di]->channels; @@ -941,7 +1039,7 @@ isdn_free_queue(&dev->drv[di]->rpqueue[i]); kfree(dev->drv[di]->rpqueue); kfree(dev->drv[di]->rcv_waitq); -#if LINUX_VERSION_CODE < 131841 +#ifndef COMPAT_HAS_NEW_WAITQ kfree(dev->drv[di]->snd_waitq); #endif kfree(dev->drv[di]); @@ -954,6 +1052,22 @@ break; case CAPI_PUT_MESSAGE: return(isdn_capi_rec_hl_msg(&c->parm.cmsg)); +#ifdef CONFIG_ISDN_TTY_FAX + case ISDN_STAT_FAXIND: + isdn_tty_stat_callback(i, c); + break; +#endif +#ifdef CONFIG_ISDN_AUDIO + case ISDN_STAT_AUDIO: + isdn_tty_stat_callback(i, c); + break; +#endif +#ifdef CONFIG_ISDN_DIVERSION + case ISDN_STAT_PROT: + case ISDN_STAT_REDIR: + if (divert_if) + return(divert_if->stat_callback(c)); +#endif CONFIG_ISDN_DIVERSION default: return -1; } @@ -989,10 +1103,10 @@ * of the mapping (di,ch)<->minor, happen during the sleep? --he */ int -#if LINUX_VERSION_CODE < 131841 -isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, struct wait_queue **sleep) -#else +#ifdef COMPAT_HAS_NEW_WAITQ isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, wait_queue_head_t *sleep) +#else +isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, struct wait_queue **sleep) #endif { int left; @@ -1021,7 +1135,7 @@ if (ISDN_AUDIO_SKB_LOCK(skb)) break; ISDN_AUDIO_SKB_LOCK(skb) = 1; - if (ISDN_AUDIO_SKB_DLECOUNT(skb)) { + if ((ISDN_AUDIO_SKB_DLECOUNT(skb)) || (dev->drv[di]->DLEflag & (1 << channel))) { char *p = skb->data; unsigned long DLEmask = (1 << channel); @@ -1320,11 +1434,11 @@ return mask; } if (minor >= ISDN_MINOR_CTRL && minor <= ISDN_MINOR_CTRLMAX) { - poll_wait(file, &(dev->drv[drvidx]->st_waitq), wait); if (drvidx < 0) { - printk(KERN_ERR "isdn_common: isdn_poll 1 -> what the hell\n"); - return POLLERR; + /* driver deregistered while file open */ + return POLLHUP; } + poll_wait(file, &(dev->drv[drvidx]->st_waitq), wait); mask = POLLOUT | POLLWRNORM; if (dev->drv[drvidx]->stavail) { mask |= POLLIN | POLLRDNORM; @@ -1938,6 +2052,8 @@ if ((dev->usage[i] & ISDN_USAGE_EXCLUSIVE) && ((pre_dev != d) || (pre_chan != dev->chanmap[i]))) continue; + if (dev->usage[i] & ISDN_USAGE_DISABLED) + continue; /* usage not allowed */ if (dev->drv[d]->flags & DRV_FLAG_RUNNING) { if (((dev->drv[d]->interface->features & features) == features) || (((dev->drv[d]->interface->features & vfeatures) == vfeatures) && @@ -2132,13 +2248,12 @@ int j, k, m; ulong flags; -#if LINUX_VERSION_CODE >= 131841 +#ifdef COMPAT_HAS_NEW_WAITQ init_waitqueue_head(&d->st_waitq); #endif if (d->flags & DRV_FLAG_RUNNING) return -1; - if (n < 1) - return 0; + if (n < 1) return 0; m = (adding) ? d->channels + n : n; @@ -2185,13 +2300,13 @@ if ((adding) && (d->rcv_waitq)) kfree(d->rcv_waitq); -#if LINUX_VERSION_CODE < 131841 - if (!(d->rcv_waitq = (struct wait_queue **) - kmalloc(sizeof(struct wait_queue *) * m, GFP_KERNEL))) { -#else +#ifdef COMPAT_HAS_NEW_WAITQ d->rcv_waitq = (wait_queue_head_t *) kmalloc(sizeof(wait_queue_head_t) * 2 * m, GFP_KERNEL); if (!d->rcv_waitq) { +#else + if (!(d->rcv_waitq = (struct wait_queue **) + kmalloc(sizeof(struct wait_queue *) * m, GFP_KERNEL))) { #endif printk(KERN_WARNING "register_isdn: Could not alloc rcv_waitq\n"); if (!adding) { @@ -2201,7 +2316,13 @@ } return -1; } -#if LINUX_VERSION_CODE < 131841 +#ifdef COMPAT_HAS_NEW_WAITQ + d->snd_waitq = d->rcv_waitq + m; + for (j = 0; j < m; j++) { + init_waitqueue_head(&d->rcv_waitq[m]); + init_waitqueue_head(&d->snd_waitq[m]); + } +#else memset((char *) d->rcv_waitq, 0, sizeof(struct wait_queue *) * m); if ((adding) && (d->snd_waitq)) @@ -2218,12 +2339,6 @@ return -1; } memset((char *) d->snd_waitq, 0, sizeof(struct wait_queue *) * m); -#else - d->snd_waitq = d->rcv_waitq + m; - for (j = 0; j < m; j++) { - init_waitqueue_head(&d->rcv_waitq[m]); - init_waitqueue_head(&d->snd_waitq[m]); - } #endif dev->channels += n; @@ -2245,6 +2360,60 @@ * Low-level-driver registration */ + +#ifdef CONFIG_ISDN_DIVERSION +extern isdn_divert_if *divert_if; + +static char *map_drvname(int di) +{ + if ((di < 0) || (di >= ISDN_MAX_DRIVERS)) + return(NULL); + return(dev->drvid[di]); /* driver name */ +} /* map_drvname */ + +static int map_namedrv(char *id) +{ int i; + + for (i = 0; i < ISDN_MAX_DRIVERS; i++) + { if (!strcmp(dev->drvid[i],id)) + return(i); + } + return(-1); +} /* map_namedrv */ + +int DIVERT_REG_NAME(isdn_divert_if *i_div) +{ + if (i_div->if_magic != DIVERT_IF_MAGIC) + return(DIVERT_VER_ERR); + switch (i_div->cmd) + { + case DIVERT_CMD_REL: + if (divert_if != i_div) + return(DIVERT_REL_ERR); + divert_if = NULL; /* free interface */ + MOD_DEC_USE_COUNT; + return(DIVERT_NO_ERR); + + case DIVERT_CMD_REG: + if (divert_if) + return(DIVERT_REG_ERR); + i_div->ll_cmd = isdn_command; /* set command function */ + i_div->drv_to_name = map_drvname; + i_div->name_to_drv = map_namedrv; + MOD_INC_USE_COUNT; + divert_if = i_div; /* remember interface */ + return(DIVERT_NO_ERR); + + default: + return(DIVERT_CMD_ERR); + } +} /* DIVERT_REG_NAME */ + +EXPORT_SYMBOL(DIVERT_REG_NAME); + +#endif CONFIG_ISDN_DIVERSION + + EXPORT_SYMBOL(register_isdn); EXPORT_SYMBOL(register_isdn_module); EXPORT_SYMBOL(unregister_isdn_module); @@ -2352,18 +2521,18 @@ memset((char *) dev, 0, sizeof(isdn_dev)); init_timer(&dev->timer); dev->timer.function = isdn_timer_funct; -#if LINUX_VERSION_CODE < 131841 - dev->sem = MUTEX; -#else +#ifdef COMPAT_HAS_NEW_WAITQ init_MUTEX(&dev->sem); init_waitqueue_head(&dev->info_waitq); +#else + dev->sem = MUTEX; #endif for (i = 0; i < ISDN_MAX_CHANNELS; i++) { dev->drvmap[i] = -1; dev->chanmap[i] = -1; dev->m_idx[i] = -1; strcpy(dev->num[i], "???"); -#if LINUX_VERSION_CODE >= 131841 +#ifdef COMPAT_HAS_NEW_WAITQ init_waitqueue_head(&dev->mdm.info[i].open_wait); init_waitqueue_head(&dev->mdm.info[i].close_wait); #endif @@ -2452,6 +2621,9 @@ for (i = 0; i < ISDN_MAX_CHANNELS; i++) { isdn_tty_cleanup_xmit(&dev->mdm.info[i]); kfree(dev->mdm.info[i].xmit_buf - 4); +#ifdef CONFIG_ISDN_TTY_FAX + kfree(dev->mdm.info[i].fax); +#endif } if (unregister_chrdev(ISDN_MAJOR, "isdn") != 0) { printk(KERN_WARNING "isdn: controldevice busy, remove cancelled\n"); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/isdn_common.h linux/drivers/isdn/isdn_common.h --- v2.3.13/linux/drivers/isdn/isdn_common.h Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/isdn_common.h Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_common.h,v 1.15 1999/04/18 14:06:50 fritz Exp $ +/* $Id: isdn_common.h,v 1.16 1999/07/01 08:29:54 keil Exp $ * header for Linux ISDN subsystem, common used functions and debugging-switches (linklevel). * @@ -21,6 +21,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_common.h,v $ + * Revision 1.16 1999/07/01 08:29:54 keil + * compatibility to 2.3 kernel + * * Revision 1.15 1999/04/18 14:06:50 fritz * Removed TIMRU stuff. * @@ -115,10 +118,10 @@ extern void isdn_timer_ctrl(int tf, int onoff); extern void isdn_unexclusive_channel(int di, int ch); extern int isdn_getnum(char **); -#if LINUX_VERSION_CODE < 131841 -extern int isdn_readbchan(int, int, u_char *, u_char *, int, struct wait_queue**); -#else +#ifdef COMPAT_HAS_NEW_WAITQ extern int isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *); +#else +extern int isdn_readbchan(int, int, u_char *, u_char *, int, struct wait_queue**); #endif extern int isdn_get_free_channel(int, int, int, int, int); extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/isdn_concap.c linux/drivers/isdn/isdn_concap.c --- v2.3.13/linux/drivers/isdn/isdn_concap.c Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/isdn_concap.c Wed Aug 18 11:38:57 1999 @@ -53,7 +53,7 @@ int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *skb) { int tmp; - struct device *ndev = concap -> net_dev; + struct net_device *ndev = concap -> net_dev; isdn_net_local *lp = (isdn_net_local *) ndev->priv; IX25DEBUG( "isdn_concap_dl_data_req: %s \n", concap->net_dev->name); @@ -66,7 +66,7 @@ int isdn_concap_dl_connect_req(struct concap_proto *concap) { - struct device *ndev = concap -> net_dev; + struct net_device *ndev = concap -> net_dev; isdn_net_local *lp = (isdn_net_local *) ndev->priv; int ret; IX25DEBUG( "isdn_concap_dl_connect_req: %s \n", ndev -> name); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c --- v2.3.13/linux/drivers/isdn/isdn_net.c Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/isdn_net.c Wed Aug 18 11:38:57 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_net.c,v 1.84 1999/04/18 14:06:55 fritz Exp $ +/* $Id: isdn_net.c,v 1.88 1999/07/07 10:13:31 detabc Exp $ * Linux ISDN subsystem, network interfaces and related functions (linklevel). * @@ -21,6 +21,19 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_net.c,v $ + * Revision 1.88 1999/07/07 10:13:31 detabc + * remove unused messages + * + * Revision 1.87 1999/07/06 07:53:53 calle + * calls to dev_alloc_skb waste 16 bytes of memory, if we calculate the + * right header space for the lowlevel driver. using alloc_skb instead. + * + * Revision 1.86 1999/06/09 10:12:05 paul + * thinko in previous patch + * + * Revision 1.85 1999/06/07 19:42:39 paul + * isdn_net_getpeer() fixed to return correct `outgoing' flag + * * Revision 1.84 1999/04/18 14:06:55 fritz * Removed TIMRU stuff. * @@ -68,7 +81,7 @@ * Added more locking stuff in tty_write. * * Revision 1.71 1998/06/18 22:43:08 fritz - * Bugfix: Setting ndev->do_ioctl had beed accidetly removed at abc-cleanup. + * Bugfix: Setting ndev->do_ioctl had beed accidetly removed at cleanup. * * Revision 1.70 1998/06/17 19:50:49 he * merged with 2.1.10[34] (cosmetics and udelay() -> mdelay()) @@ -80,40 +93,13 @@ * so autodial is suppressed for that device until it is switched on using * 'isdnctrl status dev-name on'. * - * Revision 1.68 1998/06/07 00:20:05 fritz - * abc cleanup. * - * Revision 1.67 1998/06/02 12:10:08 detabc - * wegen einer einstweiliger verfuegung gegen DW ist zur zeit - * die abc-extension bis zur klaerung der rechtslage nicht verfuegbar * * Revision 1.66 1998/05/26 22:39:24 he * sync'ed with 2.1.102 where appropriate (CAPABILITY changes) * concap typo * cleared dev.tbusy in isdn_net BCONN status callback * - * Revision 1.65 1998/05/22 10:01:11 detabc - * in case of a icmp-unreach condition the tcp-keepalive-entrys - * will be dropped from the internal double-link-list (only abc-extension). - * send icmp unreach only if the skb->protocol == ETH_P_IP - * speedup abc-no-dchan redial - * - * Revision 1.64 1998/05/07 19:58:39 detabc - * bugfix in abc_delayed_hangup - * optimize keepalive-tests for abc_rawip - * - * Revision 1.63 1998/05/05 23:23:36 detabc - * change ICMP_HOST_UNREACH to ICMP_NET_UNREACH (only abc-ext.) - * set dev->tbusy to zero in isdn_net_unreachable() (only abc-ext.) - * drop all new packets and send ICMP_NET_UNREACH for - * min. dialwait to max. dialwait * 6 time. (only abc-ext.) - * change random-deliver of packets (small first) from all emcapsulation - * to only rawip with ABC-Router-Flag enabled. - * - * Revision 1.62 1998/05/03 17:40:42 detabc - * Include abc-extension-support for >= 2.1.x Kernels in - * isdn_net.c and isdn_common.c. alpha-test OK and running ! - * * Revision 1.61 1998/04/16 19:19:42 keil * Fix from vger (tx max qlength) * @@ -371,17 +357,17 @@ /* Prototypes */ int isdn_net_force_dial_lp(isdn_net_local *); -static int isdn_net_start_xmit(struct sk_buff *, struct device *); -static int isdn_net_xmit(struct device *, isdn_net_local *, struct sk_buff *); +static int isdn_net_start_xmit(struct sk_buff *, struct net_device *); +static int isdn_net_xmit(struct net_device *, isdn_net_local *, struct sk_buff *); -char *isdn_net_revision = "$Revision: 1.84 $"; +char *isdn_net_revision = "$Revision: 1.88 $"; /* * Code for raw-networking over ISDN */ static void -isdn_net_unreachable(struct device *dev, struct sk_buff *skb, char *reason) +isdn_net_unreachable(struct net_device *dev, struct sk_buff *skb, char *reason) { if(skb) { @@ -403,7 +389,7 @@ } static void -isdn_net_reset(struct device *dev) +isdn_net_reset(struct net_device *dev) { #ifdef CONFIG_ISDN_X25 struct concap_device_ops * dops = @@ -426,10 +412,10 @@ /* Open/initialize the board. */ static int -isdn_net_open(struct device *dev) +isdn_net_open(struct net_device *dev) { int i; - struct device *p; + struct net_device *p; struct in_device *in_dev; isdn_net_reset(dev); @@ -616,7 +602,7 @@ lp->stats.tx_packets++; lp->stats.tx_bytes += c->parm.length; if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP && lp->sav_skb) { - struct device *mdev; + struct net_device *mdev; if (lp->master) mdev = lp->master; else @@ -1060,7 +1046,7 @@ * Perform hangup for a net-interface. */ void -isdn_net_hangup(struct device *d) +isdn_net_hangup(struct net_device *d) { isdn_net_local *lp = (isdn_net_local *) d->priv; isdn_ctrl cmd; @@ -1191,7 +1177,7 @@ * Side-effects: ndev->tbusy is cleared on success. */ int -isdn_net_send_skb(struct device *ndev, isdn_net_local * lp, +isdn_net_send_skb(struct net_device *ndev, isdn_net_local * lp, struct sk_buff *skb) { int ret; @@ -1224,7 +1210,7 @@ */ static int -isdn_net_xmit(struct device *ndev, isdn_net_local * lp, struct sk_buff *skb) +isdn_net_xmit(struct net_device *ndev, isdn_net_local * lp, struct sk_buff *skb) { int ret; @@ -1280,7 +1266,7 @@ } static void -isdn_net_adjust_hdr(struct sk_buff *skb, struct device *dev) +isdn_net_adjust_hdr(struct sk_buff *skb, struct net_device *dev) { isdn_net_local *lp = (isdn_net_local *) dev->priv; if (!skb) @@ -1300,7 +1286,7 @@ * and start dialing. */ static int -isdn_net_start_xmit(struct sk_buff *skb, struct device *ndev) +isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev) { isdn_net_local *lp = (isdn_net_local *) ndev->priv; #ifdef CONFIG_ISDN_X25 @@ -1452,9 +1438,9 @@ * Shutdown a net-interface. */ static int -isdn_net_close(struct device *dev) +isdn_net_close(struct net_device *dev) { - struct device *p; + struct net_device *p; #ifdef CONFIG_ISDN_X25 struct concap_proto * cprot = ( (isdn_net_local *) dev->priv ) -> netdev -> cprot; @@ -1490,7 +1476,7 @@ * Get statistics */ static struct enet_statistics * -isdn_net_get_stats(struct device *dev) +isdn_net_get_stats(struct net_device *dev) { isdn_net_local *lp = (isdn_net_local *) dev->priv; return &lp->stats; @@ -1506,7 +1492,7 @@ */ static unsigned short -isdn_net_type_trans(struct sk_buff *skb, struct device *dev) +isdn_net_type_trans(struct sk_buff *skb, struct net_device *dev) { struct ethhdr *eth; unsigned char *rawp; @@ -1553,7 +1539,7 @@ isdn_net_slarp_send(isdn_net_local *lp, int is_reply) { unsigned short hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen; - struct sk_buff *skb = dev_alloc_skb(hl + sizeof(cisco_hdr) + sizeof(cisco_slarp)); + struct sk_buff *skb = alloc_skb(hl + sizeof(cisco_hdr) + sizeof(cisco_slarp), GFP_ATOMIC); unsigned long t = (jiffies / HZ * 1000000); int len; cisco_hdr *ch; @@ -1644,7 +1630,7 @@ * Got a packet from ISDN-Channel. */ static void -isdn_net_receive(struct device *ndev, struct sk_buff *skb) +isdn_net_receive(struct net_device *ndev, struct sk_buff *skb) { isdn_net_local *lp = (isdn_net_local *) ndev->priv; isdn_net_local *olp = lp; /* original 'lp' */ @@ -1793,7 +1779,7 @@ } static int -my_eth_header(struct sk_buff *skb, struct device *dev, unsigned short type, +my_eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { struct ethhdr *eth = (struct ethhdr *) skb_push(skb, ETH_HLEN); @@ -1838,7 +1824,7 @@ */ static int -isdn_net_header(struct sk_buff *skb, struct device *dev, unsigned short type, +isdn_net_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned plen) { isdn_net_local *lp = dev->priv; @@ -1894,7 +1880,7 @@ static int isdn_net_rebuild_header(struct sk_buff *skb) { - struct device *dev = skb->dev; + struct net_device *dev = skb->dev; isdn_net_local *lp = dev->priv; int ret = 0; @@ -1926,7 +1912,7 @@ * Interface-setup. (called just after registering a new interface) */ static int -isdn_net_init(struct device *ndev) +isdn_net_init(struct net_device *ndev) { ushort max_hlhdr_len = 0; isdn_net_local *lp = (isdn_net_local *) ndev->priv; @@ -2437,7 +2423,7 @@ * Allocate a new network-interface and initialize its data structures. */ char * -isdn_net_new(char *name, struct device *master) +isdn_net_new(char *name, struct net_device *master) { isdn_net_dev *netdev; @@ -2466,8 +2452,8 @@ netdev->local->p_encap = ISDN_NET_ENCAP_RAWIP; if (master) { /* Device shall be a slave */ - struct device *p = (((isdn_net_local *) master->priv)->slave); - struct device *q = master; + struct net_device *p = (((isdn_net_local *) master->priv)->slave); + struct net_device *q = master; netdev->local->master = master; /* Put device at end of slave-chain */ @@ -2928,7 +2914,7 @@ /* for pre-bound channels, we need this extra check */ if ( strncmp(dev->num[idx],"???",3) == 0 ) return -ENOTCONN; strncpy(phone->phone,dev->num[idx],ISDN_MSNLEN); - phone->outgoing=USG_OUTGOING(idx); + phone->outgoing=USG_OUTGOING(dev->usage[idx]); if ( copy_to_user(peer,phone,sizeof(*peer)) ) return -EFAULT; return 0; } @@ -3004,7 +2990,7 @@ isdn_net_force_hangup(char *name) { isdn_net_dev *p = isdn_net_findif(name); - struct device *q; + struct net_device *q; if (p) { if (p->local->isdn_device < 0) diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/isdn_net.h linux/drivers/isdn/isdn_net.h --- v2.3.13/linux/drivers/isdn/isdn_net.h Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/isdn_net.h Wed Aug 18 11:38:57 1999 @@ -100,7 +100,7 @@ #define CISCO_SLARP_REQUEST 1 #define CISCO_SLARP_KEEPALIVE 2 -extern char *isdn_net_new(char *, struct device *); +extern char *isdn_net_new(char *, struct net_device *); extern char *isdn_net_newslave(char *); extern int isdn_net_rm(char *); extern int isdn_net_rmall(void); @@ -112,13 +112,13 @@ extern int isdn_net_getpeer(isdn_net_ioctl_phone *, isdn_net_ioctl_phone *); extern int isdn_net_delphone(isdn_net_ioctl_phone *); extern int isdn_net_find_icall(int, int, int, setup_parm); -extern void isdn_net_hangup(struct device *); +extern void isdn_net_hangup(struct net_device *); extern void isdn_net_dial(void); extern void isdn_net_autohup(void); extern int isdn_net_force_hangup(char *); extern int isdn_net_force_dial(char *); extern isdn_net_dev *isdn_net_findif(char *); -extern int isdn_net_send_skb(struct device *, isdn_net_local *, +extern int isdn_net_send_skb(struct net_device *, isdn_net_local *, struct sk_buff *); extern int isdn_net_rcv_skb(int, struct sk_buff *); extern void isdn_net_slarp_out(void); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/isdn_ppp.c linux/drivers/isdn/isdn_ppp.c --- v2.3.13/linux/drivers/isdn/isdn_ppp.c Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/isdn_ppp.c Wed Aug 18 11:38:57 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_ppp.c,v 1.47 1999/04/18 14:06:59 fritz Exp $ +/* $Id: isdn_ppp.c,v 1.49 1999/07/06 07:47:11 calle Exp $ * * Linux ISDN subsystem, functions for synchronous PPP (linklevel). * @@ -19,6 +19,14 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_ppp.c,v $ + * Revision 1.49 1999/07/06 07:47:11 calle + * bugfix: dev_alloc_skb only reserve 16 bytes. We need to look at the + * hdrlen the driver want. So I changed dev_alloc_skb calls + * to alloc_skb and skb_reserve. + * + * Revision 1.48 1999/07/01 08:29:56 keil + * compatibility to 2.3 kernel + * * Revision 1.47 1999/04/18 14:06:59 fritz * Removed TIMRU stuff. * @@ -261,7 +269,7 @@ static void isdn_ppp_free_mpqueue(isdn_net_dev *); #endif -char *isdn_ppp_revision = "$Revision: 1.47 $"; +char *isdn_ppp_revision = "$Revision: 1.49 $"; static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS]; static struct isdn_ppp_compressor *ipc_head = NULL; @@ -430,7 +438,7 @@ ippp_table[lp->ppp_slot]->state = IPPP_OPEN | IPPP_CONNECT | IPPP_NOBLOCK; -#if LINUX_VERSION_CODE < 131841 +#ifndef COMPAT_HAS_NEW_WAITQ if (ippp_table[lp->ppp_slot]->wq) #endif wake_up_interruptible(&ippp_table[lp->ppp_slot]->wq); @@ -450,10 +458,10 @@ return 0; is = ippp_table[slot]; -#if LINUX_VERSION_CODE < 131841 - if (is->state && is->wq) -#else +#ifdef COMPAT_HAS_NEW_WAITQ if (is->state) +#else + if (is->state && is->wq) #endif wake_up_interruptible(&is->wq); @@ -519,10 +527,10 @@ is->mru = 1524; /* MRU, default 1524 */ is->maxcid = 16; /* VJ: maxcid */ is->tk = current; -#if LINUX_VERSION_CODE < 131841 - is->wq = NULL; /* read() wait queue */ -#else +#ifdef COMPAT_HAS_NEW_WAITQ init_waitqueue_head(&is->wq); +#else + is->wq = NULL; /* read() wait queue */ #endif is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */ is->last = is->rq; @@ -891,7 +899,7 @@ is->last = bl->next; restore_flags(flags); -#if LINUX_VERSION_CODE < 131841 +#ifndef COMPAT_HAS_NEW_WAITQ if (is->wq) #endif wake_up_interruptible(&is->wq); @@ -983,13 +991,21 @@ if ((dev->drv[lp->isdn_device]->flags & DRV_FLAG_RUNNING) && lp->dialstate == 0 && (lp->flags & ISDN_NET_CONNECTED)) { + unsigned short hl; int cnt; struct sk_buff *skb; - skb = dev_alloc_skb(count); + /* + * we need to reserve enought space in front of + * sk_buff. old call to dev_alloc_skb only reserved + * 16 bytes, now we are looking what the driver want + */ + hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen; + skb = alloc_skb(hl+count, GFP_ATOMIC); if (!skb) { printk(KERN_WARNING "isdn_ppp_write: out of memory!\n"); return count; } + skb_reserve(skb, hl); if (copy_from_user(skb_put(skb, count), buf, count)) return -EFAULT; if (is->debug & 0x40) { @@ -1271,7 +1287,7 @@ static void isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb, int proto) { - struct device *dev = &net_dev->dev; + struct net_device *dev = &net_dev->dev; struct ippp_struct *is = ippp_table[lp->ppp_slot]; if (is->debug & 0x10) { @@ -1416,9 +1432,9 @@ */ int -isdn_ppp_xmit(struct sk_buff *skb, struct device *dev) +isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev) { - struct device *mdev = ((isdn_net_local *) (dev->priv))->master; /* get master (for redundancy) */ + struct net_device *mdev = ((isdn_net_local *) (netdev->priv))->master; /* get master (for redundancy) */ isdn_net_local *lp,*mlp; isdn_net_dev *nd; unsigned int proto = PPP_IP; /* 0x21 */ @@ -1427,8 +1443,8 @@ if (mdev) mlp = (isdn_net_local *) (mdev->priv); else { - mdev = dev; - mlp = (isdn_net_local *) (dev->priv); + mdev = netdev; + mlp = (isdn_net_local *) (netdev->priv); } nd = mlp->netdev; /* get master lp */ ipts = ippp_table[mlp->ppp_slot]; @@ -1441,7 +1457,7 @@ ipts->old_pa_dstaddr = mdev->pa_dstaddr; #endif if (ipts->debug & 0x1) - printk(KERN_INFO "%s: IP frame delayed.\n", dev->name); + printk(KERN_INFO "%s: IP frame delayed.\n", netdev->name); return 1; } @@ -1506,12 +1522,19 @@ #ifdef CONFIG_ISDN_PPP_VJ if (proto == PPP_IP && ipts->pppcfg & SC_COMP_TCP) { /* ipts here? probably yes, but check this again */ struct sk_buff *new_skb; - - new_skb = dev_alloc_skb(skb->len); + unsigned short hl; + /* + * we need to reserve enought space in front of + * sk_buff. old call to dev_alloc_skb only reserved + * 16 bytes, now we are looking what the driver want. + */ + hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen; + new_skb = alloc_skb(hl+skb->len, GFP_ATOMIC); if (new_skb) { u_char *buf; int pktlen; + skb_reserve(new_skb, hl); new_skb->dev = skb->dev; skb_put(new_skb, skb->len); buf = skb->data; @@ -1611,9 +1634,9 @@ printk(KERN_DEBUG "skb xmit: len: %d\n", (int) skb->len); isdn_ppp_frame_log("xmit", skb->data, skb->len, 32,ipt->unit,lp->ppp_slot); } - if (isdn_net_send_skb(dev, lp, skb)) { + if (isdn_net_send_skb(netdev, lp, skb)) { if (lp->sav_skb) { /* whole sav_skb processing with disabled IRQs ?? */ - printk(KERN_ERR "%s: whoops .. there is another stored skb!\n", dev->name); + printk(KERN_ERR "%s: whoops .. there is another stored skb!\n", netdev->name); dev_kfree_skb(skb); } else lp->sav_skb = skb; @@ -1985,7 +2008,7 @@ */ static int -isdn_ppp_dev_ioctl_stats(int slot, struct ifreq *ifr, struct device *dev) +isdn_ppp_dev_ioctl_stats(int slot, struct ifreq *ifr, struct net_device *dev) { struct ppp_stats *res, t; @@ -2025,7 +2048,7 @@ } int -isdn_ppp_dev_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +isdn_ppp_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { int error=0; char *r; @@ -2088,7 +2111,7 @@ #ifdef CONFIG_ISDN_MPP isdn_net_dev *ndev; isdn_net_local *lp; - struct device *sdev; + struct net_device *sdev; if (!(ndev = isdn_net_findif(name))) return 1; @@ -2119,7 +2142,7 @@ #ifdef CONFIG_ISDN_MPP isdn_net_dev *ndev; isdn_net_local *lp; - struct device *sdev; + struct net_device *sdev; if (!(ndev = isdn_net_findif(name))) return 1; diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/isdn_ppp.h linux/drivers/isdn/isdn_ppp.h --- v2.3.13/linux/drivers/isdn/isdn_ppp.h Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/isdn_ppp.h Wed Aug 18 11:38:57 1999 @@ -78,9 +78,9 @@ extern void isdn_ppp_cleanup(void); extern int isdn_ppp_free(isdn_net_local *); extern int isdn_ppp_bind(isdn_net_local *); -extern int isdn_ppp_xmit(struct sk_buff *, struct device *); +extern int isdn_ppp_xmit(struct sk_buff *, struct net_device *); extern void isdn_ppp_receive(isdn_net_dev *, isdn_net_local *, struct sk_buff *); -extern int isdn_ppp_dev_ioctl(struct device *, struct ifreq *, int); +extern int isdn_ppp_dev_ioctl(struct net_device *, struct ifreq *, int); extern unsigned int isdn_ppp_poll(struct file *, struct poll_table_struct *); extern int isdn_ppp_ioctl(int, struct file *, unsigned int, unsigned long); extern void isdn_ppp_release(int, struct file *); diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/isdn_tty.c linux/drivers/isdn/isdn_tty.c --- v2.3.13/linux/drivers/isdn/isdn_tty.c Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/isdn_tty.c Thu Aug 12 09:42:33 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_tty.c,v 1.63 1999/04/12 12:33:39 fritz Exp $ +/* $Id: isdn_tty.c,v 1.72 1999/07/31 12:59:45 armin Exp $ * Linux ISDN subsystem, tty functions and AT-command emulator (linklevel). * @@ -20,6 +20,43 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_tty.c,v $ + * Revision 1.72 1999/07/31 12:59:45 armin + * Added tty fax capabilities. + * + * Revision 1.71 1999/07/27 10:34:34 armin + * Fixed last change. Did not compile with AUDIO support off. + * + * Revision 1.70 1999/07/25 16:17:58 keil + * Fix Suspend/Resume + * + * Revision 1.69 1999/07/25 12:56:15 armin + * isdn_tty_at_cout() now queues the message if online and + * data is in queue or flip buffer is full. + * needed for fax connections. + * + * Revision 1.68 1999/07/11 17:51:51 armin + * Bugfix, "-" was missing for AT&L settings. + * + * Revision 1.67 1999/07/11 17:14:12 armin + * Added new layer 2 and 3 protocols for Fax and DSP functions. + * Moved "Add CPN to RING message" to new register S23, + * "Display message" is now correct on register S13 bit 7. + * New audio command AT+VDD implemented (deactivate DTMF decoder and + * activate possible existing hardware/DSP decoder). + * Moved some tty defines to .h file. + * Made whitespace possible in AT command line. + * Some AT-emulator output bugfixes. + * First Fax G3 implementations. + * + * Revision 1.66 1999/07/07 10:13:46 detabc + * remove unused messages + * + * Revision 1.65 1999/07/04 21:01:59 werner + * Added support for keypad and display (ported from 2.0) + * + * Revision 1.64 1999/07/01 08:30:00 keil + * compatibility to 2.3 kernel + * * Revision 1.63 1999/04/12 12:33:39 fritz * Changes from 2.0 tree. * @@ -61,24 +98,12 @@ * brute force fix to avoid Ugh's in isdn_tty_write() * cleaned up some dead code * - * Revision 1.54 1998/06/07 00:20:13 fritz - * abc cleanup. * - * Revision 1.53 1998/06/02 12:10:16 detabc - * wegen einer einstweiliger verfuegung gegen DW ist zur zeit - * die abc-extension bis zur klaerung der rechtslage nicht verfuegbar * * Revision 1.52 1998/03/19 13:18:21 keil * Start of a CAPI like interface for supplementary Service * first service: SUSPEND * - * Revision 1.51 1998/03/08 14:26:11 detabc - * change kfree_skb to dev_kfree_skb - * remove SET_SKB_FREE - * - * Revision 1.50 1998/03/08 13:14:28 detabc - * abc-extension support for kernels > 2.1.x - * first try (sorry experimental) * * Revision 1.49 1998/03/08 00:01:59 fritz * Bugfix: Lowlevel module usage and channel usage were not @@ -303,7 +328,6 @@ static void isdn_tty_check_esc(const u_char *, u_char, int, int *, int *, int); static void isdn_tty_modem_reset_regs(modem_info *, int); static void isdn_tty_cmd_ATA(modem_info *); -static void isdn_tty_at_cout(char *, modem_info *); static void isdn_tty_flush_buffer(struct tty_struct *); static void isdn_tty_modem_result(int, modem_info *); #ifdef CONFIG_ISDN_AUDIO @@ -321,64 +345,8 @@ static int si2bit[8] = {4, 1, 4, 4, 4, 4, 4, 4}; -char *isdn_tty_revision = "$Revision: 1.63 $"; +char *isdn_tty_revision = "$Revision: 1.72 $"; -#define DLE 0x10 -#define ETX 0x03 -#define DC4 0x14 - -/* - * Definition of some special Registers of AT-Emulator - */ -#define REG_RINGATA 0 -#define REG_RINGCNT 1 -#define REG_ESC 2 -#define REG_CR 3 -#define REG_LF 4 -#define REG_BS 5 - -#define REG_WAITC 7 - -#define REG_RESP 12 -#define BIT_RESP 1 -#define REG_RESPNUM 12 -#define BIT_RESPNUM 2 -#define REG_ECHO 12 -#define BIT_ECHO 4 -#define REG_DCD 12 -#define BIT_DCD 8 -#define REG_CTS 12 -#define BIT_CTS 16 -#define REG_DTRR 12 -#define BIT_DTRR 32 -#define REG_DSR 12 -#define BIT_DSR 64 -#define REG_CPPP 12 -#define BIT_CPPP 128 - -#define REG_T70 13 -#define BIT_T70 2 -#define BIT_T70_EXT 32 -#define REG_DTRHUP 13 -#define BIT_DTRHUP 4 -#define REG_RESPXT 13 -#define BIT_RESPXT 8 -#define REG_CIDONCE 13 -#define BIT_CIDONCE 16 -#define REG_RUNG 13 -#define BIT_RUNG 64 -#define REG_RESRXT 13 -#define BIT_RESRXT 128 - -#define REG_L2PROT 14 -#define REG_L3PROT 15 -#define REG_PSIZE 16 -#define REG_WSIZE 17 -#define REG_SI1 18 -#define REG_SI2 19 -#define REG_SI1I 20 -#define REG_PLAN 21 -#define REG_SCREEN 22 /* isdn_tty_try_read() is called from within isdn_tty_rcv_skb() * to stuff incoming data directly into a tty's flip-buffer. This @@ -514,7 +482,7 @@ #ifdef CONFIG_ISDN_AUDIO ifmt = 1; - if (info->vonline) + if ((info->vonline) && (!info->emu.vpar[4])) isdn_audio_calc_dtmf(info, skb->data, skb->len, ifmt); if ((info->vonline & 1) && (info->emu.vpar[1])) isdn_audio_calc_silence(info, skb->data, skb->len, ifmt); @@ -580,6 +548,15 @@ ISDN_AUDIO_SKB_DLECOUNT(skb) = isdn_tty_countDLE(skb->data, skb->len); } +#ifdef CONFIG_ISDN_TTY_FAX + else { + if (info->faxonline & 2) { + isdn_tty_fax_bitorder(info, skb); + ISDN_AUDIO_SKB_DLECOUNT(skb) = + isdn_tty_countDLE(skb->data, skb->len); + } + } +#endif #endif /* Try to deliver directly via tty-flip-buf if queue is empty */ save_flags(flags); @@ -909,6 +886,35 @@ } } +/* + * return the usage calculated by si and layer 2 protocol + */ +int +isdn_calc_usage(int si, int l2) +{ + int usg = ISDN_USAGE_MODEM; + +#ifdef CONFIG_ISDN_AUDIO + if (si == 1) { + switch(l2) { + case ISDN_PROTO_L2_MODEM: + usg = ISDN_USAGE_MODEM; + break; +#ifdef CONFIG_ISDN_TTY_FAX + case ISDN_PROTO_L2_FAX: + usg = ISDN_USAGE_FAX; + break; +#endif + case ISDN_PROTO_L2_TRANS: + default: + usg = ISDN_USAGE_VOICE; + break; + } + } +#endif + return(usg); +} + /* isdn_tty_dial() performs dialing of a tty an the necessary * setup of the lower levels before that. */ @@ -928,8 +934,14 @@ si = bit2si[j]; break; } + usg = isdn_calc_usage(si, l2); #ifdef CONFIG_ISDN_AUDIO - if ((si == 1) && (l2 != ISDN_PROTO_L2_MODEM)) { + if ((si == 1) && + (l2 != ISDN_PROTO_L2_MODEM) +#ifdef CONFIG_ISDN_TTY_FAX + && (l2 != ISDN_PROTO_L2_FAX) +#endif + ) { l2 = ISDN_PROTO_L2_TRANS; usg = ISDN_USAGE_VOICE; } @@ -967,6 +979,12 @@ cmd.driver = info->isdn_driver; cmd.command = ISDN_CMD_SETL3; cmd.arg = info->isdn_channel + (m->mdmreg[REG_L3PROT] << 8); +#ifdef CONFIG_ISDN_TTY_FAX + if (l2 == ISDN_PROTO_L2_FAX) { + cmd.parm.fax = info->fax; + info->fax->direction = ISDN_TTY_FAX_CONN_OUT; + } +#endif isdn_command(&cmd); cmd.driver = info->isdn_driver; cmd.arg = info->isdn_channel; @@ -989,7 +1007,7 @@ * ISDN-line (hangup). The usage-status is cleared * and some cleanup is done also. */ -static void +void isdn_tty_modem_hup(modem_info * info, int local) { isdn_ctrl cmd; @@ -1010,6 +1028,12 @@ } #ifdef CONFIG_ISDN_AUDIO info->vonline = 0; +#ifdef CONFIG_ISDN_TTY_FAX + info->faxonline = 0; + info->fax->phase = ISDN_FAX_PHASE_IDLE; +#endif + info->emu.vpar[4] = 0; + info->emu.vpar[5] = 8; if (info->dtmf_state) { kfree(info->dtmf_state); info->dtmf_state = NULL; @@ -1041,9 +1065,8 @@ } isdn_all_eaz(info->isdn_driver, info->isdn_channel); info->emu.mdmreg[REG_RINGCNT] = 0; - usage = ((info->emu.mdmreg[REG_SI1I] != 1) || - (info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM)) ? - ISDN_USAGE_MODEM : ISDN_USAGE_VOICE; + usage = isdn_calc_usage(info->emu.mdmreg[REG_SI1I], + info->emu.mdmreg[REG_L2PROT]); isdn_free_channel(info->isdn_driver, info->isdn_channel, usage); } @@ -1130,8 +1153,14 @@ si = bit2si[j]; break; } + usg = isdn_calc_usage(si, l2); #ifdef CONFIG_ISDN_AUDIO - if ((si == 1) && (l2 != ISDN_PROTO_L2_MODEM)) { + if ((si == 1) && + (l2 != ISDN_PROTO_L2_MODEM) +#ifdef CONFIG_ISDN_TTY_FAX + && (l2 != ISDN_PROTO_L2_FAX) +#endif + ) { l2 = ISDN_PROTO_L2_TRANS; usg = ISDN_USAGE_VOICE; } @@ -1184,11 +1213,11 @@ cmd.parm.cmsg.para[5] = l; strncpy(&cmd.parm.cmsg.para[6], id, l); cmd.command =CAPI_PUT_MESSAGE; -/* info->dialing = 1; - strcpy(dev->num[i], n); + info->dialing = 1; +// strcpy(dev->num[i], n); isdn_info_update(); -*/ isdn_command(&cmd); + isdn_timer_ctrl(ISDN_TIMER_CARRIER, 1); } } @@ -1218,8 +1247,14 @@ si = bit2si[j]; break; } + usg = isdn_calc_usage(si, l2); #ifdef CONFIG_ISDN_AUDIO - if ((si == 1) && (l2 != ISDN_PROTO_L2_MODEM)) { + if ((si == 1) && + (l2 != ISDN_PROTO_L2_MODEM) +#ifdef CONFIG_ISDN_TTY_FAX + && (l2 != ISDN_PROTO_L2_FAX) +#endif + ) { l2 = ISDN_PROTO_L2_TRANS; usg = ISDN_USAGE_VOICE; } @@ -1863,11 +1898,11 @@ static int isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info * info) { -#if LINUX_VERSION_CODE < 131841 +#ifdef COMPAT_HAS_NEW_WAITQ + DECLARE_WAITQUEUE(wait, NULL); +#else struct wait_queue wait = {current, NULL}; -#else - DECLARE_WAITQUEUE(wait, NULL); #endif int do_clocal = 0; unsigned long flags; @@ -2191,6 +2226,7 @@ m->profile[18] = 4; m->profile[19] = 0; m->profile[20] = 0; + m->profile[23] = 0; m->pmsn[0] = '\0'; m->plmsn[0] = '\0'; } @@ -2203,6 +2239,42 @@ m->vpar[1] = 0; /* Silence detection level (0 = none ) */ m->vpar[2] = 70; /* Silence interval (7 sec. ) */ m->vpar[3] = 2; /* Compression type (1 = ADPCM-2 ) */ + m->vpar[4] = 0; /* DTMF detection level (0 = softcode ) */ + m->vpar[5] = 8; /* DTMF interval (8 * 5 ms. ) */ +} +#endif + +#ifdef CONFIG_ISDN_TTY_FAX +static void +isdn_tty_modem_reset_faxpar(modem_info * info) +{ + T30_s *f = info->fax; + + f->code = 0; + f->phase = ISDN_FAX_PHASE_IDLE; + f->direction = 0; + f->resolution = 1; /* fine */ + f->rate = 5; /* 14400 bit/s */ + f->width = 0; + f->length = 0; + f->compression = 0; + f->ecm = 0; + f->binary = 0; + f->scantime = 0; + memset(&f->id[0], 32, FAXIDLEN - 1); + f->id[FAXIDLEN - 1] = 0; + f->badlin = 0; + f->badmul = 0; + f->bor = 0; + f->nbc = 0; + f->cq = 0; + f->cr = 0; + f->ctcrty = 0; + f->minsp = 0; + f->phcto = 30; + f->rel = 0; + memset(&f->pollid[0], 32, FAXIDLEN - 1); + f->pollid[FAXIDLEN - 1] = 0; } #endif @@ -2219,6 +2291,9 @@ #ifdef CONFIG_ISDN_AUDIO isdn_tty_modem_reset_vpar(m); #endif +#ifdef CONFIG_ISDN_TTY_FAX + isdn_tty_modem_reset_faxpar(info); +#endif m->mdmcmdl = 0; } @@ -2291,10 +2366,16 @@ } for (i = 0; i < ISDN_MAX_CHANNELS; i++) { info = &m->info[i]; -#if LINUX_VERSION_CODE < 131841 - info->write_sem = MUTEX; -#else +#ifdef CONFIG_ISDN_TTY_FAX + if (!(info->fax = kmalloc(sizeof(T30_s), GFP_KERNEL))) { + printk(KERN_ERR "Could not allocate fax t30-buffer\n"); + return -3; + } +#endif +#ifdef COMPAT_HAS_NEW_WAITQ init_MUTEX(&info->write_sem); +#else + info->write_sem = MUTEX; #endif sprintf(info->last_cause, "0000"); sprintf(info->last_num, "none"); @@ -2312,14 +2393,14 @@ info->blocked_open = 0; info->callout_termios = m->cua_modem.init_termios; info->normal_termios = m->tty_modem.init_termios; -#if LINUX_VERSION_CODE < 131841 - info->open_wait = 0; - info->close_wait = 0; -#else +#ifdef COMPAT_HAS_NEW_WAITQ init_waitqueue_head(&info->open_wait); init_waitqueue_head(&info->close_wait); -#endif +#else + info->open_wait = 0; + info->close_wait = 0; info->isdn_driver = -1; +#endif info->isdn_channel = -1; info->drv_index = -1; info->xmit_size = ISDN_SERIAL_XMIT_SIZE; @@ -2371,8 +2452,15 @@ break; } return ret; - } else - return isdn_wildmat(cid, isdn_map_eaz2msn(emu->msn, di)); + } else { + int tmp; + tmp = isdn_wildmat(cid, isdn_map_eaz2msn(emu->msn, di)); +#ifdef ISDN_DEBUG_MODEM_ICALL + printk(KERN_DEBUG "m_fi: mmsn=%s -> tmp=%d\n", + isdn_map_eaz2msn(emu->msn, di), tmp); +#endif + return tmp; + } } /* @@ -2424,7 +2512,7 @@ (info->emu.mdmreg[REG_SI2] == si2)) { /* SI2 is matching */ idx = isdn_dc2minor(di, ch); #ifdef ISDN_DEBUG_MODEM_ICALL - printk(KERN_DEBUG "m_fi: match1\n"); + printk(KERN_DEBUG "m_fi: match1 wret=%d\n", wret); printk(KERN_DEBUG "m_fi: idx=%d flags=%08lx drv=%d ch=%d usg=%d\n", idx, info->flags, info->isdn_driver, info->isdn_channel, dev->usage[idx]); @@ -2446,8 +2534,7 @@ info->drv_index = idx; dev->m_idx[idx] = info->line; dev->usage[idx] &= ISDN_USAGE_EXCLUSIVE; - dev->usage[idx] |= ((si1 != 1) || (info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM)) ? - ISDN_USAGE_MODEM : ISDN_USAGE_VOICE; + dev->usage[idx] |= isdn_calc_usage(si1, info->emu.mdmreg[REG_L2PROT]); strcpy(dev->num[idx], nr); strcpy(info->emu.cpn, eaz); info->emu.mdmreg[REG_SI1I] = si2bit[si1]; @@ -2514,6 +2601,19 @@ /* Signal cause to tty-device */ strncpy(info->last_cause, c->parm.num, 5); return 1; + case ISDN_STAT_DISPLAY: +#ifdef ISDN_TTY_STAT_DEBUG + printk(KERN_DEBUG "tty_STAT_DISPLAY ttyI%d\n", info->line); +#endif + /* Signal display to tty-device */ + if ((info->emu.mdmreg[REG_DISPLAY] & BIT_DISPLAY) && + !(info->emu.mdmreg[REG_RESPNUM] & BIT_RESPNUM)) { + isdn_tty_at_cout("\r\n", info); + isdn_tty_at_cout("DISPLAY: ", info); + isdn_tty_at_cout(c->parm.display, info); + isdn_tty_at_cout("\r\n", info); + } + return 1; case ISDN_STAT_DCONN: #ifdef ISDN_TTY_STAT_DEBUG printk(KERN_DEBUG "tty_STAT_DCONN ttyI%d\n", info->line); @@ -2612,6 +2712,27 @@ } } return 1; +#ifdef CONFIG_ISDN_TTY_FAX + case ISDN_STAT_FAXIND: + if (TTY_IS_ACTIVE(info)) { + isdn_tty_fax_command(info); + } + break; +#endif +#ifdef CONFIG_ISDN_AUDIO + case ISDN_STAT_AUDIO: + if (TTY_IS_ACTIVE(info)) { + switch(c->parm.num[0]) { + case ISDN_AUDIO_DTMF: + if (info->vonline) { + isdn_audio_put_dle_code(info, + c->parm.num[1]); + } + break; + } + } + break; +#endif } } return 0; @@ -2621,13 +2742,13 @@ Modem-Emulator-Routines *********************************************************************/ -#define cmdchar(c) ((c>' ')&&(c<=0x7f)) +#define cmdchar(c) ((c>=' ')&&(c<=0x7f)) /* * Put a message from the AT-emulator into receive-buffer of tty, * convert CR, LF, and BS to values in modem-registers 3, 4 and 5. */ -static void +void isdn_tty_at_cout(char *msg, modem_info * info) { struct tty_struct *tty; @@ -2635,6 +2756,8 @@ char *p; char c; ulong flags; + struct sk_buff *skb = 0; + char *sp = 0; if (!msg) { printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n"); @@ -2643,6 +2766,34 @@ save_flags(flags); cli(); tty = info->tty; + if ((info->flags & ISDN_ASYNC_CLOSING) || (!tty)) { + restore_flags(flags); + return; + } + + /* use queue instead of direct flip, if online and */ + /* data is in queue or flip buffer is full */ + if ((info->online) && (((tty->flip.count + strlen(msg)) >= TTY_FLIPBUF_SIZE) || + (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel])))) { + skb = alloc_skb(strlen(msg) +#ifdef CONFIG_ISDN_AUDIO + + sizeof(isdn_audio_skb) +#endif + , GFP_ATOMIC); + if (!skb) { + restore_flags(flags); + return; + } +#ifdef CONFIG_ISDN_AUDIO + skb_reserve(skb, sizeof(isdn_audio_skb)); +#endif + sp = skb_put(skb, strlen(msg)); +#ifdef CONFIG_ISDN_AUDIO + ISDN_AUDIO_SKB_DLECOUNT(skb) = 0; + ISDN_AUDIO_SKB_LOCK(skb) = 0; +#endif + } + for (p = msg; *p; p++) { switch (*p) { case '\r': @@ -2657,16 +2808,26 @@ default: c = *p; } - if ((info->flags & ISDN_ASYNC_CLOSING) || (!tty)) { - restore_flags(flags); - return; + if (skb) { + *sp++ = c; + } else { + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + break; + tty_insert_flip_char(tty, c, 0); } - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - break; - tty_insert_flip_char(tty, c, 0); } - restore_flags(flags); - queue_task(&tty->flip.tqueue, &tq_timer); + if (skb) { + __skb_queue_tail(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel], skb); + dev->drv[info->isdn_driver]->rcvcount[info->isdn_channel] += skb->len; + restore_flags(flags); + /* Schedule dequeuing */ + if ((dev->modempoll) && (info->rcvsched)) + isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1); + + } else { + restore_flags(flags); + queue_task(&tty->flip.tqueue, &tq_timer); + } } /* @@ -2847,7 +3008,7 @@ break; case 2: /* Append CPN, if enabled */ - if ((m->mdmreg[REG_RESRXT] & BIT_RESRXT)) { + if ((m->mdmreg[REG_CPN] & BIT_CPN)) { sprintf(s, "/%s", m->cpn); isdn_tty_at_cout(s, info); } @@ -2954,8 +3115,9 @@ int limit=39; /* MUST match the size in isdn_tty_parse to avoid buffer overflow */ - while (strchr("0123456789,#.*WPTS-", *p) && *p && --cnt>0) { - if ((*p >= '0' && *p <= '9') || ((*p == 'S') && first)) + while (strchr(" 0123456789,#.*WPTS-", *p) && *p && --cnt>0) { + if ((*p >= '0' && *p <= '9') || ((*p == 'S') && first) || + (*p == '*') || (*p == '#')) *q++ = *p; p++; if(!--limit) @@ -3008,6 +3170,9 @@ case ISDN_PROTO_L2_MODEM: isdn_tty_at_cout("modem", info); break; + case ISDN_PROTO_L2_FAX: + isdn_tty_at_cout("fax", info); + break; default: isdn_tty_at_cout("unknown", info); break; @@ -3107,8 +3272,8 @@ /* &L -Set Numbers to listen on */ p[0]++; i = 0; - while ((strchr("0123456789,*[]?;", *p[0])) && - (i < ISDN_LMSNLEN)) + while ((strchr("0123456789,-*[]?;", *p[0])) && + (i < ISDN_LMSNLEN) && *p[0]) m->lmsn[i++] = *p[0]++; m->lmsn[i] = '\0'; break; @@ -3264,7 +3429,7 @@ int bval; mreg = isdn_getnum(p); - if (mreg < 0 || mreg > ISDN_MODEM_ANZREG) + if (mreg < 0 || mreg >= ISDN_MODEM_ANZREG) PARSE_ERROR1; switch (*p[0]) { case '=': @@ -3338,7 +3503,7 @@ /* If more than one bit set in reg18, autoselect Layer2 */ if ((m->mdmreg[REG_SI1] & m->mdmreg[REG_SI1I]) != m->mdmreg[REG_SI1]) { if (m->mdmreg[REG_SI1I] == 1) { - if (l2 != ISDN_PROTO_L2_MODEM) + if ((l2 != ISDN_PROTO_L2_MODEM) && (l2 != ISDN_PROTO_L2_FAX)) l2 = ISDN_PROTO_L2_TRANS; } else l2 = ISDN_PROTO_L2_X75I; @@ -3352,6 +3517,12 @@ cmd.driver = info->isdn_driver; cmd.command = ISDN_CMD_SETL3; cmd.arg = info->isdn_channel + (m->mdmreg[REG_L3PROT] << 8); +#ifdef CONFIG_ISDN_TTY_FAX + if (l2 == ISDN_PROTO_L2_FAX) { + cmd.parm.fax = info->fax; + info->fax->direction = ISDN_TTY_FAX_CONN_IN; + } +#endif isdn_command(&cmd); cmd.driver = info->isdn_driver; cmd.arg = info->isdn_channel; @@ -3372,7 +3543,6 @@ isdn_tty_cmd_PLUSF(char **p, modem_info * info) { atemu *m = &info->emu; - int par; char rs[20]; if (!strncmp(p[0], "CLASS", 5)) { @@ -3382,6 +3552,10 @@ p[0]++; sprintf(rs, "\r\n%d", (m->mdmreg[REG_SI1] & 1) ? 8 : 0); +#ifdef CONFIG_ISDN_TTY_FAX + if (m->mdmreg[REG_L2PROT] == ISDN_PROTO_L2_FAX) + sprintf(rs, "\r\n2"); +#endif isdn_tty_at_cout(rs, info); break; case '=': @@ -3389,23 +3563,37 @@ switch (*p[0]) { case '0': p[0]++; + m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I; + m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_TRANS; m->mdmreg[REG_SI1] = 4; info->xmit_size = m->mdmreg[REG_PSIZE] * 16; break; +#ifdef CONFIG_ISDN_TTY_FAX case '2': - printk(KERN_DEBUG "isdn_tty: FCLASS=2\n"); p[0]++; + m->mdmreg[REG_SI1] = 1; + m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_FAX; + m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_FAX; + info->xmit_size = + m->mdmreg[REG_PSIZE] * 16; break; +#endif case '8': p[0]++; + /* L2 will change on dialout with si=1 */ + m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I; + m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_TRANS; m->mdmreg[REG_SI1] = 5; info->xmit_size = VBUF; break; case '?': p[0]++; - isdn_tty_at_cout("\r\n0,2,8", - info); +#ifdef CONFIG_ISDN_TTY_FAX + isdn_tty_at_cout("\r\n0,2,8", info); +#else + isdn_tty_at_cout("\r\n0,8", info); +#endif break; default: PARSE_ERROR1; @@ -3416,115 +3604,11 @@ } return 0; } - if (!strncmp(p[0], "AA", 2)) { - p[0] += 2; - switch (*p[0]) { - case '?': - p[0]++; - sprintf(rs, "\r\n%d", - m->mdmreg[REG_RINGATA]); - isdn_tty_at_cout(rs, info); - break; - case '=': - p[0]++; - par = isdn_getnum(p); - if ((par < 0) || (par > 255)) - PARSE_ERROR1; - m->mdmreg[REG_RINGATA] = par; - break; - default: - PARSE_ERROR1; - } - return 0; - } - if (!strncmp(p[0], "TBC=", 4)) { /* UNKLAR !! */ - p[0] += 4; - printk(KERN_DEBUG "isdn_tty: Fax FTBC=%c\n", *p[0]); - switch (*p[0]) { - case '0': - p[0]++; - break; - default: - PARSE_ERROR1; - } - return 0; - } - if (!strncmp(p[0], "BOR=", 4)) { /* UNKLAR !! */ - p[0] += 4; - printk(KERN_DEBUG "isdn_tty: Fax FBOR=%c\n", *p[0]); - switch (*p[0]) { - case '0': - p[0]++; - break; - default: - PARSE_ERROR1; - } - return 0; - } - if (!strncmp(p[0], "DCC=", 4)) { /* SETUP irgendwie !! */ - int i, val[]={0,0,0,0,0,0,0,0}; - - p[0] += 4; - if (*p[0] == '?') { - isdn_tty_at_cout("\r\n(0,1),(0-5),(0-2),(0-2),(0,1),(0),(0),(0-7)",info); - p[0]++; - } else { - for (i=0; (*p[0]>='0') && (*p[0]<='9'); i++) { - val[i] = *p[0] - 48; - p[0]++; - if (*p[0] == ',') - p[0]++; - } - printk(KERN_DEBUG "isdn_tty: Fax Setup values=%d,%d,%d,%d,%d,%d,%d,%d\n", - val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]); - } - return 0; - } - if (!strncmp(p[0], "LID=", 4)) { /* set sender ID !! */ - char senderID[80]; - int i; - - p[0] += 4; - if (*p[0] =='"') - p[0]++; - for(i=0; (*p[0]) && (*p[0] != '"'); i++) - senderID[i] = *p[0]++; - senderID[i] = 0; - if (*p[0] =='"') - p[0]++; - printk(KERN_DEBUG "isdn_tty: Fax sender=>%s<\n", senderID); - return 0; - } - if (!strncmp(p[0], "MFR?", 4)) { - p[0] += 4; - printk(KERN_DEBUG "isdn_tty: FMFR?\n"); - isdn_tty_at_cout("\r\nISDNfax", info); - return 0; - } - if (!strncmp(p[0], "MDL?", 4)) { - p[0] += 4; - printk(KERN_DEBUG "isdn_tty: FMDL?\n"); - isdn_tty_at_cout("\r\nAVM-B1", info); - return 0; - } - if (!strncmp(p[0], "AP=?", 4)) { - p[0] += 4; - printk(KERN_DEBUG "isdn_tty: FAP=?\n"); - return 0; - } - if (!strncmp(p[0], "PHCTO=", 6)) { - /* beim trace mit dem zyxel folgt der wert 30 ;*/ - p[0] += 6; - printk(KERN_DEBUG "isdn_tty: FPHCTO=%s\n", p[0]); - return 0; - } - if (!strncmp(p[0], "CR=", 3)) { - p[0] += 3; - printk(KERN_DEBUG "isdn_tty: FCR=%s\n", p[0]); - return 0; - } - printk(KERN_DEBUG "isdn_tty: unknown token=>AT+F%s<\n", p[0]); +#ifdef CONFIG_ISDN_TTY_FAX + return (isdn_tty_cmd_PLUSF_FAX(p, info)); +#else PARSE_ERROR1; +#endif } /* @@ -3534,8 +3618,9 @@ isdn_tty_cmd_PLUSV(char **p, modem_info * info) { atemu *m = &info->emu; + isdn_ctrl cmd; static char *vcmd[] = - {"NH", "IP", "LS", "RX", "SD", "SM", "TX", NULL}; + {"NH", "IP", "LS", "RX", "SD", "SM", "TX", "DD", NULL}; int i; int par1; int par2; @@ -3711,9 +3796,9 @@ info); isdn_tty_at_cout("4;ADPCM;4;0;(8000)\r\n", info); - isdn_tty_at_cout("5;ALAW;8;0;(8000)", + isdn_tty_at_cout("5;ALAW;8;0;(8000)\r\n", info); - isdn_tty_at_cout("6;ULAW;8;0;(8000)", + isdn_tty_at_cout("6;ULAW;8;0;(8000)\r\n", info); break; default: @@ -3752,6 +3837,52 @@ isdn_tty_modem_result(1, info); return 0; break; + case 7: + /* AT+VDD - DTMF detection */ + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n<%d>,<%d>", + m->vpar[4], + m->vpar[5]); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if ((*p[0]>='0') && (*p[0]<='9')) { + if (info->online != 1) + PARSE_ERROR1; + par1 = isdn_getnum(p); + if ((par1 < 0) || (par1 > 15)) + PARSE_ERROR1; + if (*p[0] != ',') + PARSE_ERROR1; + p[0]++; + par2 = isdn_getnum(p); + if ((par2 < 0) || (par2 > 255)) + PARSE_ERROR1; + m->vpar[4] = par1; + m->vpar[5] = par2; + cmd.driver = info->isdn_driver; + cmd.command = ISDN_CMD_AUDIO; + cmd.arg = info->isdn_channel + (ISDN_AUDIO_SETDD << 8); + cmd.parm.num[0] = par1; + cmd.parm.num[1] = par2; + isdn_command(&cmd); + break; + } else + if (*p[0] == '?') { + p[0]++; + isdn_tty_at_cout("\r\n<0-15>,<0-255>", + info); + break; + } else + PARSE_ERROR1; + break; + default: + PARSE_ERROR1; + } + break; default: PARSE_ERROR1; } @@ -3774,6 +3905,9 @@ #endif for (p = &m->mdmcmd[2]; *p;) { switch (*p) { + case ' ': + p++; + break; case 'A': /* A - Accept incoming call */ p++; @@ -3919,8 +4053,10 @@ isdn_tty_suspend(ds, info, m); break; case 'R': /* RESUME */ + p++; isdn_tty_get_msnstr(ds, &p); isdn_tty_resume(ds, info, m); + break; case 'M': /* MESSAGE */ p++; isdn_tty_send_msg(info, m, p); @@ -3981,7 +4117,7 @@ eb[1] = 0; isdn_tty_at_cout(eb, info); } - if (m->mdmcmdl >= 2) + if ((m->mdmcmdl >= 2) && (!(strncmp(m->mdmcmd, "AT", 2)))) isdn_tty_parse_at(info); m->mdmcmdl = 0; continue; @@ -4007,15 +4143,16 @@ switch (m->mdmcmdl) { case 0: if (c == 'A') - m->mdmcmd[m->mdmcmdl++] = c; + m->mdmcmd[m->mdmcmdl] = c; break; case 1: if (c == 'T') - m->mdmcmd[m->mdmcmdl++] = c; + m->mdmcmd[m->mdmcmdl] = c; break; default: - m->mdmcmd[m->mdmcmdl++] = c; + m->mdmcmd[m->mdmcmdl] = c; } + m->mdmcmd[++m->mdmcmdl] = 0; } } } diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/isdn_tty.h linux/drivers/isdn/isdn_tty.h --- v2.3.13/linux/drivers/isdn/isdn_tty.h Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/isdn_tty.h Sun Aug 15 11:49:08 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_tty.h,v 1.13 1999/04/12 12:33:46 fritz Exp $ +/* $Id: isdn_tty.h,v 1.15 1999/07/31 12:59:48 armin Exp $ * header for Linux ISDN subsystem, tty related functions (linklevel). * @@ -20,6 +20,20 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_tty.h,v $ + * Revision 1.15 1999/07/31 12:59:48 armin + * Added tty fax capabilities. + * + * Revision 1.14 1999/07/11 17:14:15 armin + * Added new layer 2 and 3 protocols for Fax and DSP functions. + * Moved "Add CPN to RING message" to new register S23, + * "Display message" is now correct on register S13 bit 7. + * New audio command AT+VDD implemented (deactivate DTMF decoder and + * activate possible existing hardware/DSP decoder). + * Moved some tty defines to .h file. + * Made whitespace possible in AT command line. + * Some AT-emulator output bugfixes. + * First Fax G3 implementations. + * * Revision 1.13 1999/04/12 12:33:46 fritz * Changes from 2.0 tree. * @@ -72,6 +86,69 @@ * */ +#include + +#define DLE 0x10 +#define ETX 0x03 +#define DC4 0x14 + + +/* + * Definition of some special Registers of AT-Emulator + */ +#define REG_RINGATA 0 +#define REG_RINGCNT 1 +#define REG_ESC 2 +#define REG_CR 3 +#define REG_LF 4 +#define REG_BS 5 + +#define REG_WAITC 7 + +#define REG_RESP 12 +#define BIT_RESP 1 +#define REG_RESPNUM 12 +#define BIT_RESPNUM 2 +#define REG_ECHO 12 +#define BIT_ECHO 4 +#define REG_DCD 12 +#define BIT_DCD 8 +#define REG_CTS 12 +#define BIT_CTS 16 +#define REG_DTRR 12 +#define BIT_DTRR 32 +#define REG_DSR 12 +#define BIT_DSR 64 +#define REG_CPPP 12 +#define BIT_CPPP 128 + +#define REG_T70 13 +#define BIT_T70 2 +#define BIT_T70_EXT 32 +#define REG_DTRHUP 13 +#define BIT_DTRHUP 4 +#define REG_RESPXT 13 +#define BIT_RESPXT 8 +#define REG_CIDONCE 13 +#define BIT_CIDONCE 16 +#define REG_RUNG 13 +#define BIT_RUNG 64 +#define REG_DISPLAY 13 +#define BIT_DISPLAY 128 + +#define REG_L2PROT 14 +#define REG_L3PROT 15 +#define REG_PSIZE 16 +#define REG_WSIZE 17 +#define REG_SI1 18 +#define REG_SI2 19 +#define REG_SI1I 20 +#define REG_PLAN 21 +#define REG_SCREEN 22 + +#define REG_CPN 23 +#define BIT_CPN 1 + extern void isdn_tty_modem_escape(void); extern void isdn_tty_modem_ring(void); extern void isdn_tty_carrier_timeout(void); @@ -83,3 +160,10 @@ extern int isdn_tty_stat_callback(int, isdn_ctrl *); extern int isdn_tty_rcv_skb(int, int, int, struct sk_buff *); extern int isdn_tty_capi_facility(capi_msg *cm); +extern void isdn_tty_at_cout(char *, modem_info *); +extern void isdn_tty_modem_hup(modem_info *, int); +#ifdef CONFIG_ISDN_TTY_FAX +extern int isdn_tty_cmd_PLUSF_FAX(char **, modem_info *); +extern int isdn_tty_fax_command(modem_info *); +extern void isdn_tty_fax_bitorder(modem_info *, struct sk_buff *); +#endif diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/isdn_ttyfax.c linux/drivers/isdn/isdn_ttyfax.c --- v2.3.13/linux/drivers/isdn/isdn_ttyfax.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/isdn_ttyfax.c Sun Aug 15 11:49:08 1999 @@ -0,0 +1,1200 @@ +/* $Id: isdn_ttyfax.c,v 1.2 1999/08/05 10:36:10 armin Exp $ + * Linux ISDN subsystem, tty_fax AT-command emulator (linklevel). + * + * Copyright 1999 by Armin Schindler (mac@melware.de) + * Copyright 1999 by Ralf Spachmann (mel@melware.de) + * Copyright 1999 by Cytronics & Melware + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Log: isdn_ttyfax.c,v $ + * Revision 1.2 1999/08/05 10:36:10 armin + * Bugfix: kernel oops on getting revision. + * + * Revision 1.1 1999/07/31 12:59:50 armin + * Added tty fax capabilities. + * + * + */ + +#undef ISDN_TTY_FAX_STAT_DEBUG +#undef ISDN_TTY_FAX_CMD_DEBUG + +#define __NO_VERSION__ +#include +#include +#include "isdn_common.h" +#include "isdn_tty.h" +#include "isdn_ttyfax.h" + + +static char *isdn_tty_fax_revision = "$Revision: 1.2 $"; + +#define PARSE_ERROR1 { isdn_tty_fax_modem_result(1, info); return 1; } + +static char * +isdn_getrev(const char *revision) +{ + char *rev; + char *p; + + if ((p = strchr(revision, ':'))) { + rev = p + 2; + p = strchr(rev, '$'); + *--p = 0; + } else + rev = "???"; + return rev; +} + + +/* + * Fax Class 2 Modem results + * + */ +static void isdn_tty_fax_modem_result(int code, modem_info * info) +{ + atemu *m = &info->emu; + T30_s *f = info->fax; + char rs[50]; + char rss[50]; + char *rp; + int i; + static char *msg[] = + {"OK", "ERROR", "+FCON", "+FCSI:", "+FDIS:", + "+FHNG:", "+FDCS:", "CONNECT", "+FTSI:", + "+FCFR", "+FPTS:", "+FET:" }; + + + isdn_tty_at_cout("\r\n", info); + isdn_tty_at_cout(msg[code], info); + +#ifdef ISDN_TTY_FAX_CMD_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax send %s on ttyI%d\n", + msg[code], info->line); +#endif + switch (code) { + case 0: /* OK */ + break; + case 1: /* ERROR */ + break; + case 2: /* +FCON */ + /* Append CPN, if enabled */ + if ((m->mdmreg[REG_CPN] & BIT_CPN) && + (!(dev->usage[info->isdn_channel] & ISDN_USAGE_OUTGOING))) { + sprintf(rs, "/%s", m->cpn); + isdn_tty_at_cout(rs, info); + } + info->online = 1; + f->fet = 0; + if (f->phase == ISDN_FAX_PHASE_A) + f->phase = ISDN_FAX_PHASE_B; + break; + case 3: /* +FCSI */ + case 8: /* +FTSI */ + sprintf(rs, "\"%s\"", f->r_id); + isdn_tty_at_cout(rs, info); + break; + case 4: /* +FDIS */ + rs[0] = 0; + rp = &f->r_resolution; + for(i = 0; i < 8; i++) { + sprintf(rss, "%c%s", rp[i] + 48, + (i < 7) ? "," : ""); + strcat(rs, rss); + } + isdn_tty_at_cout(rs, info); +#ifdef ISDN_TTY_FAX_CMD_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax DIS=%s on ttyI%d\n", + rs, info->line); +#endif + break; + case 5: /* +FHNG */ + sprintf(rs, "%d", f->code); + isdn_tty_at_cout(rs, info); + info->faxonline = 0; + break; + case 6: /* +FDCS */ + rs[0] = 0; + rp = &f->r_resolution; + for(i = 0; i < 8; i++) { + sprintf(rss, "%c%s", rp[i] + 48, + (i < 7) ? "," : ""); + strcat(rs, rss); + } + isdn_tty_at_cout(rs, info); +#ifdef ISDN_TTY_FAX_CMD_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax DCS=%s on ttyI%d\n", + rs, info->line); +#endif + break; + case 7: /* CONNECT */ + info->faxonline |= 2; + break; + case 9: /* FCFR */ + break; + case 10: /* FPTS */ + isdn_tty_at_cout("1", info); + break; + case 11: /* FET */ + sprintf(rs, "%d", f->fet); + isdn_tty_at_cout(rs, info); + break; + } + + isdn_tty_at_cout("\r\n", info); + + switch (code) { + case 7: /* CONNECT */ + info->online = 2; + if (info->faxonline & 1) { + sprintf(rs, "%c", XON); + isdn_tty_at_cout(rs, info); + } + break; + } +} + +int +isdn_tty_fax_command(modem_info * info) +{ + T30_s *f = info->fax; + char rs[10]; + +#ifdef ISDN_TTY_FAX_CMD_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax cmd %d on ttyI%d\n", + f->r_code, info->line); +#endif + switch(f->r_code) { + case ISDN_TTY_FAX_FCON: + info->faxonline = 1; + isdn_tty_fax_modem_result(2, info); /* +FCON */ + return(0); + case ISDN_TTY_FAX_FCON_I: + info->faxonline = 16; + isdn_tty_fax_modem_result(2, info); /* +FCON */ + return(0); + case ISDN_TTY_FAX_RID: + if (info->faxonline & 1) + isdn_tty_fax_modem_result(3, info); /* +FCSI */ + if (info->faxonline & 16) + isdn_tty_fax_modem_result(8, info); /* +FTSI */ + return(0); + case ISDN_TTY_FAX_DIS: + isdn_tty_fax_modem_result(4, info); /* +FDIS */ + return(0); + case ISDN_TTY_FAX_HNG: + if (f->phase == ISDN_FAX_PHASE_C) { + if (f->direction == ISDN_TTY_FAX_CONN_IN) { + sprintf(rs, "%c%c", DLE, ETX); + isdn_tty_at_cout(rs, info); + } else { + sprintf(rs, "%c", 0x18); + isdn_tty_at_cout(rs, info); + } + info->faxonline &= ~2; /* leave data mode */ + info->online = 1; + } + f->phase = ISDN_FAX_PHASE_E; + isdn_tty_fax_modem_result(5, info); /* +FHNG */ + isdn_tty_fax_modem_result(0, info); /* OK */ + return(0); + case ISDN_TTY_FAX_DCS: + isdn_tty_fax_modem_result(6, info); /* +FDCS */ + isdn_tty_fax_modem_result(7, info); /* CONNECT */ + f->phase = ISDN_FAX_PHASE_C; + return(0); + case ISDN_TTY_FAX_TRAIN_OK: + isdn_tty_fax_modem_result(6, info); /* +FDCS */ + isdn_tty_fax_modem_result(0, info); /* OK */ + return(0); + case ISDN_TTY_FAX_SENT: + isdn_tty_fax_modem_result(0, info); /* OK */ + return(0); + case ISDN_TTY_FAX_CFR: + isdn_tty_fax_modem_result(9, info); /* +FCFR */ + return(0); + case ISDN_TTY_FAX_ET: + sprintf(rs, "%c%c", DLE, ETX); + isdn_tty_at_cout(rs, info); + isdn_tty_fax_modem_result(10, info); /* +FPTS */ + isdn_tty_fax_modem_result(11, info); /* +FET */ + isdn_tty_fax_modem_result(0, info); /* OK */ + info->faxonline &= ~2; /* leave data mode */ + info->online = 1; + f->phase = ISDN_FAX_PHASE_D; + return(0); + case ISDN_TTY_FAX_PTS: + isdn_tty_fax_modem_result(10, info); /* +FPTS */ + if (f->direction == ISDN_TTY_FAX_CONN_OUT) { + if (f->fet == 1) + f->phase = ISDN_FAX_PHASE_B; + if (f->fet == 0) + isdn_tty_fax_modem_result(0, info); /* OK */ + } + return(0); + case ISDN_TTY_FAX_EOP: + info->faxonline &= ~2; /* leave data mode */ + info->online = 1; + f->phase = ISDN_FAX_PHASE_D; + return(0); + + } + return(-1); +} + + +void +isdn_tty_fax_bitorder(modem_info *info, struct sk_buff *skb) +{ + __u8 LeftMask; + __u8 RightMask; + __u8 fBit; + __u8 Data; + int i; + + if (!info->fax->bor) { + for(i = 0; i < skb->len; i++) { + Data = skb->data[i]; + for ( + LeftMask = 0x80, RightMask = 0x01; + LeftMask > RightMask; + LeftMask >>= 1, RightMask <<= 1 + ) { + fBit = (Data & LeftMask); + if (Data & RightMask) + Data |= LeftMask; + else + Data &= ~LeftMask; + if (fBit) + Data |= RightMask; + else + Data &= ~RightMask; + + } + skb->data[i] = Data; + } + } +} + +/* + * Parse AT+F.. FAX class 2 commands + */ + +int isdn_tty_cmd_PLUSF_FAX(char **p, modem_info * info) +{ + atemu *m = &info->emu; + T30_s *f = info->fax; + isdn_ctrl cmd; + int par; + char rs[50]; + char rss[50]; + int maxdccval[]={1,5,2,2,3,2,0,7}; + + /* FAA still unchanged */ + if (!strncmp(p[0], "AA", 2)) { /* TODO */ + p[0] += 2; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n%d", 0); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + par = isdn_getnum(p); + if ((par < 0) || (par > 255)) + PARSE_ERROR1; + break; + default: + PARSE_ERROR1; + } + return 0; + } + + /* BADLIN=value - dummy 0=disable errorchk disabled, 1-255 nr. of lines for making page bad */ + if (!strncmp(p[0], "BADLIN", 6)) { + p[0] += 6; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n%d",f->badlin); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') + { + p[0]++; + sprintf(rs, "\r\n0-255"); + isdn_tty_at_cout(rs, info); + } + else + { + par = isdn_getnum(p); + if ((par < 0) || (par > 255)) + PARSE_ERROR1; + f->badlin = par; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FBADLIN=%d\n", par); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } + + /* BADMUL=value - dummy 0=disable errorchk disabled (treshold multiplier) */ + if (!strncmp(p[0], "BADMUL", 6)){ + p[0] +=6; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n%d", f->badmul); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') + { + p[0]++; + sprintf(rs, "\r\n0-255"); + isdn_tty_at_cout(rs, info); + } + else + { + par = isdn_getnum(p); + if ((par < 0) || (par > 255)) + PARSE_ERROR1; + f->badmul = par; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FBADMUL=%d\n", par); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } + + /* BOR=n - Phase C bit order, 0=direct, 1=reverse */ + if (!strncmp(p[0], "BOR", 3)){ + p[0] +=3; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n%d", f->bor); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') + { + p[0]++; + sprintf(rs, "\r\n0,1"); + isdn_tty_at_cout(rs, info); + } + else + { + par = isdn_getnum(p); + if ((par < 0) || (par > 1)) + PARSE_ERROR1; + f->bor = par; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FBOR=%d\n", par); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } + + /* NBC=n - No Best Capabilities */ + if (!strncmp(p[0], "NBC", 3)){ + p[0] +=3; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n%d", f->nbc); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') + { + p[0]++; + sprintf(rs, "\r\n0,1"); + isdn_tty_at_cout(rs, info); + } + else + { + par = isdn_getnum(p); + if ((par < 0) || (par > 1)) + PARSE_ERROR1; + f->nbc = par; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FNBC=%d\n", par); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } + + /* BUF? - Readonly buffersize readout */ + if (!strncmp(p[0], "BUF?", 4)) { + p[0] += 4; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FBUF? (%d) \n", (16 * m->mdmreg[REG_PSIZE])); +#endif + p[0]++; + sprintf(rs, "\r\n %d ", (16 * m->mdmreg[REG_PSIZE])); + isdn_tty_at_cout(rs, info); + return 0; + } + + /* CIG=string - local fax station id string for polling rx */ + if (!strncmp(p[0], "CIG", 3)) { + int i, r; + p[0] += 3; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n\"%s\"", f->pollid); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') + { + p[0]++; + sprintf(rs, "\r\n\"STRING\""); + isdn_tty_at_cout(rs, info); + } + else + { + if (*p[0] =='"') + p[0]++; + for(i=0; (*p[0]) && i < (FAXIDLEN-1) && (*p[0] != '"'); i++) + { + f->pollid[i] = *p[0]++; + } + if (*p[0] =='"') + p[0]++; + for(r=i; r < FAXIDLEN; r++) + { + f->pollid[r] = 32; + } + f->pollid[FAXIDLEN-1] = 0; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax local poll ID rx \"%s\"\n", f->pollid); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } + + /* CQ=n - copy qlty chk, 0= no chk, 1=only 1D chk, 2=1D+2D chk */ + if (!strncmp(p[0], "CQ", 2)) { + p[0] += 2; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n%d", f->cq); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') + { + p[0]++; + sprintf(rs, "\r\n0,1,2"); + isdn_tty_at_cout(rs, info); + } + else + { + par = isdn_getnum(p); + if ((par < 0) || (par > 2)) + PARSE_ERROR1; + f->cq = par; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FCQ=%d\n", par); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } + + /* CR=n - can receive? 0= no data rx or poll remote dev, 1=do receive data or poll remote dev */ + if (!strncmp(p[0], "CR", 2)) { + p[0] += 2; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n%d", f->cr); /* read actual value from struct and print */ + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') + { + p[0]++; + sprintf(rs, "\r\n0,1"); /* display online help */ + isdn_tty_at_cout(rs, info); + } + else + { + par = isdn_getnum(p); + if ((par < 0) || (par > 1)) + PARSE_ERROR1; + f->cr = par; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FCR=%d\n", par); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } + + /* CTCRTY=value - ECM retry count */ + if (!strncmp(p[0], "CTCRTY", 6)){ + p[0] +=6; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n%d",f->ctcrty); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') + { + p[0]++; + sprintf(rs, "\r\n0-255"); + isdn_tty_at_cout(rs, info); + } + else + { + par = isdn_getnum(p); + if ((par < 0) || (par > 255)) + PARSE_ERROR1; + f->ctcrty = par; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FCTCRTY=%d\n", par); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } + + /* DCC=vr,br,wd,ln,df,ec,bf,st - DCE capabilities parms */ + if (!strncmp(p[0], "DCC", 3)) { + char *rp = &f->resolution; + int i; + + p[0] += 3; + switch(*p[0]) { + case '?': + p[0]++; + strcpy(rs, "\r\n"); + for(i = 0; i < 8; i++) { + sprintf(rss, "%c%s", rp[i] + 48, + (i < 7) ? "," : ""); + strcat(rs, rss); + } + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') { + isdn_tty_at_cout("\r\n(0,1),(0-5),(0-2),(0-2),(0-3),(0-2),(0),(0-7)",info); + p[0]++; + } else { + for (i=0; (((*p[0]>='0')&&(*p[0]<='9'))||(*p[0]==','))&&(i<8); i++) { + if (*p[0] != ',') { + if ((*p[0] - 48) > maxdccval[i]) { + PARSE_ERROR1; + } + rp[i] = *p[0] - 48; + p[0]++; + if (*p[0] == ',') + p[0]++; + } else p[0]++; + } +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FDCC capabilities DCE=%d,%d,%d,%d,%d,%d,%d,%d\n", + rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7]); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } + + /* DIS=vr,br,wd,ln,df,ec,bf,st - current session parms */ + if (!strncmp(p[0], "DIS", 3)) { + char *rp = &f->resolution; + int i; + + p[0] += 3; + switch(*p[0]) { + case '?': + p[0]++; + strcpy(rs, "\r\n"); + for(i = 0; i < 8; i++) { + sprintf(rss, "%c%s", rp[i] + 48, + (i < 7) ? "," : ""); + strcat(rs, rss); + } + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') { + isdn_tty_at_cout("\r\n(0,1),(0-5),(0-2),(0-2),(0-3),(0-2),(0),(0-7)",info); + p[0]++; + } else { + for (i=0; (((*p[0]>='0')&&(*p[0]<='9'))||(*p[0]==','))&&(i<8); i++) { + if (*p[0] != ',') { + if ((*p[0] - 48) > maxdccval[i]) { + PARSE_ERROR1; + } + rp[i] = *p[0] - 48; + p[0]++; + if (*p[0] == ',') + p[0]++; + } else p[0]++; + } +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FDIS session parms=%d,%d,%d,%d,%d,%d,%d,%d\n", + rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7]); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } + + /* DR - Receive Phase C data command, initiates document reception */ + if (!strncmp(p[0], "DR", 2)) { + p[0] += 2; + if ((info->faxonline & 16) && /* incoming connection */ + ((f->phase == ISDN_FAX_PHASE_B) || (f->phase == ISDN_FAX_PHASE_D))) { +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FDR\n"); +#endif + f->code = ISDN_TTY_FAX_DR; + cmd.driver = info->isdn_driver; + cmd.arg = info->isdn_channel; + cmd.command = ISDN_CMD_FAXCMD; + isdn_command(&cmd); + if (f->phase == ISDN_FAX_PHASE_B) { + f->phase = ISDN_FAX_PHASE_C; + } else if (f->phase == ISDN_FAX_PHASE_D) { + switch(f->fet) { + case 0: /* next page will be received */ + f->phase = ISDN_FAX_PHASE_C; + isdn_tty_fax_modem_result(7, info); /* CONNECT */ + break; + case 1: /* next doc will be received */ + f->phase = ISDN_FAX_PHASE_B; + break; + case 2: /* fax session is terminating */ + f->phase = ISDN_FAX_PHASE_E; + break; + default: + PARSE_ERROR1; + } + } + } else { + PARSE_ERROR1; + } + return 1; + } + + /* DT=df,vr,wd,ln - TX phase C data command (release DCE to proceed with negotiation) */ + if (!strncmp(p[0], "DT", 2)) { + int i, val[]={4,0,2,3}; + char *rp = &f->resolution; + + p[0] += 2; + if (!info->faxonline & 1) /* not outgoing connection */ + PARSE_ERROR1; + + for (i=0; (((*p[0]>='0')&&(*p[0]<='9'))||(*p[0]==','))&&(i<4); i++) { + if (*p[0] != ',') { + if ((*p[0] - 48) > maxdccval[val[i]]) { + PARSE_ERROR1; + } + rp[val[i]] = *p[0] - 48; + p[0]++; + if (*p[0] == ',') + p[0]++; + } else p[0]++; + } +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FDT tx data command parms=%d,%d,%d,%d\n", + rp[4], rp[0], rp[2], rp[3]); +#endif + if ((f->phase == ISDN_FAX_PHASE_B) || (f->phase == ISDN_FAX_PHASE_D)) { + f->code = ISDN_TTY_FAX_DT; + cmd.driver = info->isdn_driver; + cmd.arg = info->isdn_channel; + cmd.command = ISDN_CMD_FAXCMD; + isdn_command(&cmd); + if (f->phase == ISDN_FAX_PHASE_D) { + f->phase = ISDN_FAX_PHASE_C; + isdn_tty_fax_modem_result(7, info); /* CONNECT */ + } + } else { + PARSE_ERROR1; + } + return 1; + } + + /* ECM=n - Error mode control 0=disabled, 2=enabled, handled by DCE alone incl. buff of partial pages */ + if (!strncmp(p[0], "ECM", 3)) { + p[0] += 3; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n%d",f->ecm); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') + { + p[0]++; + sprintf(rs, "\r\n0,2"); + isdn_tty_at_cout(rs, info); + } + else + { + par = isdn_getnum(p); + if ((par != 0) && (par != 2)) + PARSE_ERROR1; + f->ecm = par; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FECM=%d\n", par); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } + + /* ET=n - End of page or document */ + if (!strncmp(p[0], "ET=", 3)) { + p[0] += 3; + if (*p[0] == '?') { + p[0]++; + sprintf(rs, "\r\n0-2"); + isdn_tty_at_cout(rs, info); + } else { + if ((f->phase != ISDN_FAX_PHASE_D) || (!info->faxonline & 1)) + PARSE_ERROR1; + par = isdn_getnum(p); + if ((par < 0) || (par > 2)) + PARSE_ERROR1; + f->fet = par; + f->code = ISDN_TTY_FAX_ET; + cmd.driver = info->isdn_driver; + cmd.arg = info->isdn_channel; + cmd.command = ISDN_CMD_FAXCMD; + isdn_command(&cmd); +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FET=%d\n", par); +#endif + return 1; + } + return 0; + } + + /* K - terminate */ + if (!strncmp(p[0], "K", 1)) { + p[0] += 1; + if ((f->phase == ISDN_FAX_PHASE_IDLE) || (f->phase == ISDN_FAX_PHASE_E)) + PARSE_ERROR1; + isdn_tty_modem_hup(info, 1); + return 1; + } + + /* LID=string - local fax ID */ + if (!strncmp(p[0], "LID", 3)) { + int i, r; + p[0] += 3; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n\"%s\"", f->id); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') + { + p[0]++; + sprintf(rs, "\r\n\"STRING\""); + isdn_tty_at_cout(rs, info); + } + else + { + if (*p[0] =='"') + p[0]++; + for(i=0; (*p[0]) && i < (FAXIDLEN-1) && (*p[0] != '"'); i++) + { + f->id[i] = *p[0]++; + } + if (*p[0] =='"') + p[0]++; + for(r=i; r < FAXIDLEN; r++) + { + f->id[r] = 32; + } + f->id[FAXIDLEN-1] = 0; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax local ID \"%s\"\n", f->id); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } + +#if 0 + /* LO=n - Flow control opts */ + if (!strncmp(p[0], "LO", 2)) { /* TODO */ + p[0] += 2; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n%d",f->lo); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') + { + p[0]++; + sprintf(rs, "\r\n0,1,2"); + isdn_tty_at_cout(rs, info); + } + else + { + par = isdn_getnum(p); + if ((par < 0) || (par > 2)) + PARSE_ERROR1; + f->lo = par; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FLO=%d\n", par); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } +#endif +#if 0 + /* LPL=n - Doc for polling cmd */ + if (!strncmp(p[0], "LPL", 3)) { /* TODO */ + p[0] += 3; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n%d",f->lpl); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') + { + p[0]++; + sprintf(rs, "\r\n0,1"); + isdn_tty_at_cout(rs, info); + } + else + { + par = isdn_getnum(p); + if ((par < 0) || (par > 1)) + PARSE_ERROR1; + f->lpl = par; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FLPL=%d\n", par); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } +#endif + + /* MDL? - DCE Model */ + if (!strncmp(p[0], "MDL?", 4)) { + p[0] += 4; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: FMDL?\n"); +#endif + isdn_tty_at_cout("\r\nisdn4linux", info); + return 0; + } + + /* MFR? - DCE Manufacturer */ + if (!strncmp(p[0], "MFR?", 4)) { + p[0] += 4; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: FMFR?\n"); +#endif + isdn_tty_at_cout("\r\nisdn4linux", info); + return 0; + } + + /* MINSP=n - Minimum Speed for Phase C */ + if (!strncmp(p[0], "MINSP", 5)) { + p[0] += 5; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n%d",f->minsp); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') + { + p[0]++; + sprintf(rs, "\r\n0-5"); + isdn_tty_at_cout(rs, info); + } + else + { + par = isdn_getnum(p); + if ((par < 0) || (par > 5)) + PARSE_ERROR1; + f->minsp = par; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FMINSP=%d\n", par); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } + + /* PHCTO=value - DTE phase C timeout */ + if (!strncmp(p[0], "PHCTO", 5)){ + p[0] +=5; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n%d",f->phcto); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') + { + p[0]++; + sprintf(rs, "\r\n0-255"); + isdn_tty_at_cout(rs, info); + } + else + { + par = isdn_getnum(p); + if ((par < 0) || (par > 255)) + PARSE_ERROR1; + f->phcto = par; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FPHCTO=%d\n", par); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } + +#if 0 + /* PTS=n - Page transfer status */ + if (!strncmp(p[0], "PTS", 3)) { /* TODO */ + p[0] += 3; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n%d",f->pts); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') + { + p[0]++; + sprintf(rs, "\r\n0-5"); + isdn_tty_at_cout(rs, info); + } + else + { + par = isdn_getnum(p); + if ((par < 0) || (par > 5)) + PARSE_ERROR1; + f->pts = par; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FPTS=%d\n", par); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } +#endif + + /* REL=n - Phase C received EOL alignment */ + if (!strncmp(p[0], "REL", 3)) { + p[0] += 3; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n%d",f->rel); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') + { + p[0]++; + sprintf(rs, "\r\n0,1"); + isdn_tty_at_cout(rs, info); + } + else + { + par = isdn_getnum(p); + if ((par < 0) || (par > 1)) + PARSE_ERROR1; + f->rel = par; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FREL=%d\n", par); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } + + /* REV? - DCE Revision */ + if (!strncmp(p[0], "REV?", 4)) { + p[0] += 4; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: FREV?\n"); +#endif + strcpy(rss, isdn_tty_fax_revision); + sprintf(rs, "\r\nRev: %s", isdn_getrev(rss)); + isdn_tty_at_cout(rs, info); + return 0; + } + +#if 0 + /* SPL=n - Enable polling */ + if (!strncmp(p[0], "SPL", 3)) { /* TODO */ + p[0] += 3; + switch (*p[0]) { + case '?': + p[0]++; + sprintf(rs, "\r\n%d", f->spl); + isdn_tty_at_cout(rs, info); + break; + case '=': + p[0]++; + if (*p[0] == '?') + { + p[0]++; + sprintf(rs, "\r\n0,1"); + isdn_tty_at_cout(rs, info); + } + else + { + par = isdn_getnum(p); + if ((par < 0) || (par > 1)) + PARSE_ERROR1; + f->spl = par; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FSPL=%d\n", par); +#endif + } + break; + default: + PARSE_ERROR1; + } + return 0; + } +#endif + + /* Phase C Transmit Data Block Size */ + if (!strncmp(p[0], "TBC=", 4)) { /* dummy, not used */ + p[0] += 4; +#ifdef ISDN_TTY_FAX_STAT_DEBUG + printk(KERN_DEBUG "isdn_tty: Fax FTBC=%c\n", *p[0]); +#endif + switch (*p[0]) { + case '0': + p[0]++; + break; + default: + PARSE_ERROR1; + } + return 0; + } + + printk(KERN_DEBUG "isdn_tty: unknown token=>AT+F%s<\n", p[0]); + PARSE_ERROR1; +} + diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/isdn_ttyfax.h linux/drivers/isdn/isdn_ttyfax.h --- v2.3.13/linux/drivers/isdn/isdn_ttyfax.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/isdn_ttyfax.h Thu Aug 12 09:42:33 1999 @@ -0,0 +1,33 @@ +/* $Id: isdn_ttyfax.h,v 1.1 1999/07/31 12:59:51 armin Exp $ + * header for Linux ISDN subsystem, tty_fax related functions (linklevel). + * + * Copyright 1999 by Armin Schindler (mac@melware.de) + * Copyright 1999 by Ralf Spachmann (mel@melware.de) + * Copyright 1999 by Cytronics & Melware + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Log: isdn_ttyfax.h,v $ + * Revision 1.1 1999/07/31 12:59:51 armin + * Added tty fax capabilities. + * + * + */ + + +#define XON 0x11 +#define XOFF 0x13 +#define DC2 0x12 + diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/isdn_x25iface.c linux/drivers/isdn/isdn_x25iface.c --- v2.3.13/linux/drivers/isdn/isdn_x25iface.c Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/isdn_x25iface.c Wed Aug 18 11:38:57 1999 @@ -57,7 +57,7 @@ void isdn_x25iface_proto_del( struct concap_proto * ); int isdn_x25iface_proto_close( struct concap_proto * ); int isdn_x25iface_proto_restart( struct concap_proto *, - struct device *, + struct net_device *, struct concap_device_ops *); int isdn_x25iface_xmit( struct concap_proto *, struct sk_buff * ); int isdn_x25iface_receive( struct concap_proto *, struct sk_buff * ); @@ -175,7 +175,7 @@ /* (re-)initialize the data structures for x25iface encapsulation */ int isdn_x25iface_proto_restart(struct concap_proto *cprot, - struct device *ndev, + struct net_device *ndev, struct concap_device_ops *dops) { ix25_pdata_t * pda = cprot -> proto_data ; diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/pcbit/drv.c linux/drivers/isdn/pcbit/drv.c --- v2.3.13/linux/drivers/isdn/pcbit/drv.c Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/pcbit/drv.c Thu Aug 12 09:42:33 1999 @@ -86,7 +86,7 @@ dev_pcbit[board] = dev; memset(dev, 0, sizeof(struct pcbit_dev)); -#if LINUX_VERSION_CODE >= 131841 +#ifdef COMPAT_HAS_NEW_WAITQ init_waitqueue_head(&dev->set_running_wq); #endif diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/pcbit/pcbit.h linux/drivers/isdn/pcbit/pcbit.h --- v2.3.13/linux/drivers/isdn/pcbit/pcbit.h Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/pcbit/pcbit.h Thu Aug 12 09:42:33 1999 @@ -68,10 +68,10 @@ struct frame_buf *write_queue; /* Protocol start */ -#if LINUX_VERSION_CODE < 131841 - struct wait_queue *set_running_wq; -#else +#ifdef COMPAT_HAS_NEW_WAITQ wait_queue_head_t set_running_wq; +#else + struct wait_queue *set_running_wq; #endif struct timer_list set_running_timer; diff -u --recursive --new-file v2.3.13/linux/drivers/macintosh/mac_keyb.c linux/drivers/macintosh/mac_keyb.c --- v2.3.13/linux/drivers/macintosh/mac_keyb.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/macintosh/mac_keyb.c Thu Aug 12 11:50:14 1999 @@ -44,7 +44,6 @@ #include #include #include -#include #include #include diff -u --recursive --new-file v2.3.13/linux/drivers/macintosh/macserial.c linux/drivers/macintosh/macserial.c --- v2.3.13/linux/drivers/macintosh/macserial.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/macintosh/macserial.c Thu Aug 12 11:50:14 1999 @@ -39,7 +39,6 @@ #ifdef CONFIG_KGDB #include #endif -#include #include "macserial.h" diff -u --recursive --new-file v2.3.13/linux/drivers/misc/Config.in linux/drivers/misc/Config.in --- v2.3.13/linux/drivers/misc/Config.in Wed Dec 31 16:00:00 1969 +++ linux/drivers/misc/Config.in Mon Aug 9 15:06:52 1999 @@ -0,0 +1,12 @@ +# +# Misc strange devices +# +mainmenu_option next_comment +comment 'Misc devices' + +# PIIX4 ACPI requires PCI for setup and a hardcoded TSC for timing +if [ "$CONFIG_PCI" = "y" -a "$CONFIG_X86_TSC" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool 'PIIX4 ACPI support' CONFIG_PIIX4_ACPI +fi + +endmenu diff -u --recursive --new-file v2.3.13/linux/drivers/misc/Makefile linux/drivers/misc/Makefile --- v2.3.13/linux/drivers/misc/Makefile Wed Dec 31 16:00:00 1969 +++ linux/drivers/misc/Makefile Mon Aug 9 14:12:48 1999 @@ -0,0 +1,27 @@ +# +# Makefile for misc devices that really don't fit anywhere else. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now inherited from the +# parent makes.. +# + +SUB_DIRS := +MOD_SUB_DIRS := $(SUB_DIRS) +ALL_SUB_DIRS := $(SUB_DIRS) + +O_TARGET := misc.o +M_OBJS := +O_OBJS := +OX_OBJS := + +ifdef CONFIG_PIIX4_ACPI +O_OBJS += piix4_acpi.o +endif + +include $(TOPDIR)/Rules.make + +fastdep: diff -u --recursive --new-file v2.3.13/linux/drivers/misc/piix4_acpi.c linux/drivers/misc/piix4_acpi.c --- v2.3.13/linux/drivers/misc/piix4_acpi.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/misc/piix4_acpi.c Fri Aug 13 13:50:58 1999 @@ -0,0 +1,214 @@ +/* + * linux/drivers/misc/piix4_acpi.c + * + * (C) Copyright 1999 Linus Torvalds + * + * A PM driver for the ACPI portion of the Intel PIIX4 + * chip. + * + * This has been known to occasionally work on some laptops. + * + * It probably only works on Intel PII machines that support + * the STPCLK protocol. + */ + +#include +#include +#include + +#include + +extern void (*acpi_idle)(void); + +/* + * This first part should be common to all ACPI + * CPU sleep functionality. Assuming we get the + * timing heuristics in a better shape than "none" ;) + */ + +typedef void (*sleep_fn_t)(void); + +/* + * Our "sleep mode" is a fixed point number + * with two binary places, ranging between + * [0 .. 3[ + */ +#define Cx_SHIFT 2 +#define MAXMODE ((3 << Cx_SHIFT)-1) + +/* + * NOTE! + * + * Right now this always defaults to C3, which is just broken. + * The exit latency is usually too high for much busy IO activity, + * and generally it's not always the best thing to do. + * + * We should just read the cycle counter around all the cases, + * and if we pause for a long time we go to a deeper sleep, while + * a short wait makes us go into a lighter sleep. + */ +static void common_acpi_idle(sleep_fn_t *sleep) +{ + int mode = MAXMODE; + + while (1) { + while (!current->need_resched) { + unsigned int time; + + time = get_cycles(); + sleep[(mode) >> Cx_SHIFT](); + time = get_cycles() - time; + + /* + * Yeah, yeah, yeah. + * if (time > Large && mode < MAXMODE) mode++; + * if (time < Small && mode > 0) mode--; + * Yadda-yadda-yadda. + * + * "Large" is on the order of half a timer tick. + * "Small" is on the order of Large >> 2 or so. + * + * Somebody should _really_ look at the exact + * details. The ACPI bios would give some made-up + * numbers, they might be useful (or maybe not: + * they are probably tuned for whatever Windows + * does, so don't take them for granted). + */ + } + schedule(); + check_pgt_cache(); + } +} + +/* Ok, here starts the magic PIIX4 knowledge */ + +/* + * Ehh.. We "know" about the northbridge + * bus arbitration stuff. Maybe somebody + * should actually verify this some day? + */ +#define NORTHBRIDGE_CONTROL 0x22 +#define NB_ARBITRATE 0x01 + +/* + * PIIX4 ACPI IO offsets and defines + */ +#define PMEN 0x02 +#define PMCNTRL 0x04 +#define PMTMR 0x08 +#define GPSTS 0x0c +#define GPEN 0x0E + +#define PCNTRL 0x10 +#define CC_EN 0x0200 +#define BST_EN 0x0400 +#define SLEEP_EN 0x0800 +#define STPCLK_EN 0x1000 +#define CLKRUN_EN 0x2000 + +#define PLVL2 0x14 +#define PLVL3 0x15 + +/* + * PIIX4 ACPI PCI configurations offsets and defines + */ +#define DEVACTB 0x58 +#define BRLD_EN_IRQ0 0x01 +#define BRLD_EN_IRQ 0x02 + +#define PMREGMISC 0x80 +#define PMIOSE 0x01 + +static unsigned int piix4_base_address = 0; + +static void piix4_c1_sleep(void) +{ + asm volatile("sti ; hlt" : : : "memory"); +} + +static void piix4_c2_sleep(void) +{ + outl(CLKRUN_EN | CC_EN, piix4_base_address + PCNTRL); + inb(piix4_base_address + PLVL2); +} + +static void piix4_c3_sleep(void) +{ + __cli(); + outl(CLKRUN_EN | CC_EN | STPCLK_EN | SLEEP_EN, piix4_base_address + PCNTRL); + outb(NB_ARBITRATE, NORTHBRIDGE_CONTROL); + inb(piix4_base_address + PLVL3); + outb(0, NORTHBRIDGE_CONTROL); + __sti(); +} + +static sleep_fn_t piix4_sleep[] = { + piix4_c1_sleep, /* low-latency C1 (ie "sti ; hlt") */ + piix4_c2_sleep, /* medium latency C2 (ie LVL2 stopckl) */ + piix4_c3_sleep /* high-latency C3 (ie LVL3 sleep) */ +}; + +static void piix4_acpi_idle(void) +{ + common_acpi_idle(piix4_sleep); +} + +static int __init piix4_acpi_init(void) +{ + /* This is the PIIX4 ACPI device */ + struct pci_dev *dev; + u32 base, val; + u16 cmd; + u8 pmregmisc; + +#ifdef __SMP__ + /* + * We can't really do idle things with multiple CPU's, I'm + * afraid. We'd need a per-CPU ACPI device. + */ + if (smp_num_cpus > 1) + return -1; +#endif + dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL); + + if (!dev) + return -1; + + /* + * Read the IO base value, and verify that it makes sense + * + * We could enable this if it wasn't enabled before, but + * let's walk before we run.. + */ + pci_read_config_word(dev, PCI_COMMAND, &cmd); + if (!(cmd & PCI_COMMAND_IO)) + return -1; + + pci_read_config_byte(dev, PMREGMISC, &pmregmisc); + if (!(pmregmisc & PMIOSE)) + return -1; + + pci_read_config_dword(dev, 0x40, &base); + if (!(base & PCI_BASE_ADDRESS_SPACE_IO)) + return -1; + + base &= PCI_BASE_ADDRESS_IO_MASK; + if (!base) + return -1; + + printk("Found PIIX4 ACPI device at %04x\n", base); + piix4_base_address = base; + + /* Enable stopcklock, sleep and bursts, along with clock control */ + outl(CLKRUN_EN | CC_EN | STPCLK_EN | SLEEP_EN, piix4_base_address + PCNTRL); + + /* Make all unmasked interrupts be BREAK events */ + pci_read_config_dword(dev, DEVACTB, &val); + pci_write_config_dword(dev, DEVACTB, val | BRLD_EN_IRQ0 | BRLD_EN_IRQ); + + /* Set up the new idle handler.. */ + acpi_idle = piix4_acpi_idle; + return 0; +} + +__initcall(piix4_acpi_init); diff -u --recursive --new-file v2.3.13/linux/drivers/net/3c501.c linux/drivers/net/3c501.c --- v2.3.13/linux/drivers/net/3c501.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/3c501.c Wed Aug 18 11:36:41 1999 @@ -116,16 +116,16 @@ * Index to functions. */ -int el1_probe(struct device *dev); -static int el1_probe1(struct device *dev, int ioaddr); -static int el_open(struct device *dev); -static int el_start_xmit(struct sk_buff *skb, struct device *dev); +int el1_probe(struct net_device *dev); +static int el1_probe1(struct net_device *dev, int ioaddr); +static int el_open(struct net_device *dev); +static int el_start_xmit(struct sk_buff *skb, struct net_device *dev); static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void el_receive(struct device *dev); -static void el_reset(struct device *dev); -static int el1_close(struct device *dev); -static struct net_device_stats *el1_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static void el_receive(struct net_device *dev); +static void el_reset(struct net_device *dev); +static int el1_close(struct net_device *dev); +static struct net_device_stats *el1_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); #define EL1_IO_EXTENT 16 @@ -210,7 +210,7 @@ struct netdev_entry el1_drv = {"3c501", el1_probe1, EL1_IO_EXTENT, netcard_portlist}; #else -int __init el1_probe(struct device *dev) +int __init el1_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -237,7 +237,7 @@ * The actual probe. */ -static int __init el1_probe1(struct device *dev, int ioaddr) +static int __init el1_probe1(struct net_device *dev, int ioaddr) { struct net_local *lp; const char *mname; /* Vendor name */ @@ -355,7 +355,7 @@ * Open/initialize the board. */ -static int el_open(struct device *dev) +static int el_open(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -374,7 +374,7 @@ return 0; } -static int el_start_xmit(struct sk_buff *skb, struct device *dev) +static int el_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -480,7 +480,7 @@ static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *lp; int ioaddr; int axsr; /* Aux. status reg. */ @@ -661,7 +661,7 @@ * We must check everything to see if it is good. */ -static void el_receive(struct device *dev) +static void el_receive(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -717,7 +717,7 @@ return; } -static void el_reset(struct device *dev) +static void el_reset(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -742,7 +742,7 @@ sti(); } -static int el1_close(struct device *dev) +static int el1_close(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -763,7 +763,7 @@ return 0; } -static struct net_device_stats *el1_get_stats(struct device *dev) +static struct net_device_stats *el1_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; return &lp->stats; @@ -774,7 +774,7 @@ * best-effort filtering. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -799,7 +799,7 @@ static char devicename[9] = { 0, }; -static struct device dev_3c501 = +static struct net_device dev_3c501 = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, diff -u --recursive --new-file v2.3.13/linux/drivers/net/3c503.c linux/drivers/net/3c503.c --- v2.3.13/linux/drivers/net/3c503.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/3c503.c Wed Aug 18 11:36:41 1999 @@ -52,9 +52,9 @@ #include "3c503.h" #define WRD_COUNT 4 -int el2_probe(struct device *dev); -int el2_pio_probe(struct device *dev); -int el2_probe1(struct device *dev, int ioaddr); +int el2_probe(struct net_device *dev); +int el2_pio_probe(struct net_device *dev); +int el2_probe1(struct net_device *dev, int ioaddr); /* A zero-terminated list of I/O addresses to be probed in PIO mode. */ static unsigned int netcard_portlist[] __initdata = @@ -71,15 +71,15 @@ {"3c503pio", el2_pioprobe1, EL1_IO_EXTENT, netcard_portlist}; #endif -static int el2_open(struct device *dev); -static int el2_close(struct device *dev); -static void el2_reset_8390(struct device *dev); -static void el2_init_card(struct device *dev); -static void el2_block_output(struct device *dev, int count, +static int el2_open(struct net_device *dev); +static int el2_close(struct net_device *dev); +static void el2_reset_8390(struct net_device *dev); +static void el2_init_card(struct net_device *dev); +static void el2_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page); -static void el2_block_input(struct device *dev, int count, struct sk_buff *skb, +static void el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void el2_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); @@ -91,7 +91,7 @@ ethercard jumpered to programmed-I/O mode. */ int __init -el2_probe(struct device *dev) +el2_probe(struct net_device *dev) { int *addr, addrs[] = { 0xddffe, 0xd9ffe, 0xcdffe, 0xc9ffe, 0}; int base_addr = dev->base_addr; @@ -126,7 +126,7 @@ /* Try all of the locations that aren't obviously empty. This touches a lot of locations, and is much riskier than the code above. */ int __init -el2_pio_probe(struct device *dev) +el2_pio_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -152,7 +152,7 @@ returning non-zero on success. If found, set the station address and memory parameters in DEVICE. */ int __init -el2_probe1(struct device *dev, int ioaddr) +el2_probe1(struct net_device *dev, int ioaddr) { int i, iobase_reg, membase_reg, saved_406, wordlength; static unsigned version_printed = 0; @@ -334,7 +334,7 @@ } static int -el2_open(struct device *dev) +el2_open(struct net_device *dev) { if (dev->irq < 2) { @@ -370,7 +370,7 @@ } static int -el2_close(struct device *dev) +el2_close(struct net_device *dev) { free_irq(dev->irq, dev); dev->irq = ei_status.saved_irq; @@ -386,7 +386,7 @@ Bad ring buffer packet header */ static void -el2_reset_8390(struct device *dev) +el2_reset_8390(struct net_device *dev) { if (ei_debug > 1) { printk("%s: Resetting the 3c503 board...", dev->name); @@ -402,7 +402,7 @@ /* Initialize the 3c503 GA registers after a reset. */ static void -el2_init_card(struct device *dev) +el2_init_card(struct net_device *dev) { /* Unmap the station PROM and select the DIX or BNC connector. */ outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL); @@ -434,7 +434,7 @@ * out through the ASIC FIFO. */ static void -el2_block_output(struct device *dev, int count, +el2_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { unsigned short int *wrd; @@ -507,7 +507,7 @@ /* Read the 4 byte, page aligned 8390 specific header. */ static void -el2_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int boguscount; unsigned long hdr_start = dev->mem_start + ((ring_page - EL2_MB1_START_PG)<<8); @@ -546,7 +546,7 @@ static void -el2_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int boguscount = 0; unsigned short int *buf; @@ -625,7 +625,7 @@ #define NAMELEN 8 /* #of chars for storing dev->name */ static char namelist[NAMELEN * MAX_EL2_CARDS] = { 0, }; -static struct device dev_el2[MAX_EL2_CARDS] = { +static struct net_device dev_el2[MAX_EL2_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -649,7 +649,7 @@ int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) { - struct device *dev = &dev_el2[this_dev]; + struct net_device *dev = &dev_el2[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -679,7 +679,7 @@ int this_dev; for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) { - struct device *dev = &dev_el2[this_dev]; + struct net_device *dev = &dev_el2[this_dev]; if (dev->priv != NULL) { void *priv = dev->priv; /* NB: el2_close() handles free_irq */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/3c505.c linux/drivers/net/3c505.c --- v2.3.13/linux/drivers/net/3c505.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/3c505.c Wed Aug 18 11:36:41 1999 @@ -221,7 +221,7 @@ return inb(base_addr + PORT_COMMAND); } -static inline void outb_control(unsigned char val, struct device *dev) +static inline void outb_control(unsigned char val, struct net_device *dev) { outb(val, dev->base_addr + PORT_CONTROL); ((elp_device *)(dev->priv))->hcr_val = val; @@ -276,16 +276,16 @@ return stat1; } -static inline void set_hsf(struct device *dev, int hsf) +static inline void set_hsf(struct net_device *dev, int hsf) { cli(); outb_control((HCR_VAL(dev) & ~HSF_PCB_MASK) | hsf, dev); sti(); } -static int start_receive(struct device *, pcb_struct *); +static int start_receive(struct net_device *, pcb_struct *); -inline static void adapter_reset(struct device *dev) +inline static void adapter_reset(struct net_device *dev) { int timeout; elp_device *adapter = dev->priv; @@ -323,7 +323,7 @@ * never happen in theory, but seems to occur occasionally if the card gets * prodded at the wrong time. */ -static inline void check_3c505_dma(struct device *dev) +static inline void check_3c505_dma(struct net_device *dev) { elp_device *adapter = dev->priv; if (adapter->dmaing && time_after(jiffies, adapter->current_dma.start_time + 10)) { @@ -371,7 +371,7 @@ } /* Check to see if the receiver needs restarting, and kick it if so */ -static inline void prime_rx(struct device *dev) +static inline void prime_rx(struct net_device *dev) { elp_device *adapter = dev->priv; while (adapter->rx_active < ELP_RX_PCBS && dev->start) { @@ -404,7 +404,7 @@ * timeout is reduced to 500us). */ -static int send_pcb(struct device *dev, pcb_struct * pcb) +static int send_pcb(struct net_device *dev, pcb_struct * pcb) { int i; int timeout; @@ -487,7 +487,7 @@ * *****************************************************************/ -static int receive_pcb(struct device *dev, pcb_struct * pcb) +static int receive_pcb(struct net_device *dev, pcb_struct * pcb) { int i, j; int total_length; @@ -571,7 +571,7 @@ * ******************************************************/ -static int start_receive(struct device *dev, pcb_struct * tx_pcb) +static int start_receive(struct net_device *dev, pcb_struct * tx_pcb) { int status; elp_device *adapter = dev->priv; @@ -599,7 +599,7 @@ * ******************************************************/ -static void receive_packet(struct device *dev, int len) +static void receive_packet(struct net_device *dev, int len) { int rlen; elp_device *adapter = dev->priv; @@ -668,7 +668,7 @@ int len; int dlen; int icount = 0; - struct device *dev; + struct net_device *dev; elp_device *adapter; int timeout; @@ -885,7 +885,7 @@ * ******************************************************/ -static int elp_open(struct device *dev) +static int elp_open(struct net_device *dev) { elp_device *adapter; @@ -1022,7 +1022,7 @@ * ******************************************************/ -static int send_packet(struct device *dev, struct sk_buff *skb) +static int send_packet(struct net_device *dev, struct sk_buff *skb) { elp_device *adapter = dev->priv; unsigned long target; @@ -1092,7 +1092,7 @@ * ******************************************************/ -static int elp_start_xmit(struct sk_buff *skb, struct device *dev) +static int elp_start_xmit(struct sk_buff *skb, struct net_device *dev) { if (dev->interrupt) { printk("%s: start_xmit aborted (in irq)\n", dev->name); @@ -1157,7 +1157,7 @@ * ******************************************************/ -static struct net_device_stats *elp_get_stats(struct device *dev) +static struct net_device_stats *elp_get_stats(struct net_device *dev) { elp_device *adapter = (elp_device *) dev->priv; @@ -1194,7 +1194,7 @@ * ******************************************************/ -static int elp_close(struct device *dev) +static int elp_close(struct net_device *dev) { elp_device *adapter; @@ -1247,7 +1247,7 @@ * ************************************************************/ -static void elp_set_mc_list(struct device *dev) +static void elp_set_mc_list(struct net_device *dev) { elp_device *adapter = (elp_device *) dev->priv; struct dev_mc_list *dmi = dev->mc_list; @@ -1306,7 +1306,7 @@ * ******************************************************/ -static inline void elp_init(struct device *dev) +static inline void elp_init(struct net_device *dev) { elp_device *adapter = dev->priv; @@ -1339,7 +1339,7 @@ * Called only by elp_autodetect ************************************************************/ -static int __init elp_sense(struct device *dev) +static int __init elp_sense(struct net_device *dev) { int timeout; int addr = dev->base_addr; @@ -1406,7 +1406,7 @@ * Called only by eplus_probe *************************************************************/ -static int __init elp_autodetect(struct device *dev) +static int __init elp_autodetect(struct net_device *dev) { int idx = 0; @@ -1450,7 +1450,7 @@ * work at all if it was in a weird state). */ -int __init elplus_probe(struct device *dev) +int __init elplus_probe(struct net_device *dev) { elp_device *adapter; int i, tries, tries1, timeout, okay; @@ -1654,7 +1654,7 @@ #ifdef MODULE #define NAMELEN 9 static char devicename[ELP_MAX_CARDS][NAMELEN] = {{0,}}; -static struct device dev_3c505[ELP_MAX_CARDS] = +static struct net_device dev_3c505[ELP_MAX_CARDS] = { { NULL, /* device name is inserted by net_init.c */ 0, 0, 0, 0, @@ -1674,7 +1674,7 @@ int this_dev, found = 0; for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) { - struct device *dev = &dev_3c505[this_dev]; + struct net_device *dev = &dev_3c505[this_dev]; dev->name = devicename[this_dev]; dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -1703,7 +1703,7 @@ int this_dev; for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) { - struct device *dev = &dev_3c505[this_dev]; + struct net_device *dev = &dev_3c505[this_dev]; if (dev->priv != NULL) { unregister_netdev(dev); kfree(dev->priv); diff -u --recursive --new-file v2.3.13/linux/drivers/net/3c507.c linux/drivers/net/3c507.c --- v2.3.13/linux/drivers/net/3c507.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/3c507.c Wed Aug 18 11:36:41 1999 @@ -279,18 +279,18 @@ /* Index to functions, as function prototypes. */ -extern int el16_probe(struct device *dev); /* Called from Space.c */ +extern int el16_probe(struct net_device *dev); /* Called from Space.c */ -static int el16_probe1(struct device *dev, int ioaddr); -static int el16_open(struct device *dev); -static int el16_send_packet(struct sk_buff *skb, struct device *dev); +static int el16_probe1(struct net_device *dev, int ioaddr); +static int el16_open(struct net_device *dev); +static int el16_send_packet(struct sk_buff *skb, struct net_device *dev); static void el16_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void el16_rx(struct device *dev); -static int el16_close(struct device *dev); -static struct net_device_stats *el16_get_stats(struct device *dev); +static void el16_rx(struct net_device *dev); +static int el16_close(struct net_device *dev); +static struct net_device_stats *el16_get_stats(struct net_device *dev); -static void hardware_send_packet(struct device *dev, void *buf, short length); -static void init_82586_mem(struct device *dev); +static void hardware_send_packet(struct net_device *dev, void *buf, short length); +static void init_82586_mem(struct net_device *dev); #ifdef HAVE_DEVLIST @@ -305,7 +305,7 @@ device and return success. */ -int __init el16_probe(struct device *dev) +int __init el16_probe(struct net_device *dev) { int base_addr = dev ? dev->base_addr : 0; int i; @@ -326,7 +326,7 @@ return ENODEV; } -int __init el16_probe1(struct device *dev, int ioaddr) +int __init el16_probe1(struct net_device *dev, int ioaddr) { static unsigned char init_ID_done = 0, version_printed = 0; int i, irq, irqval; @@ -432,7 +432,7 @@ return 0; } -static int el16_open(struct device *dev) +static int el16_open(struct net_device *dev) { /* Initialize the 82586 memory and start it. */ init_82586_mem(dev); @@ -446,7 +446,7 @@ return 0; } -static int el16_send_packet(struct sk_buff *skb, struct device *dev) +static int el16_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -514,7 +514,7 @@ Handle the network interface interrupts. */ static void el16_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *lp; int ioaddr, status, boguscount = 0; ushort ack_cmd = 0; @@ -592,7 +592,7 @@ if ((status & 0x0070) != 0x0040 && dev->start) { - static void init_rx_bufs(struct device *); + static void init_rx_bufs(struct net_device *); /* The Rx unit is not ready, it must be hung. Restart the receiver by initializing the rx buffers, and issuing an Rx start command. */ if (net_debug) @@ -616,7 +616,7 @@ return; } -static int el16_close(struct device *dev) +static int el16_close(struct net_device *dev) { int ioaddr = dev->base_addr; unsigned long shmem = dev->mem_start; @@ -642,7 +642,7 @@ /* Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *el16_get_stats(struct device *dev) +static struct net_device_stats *el16_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -652,7 +652,7 @@ } /* Initialize the Rx-block list. */ -static void init_rx_bufs(struct device *dev) +static void init_rx_bufs(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned long write_ptr; @@ -695,7 +695,7 @@ writew(lp->rx_head,write_ptr+2); /* Link */ } -static void init_82586_mem(struct device *dev) +static void init_82586_mem(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; short ioaddr = dev->base_addr; @@ -753,7 +753,7 @@ return; } -static void hardware_send_packet(struct device *dev, void *buf, short length) +static void hardware_send_packet(struct net_device *dev, void *buf, short length) { struct net_local *lp = (struct net_local *)dev->priv; short ioaddr = dev->base_addr; @@ -798,7 +798,7 @@ dev->tbusy = 0; } -static void el16_rx(struct device *dev) +static void el16_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned long shmem = dev->mem_start; @@ -869,7 +869,7 @@ } #ifdef MODULE static char devicename[9] = { 0, }; -static struct device dev_3c507 = { +static struct net_device dev_3c507 = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0, 0, diff -u --recursive --new-file v2.3.13/linux/drivers/net/3c509.c linux/drivers/net/3c509.c --- v2.3.13/linux/drivers/net/3c509.c Thu May 6 14:02:34 1999 +++ linux/drivers/net/3c509.c Wed Aug 18 11:36:41 1999 @@ -129,7 +129,7 @@ struct el3_private { struct enet_statistics stats; - struct device *next_dev; + struct net_device *next_dev; spinlock_t lock; /* skb send-queue */ int head, size; @@ -137,18 +137,18 @@ char mca_slot; }; static int id_port = 0x110; /* Start with 0x110 to avoid new sound cards.*/ -static struct device *el3_root_dev = NULL; +static struct net_device *el3_root_dev = NULL; static ushort id_read_eeprom(int index); static ushort read_eeprom(int ioaddr, int index); -static int el3_open(struct device *dev); -static int el3_start_xmit(struct sk_buff *skb, struct device *dev); +static int el3_open(struct net_device *dev); +static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev); static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void update_stats(struct device *dev); -static struct enet_statistics *el3_get_stats(struct device *dev); -static int el3_rx(struct device *dev); -static int el3_close(struct device *dev); -static void set_multicast_list(struct device *dev); +static void update_stats(struct net_device *dev); +static struct enet_statistics *el3_get_stats(struct net_device *dev); +static int el3_rx(struct net_device *dev); +static int el3_close(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); #ifdef CONFIG_MCA struct el3_mca_adapters_struct { @@ -166,7 +166,7 @@ }; #endif -int el3_probe(struct device *dev) +int el3_probe(struct net_device *dev) { short lrs_state = 0xff, i; int ioaddr, irq, if_port; @@ -425,7 +425,7 @@ static int -el3_open(struct device *dev) +el3_open(struct net_device *dev) { int ioaddr = dev->base_addr; int i; @@ -505,7 +505,7 @@ } static int -el3_start_xmit(struct sk_buff *skb, struct device *dev) +el3_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct el3_private *lp = (struct el3_private *)dev->priv; int ioaddr = dev->base_addr; @@ -615,7 +615,7 @@ static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct el3_private *lp; int ioaddr, status; int i = max_interrupt_work; @@ -708,7 +708,7 @@ static struct enet_statistics * -el3_get_stats(struct device *dev) +el3_get_stats(struct net_device *dev) { struct el3_private *lp = (struct el3_private *)dev->priv; unsigned long flags; @@ -729,7 +729,7 @@ operation, and it's simpler for the rest of the driver to assume that window 1 is always valid rather than use a special window-state variable. */ -static void update_stats(struct device *dev) +static void update_stats(struct net_device *dev) { struct el3_private *lp = (struct el3_private *)dev->priv; int ioaddr = dev->base_addr; @@ -759,7 +759,7 @@ } static int -el3_rx(struct device *dev) +el3_rx(struct net_device *dev) { struct el3_private *lp = (struct el3_private *)dev->priv; int ioaddr = dev->base_addr; @@ -829,7 +829,7 @@ * Set or clear the multicast filter for this adaptor. */ static void -set_multicast_list(struct device *dev) +set_multicast_list(struct net_device *dev) { unsigned long flags; struct el3_private *lp = (struct el3_private *)dev->priv; @@ -856,7 +856,7 @@ } static int -el3_close(struct device *dev) +el3_close(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -926,7 +926,7 @@ void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ while (el3_root_dev) { diff -u --recursive --new-file v2.3.13/linux/drivers/net/3c515.c linux/drivers/net/3c515.c --- v2.3.13/linux/drivers/net/3c515.c Mon Jun 7 16:18:58 1999 +++ linux/drivers/net/3c515.c Wed Aug 18 11:36:41 1999 @@ -293,7 +293,7 @@ struct vortex_private { char devname[8]; /* "ethN" string, also for kernel debug. */ const char *product_name; - struct device *next_module; + struct net_device *next_module; /* The Rx and Tx rings are here to keep them quad-word-aligned. */ struct boom_rx_desc rx_ring[RX_RING_SIZE]; struct boom_tx_desc tx_ring[TX_RING_SIZE]; @@ -343,21 +343,21 @@ { "Default", 0, 0xFF, XCVR_10baseT, 10000}, }; -static int vortex_scan(struct device *dev); -static struct device *vortex_found_device(struct device *dev, int ioaddr, +static int vortex_scan(struct net_device *dev); +static struct net_device *vortex_found_device(struct net_device *dev, int ioaddr, int irq, int product_index, int options); -static int vortex_probe1(struct device *dev); -static int vortex_open(struct device *dev); +static int vortex_probe1(struct net_device *dev); +static int vortex_open(struct net_device *dev); static void vortex_timer(unsigned long arg); -static int vortex_start_xmit(struct sk_buff *skb, struct device *dev); -static int vortex_rx(struct device *dev); -static int boomerang_rx(struct device *dev); +static int vortex_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int vortex_rx(struct net_device *dev); +static int boomerang_rx(struct net_device *dev); static void vortex_interrupt IRQ(int irq, void *dev_id, struct pt_regs *regs); -static int vortex_close(struct device *dev); -static void update_stats(int addr, struct device *dev); -static struct enet_statistics *vortex_get_stats(struct device *dev); -static void set_rx_mode(struct device *dev); +static int vortex_close(struct net_device *dev); +static void update_stats(int addr, struct net_device *dev); +static struct enet_statistics *vortex_get_stats(struct net_device *dev); +static void set_rx_mode(struct net_device *dev); /* Unlike the other PCI cards the 59x cards don't need a large contiguous @@ -381,7 +381,7 @@ #ifdef MODULE static int debug = -1; /* A list of all installed Vortex devices, for removing the driver module. */ -static struct device *root_vortex_dev = NULL; +static struct net_device *root_vortex_dev = NULL; int init_module(void) @@ -399,7 +399,7 @@ } #else -int tc515_probe(struct device *dev) +int tc515_probe(struct net_device *dev) { int cards_found = 0; @@ -412,7 +412,7 @@ } #endif /* not MODULE */ -static int vortex_scan(struct device *dev) +static int vortex_scan(struct net_device *dev) { int cards_found = 0; static int ioaddr = 0x100; @@ -452,7 +452,7 @@ return cards_found; } -static struct device *vortex_found_device(struct device *dev, int ioaddr, +static struct net_device *vortex_found_device(struct net_device *dev, int ioaddr, int irq, int product_index, int options) { @@ -460,13 +460,13 @@ #ifdef MODULE /* Allocate and fill new device structure. */ - int dev_size = sizeof(struct device) + + int dev_size = sizeof(struct net_device) + sizeof(struct vortex_private) + 15; /* Pad for alignment */ - dev = (struct device *) kmalloc(dev_size, GFP_KERNEL); + dev = (struct net_device *) kmalloc(dev_size, GFP_KERNEL); memset(dev, 0, dev_size); /* Align the Rx and Tx ring entries. */ - dev->priv = (void *)(((long)dev + sizeof(struct device) + 15) & ~15); + dev->priv = (void *)(((long)dev + sizeof(struct net_device) + 15) & ~15); vp = (struct vortex_private *)dev->priv; dev->name = vp->devname; /* An empty string. */ dev->base_addr = ioaddr; @@ -517,7 +517,7 @@ return dev; } -static int vortex_probe1(struct device *dev) +static int vortex_probe1(struct net_device *dev) { int ioaddr = dev->base_addr; struct vortex_private *vp = (struct vortex_private *)dev->priv; @@ -607,7 +607,7 @@ static int -vortex_open(struct device *dev) +vortex_open(struct net_device *dev) { int ioaddr = dev->base_addr; struct vortex_private *vp = (struct vortex_private *)dev->priv; @@ -778,7 +778,7 @@ static void vortex_timer(unsigned long data) { #ifdef AUTOMEDIA - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct vortex_private *vp = (struct vortex_private *)dev->priv; int ioaddr = dev->base_addr; unsigned long flags; @@ -850,7 +850,7 @@ } static int -vortex_start_xmit(struct sk_buff *skb, struct device *dev) +vortex_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; int ioaddr = dev->base_addr; @@ -1018,7 +1018,7 @@ static void vortex_interrupt IRQ(int irq, void *dev_id, struct pt_regs *regs) { /* Use the now-standard shared IRQ implementation. */ - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct vortex_private *lp; int ioaddr, status; int latency; @@ -1162,7 +1162,7 @@ } static int -vortex_rx(struct device *dev) +vortex_rx(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; int ioaddr = dev->base_addr; @@ -1232,7 +1232,7 @@ } static int -boomerang_rx(struct device *dev) +boomerang_rx(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; int entry = vp->cur_rx % RX_RING_SIZE; @@ -1322,7 +1322,7 @@ } static int -vortex_close(struct device *dev) +vortex_close(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; int ioaddr = dev->base_addr; @@ -1388,7 +1388,7 @@ } static struct enet_statistics * -vortex_get_stats(struct device *dev) +vortex_get_stats(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; unsigned long flags; @@ -1409,7 +1409,7 @@ table. This is done by checking that the ASM (!) code generated uses atomic updates with '+='. */ -static void update_stats(int ioaddr, struct device *dev) +static void update_stats(int ioaddr, struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; @@ -1445,7 +1445,7 @@ multicast setting is to receive all multicast frames. At least the chip has a very clean way to set the mode, unlike many others. */ static void -set_rx_mode(struct device *dev) +set_rx_mode(struct net_device *dev) { int ioaddr = dev->base_addr; short new_mode; @@ -1466,7 +1466,7 @@ void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ while (root_vortex_dev) { diff -u --recursive --new-file v2.3.13/linux/drivers/net/3c523.c linux/drivers/net/3c523.c --- v2.3.13/linux/drivers/net/3c523.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/3c523.c Wed Aug 18 11:36:41 1999 @@ -182,23 +182,23 @@ elmc_id_reset586(); } } } static void elmc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr); -static int elmc_open(struct device *dev); -static int elmc_close(struct device *dev); -static int elmc_send_packet(struct sk_buff *, struct device *); -static struct net_device_stats *elmc_get_stats(struct device *dev); +static int elmc_open(struct net_device *dev); +static int elmc_close(struct net_device *dev); +static int elmc_send_packet(struct sk_buff *, struct net_device *); +static struct net_device_stats *elmc_get_stats(struct net_device *dev); #ifdef ELMC_MULTICAST -static void set_multicast_list(struct device *dev); +static void set_multicast_list(struct net_device *dev); #endif /* helper-functions */ -static int init586(struct device *dev); -static int check586(struct device *dev, unsigned long where, unsigned size); -static void alloc586(struct device *dev); -static void startrecv586(struct device *dev); -static void *alloc_rfa(struct device *dev, void *ptr); -static void elmc_rcv_int(struct device *dev); -static void elmc_xmt_int(struct device *dev); -static void elmc_rnr_int(struct device *dev); +static int init586(struct net_device *dev); +static int check586(struct net_device *dev, unsigned long where, unsigned size); +static void alloc586(struct net_device *dev); +static void startrecv586(struct net_device *dev); +static void *alloc_rfa(struct net_device *dev, void *ptr); +static void elmc_rcv_int(struct net_device *dev); +static void elmc_xmt_int(struct net_device *dev); +static void elmc_rnr_int(struct net_device *dev); struct priv { struct net_device_stats stats; @@ -268,7 +268,7 @@ * close device */ -static int elmc_close(struct device *dev) +static int elmc_close(struct net_device *dev) { elmc_id_reset586(); /* the hard way to stop the receiver */ @@ -288,7 +288,7 @@ * open device */ -static int elmc_open(struct device *dev) +static int elmc_open(struct net_device *dev) { elmc_id_attn586(); /* disable interrupts */ @@ -319,7 +319,7 @@ * Check to see if there's an 82586 out there. */ -static int __init check586(struct device *dev, unsigned long where, unsigned size) +static int __init check586(struct net_device *dev, unsigned long where, unsigned size) { struct priv *p = (struct priv *) dev->priv; char *iscp_addrs[2]; @@ -359,7 +359,7 @@ * set iscp at the right place, called by elmc_probe and open586. */ -void alloc586(struct device *dev) +void alloc586(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -394,7 +394,7 @@ static int elmc_getinfo(char *buf, int slot, void *d) { int len = 0; - struct device *dev = (struct device *) d; + struct net_device *dev = (struct net_device *) d; int i; if (dev == NULL) @@ -422,7 +422,7 @@ /*****************************************************************/ -int __init elmc_probe(struct device *dev) +int __init elmc_probe(struct net_device *dev) { static int slot = 0; int base_addr = dev ? dev->base_addr : 0; @@ -593,7 +593,7 @@ * needs a correct 'allocated' memory */ -static int init586(struct device *dev) +static int init586(struct net_device *dev) { void *ptr; unsigned long s; @@ -831,7 +831,7 @@ * It sets up the Receive Frame Area (RFA). */ -static void *alloc_rfa(struct device *dev, void *ptr) +static void *alloc_rfa(struct net_device *dev, void *ptr) { volatile struct rfd_struct *rfd = (struct rfd_struct *) ptr; volatile struct rbd_struct *rbd; @@ -877,7 +877,7 @@ static void elmc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; unsigned short stat; struct priv *p; @@ -952,7 +952,7 @@ * receive-interrupt */ -static void elmc_rcv_int(struct device *dev) +static void elmc_rcv_int(struct net_device *dev) { int status; unsigned short totlen; @@ -999,7 +999,7 @@ * handle 'Receiver went not ready'. */ -static void elmc_rnr_int(struct device *dev) +static void elmc_rnr_int(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -1021,7 +1021,7 @@ * handle xmit - interrupt */ -static void elmc_xmt_int(struct device *dev) +static void elmc_xmt_int(struct net_device *dev) { int status; struct priv *p = (struct priv *) dev->priv; @@ -1066,7 +1066,7 @@ * (re)start the receiver */ -static void startrecv586(struct device *dev) +static void startrecv586(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -1080,7 +1080,7 @@ * send frame */ -static int elmc_send_packet(struct sk_buff *skb, struct device *dev) +static int elmc_send_packet(struct sk_buff *skb, struct net_device *dev) { int len; #ifndef NO_NOPCOMMANDS @@ -1192,7 +1192,7 @@ * Someone wanna have the statistics */ -static struct net_device_stats *elmc_get_stats(struct device *dev) +static struct net_device_stats *elmc_get_stats(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; unsigned short crc, aln, rsc, ovrn; @@ -1219,7 +1219,7 @@ */ #ifdef ELMC_MULTICAST -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { if (!dev->start) { /* without a running interface, promiscuous doesn't work */ @@ -1244,7 +1244,7 @@ static char devicenames[NAMELEN * MAX_3C523_CARDS] = {0,}; -static struct device dev_elmc[MAX_3C523_CARDS] = +static struct net_device dev_elmc[MAX_3C523_CARDS] = { { NULL /*"3c523" */ , 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL @@ -1263,7 +1263,7 @@ /* Loop until we either can't find any more cards, or we have MAX_3C523_CARDS */ for(this_dev=0; this_devname=devicenames+(NAMELEN*this_dev); dev->irq=irq[this_dev]; dev->base_addr=io[this_dev]; @@ -1285,7 +1285,7 @@ int this_dev; for(this_dev=0; this_devpriv) { /* shutdown interrupts on the card */ elmc_id_reset586(); diff -u --recursive --new-file v2.3.13/linux/drivers/net/3c527.c linux/drivers/net/3c527.c --- v2.3.13/linux/drivers/net/3c527.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/3c527.c Wed Aug 18 11:36:41 1999 @@ -129,15 +129,15 @@ /* Index to functions, as function prototypes. */ -extern int mc32_probe(struct device *dev); +extern int mc32_probe(struct net_device *dev); -static int mc32_probe1(struct device *dev, int ioaddr); -static int mc32_open(struct device *dev); -static int mc32_send_packet(struct sk_buff *skb, struct device *dev); +static int mc32_probe1(struct net_device *dev, int ioaddr); +static int mc32_open(struct net_device *dev); +static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev); static void mc32_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int mc32_close(struct device *dev); -static struct net_device_stats *mc32_get_stats(struct device *dev); -static void mc32_set_multicast_list(struct device *dev); +static int mc32_close(struct net_device *dev); +static struct net_device_stats *mc32_get_stats(struct net_device *dev); +static void mc32_set_multicast_list(struct net_device *dev); /* * Check for a network adaptor of this type, and return '0' iff one exists. @@ -147,7 +147,7 @@ * (detachable devices only). */ -int __init mc32_probe(struct device *dev) +int __init mc32_probe(struct net_device *dev) { static int current_mca_slot = -1; int i; @@ -183,7 +183,7 @@ * probes on the ISA bus. A good device probes avoids doing writes, and * verifies that the correct device exists and functions. */ -static int __init mc32_probe1(struct device *dev, int slot) +static int __init mc32_probe1(struct net_device *dev, int slot) { static unsigned version_printed = 0; int i; @@ -435,7 +435,7 @@ * Polled command stuff */ -static void mc32_ring_poll(struct device *dev) +static void mc32_ring_poll(struct net_device *dev) { int ioaddr = dev->base_addr; while(!(inb(ioaddr+HOST_STATUS)&HOST_STATUS_CRR)); @@ -446,7 +446,7 @@ * Send exec commands */ -static int mc32_command(struct device *dev, u16 cmd, void *data, int len) +static int mc32_command(struct net_device *dev, u16 cmd, void *data, int len) { struct mc32_local *lp = (struct mc32_local *)dev->priv; int ioaddr = dev->base_addr; @@ -488,7 +488,7 @@ * RX abort */ -static void mc32_rx_abort(struct device *dev) +static void mc32_rx_abort(struct net_device *dev) { struct mc32_local *lp = (struct mc32_local *)dev->priv; int ioaddr = dev->base_addr; @@ -504,7 +504,7 @@ * RX enable */ -static void mc32_rx_begin(struct device *dev) +static void mc32_rx_begin(struct net_device *dev) { struct mc32_local *lp = (struct mc32_local *)dev->priv; int ioaddr = dev->base_addr; @@ -518,7 +518,7 @@ lp->rx_halted=0; } -static void mc32_tx_abort(struct device *dev) +static void mc32_tx_abort(struct net_device *dev) { struct mc32_local *lp = (struct mc32_local *)dev->priv; int ioaddr = dev->base_addr; @@ -565,7 +565,7 @@ * TX enable */ -static void mc32_tx_begin(struct device *dev) +static void mc32_tx_begin(struct net_device *dev) { struct mc32_local *lp = (struct mc32_local *)dev->priv; int ioaddr = dev->base_addr; @@ -588,7 +588,7 @@ * Load the rx ring */ -static int mc32_load_rx_ring(struct device *dev) +static int mc32_load_rx_ring(struct net_device *dev) { struct mc32_local *lp = (struct mc32_local *)dev->priv; int i; @@ -652,7 +652,7 @@ * sometime after booting when the 'ifconfig' program is run. */ -static int mc32_open(struct device *dev) +static int mc32_open(struct net_device *dev) { int ioaddr = dev->base_addr; u16 zero_word=0; @@ -717,7 +717,7 @@ return 0; } -static int mc32_send_packet(struct sk_buff *skb, struct device *dev) +static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev) { struct mc32_local *lp = (struct mc32_local *)dev->priv; @@ -796,12 +796,12 @@ return 0; } -static void mc32_update_stats(struct device *dev) +static void mc32_update_stats(struct net_device *dev) { } -static void mc32_rx_ring(struct device *dev) +static void mc32_rx_ring(struct net_device *dev) { struct mc32_local *lp=dev->priv; int ioaddr = dev->base_addr; @@ -879,7 +879,7 @@ */ static void mc32_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct mc32_local *lp; int ioaddr, status, boguscount = 0; int rx_event = 0; @@ -1002,7 +1002,7 @@ /* The inverse routine to mc32_open(). */ -static int mc32_close(struct device *dev) +static int mc32_close(struct net_device *dev) { struct mc32_local *lp = (struct mc32_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1050,7 +1050,7 @@ * This may be called with the card open or closed. */ -static struct net_device_stats *mc32_get_stats(struct device *dev) +static struct net_device_stats *mc32_get_stats(struct net_device *dev) { struct mc32_local *lp = (struct mc32_local *)dev->priv; return &lp->net_stats; @@ -1063,7 +1063,7 @@ * num_addrs > 0 Multicast mode, receive normal and MC packets, * and do best-effort filtering. */ -static void mc32_set_multicast_list(struct device *dev) +static void mc32_set_multicast_list(struct net_device *dev) { u16 filt; if (dev->flags&IFF_PROMISC) @@ -1110,7 +1110,7 @@ #ifdef MODULE static char devicename[9] = { 0, }; -static struct device this_device = { +static struct net_device this_device = { devicename, /* will be inserted by linux/drivers/net/mc32_init.c */ 0, 0, 0, 0, 0, 0, /* I/O address, IRQ */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/3c59x.c linux/drivers/net/3c59x.c --- v2.3.13/linux/drivers/net/3c59x.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/3c59x.c Wed Aug 18 11:36:41 1999 @@ -229,14 +229,14 @@ const char *name; u16 vendor_id, device_id, device_id_mask, flags; int drv_flags, io_size; - struct device *(*probe1)(int pci_bus, int pci_devfn, struct device *dev, + struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, long ioaddr, int irq, int chip_idx, int fnd_cnt); }; enum { IS_VORTEX=1, IS_BOOMERANG=2, IS_CYCLONE=4, HAS_PWR_CTRL=0x10, HAS_MII=0x20, HAS_NWAY=0x40, HAS_CB_FNS=0x80, }; -static struct device *vortex_probe1(int pci_bus, int pci_devfn, - struct device *dev, long ioaddr, +static struct net_device *vortex_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, int irq, int dev_id, int card_idx); static struct pci_id_info pci_tbl[] = { {"3c590 Vortex 10Mbps", 0x10B7, 0x5900, 0xffff, @@ -422,7 +422,7 @@ /* The addresses of transmit- and receive-in-place skbuffs. */ struct sk_buff* rx_skbuff[RX_RING_SIZE]; struct sk_buff* tx_skbuff[TX_RING_SIZE]; - struct device *next_module; + struct net_device *next_module; void *priv_addr; unsigned int cur_rx, cur_tx; /* The next free ring entry */ unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ @@ -482,23 +482,23 @@ }; #ifndef CARDBUS -static int vortex_scan(struct device *dev, struct pci_id_info pci_tbl[]); +static int vortex_scan(struct net_device *dev, struct pci_id_info pci_tbl[]); #endif -static int vortex_open(struct device *dev); +static int vortex_open(struct net_device *dev); static void mdio_sync(long ioaddr, int bits); static int mdio_read(long ioaddr, int phy_id, int location); static void mdio_write(long ioaddr, int phy_id, int location, int value); static void vortex_timer(unsigned long arg); -static int vortex_start_xmit(struct sk_buff *skb, struct device *dev); -static int boomerang_start_xmit(struct sk_buff *skb, struct device *dev); -static int vortex_rx(struct device *dev); -static int boomerang_rx(struct device *dev); +static int vortex_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int vortex_rx(struct net_device *dev); +static int boomerang_rx(struct net_device *dev); static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int vortex_close(struct device *dev); -static void update_stats(long ioaddr, struct device *dev); -static struct net_device_stats *vortex_get_stats(struct device *dev); -static void set_rx_mode(struct device *dev); -static int vortex_ioctl(struct device *dev, struct ifreq *rq, int cmd); +static int vortex_close(struct net_device *dev); +static void update_stats(long ioaddr, struct net_device *dev); +static struct net_device_stats *vortex_get_stats(struct net_device *dev); +static void set_rx_mode(struct net_device *dev); +static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */ @@ -507,7 +507,7 @@ static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1,}; static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; /* A list of all installed Vortex devices, for removing the driver module. */ -static struct device *root_vortex_dev = NULL; +static struct net_device *root_vortex_dev = NULL; #ifdef MODULE #ifndef CARDBUS @@ -524,7 +524,7 @@ u16 dev_id, vendor_id; u32 io; u8 bus, devfn, irq; - struct device *dev; + struct net_device *dev; int chip_idx; if (loc->bus != LOC_PCI) return NULL; @@ -566,14 +566,14 @@ static void vortex_detach(dev_node_t *node) { - struct device **devp, **next; + struct net_device **devp, **next; printk(KERN_INFO "vortex_detach(%s)\n", node->dev_name); for (devp = &root_vortex_dev; *devp; devp = next) { next = &((struct vortex_private *)(*devp)->priv)->next_module; if (strcmp((*devp)->name, node->dev_name) == 0) break; } if (*devp) { - struct device *dev = *devp; + struct net_device *dev = *devp; struct vortex_private *vp = dev->priv; if (dev->flags & IFF_UP) vortex_close(dev); @@ -608,7 +608,7 @@ } #else -int tc59x_probe(struct device *dev) +int tc59x_probe(struct net_device *dev) { static int scanned=0; if(scanned++) @@ -619,7 +619,7 @@ #endif /* not MODULE */ #ifndef CARDBUS -static int vortex_scan(struct device *dev, struct pci_id_info pci_tbl[]) +static int vortex_scan(struct net_device *dev, struct pci_id_info pci_tbl[]) { int cards_found = 0; @@ -762,8 +762,8 @@ } #endif /* ! Cardbus */ -static struct device *vortex_probe1(int pci_bus, int pci_devfn, - struct device *dev, long ioaddr, +static struct net_device *vortex_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, int irq, int chip_idx, int card_idx) { struct vortex_private *vp; @@ -964,7 +964,7 @@ static int -vortex_open(struct device *dev) +vortex_open(struct net_device *dev) { long ioaddr = dev->base_addr; struct vortex_private *vp = (struct vortex_private *)dev->priv; @@ -1159,7 +1159,7 @@ static void vortex_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr = dev->base_addr; int next_tick = 0; @@ -1261,7 +1261,7 @@ return; } -static void vortex_tx_timeout(struct device *dev) +static void vortex_tx_timeout(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1332,7 +1332,7 @@ * the cache impact. */ static void -vortex_error(struct device *dev, int status) +vortex_error(struct net_device *dev, int status) { struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1421,7 +1421,7 @@ static int -vortex_start_xmit(struct sk_buff *skb, struct device *dev) +vortex_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1483,7 +1483,7 @@ } static int -boomerang_start_xmit(struct sk_buff *skb, struct device *dev) +boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1547,7 +1547,7 @@ after the Tx thread. */ static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr; int latency, status; @@ -1672,7 +1672,7 @@ return; } -static int vortex_rx(struct device *dev) +static int vortex_rx(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1745,7 +1745,7 @@ } static int -boomerang_rx(struct device *dev) +boomerang_rx(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; int entry = vp->cur_rx % RX_RING_SIZE; @@ -1841,7 +1841,7 @@ } static int -vortex_close(struct device *dev) +vortex_close(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1901,7 +1901,7 @@ return 0; } -static struct net_device_stats *vortex_get_stats(struct device *dev) +static struct net_device_stats *vortex_get_stats(struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; unsigned long flags; @@ -1922,7 +1922,7 @@ table. This is done by checking that the ASM (!) code generated uses atomic updates with '+='. */ -static void update_stats(long ioaddr, struct device *dev) +static void update_stats(long ioaddr, struct net_device *dev) { struct vortex_private *vp = (struct vortex_private *)dev->priv; @@ -1953,7 +1953,7 @@ return; } -static int vortex_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct vortex_private *vp = (struct vortex_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1981,7 +1981,7 @@ /* Pre-Cyclone chips have no documented multicast filter, so the only multicast setting is to receive all multicast frames. At least the chip has a very clean way to set the mode, unlike many others. */ -static void set_rx_mode(struct device *dev) +static void set_rx_mode(struct net_device *dev) { long ioaddr = dev->base_addr; int new_mode; @@ -2096,7 +2096,7 @@ #ifdef MODULE void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; #ifdef CARDBUS unregister_driver(&vortex_ops); diff -u --recursive --new-file v2.3.13/linux/drivers/net/7990.c linux/drivers/net/7990.c --- v2.3.13/linux/drivers/net/7990.c Thu Jun 25 11:03:42 1998 +++ linux/drivers/net/7990.c Wed Aug 18 11:36:41 1999 @@ -101,7 +101,7 @@ #define DEBUG_IRING 0 /* Set up the Lance Rx and Tx rings and the init block */ /* Sets dev->tbusy */ -static void lance_init_ring (struct device *dev) +static void lance_init_ring (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -219,7 +219,7 @@ return 0; } -static int lance_reset (struct device *dev) +static int lance_reset (struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; int status; @@ -242,7 +242,7 @@ return status; } -static int lance_rx (struct device *dev) +static int lance_rx (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -320,7 +320,7 @@ return 0; } -static int lance_tx (struct device *dev) +static int lance_tx (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -405,7 +405,7 @@ static void lance_interrupt (int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct lance_private *lp = (struct lance_private *)dev->priv; int csr0; DECLARE_LL; @@ -460,7 +460,7 @@ dev->interrupt = 0; } -int lance_open (struct device *dev) +int lance_open (struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; DECLARE_LL; @@ -472,7 +472,7 @@ return lance_reset(dev); } -int lance_close (struct device *dev) +int lance_close (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; DECLARE_LL; @@ -489,7 +489,7 @@ return 0; } -int lance_start_xmit (struct sk_buff *skb, struct device *dev) +int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -560,7 +560,7 @@ return status; } -struct net_device_stats *lance_get_stats (struct device *dev) +struct net_device_stats *lance_get_stats (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; @@ -568,7 +568,7 @@ } /* taken from the depca driver via a2065.c */ -static void lance_load_multicast (struct device *dev) +static void lance_load_multicast (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -619,7 +619,7 @@ } -void lance_set_multicast (struct device *dev) +void lance_set_multicast (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; diff -u --recursive --new-file v2.3.13/linux/drivers/net/7990.h linux/drivers/net/7990.h --- v2.3.13/linux/drivers/net/7990.h Sat Jun 13 13:28:34 1998 +++ linux/drivers/net/7990.h Wed Aug 18 11:36:45 1999 @@ -247,10 +247,10 @@ #define LANCE_ADDR(x) ((int)(x) & ~0xff000000) /* Now the prototypes we export */ -extern int lance_open(struct device *dev); -extern int lance_close (struct device *dev); -extern int lance_start_xmit (struct sk_buff *skb, struct device *dev); -extern struct net_device_stats *lance_get_stats (struct device *dev); -extern void lance_set_multicast (struct device *dev); +extern int lance_open(struct net_device *dev); +extern int lance_close (struct net_device *dev); +extern int lance_start_xmit (struct sk_buff *skb, struct net_device *dev); +extern struct net_device_stats *lance_get_stats (struct net_device *dev); +extern void lance_set_multicast (struct net_device *dev); #endif /* ndef _7990_H */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/82596.c linux/drivers/net/82596.c --- v2.3.13/linux/drivers/net/82596.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/82596.c Wed Aug 18 11:36:41 1999 @@ -258,20 +258,20 @@ 0x00, 0x7f /* *multi IA */ }; -static int i596_open(struct device *dev); -static int i596_start_xmit(struct sk_buff *skb, struct device *dev); +static int i596_open(struct net_device *dev); +static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev); static void i596_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int i596_close(struct device *dev); -static struct net_device_stats *i596_get_stats(struct device *dev); -static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd); +static int i596_close(struct net_device *dev); +static struct net_device_stats *i596_get_stats(struct net_device *dev); +static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd); static void print_eth(char *); -static void set_multicast_list(struct device *dev); +static void set_multicast_list(struct net_device *dev); static int ticks_limit = 25; static int max_cmd_backlog = 16; -static inline void CA(struct device *dev) +static inline void CA(struct net_device *dev) { #ifdef CONFIG_MVME16x_NET if (MACH_IS_MVME16x) { @@ -291,7 +291,7 @@ } -static inline void MPU_PORT(struct device *dev, int c, volatile void *x) +static inline void MPU_PORT(struct net_device *dev, int c, volatile void *x) { #ifdef CONFIG_MVME16x_NET if (MACH_IS_MVME16x) { @@ -315,7 +315,7 @@ #if defined(CONFIG_MVME16x_NET) || defined(CONFIG_BVME6000_NET) static void i596_error(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct i596_cmd *cmd; struct i596_private *lp = (struct i596_private *) dev->priv; @@ -338,7 +338,7 @@ } #endif -static inline int init_rx_bufs(struct device *dev, int num) +static inline int init_rx_bufs(struct net_device *dev, int num) { struct i596_private *lp = (struct i596_private *) dev->priv; int i; @@ -373,7 +373,7 @@ return (i); } -static inline void remove_rx_bufs(struct device *dev) +static inline void remove_rx_bufs(struct net_device *dev) { struct i596_private *lp = (struct i596_private *) dev->priv; struct i596_rfd *rfd = WSWAPrfd(lp->scb.rfd); @@ -388,7 +388,7 @@ while (rfd != lp->rx_tail); } -static inline void init_i596_mem(struct device *dev) +static inline void init_i596_mem(struct net_device *dev) { struct i596_private *lp = (struct i596_private *) dev->priv; #if !defined(CONFIG_MVME16x_NET) && !defined(CONFIG_BVME6000_NET) @@ -528,7 +528,7 @@ return; } -static inline int i596_rx(struct device *dev) +static inline int i596_rx(struct net_device *dev) { struct i596_private *lp = (struct i596_private *) dev->priv; struct i596_rfd *rfd; @@ -645,7 +645,7 @@ lp->scb.cmd = WSWAPcmd(lp->cmd_head); } -static inline void i596_reset(struct device *dev, struct i596_private *lp, int ioaddr) +static inline void i596_reset(struct net_device *dev, struct i596_private *lp, int ioaddr) { int boguscnt = 1000; unsigned long flags; @@ -688,7 +688,7 @@ init_i596_mem(dev); } -static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd) +static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd) { struct i596_private *lp = (struct i596_private *) dev->priv; int ioaddr = dev->base_addr; @@ -746,7 +746,7 @@ } } -static int i596_open(struct device *dev) +static int i596_open(struct net_device *dev) { int i; @@ -779,7 +779,7 @@ return 0; /* Always succeed */ } -static int i596_start_xmit(struct sk_buff *skb, struct device *dev) +static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct i596_private *lp = (struct i596_private *) dev->priv; int ioaddr = dev->base_addr; @@ -878,7 +878,7 @@ printk("type %2.2X%2.2X\n", (unsigned char) add[12], (unsigned char) add[13]); } -int __init i82596_probe(struct device *dev) +int __init i82596_probe(struct net_device *dev) { int i; struct i596_private *lp; @@ -983,7 +983,7 @@ static void i596_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct i596_private *lp; short ioaddr; int boguscnt = 2000; @@ -1176,7 +1176,7 @@ return; } -static int i596_close(struct device *dev) +static int i596_close(struct net_device *dev) { struct i596_private *lp = (struct i596_private *) dev->priv; int boguscnt = 2000; @@ -1239,7 +1239,7 @@ } static struct net_device_stats * - i596_get_stats(struct device *dev) + i596_get_stats(struct net_device *dev) { struct i596_private *lp = (struct i596_private *) dev->priv; @@ -1250,7 +1250,7 @@ * Set or clear the multicast filter for this adaptor. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { struct i596_private *lp = (struct i596_private *) dev->priv; struct i596_cmd *cmd; @@ -1317,7 +1317,7 @@ #ifdef MODULE static char devicename[9] = {0,}; -static struct device dev_apricot = +static struct net_device dev_apricot = { devicename, /* device name inserted by /linux/drivers/net/net_init.c */ 0, 0, 0, 0, diff -u --recursive --new-file v2.3.13/linux/drivers/net/8390.c linux/drivers/net/8390.c --- v2.3.13/linux/drivers/net/8390.c Thu May 6 14:02:34 1999 +++ linux/drivers/net/8390.c Wed Aug 18 11:36:41 1999 @@ -76,18 +76,18 @@ /* These are the operational function interfaces to board-specific routines. - void reset_8390(struct device *dev) + void reset_8390(struct net_device *dev) Resets the board associated with DEV, including a hardware reset of the 8390. This is only called when there is a transmit timeout, and it is always followed by 8390_init(). - void block_output(struct device *dev, int count, const unsigned char *buf, + void block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) Write the COUNT bytes of BUF to the packet buffer at START_PAGE. The "page" value uses the 8390's 256-byte pages. - void get_8390_hdr(struct device *dev, struct e8390_hdr *hdr, int ring_page) + void get_8390_hdr(struct net_device *dev, struct e8390_hdr *hdr, int ring_page) Read the 4 byte, page aligned 8390 header. *If* there is a subsequent read, it will be of the rest of the packet. - void block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) + void block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) Read COUNT bytes from the packet buffer into the skb data area. Start reading from RING_OFFSET, the address as the 8390 sees it. This will always follow the read of the 8390 header. @@ -103,16 +103,16 @@ #endif /* Index to functions. */ -static void ei_tx_intr(struct device *dev); -static void ei_tx_err(struct device *dev); -static void ei_receive(struct device *dev); -static void ei_rx_overrun(struct device *dev); +static void ei_tx_intr(struct net_device *dev); +static void ei_tx_err(struct net_device *dev); +static void ei_receive(struct net_device *dev); +static void ei_rx_overrun(struct net_device *dev); /* Routines generic to NS8390-based boards. */ -static void NS8390_trigger_send(struct device *dev, unsigned int length, +static void NS8390_trigger_send(struct net_device *dev, unsigned int length, int start_page); -static void set_multicast_list(struct device *dev); -static void do_set_multicast_list(struct device *dev); +static void set_multicast_list(struct net_device *dev); +static void do_set_multicast_list(struct net_device *dev); /* * SMP and the 8390 setup. @@ -146,7 +146,7 @@ up anew at each open, even though many of these registers should only need to be set once at boot. */ -int ei_open(struct device *dev) +int ei_open(struct net_device *dev) { unsigned long flags; struct ei_device *ei_local = (struct ei_device *) dev->priv; @@ -174,7 +174,7 @@ } /* Opposite of above. Only used when "ifconfig down" is done. */ -int ei_close(struct device *dev) +int ei_close(struct net_device *dev) { struct ei_device *ei_local = (struct ei_device *) dev->priv; unsigned long flags; @@ -190,7 +190,7 @@ return 0; } -static int ei_start_xmit(struct sk_buff *skb, struct device *dev) +static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) { int e8390_base = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; @@ -404,7 +404,7 @@ void ei_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; int e8390_base; int interrupts, nr_serviced = 0; struct ei_device *ei_local; @@ -516,7 +516,7 @@ * Called with lock held */ -static void ei_tx_err(struct device *dev) +static void ei_tx_err(struct net_device *dev) { int e8390_base = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; @@ -554,7 +554,7 @@ /* We have finished a transmit: check for errors and then trigger the next packet to be sent. Called with lock held */ -static void ei_tx_intr(struct device *dev) +static void ei_tx_intr(struct net_device *dev) { int e8390_base = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; @@ -644,7 +644,7 @@ /* We have a good packet(s), get it/them out of the buffers. Called with lock held */ -static void ei_receive(struct device *dev) +static void ei_receive(struct net_device *dev) { int e8390_base = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; @@ -773,7 +773,7 @@ * computer will hate you - it takes 10mS or so. */ -static void ei_rx_overrun(struct device *dev) +static void ei_rx_overrun(struct net_device *dev) { int e8390_base = dev->base_addr; unsigned char was_txing, must_resend = 0; @@ -842,7 +842,7 @@ * Collect the stats. This is called unlocked and from several contexts. */ -static struct net_device_stats *get_stats(struct device *dev) +static struct net_device_stats *get_stats(struct net_device *dev) { int ioaddr = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; @@ -888,7 +888,7 @@ * associated with this dev structure. */ -static inline void make_mc_bits(u8 *bits, struct device *dev) +static inline void make_mc_bits(u8 *bits, struct net_device *dev) { struct dev_mc_list *dmi; @@ -917,7 +917,7 @@ * from a BH in 2.1.x. Must be called with lock held. */ -static void do_set_multicast_list(struct device *dev) +static void do_set_multicast_list(struct net_device *dev) { int e8390_base = dev->base_addr; int i; @@ -972,7 +972,7 @@ * not called too often. Must protect against both bh and irq users */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { unsigned long flags; struct ei_device *ei_local = (struct ei_device*)dev->priv; @@ -987,7 +987,7 @@ * this, as it is used by 8390 based modular drivers too. */ -int ethdev_init(struct device *dev) +int ethdev_init(struct net_device *dev) { if (ei_debug > 1) printk(version); @@ -1022,7 +1022,7 @@ * Must be called with lock held. */ -void NS8390_init(struct device *dev, int startp) +void NS8390_init(struct net_device *dev, int startp) { int e8390_base = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; @@ -1085,7 +1085,7 @@ /* Trigger a transmit start, assuming the length is valid. Always called with the page lock held */ -static void NS8390_trigger_send(struct device *dev, unsigned int length, +static void NS8390_trigger_send(struct net_device *dev, unsigned int length, int start_page) { int e8390_base = dev->base_addr; diff -u --recursive --new-file v2.3.13/linux/drivers/net/8390.h linux/drivers/net/8390.h --- v2.3.13/linux/drivers/net/8390.h Mon Dec 28 11:04:21 1998 +++ linux/drivers/net/8390.h Wed Aug 18 11:36:45 1999 @@ -53,10 +53,10 @@ #if defined(LOAD_8390_BY_KMOD) && defined(MODULE) && !defined(NS8390_CORE) /* Function pointers to be mapped onto the 8390 core support */ -static int (*S_ethdev_init)(struct device *dev); -static void (*S_NS8390_init)(struct device *dev, int startp); -static int (*S_ei_open)(struct device *dev); -static int (*S_ei_close)(struct device *dev); +static int (*S_ethdev_init)(struct net_device *dev); +static void (*S_NS8390_init)(struct net_device *dev, int startp); +static int (*S_ei_open)(struct net_device *dev); +static int (*S_ei_close)(struct net_device *dev); static void (*S_ei_interrupt)(int irq, void *dev_id, struct pt_regs *regs); @@ -143,23 +143,23 @@ #define load_8390_module(driver) 0 #define lock_8390_module() do { } while (0) #define unlock_8390_module() do { } while (0) -extern int ethdev_init(struct device *dev); -extern void NS8390_init(struct device *dev, int startp); -extern int ei_open(struct device *dev); -extern int ei_close(struct device *dev); +extern int ethdev_init(struct net_device *dev); +extern void NS8390_init(struct net_device *dev, int startp); +extern int ei_open(struct net_device *dev); +extern int ei_close(struct net_device *dev); extern void ei_interrupt(int irq, void *dev_id, struct pt_regs *regs); #endif -/* Most of these entries should be in 'struct device' (or most of the +/* Most of these entries should be in 'struct net_device' (or most of the things in there should be here!) */ /* You have one of these per-board */ struct ei_device { const char *name; - void (*reset_8390)(struct device *); - void (*get_8390_hdr)(struct device *, struct e8390_pkt_hdr *, int); - void (*block_output)(struct device *, int, const unsigned char *, int); - void (*block_input)(struct device *, int, struct sk_buff *, int); + void (*reset_8390)(struct net_device *); + void (*get_8390_hdr)(struct net_device *, struct e8390_pkt_hdr *, int); + void (*block_output)(struct net_device *, int, const unsigned char *, int); + void (*block_input)(struct net_device *, int, struct sk_buff *, int); unsigned char mcfilter[8]; unsigned open:1; unsigned word16:1; /* We have the 16-bit (vs 8-bit) version of the card. */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/Makefile linux/drivers/net/Makefile --- v2.3.13/linux/drivers/net/Makefile Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/Makefile Thu Aug 12 09:46:13 1999 @@ -1136,6 +1136,15 @@ endif endif +ifeq ($(CONFIG_CYCLADES_SYNC),m) + MX_OBJS += cycx_drv.o + M_OBJS += cyclomx.o + CYCLOMX_OBJS = cycx_main.o + ifeq ($(CONFIG_CYCLOMX_X25),y) + CYCLOMX_OBJS += cycx_x25.o + endif +endif + ifeq ($(CONFIG_X25_ASY),y) L_OBJS += x25_asy.o else diff -u --recursive --new-file v2.3.13/linux/drivers/net/Space.c linux/drivers/net/Space.c --- v2.3.13/linux/drivers/net/Space.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/Space.c Wed Aug 18 11:36:41 1999 @@ -39,107 +39,107 @@ ethernet adaptor have the name "eth[0123...]". */ -extern int ne2_probe(struct device *dev); -extern int tulip_probe(struct device *dev); -extern int hp100_probe(struct device *dev); -extern int ultra_probe(struct device *dev); -extern int ultra32_probe(struct device *dev); -extern int ultramca_probe(struct device *dev); -extern int wd_probe(struct device *dev); -extern int el2_probe(struct device *dev); -extern int ne2k_pci_probe(struct device *dev); -extern int ne_probe(struct device *dev); -extern int hp_probe(struct device *dev); -extern int hp_plus_probe(struct device *dev); -extern int znet_probe(struct device *); -extern int express_probe(struct device *); -extern int eepro_probe(struct device *); -extern int eepro100_probe(struct device *); -extern int el3_probe(struct device *); -extern int at1500_probe(struct device *); -extern int pcnet32_probe(struct device *); -extern int at1700_probe(struct device *); -extern int fmv18x_probe(struct device *); -extern int eth16i_probe(struct device *); -extern int depca_probe(struct device *); -extern int i82596_probe(struct device *); -extern int ewrk3_probe(struct device *); -extern int de4x5_probe(struct device *); -extern int el1_probe(struct device *); -extern int wavelan_probe(struct device *); -extern int arlan_probe(struct device *); -extern int el16_probe(struct device *); -extern int elmc_probe(struct device *); -extern int skmca_probe(struct device *); -extern int elplus_probe(struct device *); -extern int ac3200_probe(struct device *); -extern int es_probe(struct device *); -extern int lne390_probe(struct device *); -extern int ne3210_probe(struct device *); -extern int e2100_probe(struct device *); -extern int ni5010_probe(struct device *); -extern int ni52_probe(struct device *); -extern int ni65_probe(struct device *); -extern int sonic_probe(struct device *); -extern int SK_init(struct device *); -extern int seeq8005_probe(struct device *); -extern int tc59x_probe(struct device *); -extern int dgrs_probe(struct device *); -extern int smc_init( struct device * ); -extern int sparc_lance_probe(struct device *); -extern int happy_meal_probe(struct device *); -extern int qec_probe(struct device *); -extern int bigmac_probe(struct device *); -extern int myri_sbus_probe(struct device *); -extern int sgiseeq_probe(struct device *); -extern int atarilance_probe(struct device *); -extern int a2065_probe(struct device *); -extern int ariadne_probe(struct device *); -extern int ariadne2_probe(struct device *); -extern int hydra_probe(struct device *); -extern int apne_probe(struct device *); -extern int bionet_probe(struct device *); -extern int pamsnet_probe(struct device *); -extern int tlan_probe(struct device *); -extern int mace_probe(struct device *); -extern int bmac_probe(struct device *); -extern int cs89x0_probe(struct device *dev); -extern int ethertap_probe(struct device *dev); -extern int ether1_probe (struct device *dev); -extern int ether3_probe (struct device *dev); -extern int etherh_probe (struct device *dev); -extern int am79c961_probe(struct device *dev); -extern int epic100_probe(struct device *dev); -extern int rtl8139_probe(struct device *dev); -extern int hplance_probe(struct device *dev); -extern int bagetlance_probe(struct device *); -extern int dec_lance_probe(struct device *); -extern int mvme147lance_probe(struct device *dev); -extern int via_rhine_probe(struct device *dev); -extern int tc515_probe(struct device *dev); -extern int lance_probe(struct device *dev); -extern int rcpci_probe(struct device *); -extern int mac_onboard_sonic_probe(struct device *dev); +extern int ne2_probe(struct net_device *dev); +extern int tulip_probe(struct net_device *dev); +extern int hp100_probe(struct net_device *dev); +extern int ultra_probe(struct net_device *dev); +extern int ultra32_probe(struct net_device *dev); +extern int ultramca_probe(struct net_device *dev); +extern int wd_probe(struct net_device *dev); +extern int el2_probe(struct net_device *dev); +extern int ne2k_pci_probe(struct net_device *dev); +extern int ne_probe(struct net_device *dev); +extern int hp_probe(struct net_device *dev); +extern int hp_plus_probe(struct net_device *dev); +extern int znet_probe(struct net_device *); +extern int express_probe(struct net_device *); +extern int eepro_probe(struct net_device *); +extern int eepro100_probe(struct net_device *); +extern int el3_probe(struct net_device *); +extern int at1500_probe(struct net_device *); +extern int pcnet32_probe(struct net_device *); +extern int at1700_probe(struct net_device *); +extern int fmv18x_probe(struct net_device *); +extern int eth16i_probe(struct net_device *); +extern int depca_probe(struct net_device *); +extern int i82596_probe(struct net_device *); +extern int ewrk3_probe(struct net_device *); +extern int de4x5_probe(struct net_device *); +extern int el1_probe(struct net_device *); +extern int wavelan_probe(struct net_device *); +extern int arlan_probe(struct net_device *); +extern int el16_probe(struct net_device *); +extern int elmc_probe(struct net_device *); +extern int skmca_probe(struct net_device *); +extern int elplus_probe(struct net_device *); +extern int ac3200_probe(struct net_device *); +extern int es_probe(struct net_device *); +extern int lne390_probe(struct net_device *); +extern int ne3210_probe(struct net_device *); +extern int e2100_probe(struct net_device *); +extern int ni5010_probe(struct net_device *); +extern int ni52_probe(struct net_device *); +extern int ni65_probe(struct net_device *); +extern int sonic_probe(struct net_device *); +extern int SK_init(struct net_device *); +extern int seeq8005_probe(struct net_device *); +extern int tc59x_probe(struct net_device *); +extern int dgrs_probe(struct net_device *); +extern int smc_init( struct net_device * ); +extern int sparc_lance_probe(struct net_device *); +extern int happy_meal_probe(struct net_device *); +extern int qec_probe(struct net_device *); +extern int bigmac_probe(struct net_device *); +extern int myri_sbus_probe(struct net_device *); +extern int sgiseeq_probe(struct net_device *); +extern int atarilance_probe(struct net_device *); +extern int a2065_probe(struct net_device *); +extern int ariadne_probe(struct net_device *); +extern int ariadne2_probe(struct net_device *); +extern int hydra_probe(struct net_device *); +extern int apne_probe(struct net_device *); +extern int bionet_probe(struct net_device *); +extern int pamsnet_probe(struct net_device *); +extern int tlan_probe(struct net_device *); +extern int mace_probe(struct net_device *); +extern int bmac_probe(struct net_device *); +extern int cs89x0_probe(struct net_device *dev); +extern int ethertap_probe(struct net_device *dev); +extern int ether1_probe (struct net_device *dev); +extern int ether3_probe (struct net_device *dev); +extern int etherh_probe (struct net_device *dev); +extern int am79c961_probe(struct net_device *dev); +extern int epic100_probe(struct net_device *dev); +extern int rtl8139_probe(struct net_device *dev); +extern int hplance_probe(struct net_device *dev); +extern int bagetlance_probe(struct net_device *); +extern int dec_lance_probe(struct net_device *); +extern int mvme147lance_probe(struct net_device *dev); +extern int via_rhine_probe(struct net_device *dev); +extern int tc515_probe(struct net_device *dev); +extern int lance_probe(struct net_device *dev); +extern int rcpci_probe(struct net_device *); +extern int mac_onboard_sonic_probe(struct net_device *dev); /* Gigabit Ethernet adapters */ -extern int yellowfin_probe(struct device *dev); -extern int acenic_probe(struct device *dev); +extern int yellowfin_probe(struct net_device *dev); +extern int acenic_probe(struct net_device *dev); /* Detachable devices ("pocket adaptors") */ -extern int atp_init(struct device *); -extern int de600_probe(struct device *); -extern int de620_probe(struct device *); +extern int atp_init(struct net_device *); +extern int de600_probe(struct net_device *); +extern int de620_probe(struct net_device *); /* FDDI adapters */ -extern int dfx_probe(struct device *dev); -extern int apfddi_init(struct device *dev); +extern int dfx_probe(struct net_device *dev); +extern int apfddi_init(struct net_device *dev); /* HIPPI boards */ -extern int rr_hippi_probe(struct device *); +extern int rr_hippi_probe(struct net_device *); struct devprobe { - int (*probe)(struct device *dev); + int (*probe)(struct net_device *dev); int status; /* non-zero if autoprobe has failed */ }; @@ -150,7 +150,7 @@ * autoprobe (i.e. a probe that fails to find a card when autoprobing * will not be asked to autoprobe again). It exits when a card is found. */ -static int __init probe_list(struct device *dev, struct devprobe *plist) +static int __init probe_list(struct net_device *dev, struct devprobe *plist) { struct devprobe *p = plist; unsigned long base_addr = dev->base_addr; @@ -486,7 +486,7 @@ * Unified ethernet device probe, segmented per architecture and * per bus interface. */ -static int __init ethif_probe(struct device *dev) +static int __init ethif_probe(struct net_device *dev) { unsigned long base_addr = dev->base_addr; @@ -534,7 +534,7 @@ } #ifdef CONFIG_FDDI -static int __init fddiif_probe(struct device *dev) +static int __init fddiif_probe(struct net_device *dev) { unsigned long base_addr = dev->base_addr; @@ -556,7 +556,7 @@ #endif #ifdef CONFIG_HIPPI -static int hippi_probe(struct device *dev) +static int hippi_probe(struct net_device *dev) { /* * Damn this is ugly. @@ -579,22 +579,22 @@ #endif #ifdef CONFIG_ETHERTAP - static struct device tap0_dev = { "tap0", 0, 0, 0, 0, NETLINK_TAPBASE, 0, 0, 0, 0, NEXT_DEV, ethertap_probe, }; + static struct net_device tap0_dev = { "tap0", 0, 0, 0, 0, NETLINK_TAPBASE, 0, 0, 0, 0, NEXT_DEV, ethertap_probe, }; # undef NEXT_DEV # define NEXT_DEV (&tap0_dev) #endif #ifdef CONFIG_SDLA - extern int sdla_init(struct device *); - static struct device sdla0_dev = { "sdla0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, sdla_init, }; + extern int sdla_init(struct net_device *); + static struct net_device sdla0_dev = { "sdla0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, sdla_init, }; # undef NEXT_DEV # define NEXT_DEV (&sdla0_dev) #endif #if defined(CONFIG_LTPC) - extern int ltpc_probe(struct device *); - static struct device dev_ltpc = { + extern int ltpc_probe(struct net_device *); + static struct net_device dev_ltpc = { "lt0\0 ", 0, 0, 0, 0, 0x0, 0, @@ -604,17 +604,17 @@ #endif /* LTPC */ #if defined(CONFIG_COPS) - extern int cops_probe(struct device *); - static struct device cops2_dev = { "lt2", 0, 0, 0, 0, 0x0, 0, 0, 0, 0, NEXT_DEV, cops_probe }; - static struct device cops1_dev = { "lt1", 0, 0, 0, 0, 0x0, 0, 0, 0, 0, &cops2_dev, cops_probe }; - static struct device cops0_dev = { "lt0", 0, 0, 0, 0, 0x0, 0, 0, 0, 0, &cops1_dev, cops_probe }; + extern int cops_probe(struct net_device *); + static struct net_device cops2_dev = { "lt2", 0, 0, 0, 0, 0x0, 0, 0, 0, 0, NEXT_DEV, cops_probe }; + static struct net_device cops1_dev = { "lt1", 0, 0, 0, 0, 0x0, 0, 0, 0, 0, &cops2_dev, cops_probe }; + static struct net_device cops0_dev = { "lt0", 0, 0, 0, 0, 0x0, 0, 0, 0, 0, &cops1_dev, cops_probe }; # undef NEXT_DEV # define NEXT_DEV (&cops0_dev) #endif /* COPS */ #if defined(CONFIG_IPDDP) - extern int ipddp_init(struct device *dev); - static struct device dev_ipddp = { + extern int ipddp_init(struct net_device *dev); + static struct net_device dev_ipddp = { "ipddp0\0 ", 0, 0, 0, 0, 0x0, 0, @@ -637,22 +637,22 @@ #define ETH_NOPROBE_ADDR 0xffe0 -static struct device eth7_dev = { +static struct net_device eth7_dev = { "eth7", 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, NEXT_DEV, ethif_probe }; -static struct device eth6_dev = { +static struct net_device eth6_dev = { "eth6", 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð7_dev, ethif_probe }; -static struct device eth5_dev = { +static struct net_device eth5_dev = { "eth5", 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð6_dev, ethif_probe }; -static struct device eth4_dev = { +static struct net_device eth4_dev = { "eth4", 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð5_dev, ethif_probe }; -static struct device eth3_dev = { +static struct net_device eth3_dev = { "eth3", 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð4_dev, ethif_probe }; -static struct device eth2_dev = { +static struct net_device eth2_dev = { "eth2", 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð3_dev, ethif_probe }; -static struct device eth1_dev = { +static struct net_device eth1_dev = { "eth1", 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð2_dev, ethif_probe }; -static struct device eth0_dev = { +static struct net_device eth0_dev = { "eth0", 0, 0, 0, 0, ETH0_ADDR, ETH0_IRQ, 0, 0, 0, ð1_dev, ethif_probe }; # undef NEXT_DEV @@ -661,8 +661,8 @@ #if defined(SLIP) || defined(CONFIG_SLIP) /* To be exact, this node just hooks the initialization routines to the device structures. */ -extern int slip_init_ctrl_dev(struct device *); -static struct device slip_bootstrap = { +extern int slip_init_ctrl_dev(struct net_device *); +static struct net_device slip_bootstrap = { "slip_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, slip_init_ctrl_dev, }; #undef NEXT_DEV #define NEXT_DEV (&slip_bootstrap) @@ -671,8 +671,8 @@ #if defined(X25_ASY) || defined(CONFIG_X25_ASY) /* To be exact, this node just hooks the initialization routines to the device structures. */ -extern int x25_asy_init_ctrl_dev(struct device *); -static struct device x25_asy_bootstrap = { +extern int x25_asy_init_ctrl_dev(struct net_device *); +static struct net_device x25_asy_bootstrap = { "x25_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, x25_asy_init_ctrl_dev, }; #undef NEXT_DEV #define NEXT_DEV (&x25_asy_bootstrap) @@ -681,48 +681,48 @@ #if defined(CONFIG_MKISS) /* To be exact, this node just hooks the initialization routines to the device structures. */ -extern int mkiss_init_ctrl_dev(struct device *); -static struct device mkiss_bootstrap = { +extern int mkiss_init_ctrl_dev(struct net_device *); +static struct net_device mkiss_bootstrap = { "mkiss_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, mkiss_init_ctrl_dev, }; #undef NEXT_DEV #define NEXT_DEV (&mkiss_bootstrap) #endif /* MKISS */ #if defined(CONFIG_YAM) -extern int yam_init(struct device *); -static struct device yam_bootstrap = { +extern int yam_init(struct net_device *); +static struct net_device yam_bootstrap = { "yam", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, yam_init, }; #undef NEXT_DEV #define NEXT_DEV (&yam_bootstrap) #endif /* CONFIG_YAM */ #if defined(CONFIG_STRIP) -extern int strip_init_ctrl_dev(struct device *); -static struct device strip_bootstrap = { +extern int strip_init_ctrl_dev(struct net_device *); +static struct net_device strip_bootstrap = { "strip_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, strip_init_ctrl_dev, }; #undef NEXT_DEV #define NEXT_DEV (&strip_bootstrap) #endif /* STRIP */ #if defined(CONFIG_PPP) -extern int ppp_init(struct device *); -static struct device ppp_bootstrap = { +extern int ppp_init(struct net_device *); +static struct net_device ppp_bootstrap = { "ppp_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, ppp_init, }; #undef NEXT_DEV #define NEXT_DEV (&ppp_bootstrap) #endif /* PPP */ #ifdef CONFIG_DUMMY - extern int dummy_init(struct device *dev); - static struct device dummy_dev = { + extern int dummy_init(struct net_device *dev); + static struct net_device dummy_dev = { "dummy", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, dummy_init, }; # undef NEXT_DEV # define NEXT_DEV (&dummy_dev) #endif #ifdef CONFIG_EQUALIZER -extern int eql_init(struct device *dev); -struct device eql_dev = { +extern int eql_init(struct net_device *dev); +struct net_device eql_dev = { "eql", /* Master device for IP traffic load balancing */ 0x0, 0x0, 0x0, 0x0, /* recv end/start; mem end/start */ @@ -738,11 +738,11 @@ #ifdef CONFIG_TR /* Token-ring device probe */ -extern int ibmtr_probe(struct device *); -extern int olympic_probe(struct device *); +extern int ibmtr_probe(struct net_device *); +extern int olympic_probe(struct net_device *); static int -trif_probe(struct device *dev) +trif_probe(struct net_device *dev) { if (1 #ifdef CONFIG_IBMTR @@ -762,21 +762,21 @@ } return 0; } -static struct device tr7_dev = { +static struct net_device tr7_dev = { "tr7",0,0,0,0,0,0,0,0,0, NEXT_DEV, trif_probe }; -static struct device tr6_dev = { +static struct net_device tr6_dev = { "tr6",0,0,0,0,0,0,0,0,0, &tr7_dev, trif_probe }; -static struct device tr5_dev = { +static struct net_device tr5_dev = { "tr5",0,0,0,0,0,0,0,0,0, &tr6_dev, trif_probe }; -static struct device tr4_dev = { +static struct net_device tr4_dev = { "tr4",0,0,0,0,0,0,0,0,0, &tr5_dev, trif_probe }; -static struct device tr3_dev = { +static struct net_device tr3_dev = { "tr3",0,0,0,0,0,0,0,0,0, &tr4_dev, trif_probe }; -static struct device tr2_dev = { +static struct net_device tr2_dev = { "tr2",0,0,0,0,0,0,0,0,0, &tr3_dev, trif_probe }; -static struct device tr1_dev = { +static struct net_device tr1_dev = { "tr1",0,0,0,0,0,0,0,0,0, &tr2_dev, trif_probe }; -static struct device tr0_dev = { +static struct net_device tr0_dev = { "tr0",0,0,0,0,0,0,0,0,0, &tr1_dev, trif_probe }; # undef NEXT_DEV # define NEXT_DEV (&tr0_dev) @@ -784,34 +784,34 @@ #endif #ifdef CONFIG_FDDI - static struct device fddi7_dev = + static struct net_device fddi7_dev = {"fddi7", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, fddiif_probe}; - static struct device fddi6_dev = + static struct net_device fddi6_dev = {"fddi6", 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi7_dev, fddiif_probe}; - static struct device fddi5_dev = + static struct net_device fddi5_dev = {"fddi5", 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi6_dev, fddiif_probe}; - static struct device fddi4_dev = + static struct net_device fddi4_dev = {"fddi4", 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi5_dev, fddiif_probe}; - static struct device fddi3_dev = + static struct net_device fddi3_dev = {"fddi3", 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi4_dev, fddiif_probe}; - static struct device fddi2_dev = + static struct net_device fddi2_dev = {"fddi2", 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi3_dev, fddiif_probe}; - static struct device fddi1_dev = + static struct net_device fddi1_dev = {"fddi1", 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi2_dev, fddiif_probe}; - static struct device fddi0_dev = + static struct net_device fddi0_dev = {"fddi0", 0, 0, 0, 0, 0, 0, 0, 0, 0, &fddi1_dev, fddiif_probe}; #undef NEXT_DEV #define NEXT_DEV (&fddi0_dev) #endif #ifdef CONFIG_HIPPI - static struct device hip3_dev = + static struct net_device hip3_dev = {"hip3", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, hippi_probe}; - static struct device hip2_dev = + static struct net_device hip2_dev = {"hip2", 0, 0, 0, 0, 0, 0, 0, 0, 0, &hip3_dev, hippi_probe}; - static struct device hip1_dev = + static struct net_device hip1_dev = {"hip1", 0, 0, 0, 0, 0, 0, 0, 0, 0, &hip2_dev, hippi_probe}; - static struct device hip0_dev = + static struct net_device hip0_dev = {"hip0", 0, 0, 0, 0, 0, 0, 0, 0, 0, &hip1_dev, hippi_probe}; #undef NEXT_DEV @@ -819,15 +819,15 @@ #endif #ifdef CONFIG_APBIF - extern int bif_init(struct device *dev); - static struct device bif_dev = { + extern int bif_init(struct net_device *dev); + static struct net_device bif_dev = { "bif", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, bif_init }; # undef NEXT_DEV # define NEXT_DEV (&bif_dev) #endif -extern int loopback_init(struct device *dev); -struct device loopback_dev = { +extern int loopback_init(struct net_device *dev); +struct net_device loopback_dev = { "lo", /* Software Loopback interface */ 0x0, /* recv memory end */ 0x0, /* recv memory start */ @@ -840,5 +840,5 @@ loopback_init /* loopback_init should set up the rest */ }; -struct device *dev_base = &loopback_dev; +struct net_device *dev_base = &loopback_dev; rwlock_t dev_base_lock = RW_LOCK_UNLOCKED; diff -u --recursive --new-file v2.3.13/linux/drivers/net/a2065.c linux/drivers/net/a2065.c --- v2.3.13/linux/drivers/net/a2065.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/a2065.c Wed Aug 18 11:36:41 1999 @@ -169,7 +169,7 @@ /* Setup the Lance Rx and Tx rings */ /* Sets dev->tbusy */ -static void lance_init_ring (struct device *dev) +static void lance_init_ring (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -270,7 +270,7 @@ return 0; } -static int lance_rx (struct device *dev) +static int lance_rx (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -345,7 +345,7 @@ return 0; } -static int lance_tx (struct device *dev) +static int lance_tx (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -430,12 +430,12 @@ static void lance_interrupt (int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev; + struct net_device *dev; struct lance_private *lp; volatile struct lance_regs *ll; int csr0; - dev = (struct device *) dev_id; + dev = (struct net_device *) dev_id; lp = (struct lance_private *) dev->priv; ll = lp->ll; @@ -488,9 +488,9 @@ dev->interrupt = 0; } -struct device *last_dev = 0; +struct net_device *last_dev = 0; -static int lance_open (struct device *dev) +static int lance_open (struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -499,7 +499,7 @@ last_dev = dev; /* Install the Interrupt handler */ - if (request_irq(IRQ_AMIGA_PORTS, lance_interrupt, 0, + if (request_irq(IRQ_AMIGA_PORTS, lance_interrupt, SA_SHIRQ, "a2065 Ethernet", dev)) return -EAGAIN; @@ -521,7 +521,7 @@ return status; } -static int lance_close (struct device *dev) +static int lance_close (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -541,7 +541,7 @@ return 0; } -static inline int lance_reset (struct device *dev) +static inline int lance_reset (struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -564,7 +564,7 @@ return status; } -static int lance_start_xmit (struct sk_buff *skb, struct device *dev) +static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -644,7 +644,7 @@ return status; } -static struct net_device_stats *lance_get_stats (struct device *dev) +static struct net_device_stats *lance_get_stats (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; @@ -652,7 +652,7 @@ } /* taken from the depca driver */ -static void lance_load_multicast (struct device *dev) +static void lance_load_multicast (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -702,7 +702,7 @@ return; } -static void lance_set_multicast (struct device *dev) +static void lance_set_multicast (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -739,7 +739,7 @@ mark_bh(NET_BH); } -int __init a2065_probe(struct device *dev) +int __init a2065_probe(struct net_device *dev) { unsigned int key, is_cbm; const struct ConfigDev *cd; @@ -821,7 +821,7 @@ #ifdef MODULE static char devicename[9] = { 0, }; -static struct device a2065_dev = +static struct net_device a2065_dev = { devicename, /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/ac3200.c linux/drivers/net/ac3200.c --- v2.3.13/linux/drivers/net/ac3200.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/ac3200.c Wed Aug 18 11:36:41 1999 @@ -74,19 +74,19 @@ #define AC_START_PG 0x00 /* First page of 8390 TX buffer */ #define AC_STOP_PG 0x80 /* Last page +1 of the 8390 RX ring */ -int ac3200_probe(struct device *dev); -static int ac_probe1(int ioaddr, struct device *dev); +int ac3200_probe(struct net_device *dev); +static int ac_probe1(int ioaddr, struct net_device *dev); -static int ac_open(struct device *dev); -static void ac_reset_8390(struct device *dev); -static void ac_block_input(struct device *dev, int count, +static int ac_open(struct net_device *dev); +static void ac_reset_8390(struct net_device *dev); +static void ac_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ac_block_output(struct device *dev, const int count, +static void ac_block_output(struct net_device *dev, const int count, const unsigned char *buf, const int start_page); -static void ac_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static int ac_close_card(struct device *dev); +static int ac_close_card(struct net_device *dev); /* Probe for the AC3200. @@ -95,7 +95,7 @@ or the unique value in the station address PROM. */ -int __init ac3200_probe(struct device *dev) +int __init ac3200_probe(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; @@ -117,7 +117,7 @@ return ENODEV; } -static int __init ac_probe1(int ioaddr, struct device *dev) +static int __init ac_probe1(int ioaddr, struct net_device *dev) { int i; @@ -254,7 +254,7 @@ return 0; } -static int ac_open(struct device *dev) +static int ac_open(struct net_device *dev) { #ifdef notyet /* Someday we may enable the IRQ and shared memory here. */ @@ -271,7 +271,7 @@ return 0; } -static void ac_reset_8390(struct device *dev) +static void ac_reset_8390(struct net_device *dev) { ushort ioaddr = dev->base_addr; @@ -290,7 +290,7 @@ the start of a page, so we optimize accordingly. */ static void -ac_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = dev->mem_start + ((ring_page - AC_START_PG)<<8); memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); @@ -299,7 +299,7 @@ /* Block input and output are easy on shared memory ethercards, the only complication is when the ring buffer wraps. */ -static void ac_block_input(struct device *dev, int count, struct sk_buff *skb, +static void ac_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned long xfer_start = dev->mem_start + ring_offset - (AC_START_PG<<8); @@ -316,7 +316,7 @@ } } -static void ac_block_output(struct device *dev, int count, +static void ac_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { unsigned long shmem = dev->mem_start + ((start_page - AC_START_PG)<<8); @@ -324,7 +324,7 @@ memcpy_toio(shmem, buf, count); } -static int ac_close_card(struct device *dev) +static int ac_close_card(struct net_device *dev) { dev->start = 0; dev->tbusy = 1; @@ -349,7 +349,7 @@ #define MAX_AC32_CARDS 4 /* Max number of AC32 cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_AC32_CARDS] = { 0, }; -static struct device dev_ac32[MAX_AC32_CARDS] = { +static struct net_device dev_ac32[MAX_AC32_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -371,7 +371,7 @@ int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) { - struct device *dev = &dev_ac32[this_dev]; + struct net_device *dev = &dev_ac32[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -399,7 +399,7 @@ int this_dev; for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) { - struct device *dev = &dev_ac32[this_dev]; + struct net_device *dev = &dev_ac32[this_dev]; if (dev->priv != NULL) { void *priv = dev->priv; /* Someday free_irq may be in ac_close_card() */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/acenic.c linux/drivers/net/acenic.c --- v2.3.13/linux/drivers/net/acenic.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/acenic.c Wed Aug 18 11:36:41 1999 @@ -173,11 +173,11 @@ static const char __initdata *version = "acenic.c: v0.32 03/15/99 Jes Sorensen (Jes.Sorensen@cern.ch)\n"; -static struct device *root_dev = NULL; +static struct net_device *root_dev = NULL; static int probed __initdata = 0; -int __init acenic_probe (struct device *dev) +int __init acenic_probe (struct net_device *dev) { int boards_found = 0; int version_disp; @@ -363,7 +363,7 @@ { struct ace_private *ap; struct ace_regs *regs; - struct device *next; + struct net_device *next; short i; unsigned long flags; @@ -423,7 +423,7 @@ } -static int __init ace_init(struct device *dev, int board_idx) +static int __init ace_init(struct net_device *dev, int board_idx) { struct ace_private *ap; struct ace_regs *regs; @@ -802,7 +802,7 @@ */ static void ace_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct ace_private *ap = (struct ace_private *)dev->priv; struct ace_regs *regs = ap->regs; @@ -837,7 +837,7 @@ /* * Load the standard rx ring. */ -static int ace_load_std_rx_ring(struct device *dev) +static int ace_load_std_rx_ring(struct net_device *dev) { struct ace_private *ap; struct ace_regs *regs; @@ -906,7 +906,7 @@ * Load the jumbo rx ring, this may happen at any time if the MTU * is changed to a value > 1500. */ -static int ace_load_jumbo_rx_ring(struct device *dev) +static int ace_load_jumbo_rx_ring(struct net_device *dev) { struct ace_private *ap; struct ace_regs *regs; @@ -962,7 +962,7 @@ * Tell the firmware not to accept jumbos and flush the jumbo ring. * This function must be called with the spinlock held. */ -static int ace_flush_jumbo_rx_ring(struct device *dev) +static int ace_flush_jumbo_rx_ring(struct net_device *dev) { struct ace_private *ap; struct ace_regs *regs; @@ -998,7 +998,7 @@ * events) and are handled here, outside the main interrupt handler, * to reduce the size of the handler. */ -static u32 ace_handle_event(struct device *dev, u32 evtcsm, u32 evtprd) +static u32 ace_handle_event(struct net_device *dev, u32 evtcsm, u32 evtprd) { struct ace_private *ap; @@ -1059,7 +1059,7 @@ } -static int ace_rx_int(struct device *dev, u32 rxretprd, u32 rxretcsm) +static int ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm) { struct ace_private *ap = (struct ace_private *)dev->priv; struct ace_regs *regs = ap->regs; @@ -1210,7 +1210,7 @@ { struct ace_private *ap; struct ace_regs *regs; - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; u32 txcsm, rxretcsm, rxretprd; u32 evtcsm, evtprd; @@ -1293,7 +1293,7 @@ } -static int ace_open(struct device *dev) +static int ace_open(struct net_device *dev) { struct ace_private *ap; struct ace_regs *regs; @@ -1355,7 +1355,7 @@ } -static int ace_close(struct device *dev) +static int ace_close(struct net_device *dev) { struct ace_private *ap; struct ace_regs *regs; @@ -1405,7 +1405,7 @@ } -static int ace_start_xmit(struct sk_buff *skb, struct device *dev) +static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ace_private *ap = (struct ace_private *)dev->priv; struct ace_regs *regs = ap->regs; @@ -1450,7 +1450,7 @@ } -static int ace_change_mtu(struct device *dev, int new_mtu) +static int ace_change_mtu(struct net_device *dev, int new_mtu) { struct ace_private *ap = dev->priv; struct ace_regs *regs = ap->regs; @@ -1486,7 +1486,7 @@ /* * Set the hardware MAC address. */ -static int ace_set_mac_addr(struct device *dev, void *p) +static int ace_set_mac_addr(struct net_device *dev, void *p) { struct sockaddr *addr=p; struct ace_regs *regs; @@ -1512,7 +1512,7 @@ } -static void ace_set_multicast_list(struct device *dev) +static void ace_set_multicast_list(struct net_device *dev) { struct ace_private *ap = dev->priv; struct ace_regs *regs = ap->regs; @@ -1566,7 +1566,7 @@ } -static struct net_device_stats *ace_get_stats(struct device *dev) +static struct net_device_stats *ace_get_stats(struct net_device *dev) { struct ace_private *ap = dev->priv; @@ -1642,7 +1642,7 @@ * This operation requires the NIC to be halted and is performed with * interrupts disabled and with the spinlock hold. */ -int __init ace_load_firmware(struct device *dev) +int __init ace_load_firmware(struct net_device *dev) { struct ace_private *ap; struct ace_regs *regs; diff -u --recursive --new-file v2.3.13/linux/drivers/net/acenic.h linux/drivers/net/acenic.h --- v2.3.13/linux/drivers/net/acenic.h Mon Mar 22 08:08:12 1999 +++ linux/drivers/net/acenic.h Wed Aug 18 11:36:45 1999 @@ -634,7 +634,7 @@ __attribute__ ((aligned (L1_CACHE_BYTES))); volatile u32 tx_csm __attribute__ ((aligned (L1_CACHE_BYTES))); - struct device *next + struct net_device *next __attribute__ ((aligned (L1_CACHE_BYTES))); unsigned char *trace_buf; int fw_running, fw_up, jumbo, promisc, mcast_all; @@ -654,21 +654,21 @@ /* * Prototypes */ -static int ace_init(struct device *dev, int board_idx); -static int ace_load_std_rx_ring(struct device *dev); -static int ace_load_jumbo_rx_ring(struct device *dev); -static int ace_flush_jumbo_rx_ring(struct device *dev); +static int ace_init(struct net_device *dev, int board_idx); +static int ace_load_std_rx_ring(struct net_device *dev); +static int ace_load_jumbo_rx_ring(struct net_device *dev); +static int ace_flush_jumbo_rx_ring(struct net_device *dev); static void ace_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int ace_load_firmware(struct device *dev); -static int ace_open(struct device *dev); -static int ace_start_xmit(struct sk_buff *skb, struct device *dev); -static int ace_close(struct device *dev); +static int ace_load_firmware(struct net_device *dev); +static int ace_open(struct net_device *dev); +static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int ace_close(struct net_device *dev); static void ace_timer(unsigned long data); static void ace_dump_trace(struct ace_private *ap); -static void ace_set_multicast_list(struct device *dev); -static int ace_change_mtu(struct device *dev, int new_mtu); -static int ace_set_mac_addr(struct device *dev, void *p); -static struct net_device_stats *ace_get_stats(struct device *dev); +static void ace_set_multicast_list(struct net_device *dev); +static int ace_change_mtu(struct net_device *dev, int new_mtu); +static int ace_set_mac_addr(struct net_device *dev, void *p); +static struct net_device_stats *ace_get_stats(struct net_device *dev); static u8 read_eeprom_byte(struct ace_regs *regs, unsigned long offset); #endif /* _ACENIC_H_ */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/am79c961a.c linux/drivers/net/am79c961a.c --- v2.3.13/linux/drivers/net/am79c961a.c Fri May 8 00:42:39 1998 +++ linux/drivers/net/am79c961a.c Wed Aug 18 11:36:41 1999 @@ -36,7 +36,7 @@ static unsigned int net_debug = NET_DEBUG; static void -am79c961_setmulticastlist (struct device *dev); +am79c961_setmulticastlist (struct net_device *dev); static char *version = "am79c961 ethernet driver (c) 1995 R.M.King v0.00\n"; @@ -69,7 +69,7 @@ " : : "r" ((val) & 0xffff), "r" (0xe0000000 + ((off) << 1))); static inline void -am_writebuffer(struct device *dev, unsigned int offset, unsigned char *buf, unsigned int length) +am_writebuffer(struct net_device *dev, unsigned int offset, unsigned char *buf, unsigned int length) { offset = 0xe0000000 + (offset << 1); length = (length + 1) & ~1; @@ -115,7 +115,7 @@ } static inline unsigned short -am_readword (struct device *dev, unsigned long off) +am_readword (struct net_device *dev, unsigned long off) { unsigned long address = 0xe0000000 + (off << 1); unsigned short val; @@ -127,7 +127,7 @@ } static inline void -am_readbuffer(struct device *dev, unsigned int offset, unsigned char *buf, unsigned int length) +am_readbuffer(struct net_device *dev, unsigned int offset, unsigned char *buf, unsigned int length) { offset = 0xe0000000 + (offset << 1); length = (length + 1) & ~1; @@ -168,7 +168,7 @@ } static int -am79c961_ramtest(struct device *dev, unsigned int val) +am79c961_ramtest(struct net_device *dev, unsigned int val) { unsigned char *buffer = kmalloc (65536, GFP_KERNEL); int i, error = 0, errorcount = 0; @@ -196,7 +196,7 @@ } static void -am79c961_init_for_open(struct device *dev) +am79c961_init_for_open(struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; unsigned long hdr_addr, first_free_addr; @@ -264,7 +264,7 @@ } static int -am79c961_init(struct device *dev) +am79c961_init(struct net_device *dev) { unsigned long flags; @@ -286,7 +286,7 @@ * This is the real probe routine. */ static int -am79c961_probe1(struct device *dev) +am79c961_probe1(struct net_device *dev) { static unsigned version_printed = 0; struct dev_priv *priv; @@ -351,7 +351,7 @@ } int -am79c961_probe(struct device *dev) +am79c961_probe(struct net_device *dev) { static int initialised = 0; @@ -374,7 +374,7 @@ * there is non-reboot way to recover if something goes wrong. */ static int -am79c961_open(struct device *dev) +am79c961_open(struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; @@ -397,7 +397,7 @@ * The inverse routine to am79c961_open(). */ static int -am79c961_close(struct device *dev) +am79c961_close(struct net_device *dev) { dev->tbusy = 1; dev->start = 0; @@ -414,7 +414,7 @@ * Get the current statistics. This may be called with the card open or * closed. */ -static struct enet_statistics *am79c961_getstats (struct device *dev) +static struct enet_statistics *am79c961_getstats (struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; return &priv->stats; @@ -426,7 +426,7 @@ * We don't attempt any packet filtering. The card may have a SEEQ 8004 * in which does not have the other ethernet address registers present... */ -static void am79c961_setmulticastlist (struct device *dev) +static void am79c961_setmulticastlist (struct net_device *dev) { unsigned long flags; int i; @@ -446,7 +446,7 @@ * Transmit a packet */ static int -am79c961_sendpacket(struct sk_buff *skb, struct device *dev) +am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; @@ -494,7 +494,7 @@ static void am79c961_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct dev_priv *priv = (struct dev_priv *)dev->priv; unsigned int status; @@ -527,7 +527,7 @@ * If we have a good packet(s), get it/them out of the buffers. */ static void -am79c961_rx(struct device *dev, struct dev_priv *priv) +am79c961_rx(struct net_device *dev, struct dev_priv *priv) { unsigned long hdraddr; unsigned long pktaddr; @@ -589,7 +589,7 @@ * Update stats for the transmitted packet */ static void -am79c961_tx(struct device *dev, struct dev_priv *priv) +am79c961_tx(struct net_device *dev, struct dev_priv *priv) { do { unsigned long hdraddr; diff -u --recursive --new-file v2.3.13/linux/drivers/net/am79c961a.h linux/drivers/net/am79c961a.h --- v2.3.13/linux/drivers/net/am79c961a.h Mon Feb 16 15:50:21 1998 +++ linux/drivers/net/am79c961a.h Wed Aug 18 11:36:45 1999 @@ -114,15 +114,15 @@ unsigned long txhdr; }; -extern int am79c961_probe (struct device *dev); -static int am79c961_probe1 (struct device *dev); -static int am79c961_open (struct device *dev); -static int am79c961_sendpacket (struct sk_buff *skb, struct device *dev); +extern int am79c961_probe (struct net_device *dev); +static int am79c961_probe1 (struct net_device *dev); +static int am79c961_open (struct net_device *dev); +static int am79c961_sendpacket (struct sk_buff *skb, struct net_device *dev); static void am79c961_interrupt (int irq, void *dev_id, struct pt_regs *regs); -static void am79c961_rx (struct device *dev, struct dev_priv *priv); -static void am79c961_tx (struct device *dev, struct dev_priv *priv); -static int am79c961_close (struct device *dev); -static struct enet_statistics *am79c961_getstats (struct device *dev); -static void am79c961_setmulticastlist (struct device *dev); +static void am79c961_rx (struct net_device *dev, struct dev_priv *priv); +static void am79c961_tx (struct net_device *dev, struct dev_priv *priv); +static int am79c961_close (struct net_device *dev); +static struct enet_statistics *am79c961_getstats (struct net_device *dev); +static void am79c961_setmulticastlist (struct net_device *dev); #endif diff -u --recursive --new-file v2.3.13/linux/drivers/net/apne.c linux/drivers/net/apne.c --- v2.3.13/linux/drivers/net/apne.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/apne.c Wed Aug 18 11:36:41 1999 @@ -74,18 +74,18 @@ #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ -int apne_probe(struct device *dev); -static int apne_probe1(struct device *dev, int ioaddr); +int apne_probe(struct net_device *dev); +static int apne_probe1(struct net_device *dev, int ioaddr); -static int apne_open(struct device *dev); -static int apne_close(struct device *dev); +static int apne_open(struct net_device *dev); +static int apne_close(struct net_device *dev); -static void apne_reset_8390(struct device *dev); -static void apne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void apne_reset_8390(struct net_device *dev); +static void apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void apne_block_input(struct device *dev, int count, +static void apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void apne_block_output(struct device *dev, const int count, +static void apne_block_output(struct net_device *dev, const int count, const unsigned char *buf, const int start_page); static void apne_interrupt(int irq, void *dev_id, struct pt_regs *regs); @@ -121,7 +121,7 @@ static int apne_owned = 0; /* signal if card already owned */ -int __init apne_probe(struct device *dev) +int __init apne_probe(struct net_device *dev) { #ifndef MANUAL_CONFIG char tuple[8]; @@ -161,7 +161,7 @@ } -static int __init apne_probe1(struct device *dev, int ioaddr) +static int __init apne_probe1(struct net_device *dev, int ioaddr) { int i; unsigned char SA_prom[32]; @@ -294,7 +294,8 @@ dev->base_addr = ioaddr; /* Install the Interrupt handler */ - if (request_irq(IRQ_AMIGA_PORTS, apne_interrupt, 0, "apne Ethernet", dev)) + if (request_irq(IRQ_AMIGA_PORTS, apne_interrupt, SA_SHIRQ, + "apne Ethernet", dev)) return -EAGAIN; @@ -337,7 +338,7 @@ } static int -apne_open(struct device *dev) +apne_open(struct net_device *dev) { ei_open(dev); MOD_INC_USE_COUNT; @@ -345,7 +346,7 @@ } static int -apne_close(struct device *dev) +apne_close(struct net_device *dev) { if (ei_debug > 1) printk("%s: Shutting down ethercard.\n", dev->name); @@ -357,7 +358,7 @@ /* Hard reset the card. This used to pause for the same period that a 8390 reset command required, but that shouldn't be necessary. */ static void -apne_reset_8390(struct device *dev) +apne_reset_8390(struct net_device *dev) { unsigned long reset_start_time = jiffies; @@ -384,7 +385,7 @@ the start of a page, so we optimize accordingly. */ static void -apne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int nic_base = dev->base_addr; @@ -433,7 +434,7 @@ the packet out through the "remote DMA" dataport using writeb. */ static void -apne_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int nic_base = dev->base_addr; char *buf = skb->data; @@ -475,7 +476,7 @@ } static void -apne_block_output(struct device *dev, int count, +apne_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page) { int nic_base = NE_BASE; @@ -560,7 +561,7 @@ #ifdef MODULE static char devicename[9] = {0, }; -static struct device apne_dev = +static struct net_device apne_dev = { devicename, 0, 0, 0, 0, diff -u --recursive --new-file v2.3.13/linux/drivers/net/arc-rimi.c linux/drivers/net/arc-rimi.c --- v2.3.13/linux/drivers/net/arc-rimi.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/arc-rimi.c Wed Aug 18 11:36:41 1999 @@ -74,15 +74,15 @@ /* Internal function declarations */ -static int arcrimi_probe(struct device *dev); -static void arcrimi_rx(struct device *dev,int recbuf); -static int arcrimi_found(struct device *dev,int ioaddr,int airq,u_long shmem); -static void arcrimi_inthandler (struct device *dev); -static int arcrimi_reset (struct device *dev, int reset_delay); -static void arcrimi_setmask (struct device *dev, u_char mask); -static void arcrimi_command (struct device *dev, u_char command); -static u_char arcrimi_status (struct device *dev); -static void arcrimi_prepare_tx(struct device *dev,u_char *hdr,int hdrlen, +static int arcrimi_probe(struct net_device *dev); +static void arcrimi_rx(struct net_device *dev,int recbuf); +static int arcrimi_found(struct net_device *dev,int ioaddr,int airq,u_long shmem); +static void arcrimi_inthandler (struct net_device *dev); +static int arcrimi_reset (struct net_device *dev, int reset_delay); +static void arcrimi_setmask (struct net_device *dev, u_char mask); +static void arcrimi_command (struct net_device *dev, u_char command); +static u_char arcrimi_status (struct net_device *dev); +static void arcrimi_prepare_tx(struct net_device *dev,u_char *hdr,int hdrlen, char *data,int length,int daddr,int exceptA, int offset); static void arcrimi_openclose(int open); @@ -101,7 +101,7 @@ MODULE_PARM (node, "i"); #else void __init arcrimi_setup (char *str, int *ints); -extern struct device arcnet_devs[]; +extern struct net_device arcnet_devs[]; extern char arcnet_dev_names[][10]; extern int arcnet_num_devs; #endif @@ -140,7 +140,7 @@ * them. In fact, we can't even get their node ID automatically. So, we * need to be passed a specific shmem address, IRQ, and node ID. */ -int __init arcrimi_probe(struct device *dev) +int __init arcrimi_probe(struct net_device *dev) { BUGLVL(D_NORMAL) printk(version); BUGMSG(D_NORMAL,"Given: node %02Xh, shmem %lXh, irq %d\n", @@ -164,10 +164,10 @@ } -/* Set up the struct device associated with this card. Called after +/* Set up the struct net_device associated with this card. Called after * probing succeeds. */ -int __init arcrimi_found(struct device *dev,int node,int airq, u_long shmem) +int __init arcrimi_found(struct net_device *dev,int node,int airq, u_long shmem) { struct arcnet_local *lp; u_long first_mirror,last_mirror; @@ -275,7 +275,7 @@ * * However, it does make sure the card is in a defined state. */ -int arcrimi_reset(struct device *dev,int reset_delay) +int arcrimi_reset(struct net_device *dev,int reset_delay) { struct arcnet_local *lp=(struct arcnet_local *)dev->priv; short ioaddr=dev->mem_start + 0x800; @@ -333,21 +333,21 @@ MOD_DEC_USE_COUNT; } -static void arcrimi_setmask(struct device *dev, u_char mask) +static void arcrimi_setmask(struct net_device *dev, u_char mask) { int ioaddr=dev->mem_start+0x800; AINTMASK(mask); } -static u_char arcrimi_status(struct device *dev) +static u_char arcrimi_status(struct net_device *dev) { int ioaddr=dev->mem_start+0x800; return ARCSTATUS; } -static void arcrimi_command(struct device *dev, u_char cmd) +static void arcrimi_command(struct net_device *dev, u_char cmd) { int ioaddr=dev->mem_start+0x800; @@ -359,7 +359,7 @@ * by the card. */ static void -arcrimi_inthandler(struct device *dev) +arcrimi_inthandler(struct net_device *dev) { struct arcnet_local *lp=(struct arcnet_local *)dev->priv; int ioaddr=dev->mem_start+0x800, status, boguscount = 3, didsomething; @@ -578,7 +578,7 @@ */ static void -arcrimi_rx(struct device *dev,int recbuf) +arcrimi_rx(struct net_device *dev,int recbuf) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; int ioaddr=dev->mem_start+0x800; @@ -636,7 +636,7 @@ * by arcnet_go_tx. */ static void -arcrimi_prepare_tx(struct device *dev,u_char *hdr,int hdrlen, +arcrimi_prepare_tx(struct net_device *dev,u_char *hdr,int hdrlen, char *data,int length,int daddr,int exceptA, int offset) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -734,7 +734,7 @@ #ifdef MODULE static char devicename[9] = ""; -static struct device thiscard = { +static struct net_device thiscard = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0, 0, /* I/O address, IRQ */ @@ -744,7 +744,7 @@ int init_module(void) { - struct device *dev=&thiscard; + struct net_device *dev=&thiscard; if (device) strcpy(dev->name,device); else arcnet_makename(dev->name); @@ -771,7 +771,7 @@ void cleanup_module(void) { - struct device *dev=&thiscard; + struct net_device *dev=&thiscard; int ioaddr=dev->mem_start; if (dev->start) (*dev->stop)(dev); @@ -799,7 +799,7 @@ void __init arcrimi_setup (char *str, int *ints) { - struct device *dev; + struct net_device *dev; if (arcnet_num_devs == MAX_ARCNET_DEVS) { diff -u --recursive --new-file v2.3.13/linux/drivers/net/arcnet.c linux/drivers/net/arcnet.c --- v2.3.13/linux/drivers/net/arcnet.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/arcnet.c Wed Aug 18 11:36:41 1999 @@ -242,16 +242,16 @@ static int init_module(void); #ifdef CONFIG_ARCNET_COM90xx extern char com90xx_explicit; -extern int arc90xx_probe(struct device *dev); +extern int arc90xx_probe(struct net_device *dev); #endif #endif -void arcnet_tx_done(struct device *dev, struct arcnet_local *lp); +void arcnet_tx_done(struct net_device *dev, struct arcnet_local *lp); void arcnet_use_count (int open); -void arcnet_setup(struct device *dev); +void arcnet_setup(struct net_device *dev); void arcnet_makename(char *device); -void arcnetA_continue_tx(struct device *dev); -int arcnet_go_tx(struct device *dev,int enable_irq); +void arcnetA_continue_tx(struct net_device *dev); +int arcnet_go_tx(struct net_device *dev,int enable_irq); void arcnet_interrupt(int irq,void *dev_id,struct pt_regs *regs); void arcnet_rx(struct arcnet_local *lp, u_char *arcsoft, short length, int saddr, int daddr); @@ -266,7 +266,7 @@ EXPORT_SYMBOL(arcnet_rx); #if ARCNET_DEBUG_MAX & D_SKB -void arcnet_dump_skb(struct device *dev,struct sk_buff *skb, +void arcnet_dump_skb(struct net_device *dev,struct sk_buff *skb, char *desc); EXPORT_SYMBOL(arcnet_dump_skb); #else @@ -274,7 +274,7 @@ #endif #if (ARCNET_DEBUG_MAX & D_RX) || (ARCNET_DEBUG_MAX & D_TX) -void arcnet_dump_packet(struct device *dev,u_char *buffer,int ext, +void arcnet_dump_packet(struct net_device *dev,u_char *buffer,int ext, char *desc); EXPORT_SYMBOL(arcnet_dump_packet); #else @@ -283,41 +283,41 @@ /* Internal function prototypes */ -static int arcnet_open(struct device *dev); -static int arcnet_close(struct device *dev); -static int arcnetA_header(struct sk_buff *skb,struct device *dev, +static int arcnet_open(struct net_device *dev); +static int arcnet_close(struct net_device *dev); +static int arcnetA_header(struct sk_buff *skb,struct net_device *dev, unsigned short type,void *daddr,void *saddr,unsigned len); static int arcnetA_rebuild_header(struct sk_buff *skb); -static int arcnet_send_packet_bad(struct sk_buff *skb,struct device *dev); -static int arcnetA_send_packet(struct sk_buff *skb, struct device *dev); -static void arcnetA_rx(struct device *dev,u_char *buf, +static int arcnet_send_packet_bad(struct sk_buff *skb,struct net_device *dev); +static int arcnetA_send_packet(struct sk_buff *skb, struct net_device *dev); +static void arcnetA_rx(struct net_device *dev,u_char *buf, int length,u_char saddr, u_char daddr); -static struct net_device_stats *arcnet_get_stats(struct device *dev); +static struct net_device_stats *arcnet_get_stats(struct net_device *dev); static unsigned short arcnetA_type_trans(struct sk_buff *skb, - struct device *dev); + struct net_device *dev); #ifdef CONFIG_ARCNET_ETH /* functions specific to Ethernet-Encap */ -static int arcnetE_init(struct device *dev); -static int arcnetE_open_close(struct device *dev); -static int arcnetE_send_packet(struct sk_buff *skb, struct device *dev); -static void arcnetE_rx(struct device *dev,u_char *arcsoft, +static int arcnetE_init(struct net_device *dev); +static int arcnetE_open_close(struct net_device *dev); +static int arcnetE_send_packet(struct sk_buff *skb, struct net_device *dev); +static void arcnetE_rx(struct net_device *dev,u_char *arcsoft, int length,u_char saddr, u_char daddr); #endif #ifdef CONFIG_ARCNET_1051 /* functions specific to RFC1051 */ -static int arcnetS_init(struct device *dev); -static int arcnetS_open_close(struct device *dev); -static int arcnetS_send_packet(struct sk_buff *skb, struct device *dev); -static void arcnetS_rx(struct device *dev,u_char *buf, +static int arcnetS_init(struct net_device *dev); +static int arcnetS_open_close(struct net_device *dev); +static int arcnetS_send_packet(struct sk_buff *skb, struct net_device *dev); +static void arcnetS_rx(struct net_device *dev,u_char *buf, int length,u_char saddr, u_char daddr); -static int arcnetS_header(struct sk_buff *skb,struct device *dev, +static int arcnetS_header(struct sk_buff *skb,struct net_device *dev, unsigned short type,void *daddr,void *saddr,unsigned len); static int arcnetS_rebuild_header(struct sk_buff *skb); -static unsigned short arcnetS_type_trans(struct sk_buff *skb,struct device *dev); +static unsigned short arcnetS_type_trans(struct sk_buff *skb,struct net_device *dev); #endif @@ -330,7 +330,7 @@ /* Dump the contents of an sk_buff */ #if ARCNET_DEBUG_MAX & D_SKB -void arcnet_dump_skb(struct device *dev,struct sk_buff *skb,char *desc) +void arcnet_dump_skb(struct net_device *dev,struct sk_buff *skb,char *desc) { int i; long flags; @@ -353,7 +353,7 @@ /* Dump the contents of an ARCnet buffer */ #if (ARCNET_DEBUG_MAX & D_RX) || (ARCNET_DEBUG_MAX & D_TX) -void arcnet_dump_packet(struct device *dev,u_char *buffer,int ext,char *desc) +void arcnet_dump_packet(struct net_device *dev,u_char *buffer,int ext,char *desc) { int i; long flags; @@ -373,7 +373,7 @@ #endif -/* Setup a struct device for ARCnet. This should really be in net_init.c +/* Setup a struct net_device for ARCnet. This should really be in net_init.c * but since there are three different ARCnet devices ANYWAY... * * Actually, the whole idea of having all this kernel-dependent stuff (ie. @@ -382,7 +382,7 @@ * Intelligent defaults?! Nah. */ -void arcnet_setup(struct device *dev) +void arcnet_setup(struct net_device *dev) { dev_init_buffers(dev); @@ -421,7 +421,7 @@ * there is non-reboot way to recover if something goes wrong. */ static int -arcnet_open(struct device *dev) +arcnet_open(struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -453,10 +453,10 @@ #ifdef CONFIG_ARCNET_ETH /* Initialize the ethernet-encap protocol driver */ - lp->edev=(struct device *)kmalloc(sizeof(struct device),GFP_KERNEL); + lp->edev=(struct net_device *)kmalloc(sizeof(struct net_device),GFP_KERNEL); if (lp->edev == NULL) return -ENOMEM; - memcpy(lp->edev,dev,sizeof(struct device)); + memcpy(lp->edev,dev,sizeof(struct net_device)); lp->edev->type=ARPHRD_ETHER; lp->edev->name=(char *)kmalloc(10,GFP_KERNEL); if (lp->edev->name == NULL) { @@ -471,7 +471,7 @@ #ifdef CONFIG_ARCNET_1051 /* Initialize the RFC1051-encap protocol driver */ - lp->sdev=(struct device *)kmalloc(sizeof(struct device)+10,GFP_KERNEL); + lp->sdev=(struct net_device *)kmalloc(sizeof(struct net_device)+10,GFP_KERNEL); if(lp->sdev = NULL) { if(lp->edev) @@ -479,7 +479,7 @@ lp->edev=NULL; return -ENOMEM; } - memcpy(lp->sdev,dev,sizeof(struct device)); + memcpy(lp->sdev,dev,sizeof(struct net_device)); lp->sdev->name=(char *)(lp+1); sprintf(lp->sdev->name,"%ss",dev->name); lp->sdev->init=arcnetS_init; @@ -513,7 +513,7 @@ /* The inverse routine to arcnet_open - shuts down the card. */ static int -arcnet_close(struct device *dev) +arcnet_close(struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -591,7 +591,7 @@ /* Generic error checking routine for arcnet??_send_packet */ static int -arcnet_send_packet_bad(struct sk_buff *skb, struct device *dev) +arcnet_send_packet_bad(struct sk_buff *skb, struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -709,7 +709,7 @@ /* Called by the kernel in order to transmit a packet. */ static int -arcnetA_send_packet(struct sk_buff *skb, struct device *dev) +arcnetA_send_packet(struct sk_buff *skb, struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; int bad,oldmask=0; @@ -832,7 +832,7 @@ * arcnetAS_prepare_tx to load the next segment into the card. This function * does NOT automatically call arcnet_go_tx. */ -void arcnetA_continue_tx(struct device *dev) +void arcnetA_continue_tx(struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; int maxsegsize=XMTU-4; @@ -885,7 +885,7 @@ * to the card; TXFREEflag is always OR'ed into the memory variable either * way. */ -int arcnet_go_tx(struct device *dev,int enable_irq) +int arcnet_go_tx(struct net_device *dev,int enable_irq) { struct arcnet_local *lp=(struct arcnet_local *)dev->priv; @@ -934,7 +934,7 @@ void arcnet_interrupt(int irq,void *dev_id,struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct arcnet_local *lp; if (dev==NULL) @@ -994,7 +994,7 @@ } -void arcnet_tx_done(struct device *dev, struct arcnet_local *lp) +void arcnet_tx_done(struct net_device *dev, struct arcnet_local *lp) { if (dev->tbusy) { @@ -1026,7 +1026,7 @@ void arcnet_rx(struct arcnet_local *lp, u_char *arcsoft, short length, int saddr, int daddr) { - struct device *dev=lp->adev; + struct net_device *dev=lp->adev; BUGMSG(D_DURING,"received packet from %02Xh to %02Xh (%d bytes)\n", saddr,daddr,length); @@ -1080,7 +1080,7 @@ /* Packet receiver for "standard" RFC1201-style packets */ static void -arcnetA_rx(struct device *dev,u_char *buf, +arcnetA_rx(struct net_device *dev,u_char *buf, int length, u_char saddr, u_char daddr) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -1361,7 +1361,7 @@ * closed. */ -static struct net_device_stats *arcnet_get_stats(struct device *dev) +static struct net_device_stats *arcnet_get_stats(struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -1374,7 +1374,7 @@ * saddr=NULL means use device source address (always will anyway) * daddr=NULL means leave destination address (eg unresolved arp) */ -static int arcnetA_header(struct sk_buff *skb,struct device *dev, +static int arcnetA_header(struct sk_buff *skb,struct net_device *dev, unsigned short type,void *daddr,void *saddr,unsigned len) { struct ClientData *head = (struct ClientData *) @@ -1450,7 +1450,7 @@ static int arcnetA_rebuild_header(struct sk_buff *skb) { struct ClientData *head = (struct ClientData *)skb->data; - struct device *dev=skb->dev; + struct net_device *dev=skb->dev; struct arcnet_local *lp=(struct arcnet_local *)(dev->priv); #ifdef CONFIG_INET int status; @@ -1493,7 +1493,7 @@ * * With ARCnet we have to convert everything to Ethernet-style stuff. */ -static unsigned short arcnetA_type_trans(struct sk_buff *skb,struct device *dev) +static unsigned short arcnetA_type_trans(struct sk_buff *skb,struct net_device *dev) { struct ClientData *head; struct arcnet_local *lp=(struct arcnet_local *) (dev->priv); @@ -1541,7 +1541,7 @@ /* Initialize the arc0e device. */ -static int arcnetE_init(struct device *dev) +static int arcnetE_init(struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -1560,7 +1560,7 @@ /* Bring up/down the arc0e device - we don't actually have to do anything, * since our parent arc0 handles the card I/O itself. */ -static int arcnetE_open_close(struct device *dev) +static int arcnetE_open_close(struct net_device *dev) { return 0; } @@ -1569,7 +1569,7 @@ /* Called by the kernel in order to transmit an ethernet-type packet. */ static int -arcnetE_send_packet(struct sk_buff *skb, struct device *dev) +arcnetE_send_packet(struct sk_buff *skb, struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; int bad,oldmask=0; @@ -1655,7 +1655,7 @@ /* Packet receiver for ethernet-encap packets. */ static void -arcnetE_rx(struct device *dev,u_char *arcsoft, +arcnetE_rx(struct net_device *dev,u_char *arcsoft, int length,u_char saddr, u_char daddr) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -1695,7 +1695,7 @@ /* Initialize the arc0s device. */ -static int arcnetS_init(struct device *dev) +static int arcnetS_init(struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -1719,7 +1719,7 @@ /* Bring up/down the arc0s device - we don't actually have to do anything, * since our parent arc0 handles the card I/O itself. */ -static int arcnetS_open_close(struct device *dev) +static int arcnetS_open_close(struct net_device *dev) { return 0; } @@ -1728,7 +1728,7 @@ /* Called by the kernel in order to transmit an RFC1051-type packet. */ static int -arcnetS_send_packet(struct sk_buff *skb, struct device *dev) +arcnetS_send_packet(struct sk_buff *skb, struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; int bad,length; @@ -1791,7 +1791,7 @@ /* Packet receiver for RFC1051 packets; */ static void -arcnetS_rx(struct device *dev,u_char *buf, +arcnetS_rx(struct net_device *dev,u_char *buf, int length,u_char saddr, u_char daddr) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -1837,7 +1837,7 @@ * saddr=NULL means use device source address (always will anyway) * daddr=NULL means leave destination address (eg unresolved arp) */ -static int arcnetS_header(struct sk_buff *skb,struct device *dev, +static int arcnetS_header(struct sk_buff *skb,struct net_device *dev, unsigned short type,void *daddr,void *saddr,unsigned len) { struct S_ClientData *head = (struct S_ClientData *) @@ -1895,7 +1895,7 @@ */ static int arcnetS_rebuild_header(struct sk_buff *skb) { - struct device *dev=skb->dev; + struct net_device *dev=skb->dev; struct S_ClientData *head = (struct S_ClientData *)skb->data; struct arcnet_local *lp=(struct arcnet_local *)(dev->priv); @@ -1929,7 +1929,7 @@ * * With ARCnet we have to convert everything to Ethernet-style stuff. */ -unsigned short arcnetS_type_trans(struct sk_buff *skb,struct device *dev) +unsigned short arcnetS_type_trans(struct sk_buff *skb,struct net_device *dev) { struct S_ClientData *head; struct arcnet_local *lp=(struct arcnet_local *) (dev->priv); @@ -1993,7 +1993,7 @@ { } -struct device arcnet_devs[MAX_ARCNET_DEVS]; +struct net_device arcnet_devs[MAX_ARCNET_DEVS]; int arcnet_num_devs=0; char arcnet_dev_names[MAX_ARCNET_DEVS][10]; @@ -2079,7 +2079,7 @@ void arcnet_makename(char *device) { - struct device *dev; + struct net_device *dev; int arcnum; arcnum = 0; diff -u --recursive --new-file v2.3.13/linux/drivers/net/ariadne.c linux/drivers/net/ariadne.c --- v2.3.13/linux/drivers/net/ariadne.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/ariadne.c Wed Aug 18 11:36:41 1999 @@ -123,15 +123,15 @@ }; -static int ariadne_open(struct device *dev); -static void ariadne_init_ring(struct device *dev); -static int ariadne_start_xmit(struct sk_buff *skb, struct device *dev); -static int ariadne_rx(struct device *dev); +static int ariadne_open(struct net_device *dev); +static void ariadne_init_ring(struct net_device *dev); +static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int ariadne_rx(struct net_device *dev); static void ariadne_interrupt(int irq, void *data, struct pt_regs *fp); -static int ariadne_close(struct device *dev); -static struct net_device_stats *ariadne_get_stats(struct device *dev); +static int ariadne_close(struct net_device *dev); +static struct net_device_stats *ariadne_get_stats(struct net_device *dev); #ifdef HAVE_MULTICAST -static void set_multicast_list(struct device *dev); +static void set_multicast_list(struct net_device *dev); #endif @@ -146,7 +146,7 @@ } -int __init ariadne_probe(struct device *dev) +int __init ariadne_probe(struct net_device *dev) { unsigned int key; const struct ConfigDev *cd; @@ -193,7 +193,7 @@ } -static int ariadne_open(struct device *dev) +static int ariadne_open(struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; struct AriadneBoard *board = priv->board; @@ -293,7 +293,7 @@ dev->interrupt = 0; dev->start = 1; - if (request_irq(IRQ_AMIGA_PORTS, ariadne_interrupt, 0, + if (request_irq(IRQ_AMIGA_PORTS, ariadne_interrupt, SA_SHIRQ, "Ariadne Ethernet", dev)) return(-EAGAIN); @@ -306,7 +306,7 @@ } -static void ariadne_init_ring(struct device *dev) +static void ariadne_init_ring(struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; struct AriadneBoard *board = priv->board; @@ -353,7 +353,7 @@ } -static int ariadne_close(struct device *dev) +static int ariadne_close(struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; struct AriadneBoard *board = priv->board; @@ -385,7 +385,7 @@ static void ariadne_interrupt(int irq, void *data, struct pt_regs *fp) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct ariadne_private *priv; struct AriadneBoard *board; int csr0, boguscnt = 10; @@ -542,7 +542,7 @@ } -static int ariadne_start_xmit(struct sk_buff *skb, struct device *dev) +static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; struct AriadneBoard *board = priv->board; @@ -692,7 +692,7 @@ } -static int ariadne_rx(struct device *dev) +static int ariadne_rx(struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; int entry = priv->cur_rx % RX_RING_SIZE; @@ -780,7 +780,7 @@ } -static struct net_device_stats *ariadne_get_stats(struct device *dev) +static struct net_device_stats *ariadne_get_stats(struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; struct AriadneBoard *board = priv->board; @@ -805,7 +805,7 @@ num_addrs > 0 Multicast mode, receive normal and MC packets, and do best-effort filtering. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { struct ariadne_private *priv = (struct ariadne_private *)dev->priv; struct AriadneBoard *board = priv->board; @@ -842,7 +842,7 @@ #ifdef MODULE static char devicename[9] = { 0, }; -static struct device ariadne_dev = +static struct net_device ariadne_dev = { devicename, /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/ariadne2.c linux/drivers/net/ariadne2.c --- v2.3.13/linux/drivers/net/ariadne2.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/ariadne2.c Wed Aug 18 11:36:41 1999 @@ -65,23 +65,23 @@ #define WORDSWAP(a) ((((a)>>8)&0xff) | ((a)<<8)) -int ariadne2_probe(struct device *dev); -static int ariadne2_init(struct device *dev, unsigned int key, +int ariadne2_probe(struct net_device *dev); +static int ariadne2_init(struct net_device *dev, unsigned int key, unsigned long board); -static int ariadne2_open(struct device *dev); -static int ariadne2_close(struct device *dev); +static int ariadne2_open(struct net_device *dev); +static int ariadne2_close(struct net_device *dev); -static void ariadne2_reset_8390(struct device *dev); -static void ariadne2_get_8390_hdr(struct device *dev, +static void ariadne2_reset_8390(struct net_device *dev); +static void ariadne2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ariadne2_block_input(struct device *dev, int count, +static void ariadne2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ariadne2_block_output(struct device *dev, const int count, +static void ariadne2_block_output(struct net_device *dev, const int count, const unsigned char *buf, const int start_page); -int __init ariadne2_probe(struct device *dev) +int __init ariadne2_probe(struct net_device *dev) { unsigned int key; const struct ConfigDev *cd; @@ -100,7 +100,7 @@ return -ENODEV; } -static int __init ariadne2_init(struct device *dev, unsigned int key, +static int __init ariadne2_init(struct net_device *dev, unsigned int key, unsigned long board) { int i; @@ -180,8 +180,8 @@ dev->irq = IRQ_AMIGA_PORTS; /* Install the Interrupt handler */ - if (request_irq(IRQ_AMIGA_PORTS, ei_interrupt, 0, "AriadNE2 Ethernet", - dev)) + if (request_irq(IRQ_AMIGA_PORTS, ei_interrupt, SA_SHIRQ, + "AriadNE2 Ethernet", dev)) return -EAGAIN; /* Allocate dev->priv and fill in 8390 specific dev fields. */ @@ -221,14 +221,14 @@ return 0; } -static int ariadne2_open(struct device *dev) +static int ariadne2_open(struct net_device *dev) { ei_open(dev); MOD_INC_USE_COUNT; return 0; } -static int ariadne2_close(struct device *dev) +static int ariadne2_close(struct net_device *dev) { if (ei_debug > 1) printk("%s: Shutting down ethercard.\n", dev->name); @@ -239,7 +239,7 @@ /* Hard reset the card. This used to pause for the same period that a 8390 reset command required, but that shouldn't be necessary. */ -static void ariadne2_reset_8390(struct device *dev) +static void ariadne2_reset_8390(struct net_device *dev) { unsigned long reset_start_time = jiffies; @@ -264,7 +264,7 @@ we don't need to be concerned with ring wrap as the header will be at the start of a page, so we optimize accordingly. */ -static void ariadne2_get_8390_hdr(struct device *dev, +static void ariadne2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int nic_base = dev->base_addr; @@ -304,7 +304,7 @@ The NEx000 doesn't share the on-board packet memory -- you have to put the packet out through the "remote DMA" dataport using writeb. */ -static void ariadne2_block_input(struct device *dev, int count, +static void ariadne2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int nic_base = dev->base_addr; @@ -338,7 +338,7 @@ ei_status.dmaing &= ~0x01; } -static void ariadne2_block_output(struct device *dev, int count, +static void ariadne2_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page) { @@ -395,7 +395,7 @@ #ifdef MODULE static char devicename[9] = { 0, }; -static struct device ariadne2_dev = +static struct net_device ariadne2_dev = { devicename, 0, 0, 0, 0, diff -u --recursive --new-file v2.3.13/linux/drivers/net/arlan-proc.c linux/drivers/net/arlan-proc.c --- v2.3.13/linux/drivers/net/arlan-proc.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/arlan-proc.c Wed Aug 18 11:36:41 1999 @@ -7,10 +7,10 @@ #include #include -/* void enableReceive(struct device* dev); +/* void enableReceive(struct net_device* dev); */ -static int arlan_command(struct device * dev, int command); +static int arlan_command(struct net_device * dev, int command); #define ARLAN_STR_SIZE 0x2ff0 @@ -58,7 +58,7 @@ } -const char *arlan_diagnostic_info_string(struct device *dev) +const char *arlan_diagnostic_info_string(struct net_device *dev) { volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; @@ -113,7 +113,7 @@ } }; -static const char *arlan_hardware_type_string(struct device *dev) +static const char *arlan_hardware_type_string(struct net_device *dev) { u_char hardwareType; volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; @@ -186,7 +186,7 @@ } } -static void arlan_print_diagnostic_info(struct device *dev) +static void arlan_print_diagnostic_info(struct net_device *dev) { int i; u_char diagnosticInfo; @@ -251,7 +251,7 @@ /****************************** TEST MEMORY **************/ -static int arlan_hw_test_memory(struct device *dev) +static int arlan_hw_test_memory(struct net_device *dev) { u_char *ptr; int i; @@ -320,7 +320,7 @@ } -static int arlan_setup_card_by_book(struct device *dev) +static int arlan_setup_card_by_book(struct net_device *dev) { u_char irqLevel, configuredStatusFlag; volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; @@ -408,7 +408,7 @@ int i; int retv, pos, devnum; struct arlan_private *priva = NULL; - struct device *dev; + struct net_device *dev; pos = 0; if (write) { diff -u --recursive --new-file v2.3.13/linux/drivers/net/arlan.c linux/drivers/net/arlan.c --- v2.3.13/linux/drivers/net/arlan.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/arlan.c Wed Aug 18 11:36:41 1999 @@ -10,7 +10,7 @@ static const char *arlan_version = "C.Jennigs 97 & Elmer.Joandi@ut.ee Oct'98, http://www.ylenurme.ee/~elmer/655/"; -struct device *arlan_device[MAX_ARLANS]; +struct net_device *arlan_device[MAX_ARLANS]; int last_arlan = 0; static int SID = SIDUNKNOWN; @@ -87,20 +87,20 @@ struct arlan_conf_stru arlan_conf[MAX_ARLANS]; int arlans_found = 0; -static int arlan_probe_here(struct device *dev, int ioaddr); -static int arlan_open(struct device *dev); -static int arlan_tx(struct sk_buff *skb, struct device *dev); +static int arlan_probe_here(struct net_device *dev, int ioaddr); +static int arlan_open(struct net_device *dev); +static int arlan_tx(struct sk_buff *skb, struct net_device *dev); static void arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int arlan_close(struct device *dev); +static int arlan_close(struct net_device *dev); static struct enet_statistics * - arlan_statistics (struct device *dev); -static void arlan_set_multicast (struct device *dev); -static int arlan_hw_tx (struct device* dev, char *buf, int length ); -static int arlan_hw_config (struct device * dev); -static void arlan_tx_done_interrupt (struct device * dev, int status); -static void arlan_rx_interrupt (struct device * dev, u_char rxStatus, u_short, u_short); -static void arlan_process_interrupt (struct device * dev); -static int arlan_command(struct device * dev, int command); + arlan_statistics (struct net_device *dev); +static void arlan_set_multicast (struct net_device *dev); +static int arlan_hw_tx (struct net_device* dev, char *buf, int length ); +static int arlan_hw_config (struct net_device * dev); +static void arlan_tx_done_interrupt (struct net_device * dev, int status); +static void arlan_rx_interrupt (struct net_device * dev, u_char rxStatus, u_short, u_short); +static void arlan_process_interrupt (struct net_device * dev); +static int arlan_command(struct net_device * dev, int command); EXPORT_SYMBOL(arlan_command); @@ -162,7 +162,7 @@ -extern inline int arlan_drop_tx(struct device *dev) +extern inline int arlan_drop_tx(struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); @@ -189,7 +189,7 @@ }; -static int arlan_command(struct device *dev, int command_p) +static int arlan_command(struct net_device *dev, int command_p) { volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; @@ -532,7 +532,7 @@ }; -extern inline void arlan_command_process(struct device *dev) +extern inline void arlan_command_process(struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); @@ -553,7 +553,7 @@ } -extern inline void arlan_retransmit_now(struct device *dev) +extern inline void arlan_retransmit_now(struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); @@ -596,7 +596,7 @@ static void arlan_registration_timer(unsigned long data) { - struct device *dev = (struct device *) data; + struct net_device *dev = (struct net_device *) data; struct arlan_private *priv = (struct arlan_private *) dev->priv; int lostTime = ((int) (jiffies - priv->registrationLastSeen)) * 1000 / HZ; @@ -696,7 +696,7 @@ -static void arlan_print_registers(struct device *dev, int line) +static void arlan_print_registers(struct net_device *dev, int line) { volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; @@ -722,7 +722,7 @@ } -static int arlan_hw_tx(struct device *dev, char *buf, int length) +static int arlan_hw_tx(struct net_device *dev, char *buf, int length) { int i; @@ -827,7 +827,7 @@ } -static int arlan_hw_config(struct device *dev) +static int arlan_hw_config(struct net_device *dev) { volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; struct arlan_conf_stru *conf = ((struct arlan_private *) dev->priv)->Conf; @@ -909,7 +909,7 @@ } -static int arlan_read_card_configuration(struct device *dev) +static int arlan_read_card_configuration(struct net_device *dev) { u_char tlx415; volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; @@ -1056,7 +1056,7 @@ } -__initfunctio(int arlan_probe_everywhere(struct device *dev)) +__initfunctio(int arlan_probe_everywhere(struct net_device *dev)) { int m; int probed = 0; @@ -1113,7 +1113,7 @@ } -static int arlan_change_mtu(struct device *dev, int new_mtu) +static int arlan_change_mtu(struct net_device *dev, int new_mtu) { struct arlan_conf_stru *conf = ((struct arlan_private *) dev->priv)->Conf; @@ -1134,7 +1134,7 @@ return 0; } -static int arlan_mac_addr(struct device *dev, void *p) +static int arlan_mac_addr(struct net_device *dev, void *p) { struct sockaddr *addr = p; @@ -1154,10 +1154,10 @@ __initfunctio(static int - arlan_allocate_device(int num, struct device *devs)) + arlan_allocate_device(int num, struct net_device *devs)) { - struct device *dev; + struct net_device *dev; ARLAN_DEBUG_ENTRY("arlan_allocate_device"); @@ -1214,7 +1214,7 @@ } -__initfunctio(int arlan_probe_here(struct device *dev, int memaddr)) +__initfunctio(int arlan_probe_here(struct net_device *dev, int memaddr)) { volatile struct arlan_shmem *arlan; @@ -1249,7 +1249,7 @@ -static int arlan_open(struct device *dev) +static int arlan_open(struct net_device *dev) { struct arlan_private *priv = (struct arlan_private *) dev->priv; volatile struct arlan_shmem *arlan = priv->card; @@ -1323,7 +1323,7 @@ -static int arlan_tx(struct sk_buff *skb, struct device *dev) +static int arlan_tx(struct sk_buff *skb, struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); struct arlan_conf_stru *conf = ((struct arlan_private *) dev->priv)->Conf; @@ -1399,7 +1399,7 @@ } -extern inline int DoNotReTransmitCrap(struct device *dev) +extern inline int DoNotReTransmitCrap(struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); @@ -1409,7 +1409,7 @@ } -extern inline int DoNotWaitReTransmitCrap(struct device *dev) +extern inline int DoNotWaitReTransmitCrap(struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); @@ -1418,7 +1418,7 @@ return 0; } -extern inline void arlan_queue_retransmit(struct device *dev) +extern inline void arlan_queue_retransmit(struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); @@ -1433,7 +1433,7 @@ ARLAN_DEBUG_EXIT("arlan_queue_retransmit"); }; -extern inline void RetryOrFail(struct device *dev) +extern inline void RetryOrFail(struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); @@ -1454,7 +1454,7 @@ } -static void arlan_tx_done_interrupt(struct device *dev, int status) +static void arlan_tx_done_interrupt(struct net_device *dev, int status) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); @@ -1596,7 +1596,7 @@ } -static void arlan_rx_interrupt(struct device *dev, u_char rxStatus, u_short rxOffset, u_short pkt_len) +static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short rxOffset, u_short pkt_len) { char *skbtmp; int i = 0; @@ -1749,7 +1749,7 @@ ARLAN_DEBUG_EXIT("arlan_rx_interrupt"); } -static void arlan_process_interrupt(struct device *dev) +static void arlan_process_interrupt(struct net_device *dev) { struct arlan_private *priv = (struct arlan_private *) dev->priv; volatile struct arlan_shmem *arlan = priv->card; @@ -1859,7 +1859,7 @@ static void arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct arlan_private *priv = (struct arlan_private *) dev->priv; volatile struct arlan_shmem *arlan = priv->card; u_char rxStatus = READSHMB(arlan->rxStatus); @@ -1883,7 +1883,7 @@ } -static int arlan_close(struct device *dev) +static int arlan_close(struct net_device *dev) { struct arlan_private *priv = (struct arlan_private *) dev->priv; @@ -1929,7 +1929,7 @@ * This may be called with the card open or closed. */ -static struct enet_statistics *arlan_statistics(struct device *dev) +static struct enet_statistics *arlan_statistics(struct net_device *dev) { struct arlan_private *priv = (struct arlan_private *) dev->priv; volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; @@ -1959,7 +1959,7 @@ } -static void arlan_set_multicast(struct device *dev) +static void arlan_set_multicast(struct net_device *dev) { volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; struct arlan_conf_stru *conf = ((struct arlan_private *) dev->priv)->Conf; @@ -1992,7 +1992,7 @@ } -__initfunctio(int arlan_probe(struct device *dev)) +__initfunctio(int arlan_probe(struct net_device *dev)) { printk("Arlan driver %s\n", arlan_version); diff -u --recursive --new-file v2.3.13/linux/drivers/net/arlan.h linux/drivers/net/arlan.h --- v2.3.13/linux/drivers/net/arlan.h Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/arlan.h Wed Aug 18 11:36:45 1999 @@ -45,7 +45,7 @@ extern int init_arlan_proc(void); #endif -extern struct device *arlan_device[MAX_ARLANS]; +extern struct net_device *arlan_device[MAX_ARLANS]; static int arlan_debug; static char * siteName; static int arlan_entry_debug; diff -u --recursive --new-file v2.3.13/linux/drivers/net/at1700.c linux/drivers/net/at1700.c --- v2.3.13/linux/drivers/net/at1700.c Tue Jan 19 10:51:24 1999 +++ linux/drivers/net/at1700.c Wed Aug 18 11:36:41 1999 @@ -150,17 +150,17 @@ #define AT1700_IO_EXTENT 32 /* Index to functions, as function prototypes. */ -extern int at1700_probe(struct device *dev); +extern int at1700_probe(struct net_device *dev); -static int at1700_probe1(struct device *dev, int ioaddr); +static int at1700_probe1(struct net_device *dev, int ioaddr); static int read_eeprom(int ioaddr, int location); -static int net_open(struct device *dev); -static int net_send_packet(struct sk_buff *skb, struct device *dev); +static int net_open(struct net_device *dev); +static int net_send_packet(struct sk_buff *skb, struct net_device *dev); static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void net_rx(struct device *dev); -static int net_close(struct device *dev); -static struct enet_statistics *net_get_stats(struct device *dev); -static void set_rx_mode(struct device *dev); +static void net_rx(struct net_device *dev); +static int net_close(struct net_device *dev); +static struct enet_statistics *net_get_stats(struct net_device *dev); +static void set_rx_mode(struct net_device *dev); #ifdef CONFIG_MCA @@ -192,7 +192,7 @@ {"at1700", at1700_probe1, AT1700_IO_EXTENT, at1700_probe_list}; #else -int at1700_probe(struct device *dev) +int at1700_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -221,7 +221,7 @@ that can be done is checking a few bits and then diving right into an EEPROM read. */ -int at1700_probe1(struct device *dev, int ioaddr) +int at1700_probe1(struct net_device *dev, int ioaddr) { char fmv_irqmap[4] = {3, 7, 10, 15}; char fmv_irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15}; @@ -498,7 +498,7 @@ -static int net_open(struct device *dev) +static int net_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -535,7 +535,7 @@ } static int -net_send_packet(struct sk_buff *skb, struct device *dev) +net_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -615,7 +615,7 @@ static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *lp; int ioaddr, status; @@ -681,7 +681,7 @@ /* We have a good packet(s), get it/them out of the buffers. */ static void -net_rx(struct device *dev) +net_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -762,7 +762,7 @@ } /* The inverse routine to net_open(). */ -static int net_close(struct device *dev) +static int net_close(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -794,7 +794,7 @@ There are no on-chip counters, so this function is trivial. */ static struct enet_statistics * -net_get_stats(struct device *dev) +net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; return &lp->stats; @@ -826,7 +826,7 @@ } static void -set_rx_mode(struct device *dev) +set_rx_mode(struct net_device *dev) { int ioaddr = dev->base_addr; struct net_local *lp = (struct net_local *)dev->priv; @@ -875,7 +875,7 @@ #ifdef MODULE static char devicename[9] = { 0, }; -static struct device dev_at1700 = { +static struct net_device dev_at1700 = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0, 0, diff -u --recursive --new-file v2.3.13/linux/drivers/net/atari_bionet.c linux/drivers/net/atari_bionet.c --- v2.3.13/linux/drivers/net/atari_bionet.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/atari_bionet.c Wed Aug 18 11:36:41 1999 @@ -115,7 +115,7 @@ #include -extern struct device *init_etherdev(struct device *dev, int sizeof_private); +extern struct net_device *init_etherdev(struct net_device *dev, int sizeof_private); /* use 0 for production, 1 for verification, >2 for debug */ @@ -149,13 +149,13 @@ /* Index to functions, as function prototypes. */ -extern int bionet_probe(struct device *dev); +extern int bionet_probe(struct net_device *dev); -static int bionet_open(struct device *dev); -static int bionet_send_packet(struct sk_buff *skb, struct device *dev); -static void bionet_poll_rx(struct device *); -static int bionet_close(struct device *dev); -static struct net_device_stats *net_get_stats(struct device *dev); +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 struct timer_list bionet_timer = { NULL, NULL, 0, 0, bionet_tick }; @@ -325,7 +325,7 @@ /* Check for a network adaptor of this type, and return '0' if one exists. */ int __init -bionet_probe(struct device *dev){ +bionet_probe(struct net_device *dev){ unsigned char station_addr[6]; static unsigned version_printed = 0; static int no_more_found = 0; /* avoid "Probing for..." printed 4 times */ @@ -404,7 +404,7 @@ there is non-reboot way to recover if something goes wrong. */ static int -bionet_open(struct device *dev) { +bionet_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; if (bionet_debug > 0) @@ -430,7 +430,7 @@ } static int -bionet_send_packet(struct sk_buff *skb, struct device *dev) { +bionet_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned long flags; @@ -497,7 +497,7 @@ /* We have a good packet(s), get it/them out of the buffers. */ static void -bionet_poll_rx(struct device *dev) { +bionet_poll_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int boguscount = 10; int pkt_len, status; @@ -599,7 +599,7 @@ */ static void bionet_tick(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct net_local *lp = (struct net_local *)dev->priv; if( bionet_debug > 0 && (lp->open_time++ & 7) == 8 ) @@ -614,7 +614,7 @@ /* The inverse routine to bionet_open(). */ static int -bionet_close(struct device *dev) { +bionet_close(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; if (bionet_debug > 0) @@ -636,7 +636,7 @@ /* Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *net_get_stats(struct device *dev) +static struct net_device_stats *net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; return &lp->stats; @@ -646,7 +646,7 @@ #ifdef MODULE static char bio_name[16]; -static struct device bio_dev = +static struct net_device bio_dev = { bio_name, /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/atari_pamsnet.c linux/drivers/net/atari_pamsnet.c --- v2.3.13/linux/drivers/net/atari_pamsnet.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/atari_pamsnet.c Wed Aug 18 11:36:41 1999 @@ -111,7 +111,7 @@ #undef READ #undef WRITE -extern struct device *init_etherdev(struct device *dev, int sizeof_private); +extern struct net_device *init_etherdev(struct net_device *dev, int sizeof_private); /* use 0 for production, 1 for verification, >2 for debug */ @@ -157,13 +157,13 @@ static int get_status (void); static int calc_received (void *start_address); -extern int pamsnet_probe(struct device *dev); +extern int pamsnet_probe(struct net_device *dev); -static int pamsnet_open(struct device *dev); -static int pamsnet_send_packet(struct sk_buff *skb, struct device *dev); -static void pamsnet_poll_rx(struct device *); -static int pamsnet_close(struct device *dev); -static struct net_device_stats *net_get_stats(struct device *dev); +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 void pamsnet_intr(int irq, void *data, struct pt_regs *fp); @@ -563,7 +563,7 @@ extern int __init pamsnet_probe (dev) - struct device *dev; + struct net_device *dev; { int i; HADDR *hwaddr; @@ -661,7 +661,7 @@ there is non-reboot way to recover if something goes wrong. */ static int -pamsnet_open(struct device *dev) { +pamsnet_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; if (pamsnet_debug > 0) @@ -691,7 +691,7 @@ } static int -pamsnet_send_packet(struct sk_buff *skb, struct device *dev) { +pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned long flags; @@ -738,7 +738,7 @@ /* We have a good packet(s), get it/them out of the buffers. */ static void -pamsnet_poll_rx(struct device *dev) { +pamsnet_poll_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int boguscount; int pkt_len; @@ -813,7 +813,7 @@ */ static void pamsnet_tick(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct net_local *lp = (struct net_local *)dev->priv; if( pamsnet_debug > 0 && (lp->open_time++ & 7) == 8 ) @@ -828,7 +828,7 @@ /* The inverse routine to pamsnet_open(). */ static int -pamsnet_close(struct device *dev) { +pamsnet_close(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; if (pamsnet_debug > 0) @@ -855,7 +855,7 @@ /* Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *net_get_stats(struct device *dev) +static struct net_device_stats *net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; return &lp->stats; @@ -865,7 +865,7 @@ #ifdef MODULE static char devicename[9] = { 0, }; -static struct device pam_dev = +static struct net_device pam_dev = { devicename, /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/atarilance.c linux/drivers/net/atarilance.c --- v2.3.13/linux/drivers/net/atarilance.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/atarilance.c Wed Aug 18 11:36:41 1999 @@ -339,17 +339,17 @@ static int addr_accessible( volatile void *regp, int wordflag, int writeflag ); -static unsigned long lance_probe1( struct device *dev, struct lance_addr +static unsigned long lance_probe1( struct net_device *dev, struct lance_addr *init_rec ); -static int lance_open( struct device *dev ); -static void lance_init_ring( struct device *dev ); -static int lance_start_xmit( struct sk_buff *skb, struct device *dev ); +static int lance_open( struct net_device *dev ); +static void lance_init_ring( struct net_device *dev ); +static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ); static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp ); -static int lance_rx( struct device *dev ); -static int lance_close( struct device *dev ); -static struct net_device_stats *lance_get_stats( struct device *dev ); -static void set_multicast_list( struct device *dev ); -static int lance_set_mac_address( struct device *dev, void *addr ); +static int lance_rx( struct net_device *dev ); +static int lance_close( struct net_device *dev ); +static struct net_device_stats *lance_get_stats( struct net_device *dev ); +static void set_multicast_list( struct net_device *dev ); +static int lance_set_mac_address( struct net_device *dev, void *addr ); /************************* End of Prototypes **************************/ @@ -370,7 +370,7 @@ } -int __init atarilance_probe( struct device *dev ) +int __init atarilance_probe( struct net_device *dev ) { int i; static int found = 0; @@ -443,7 +443,7 @@ } -static unsigned long __init lance_probe1( struct device *dev, +static unsigned long __init lance_probe1( struct net_device *dev, struct lance_addr *init_rec ) { volatile unsigned short *memaddr = @@ -623,7 +623,7 @@ } -static int lance_open( struct device *dev ) +static int lance_open( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_ioreg *IO = lp->iobase; @@ -667,7 +667,7 @@ /* Initialize the LANCE Rx and Tx rings. */ -static void lance_init_ring( struct device *dev ) +static void lance_init_ring( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; int i; @@ -713,7 +713,7 @@ } -static int lance_start_xmit( struct sk_buff *skb, struct device *dev ) +static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_ioreg *IO = lp->iobase; @@ -844,7 +844,7 @@ static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct lance_private *lp; struct lance_ioreg *IO; int csr0, boguscnt = 10; @@ -952,7 +952,7 @@ } -static int lance_rx( struct device *dev ) +static int lance_rx( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; int entry = lp->cur_rx & RX_RING_MOD_MASK; @@ -1045,7 +1045,7 @@ } -static int lance_close( struct device *dev ) +static int lance_close( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_ioreg *IO = lp->iobase; @@ -1067,7 +1067,7 @@ } -static struct net_device_stats *lance_get_stats( struct device *dev ) +static struct net_device_stats *lance_get_stats( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; @@ -1082,7 +1082,7 @@ best-effort filtering. */ -static void set_multicast_list( struct device *dev ) +static void set_multicast_list( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_ioreg *IO = lp->iobase; @@ -1124,7 +1124,7 @@ /* This is needed for old RieblCards and possible for new RieblCards */ -static int lance_set_mac_address( struct device *dev, void *addr ) +static int lance_set_mac_address( struct net_device *dev, void *addr ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct sockaddr *saddr = addr; @@ -1154,7 +1154,7 @@ #ifdef MODULE static char devicename[9] = { 0, }; -static struct device atarilance_dev = +static struct net_device atarilance_dev = { devicename, /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/atp.c linux/drivers/net/atp.c --- v2.3.13/linux/drivers/net/atp.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/atp.c Wed Aug 18 11:36:41 1999 @@ -120,28 +120,28 @@ #ifdef TIMED_CHECKER #include static void atp_timed_checker(unsigned long ignored); -static struct device *atp_timed_dev; +static struct net_device *atp_timed_dev; static struct timer_list atp_timer = {NULL, NULL, 0, 0, atp_timed_checker}; #endif /* Index to functions, as function prototypes. */ -extern int atp_probe(struct device *dev); +extern int atp_probe(struct net_device *dev); -static int atp_probe1(struct device *dev, short ioaddr); -static void get_node_ID(struct device *dev); +static int atp_probe1(struct net_device *dev, short ioaddr); +static void get_node_ID(struct net_device *dev); static unsigned short eeprom_op(short ioaddr, unsigned int cmd); -static int net_open(struct device *dev); -static void hardware_init(struct device *dev); +static int net_open(struct net_device *dev); +static void hardware_init(struct net_device *dev); static void write_packet(short ioaddr, int length, unsigned char *packet, int mode); static void trigger_send(short ioaddr, int length); -static int net_send_packet(struct sk_buff *skb, struct device *dev); +static int net_send_packet(struct sk_buff *skb, struct net_device *dev); static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void net_rx(struct device *dev); +static void net_rx(struct net_device *dev); static void read_block(short ioaddr, int length, unsigned char *buffer, int data_mode); -static int net_close(struct device *dev); -static struct net_device_stats *net_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static int net_close(struct net_device *dev); +static struct net_device_stats *net_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); /* Check for a network adapter of this type, and return '0' iff one exists. @@ -151,7 +151,7 @@ (detachable devices only). */ int __init -atp_init(struct device *dev) +atp_init(struct net_device *dev) { int *port, ports[] = {0x378, 0x278, 0x3bc, 0}; int base_addr = dev->base_addr; @@ -173,7 +173,7 @@ return ENODEV; } -static int __init atp_probe1(struct device *dev, short ioaddr) +static int __init atp_probe1(struct net_device *dev, short ioaddr) { int saved_ctrl_reg, status; @@ -259,7 +259,7 @@ } /* Read the station address PROM, usually a word-wide EEPROM. */ -static void __init get_node_ID(struct device *dev) +static void __init get_node_ID(struct net_device *dev) { short ioaddr = dev->base_addr; int sa_offset = 0; @@ -321,7 +321,7 @@ This is an attachable device: if there is no dev->priv entry then it wasn't probed for at boot-time, and we need to probe for it again. */ -static int net_open(struct device *dev) +static int net_open(struct net_device *dev) { /* The interrupt line is turned off (tri-stated) when the device isn't in @@ -338,7 +338,7 @@ /* This routine resets the hardware. We initialize everything, assuming that the hardware may have been temporarily detached. */ -static void hardware_init(struct device *dev) +static void hardware_init(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -412,7 +412,7 @@ } static int -net_send_packet(struct sk_buff *skb, struct device *dev) +net_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -477,7 +477,7 @@ static void net_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *lp; int ioaddr, status, boguscount = 20; static int num_tx_since_rx = 0; @@ -634,7 +634,7 @@ #endif /* We have a good packet(s), get it/them out of the buffers. */ -static void net_rx(struct device *dev) +static void net_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -713,7 +713,7 @@ /* The inverse routine to net_open(). */ static int -net_close(struct device *dev) +net_close(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -737,7 +737,7 @@ /* Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *net_get_stats(struct device *dev) +static struct net_device_stats *net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; return &lp->stats; @@ -747,7 +747,7 @@ * Set or clear the multicast filter for this adapter. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; short ioaddr = dev->base_addr; diff -u --recursive --new-file v2.3.13/linux/drivers/net/bagetlance.c linux/drivers/net/bagetlance.c --- v2.3.13/linux/drivers/net/bagetlance.c Wed Jun 30 13:38:20 1999 +++ linux/drivers/net/bagetlance.c Wed Aug 18 11:36:41 1999 @@ -329,17 +329,17 @@ static int addr_accessible( volatile void *regp, int wordflag, int writeflag ); -static unsigned long lance_probe1( struct device *dev, struct lance_addr +static unsigned long lance_probe1( struct net_device *dev, struct lance_addr *init_rec ); -static int lance_open( struct device *dev ); -static void lance_init_ring( struct device *dev ); -static int lance_start_xmit( struct sk_buff *skb, struct device *dev ); +static int lance_open( struct net_device *dev ); +static void lance_init_ring( struct net_device *dev ); +static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ); static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp ); -static int lance_rx( struct device *dev ); -static int lance_close( struct device *dev ); -static struct net_device_stats *lance_get_stats( struct device *dev ); -static void set_multicast_list( struct device *dev ); -static int lance_set_mac_address( struct device *dev, void *addr ); +static int lance_rx( struct net_device *dev ); +static int lance_close( struct net_device *dev ); +static struct net_device_stats *lance_get_stats( struct net_device *dev ); +static void set_multicast_list( struct net_device *dev ); +static int lance_set_mac_address( struct net_device *dev, void *addr ); /************************* End of Prototypes **************************/ @@ -469,7 +469,7 @@ } -__initfunc(int bagetlance_probe( struct device *dev )) +__initfunc(int bagetlance_probe( struct net_device *dev )) { int i; static int found = 0; @@ -508,7 +508,7 @@ #define IRQ_TYPE_PRIO SA_INTERRUPT #define IRQ_SOURCE_TO_VECTOR(x) (x) -__initfunc(static unsigned long lance_probe1( struct device *dev, +__initfunc(static unsigned long lance_probe1( struct net_device *dev, struct lance_addr *init_rec )) { volatile unsigned short *memaddr = @@ -723,7 +723,7 @@ } -static int lance_open( struct device *dev ) +static int lance_open( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_ioreg *IO = lp->iobase; @@ -767,7 +767,7 @@ /* Initialize the LANCE Rx and Tx rings. */ -static void lance_init_ring( struct device *dev ) +static void lance_init_ring( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; int i; @@ -823,7 +823,7 @@ } -static int lance_start_xmit( struct sk_buff *skb, struct device *dev ) +static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_ioreg *IO = lp->iobase; @@ -962,7 +962,7 @@ static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct lance_private *lp; struct lance_ioreg *IO; int csr0, boguscnt = 10; @@ -1082,7 +1082,7 @@ } -static int lance_rx( struct device *dev ) +static int lance_rx( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; int entry = lp->cur_rx & RX_RING_MOD_MASK; @@ -1205,7 +1205,7 @@ } -static int lance_close( struct device *dev ) +static int lance_close( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_ioreg *IO = lp->iobase; @@ -1227,7 +1227,7 @@ } -static struct net_device_stats *lance_get_stats( struct device *dev ) +static struct net_device_stats *lance_get_stats( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; @@ -1242,7 +1242,7 @@ best-effort filtering. */ -static void set_multicast_list( struct device *dev ) +static void set_multicast_list( struct net_device *dev ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct lance_ioreg *IO = lp->iobase; @@ -1284,7 +1284,7 @@ /* This is needed for old RieblCards and possible for new RieblCards */ -static int lance_set_mac_address( struct device *dev, void *addr ) +static int lance_set_mac_address( struct net_device *dev, void *addr ) { struct lance_private *lp = (struct lance_private *)dev->priv; struct sockaddr *saddr = addr; @@ -1326,7 +1326,7 @@ #ifdef MODULE static char devicename[9] = { 0, }; -static struct device bagetlance_dev = +static struct net_device bagetlance_dev = { devicename, /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/bmac.c linux/drivers/net/bmac.c --- v2.3.13/linux/drivers/net/bmac.c Wed Dec 30 10:55:07 1998 +++ linux/drivers/net/bmac.c Wed Aug 18 11:36:41 1999 @@ -114,7 +114,7 @@ {"RXCV", RXCV} }; -struct device *bmac_devs = NULL; +struct net_device *bmac_devs = NULL; static int is_bmac_plus; #if 0 @@ -135,25 +135,25 @@ + sizeof(struct sk_buff_head)) static unsigned char bitrev(unsigned char b); -static int bmac_open(struct device *dev); -static int bmac_close(struct device *dev); -static int bmac_transmit_packet(struct sk_buff *skb, struct device *dev); -static struct net_device_stats *bmac_stats(struct device *dev); -static void bmac_set_multicast(struct device *dev); -static int bmac_reset_and_enable(struct device *dev, int enable); -static void bmac_start_chip(struct device *dev); -static int bmac_init_chip(struct device *dev); -static void bmac_init_registers(struct device *dev); -static void bmac_reset_chip(struct device *dev); -static int bmac_set_address(struct device *dev, void *addr); +static int bmac_open(struct net_device *dev); +static int bmac_close(struct net_device *dev); +static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev); +static struct net_device_stats *bmac_stats(struct net_device *dev); +static void bmac_set_multicast(struct net_device *dev); +static int bmac_reset_and_enable(struct net_device *dev, int enable); +static void bmac_start_chip(struct net_device *dev); +static int bmac_init_chip(struct net_device *dev); +static void bmac_init_registers(struct net_device *dev); +static void bmac_reset_chip(struct net_device *dev); +static int bmac_set_address(struct net_device *dev, void *addr); static void bmac_misc_intr(int irq, void *dev_id, struct pt_regs *regs); static void bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs); static void bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs); -static void bmac_set_timeout(struct device *dev); +static void bmac_set_timeout(struct net_device *dev); static void bmac_tx_timeout(unsigned long data); static int bmac_proc_info ( char *buffer, char **start, off_t offset, int length, int dummy); -static int bmac_output(struct sk_buff *skb, struct device *dev); -static void bmac_start(struct device *dev); +static int bmac_output(struct sk_buff *skb, struct net_device *dev); +static void bmac_start(struct net_device *dev); #define DBDMA_SET(x) ( ((x) | (x) << 16) ) #define DBDMA_CLEAR(x) ( (x) << 16) @@ -214,20 +214,20 @@ } static __inline__ -void bmwrite(struct device *dev, unsigned long reg_offset, unsigned data ) +void bmwrite(struct net_device *dev, unsigned long reg_offset, unsigned data ) { out_le16((void *)dev->base_addr + reg_offset, data); } static __inline__ -volatile unsigned short bmread(struct device *dev, unsigned long reg_offset ) +volatile unsigned short bmread(struct net_device *dev, unsigned long reg_offset ) { return in_le16((void *)dev->base_addr + reg_offset); } static void -bmac_reset_chip(struct device *dev) +bmac_reset_chip(struct net_device *dev) { struct bmac_data *bp = (struct bmac_data *) dev->priv; volatile struct dbdma_regs *rd = bp->rx_dma; @@ -247,7 +247,7 @@ #define MIFDELAY udelay(500) static unsigned int -bmac_mif_readbits(struct device *dev, int nb) +bmac_mif_readbits(struct net_device *dev, int nb) { unsigned int val = 0; @@ -267,7 +267,7 @@ } static void -bmac_mif_writebits(struct device *dev, unsigned int val, int nb) +bmac_mif_writebits(struct net_device *dev, unsigned int val, int nb) { int b; @@ -281,7 +281,7 @@ } static unsigned int -bmac_mif_read(struct device *dev, unsigned int addr) +bmac_mif_read(struct net_device *dev, unsigned int addr) { unsigned int val; @@ -302,7 +302,7 @@ } static void -bmac_mif_write(struct device *dev, unsigned int addr, unsigned int val) +bmac_mif_write(struct net_device *dev, unsigned int addr, unsigned int val) { bmwrite(dev, MIFCSR, 4); MIFDELAY; @@ -315,7 +315,7 @@ } static void -bmac_init_registers(struct device *dev) +bmac_init_registers(struct net_device *dev) { struct bmac_data *bp = (struct bmac_data *) dev->priv; volatile unsigned short regValue; @@ -396,13 +396,13 @@ #if 0 static void -bmac_disable_interrupts(struct device *dev) +bmac_disable_interrupts(struct net_device *dev) { bmwrite(dev, INTDISABLE, DisableAll); } static void -bmac_enable_interrupts(struct device *dev) +bmac_enable_interrupts(struct net_device *dev) { bmwrite(dev, INTDISABLE, EnableNormal); } @@ -410,7 +410,7 @@ static void -bmac_start_chip(struct device *dev) +bmac_start_chip(struct net_device *dev) { struct bmac_data *bp = (struct bmac_data *) dev->priv; volatile struct dbdma_regs *rd = bp->rx_dma; @@ -429,7 +429,7 @@ } static int -bmac_init_chip(struct device *dev) +bmac_init_chip(struct net_device *dev) { if (is_bmac_plus && bmac_mif_read(dev, 2) == 0x7810) { if (bmac_mif_read(dev, 4) == 0xa1) { @@ -448,7 +448,7 @@ return 1; } -static int bmac_set_address(struct device *dev, void *addr) +static int bmac_set_address(struct net_device *dev, void *addr) { unsigned char *p = addr; unsigned short *pWord16; @@ -472,7 +472,7 @@ return 0; } -static inline void bmac_set_timeout(struct device *dev) +static inline void bmac_set_timeout(struct net_device *dev) { struct bmac_data *bp = (struct bmac_data *) dev->priv; unsigned long flags; @@ -580,7 +580,7 @@ } -static int bmac_transmit_packet(struct sk_buff *skb, struct device *dev) +static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev) { struct bmac_data *bp = (struct bmac_data *) dev->priv; volatile struct dbdma_regs *td = bp->tx_dma; @@ -616,7 +616,7 @@ static void bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct bmac_data *bp = (struct bmac_data *) dev->priv; volatile struct dbdma_regs *rd = bp->rx_dma; volatile struct dbdma_cmd *cp; @@ -684,7 +684,7 @@ static void bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct bmac_data *bp = (struct bmac_data *) dev->priv; volatile struct dbdma_cmd *cp; int stat; @@ -730,7 +730,7 @@ bmac_start(dev); } -static struct net_device_stats *bmac_stats(struct device *dev) +static struct net_device_stats *bmac_stats(struct net_device *dev) { struct bmac_data *p = (struct bmac_data *) dev->priv; @@ -833,7 +833,7 @@ */ static void -bmac_rx_off(struct device *dev) +bmac_rx_off(struct net_device *dev) { unsigned short rx_cfg; @@ -846,7 +846,7 @@ } unsigned short -bmac_rx_on(struct device *dev, int hash_enable, int promisc_enable) +bmac_rx_on(struct net_device *dev, int hash_enable, int promisc_enable) { unsigned short rx_cfg; @@ -864,7 +864,7 @@ } static void -bmac_update_hash_table_mask(struct device *dev, struct bmac_data *bp) +bmac_update_hash_table_mask(struct net_device *dev, struct bmac_data *bp) { bmwrite(dev, BHASH3, bp->hash_table_mask[0]); /* bits 15 - 0 */ bmwrite(dev, BHASH2, bp->hash_table_mask[1]); /* bits 31 - 16 */ @@ -874,7 +874,7 @@ #if 0 static void -bmac_add_multi(struct device *dev, +bmac_add_multi(struct net_device *dev, struct bmac_data *bp, unsigned char *addr) { /* XXDEBUG(("bmac: enter bmac_add_multi\n")); */ @@ -886,7 +886,7 @@ } static void -bmac_remove_multi(struct device *dev, +bmac_remove_multi(struct net_device *dev, struct bmac_data *bp, unsigned char *addr) { bmac_removehash(bp, addr); @@ -902,7 +902,7 @@ num_addrs > 0 Multicast mode, receive normal and MC packets, and do best-effort filtering. */ -static void bmac_set_multicast(struct device *dev) +static void bmac_set_multicast(struct net_device *dev) { struct dev_mc_list *dmi; struct bmac_data *bp = (struct bmac_data *) dev->priv; @@ -946,7 +946,7 @@ #define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */ #define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */ -static void bmac_set_multicast(struct device *dev) +static void bmac_set_multicast(struct net_device *dev) { struct dev_mc_list *dmi = dev->mc_list; char *addrs; @@ -1014,7 +1014,7 @@ static void bmac_misc_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct bmac_data *bp = (struct bmac_data *)dev->priv; unsigned int status = bmread(dev, STATUS); if (miscintcount++ < 10) { @@ -1052,7 +1052,7 @@ #define EnetAddressOffset 20 static unsigned char -bmac_clock_out_bit(struct device *dev) +bmac_clock_out_bit(struct net_device *dev) { unsigned short data; unsigned short val; @@ -1071,7 +1071,7 @@ } static void -bmac_clock_in_bit(struct device *dev, unsigned int val) +bmac_clock_in_bit(struct net_device *dev, unsigned int val) { unsigned short data; @@ -1089,7 +1089,7 @@ } static void -reset_and_select_srom(struct device *dev) +reset_and_select_srom(struct net_device *dev) { /* first reset */ bmwrite(dev, SROMCSR, 0); @@ -1102,7 +1102,7 @@ } static unsigned short -read_srom(struct device *dev, unsigned int addr, unsigned int addr_len) +read_srom(struct net_device *dev, unsigned int addr, unsigned int addr_len) { unsigned short data, val; int i; @@ -1131,7 +1131,7 @@ */ static int -bmac_verify_checksum(struct device *dev) +bmac_verify_checksum(struct net_device *dev) { unsigned short data, storedCS; @@ -1144,7 +1144,7 @@ static void -bmac_get_station_address(struct device *dev, unsigned char *ea) +bmac_get_station_address(struct net_device *dev, unsigned char *ea) { int i; unsigned short data; @@ -1158,7 +1158,7 @@ } } -static int bmac_reset_and_enable(struct device *dev, int enable) +static int bmac_reset_and_enable(struct net_device *dev, int enable) { struct bmac_data *bp = dev->priv; unsigned long flags; @@ -1191,7 +1191,7 @@ } int -bmac_probe(struct device *dev) +bmac_probe(struct net_device *dev) { int j, rev; struct bmac_data *bp; @@ -1322,7 +1322,7 @@ return 0; } -static int bmac_open(struct device *dev) +static int bmac_open(struct net_device *dev) { /* XXDEBUG(("bmac: enter open\n")); */ /* reset the chip */ @@ -1333,7 +1333,7 @@ return 0; } -static int bmac_close(struct device *dev) +static int bmac_close(struct net_device *dev) { struct bmac_data *bp = (struct bmac_data *) dev->priv; volatile struct dbdma_regs *rd = bp->rx_dma; @@ -1379,7 +1379,7 @@ } static void -bmac_start(struct device *dev) +bmac_start(struct net_device *dev) { struct bmac_data *bp = dev->priv; int i; @@ -1399,7 +1399,7 @@ } static int -bmac_output(struct sk_buff *skb, struct device *dev) +bmac_output(struct sk_buff *skb, struct net_device *dev) { struct bmac_data *bp = dev->priv; skb_queue_tail(bp->queue, skb); @@ -1409,7 +1409,7 @@ static void bmac_tx_timeout(unsigned long data) { - struct device *dev = (struct device *) data; + struct net_device *dev = (struct net_device *) data; struct bmac_data *bp = (struct bmac_data *) dev->priv; volatile struct dbdma_regs *td = bp->tx_dma; volatile struct dbdma_regs *rd = bp->rx_dma; diff -u --recursive --new-file v2.3.13/linux/drivers/net/com20020.c linux/drivers/net/com20020.c --- v2.3.13/linux/drivers/net/com20020.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/com20020.c Wed Aug 18 11:36:41 1999 @@ -58,23 +58,23 @@ /* Internal function declarations */ -static int arc20020_probe(struct device *dev); -static void arc20020_rx(struct device *dev,int recbuf); -static int arc20020_found(struct device *dev,int ioaddr,int airq); -static void arc20020_inthandler (struct device *dev); -static int arc20020_reset (struct device *dev, int reset_delay); -static void arc20020_setmask (struct device *dev, u_char mask); -static void arc20020_command (struct device *dev, u_char command); -static u_char arc20020_status (struct device *dev); -static void arc20020_en_dis_able_TX (struct device *dev, int enable); -static void arc20020_prepare_tx(struct device *dev,u_char *hdr,int hdrlen, +static int arc20020_probe(struct net_device *dev); +static void arc20020_rx(struct net_device *dev,int recbuf); +static int arc20020_found(struct net_device *dev,int ioaddr,int airq); +static void arc20020_inthandler (struct net_device *dev); +static int arc20020_reset (struct net_device *dev, int reset_delay); +static void arc20020_setmask (struct net_device *dev, u_char mask); +static void arc20020_command (struct net_device *dev, u_char command); +static u_char arc20020_status (struct net_device *dev); +static void arc20020_en_dis_able_TX (struct net_device *dev, int enable); +static void arc20020_prepare_tx(struct net_device *dev,u_char *hdr,int hdrlen, char *data,int length,int daddr,int exceptA, int offset); static void arc20020_openclose(int open); -static void arc20020_set_mc_list(struct device *dev); -static u_char get_buffer_byte (struct device *dev, unsigned offset); -static void put_buffer_byte (struct device *dev, unsigned offset, u_char datum); -static void get_whole_buffer (struct device *dev, unsigned offset, unsigned length, char *dest); -static void put_whole_buffer (struct device *dev, unsigned offset, unsigned length, char *dest); +static void arc20020_set_mc_list(struct net_device *dev); +static u_char get_buffer_byte (struct net_device *dev, unsigned offset); +static void put_buffer_byte (struct net_device *dev, unsigned offset, u_char datum); +static void get_whole_buffer (struct net_device *dev, unsigned offset, unsigned length, char *dest); +static void put_whole_buffer (struct net_device *dev, unsigned offset, unsigned length, char *dest); /* Module parameters */ @@ -97,7 +97,7 @@ MODULE_PARM(clock,"i"); #else void __init com20020_setup (char *str, int *ints); -extern struct device arcnet_devs[]; +extern struct net_device arcnet_devs[]; extern char arcnet_dev_names[][10]; extern int arcnet_num_devs; #endif @@ -155,7 +155,7 @@ * * ****************************************************************************/ -u_char get_buffer_byte (struct device *dev, unsigned offset) +u_char get_buffer_byte (struct net_device *dev, unsigned offset) { int ioaddr=dev->base_addr; @@ -165,7 +165,7 @@ return inb(_MEMDATA); } -void put_buffer_byte (struct device *dev, unsigned offset, u_char datum) +void put_buffer_byte (struct net_device *dev, unsigned offset, u_char datum) { int ioaddr=dev->base_addr; @@ -179,7 +179,7 @@ #undef ONE_AT_A_TIME_TX #undef ONE_AT_A_TIME_RX -void get_whole_buffer (struct device *dev, unsigned offset, unsigned length, char *dest) +void get_whole_buffer (struct net_device *dev, unsigned offset, unsigned length, char *dest) { int ioaddr=dev->base_addr; @@ -194,7 +194,7 @@ #endif } -void put_whole_buffer (struct device *dev, unsigned offset, unsigned length, char *dest) +void put_whole_buffer (struct net_device *dev, unsigned offset, unsigned length, char *dest) { int ioaddr=dev->base_addr; @@ -224,7 +224,7 @@ * it's where we were told it was, and even autoirq */ -int __init arc20020_probe(struct device *dev) +int __init arc20020_probe(struct net_device *dev) { int ioaddr=dev->base_addr,status,delayval; unsigned long airqmask; @@ -324,10 +324,10 @@ } -/* Set up the struct device associated with this card. Called after +/* Set up the struct net_device associated with this card. Called after * probing succeeds. */ -int __init arc20020_found(struct device *dev,int ioaddr,int airq) +int __init arc20020_found(struct net_device *dev,int ioaddr,int airq) { struct arcnet_local *lp; @@ -444,7 +444,7 @@ * * However, it does make sure the card is in a defined state. */ -int arc20020_reset(struct device *dev,int reset_delay) +int arc20020_reset(struct net_device *dev,int reset_delay) { struct arcnet_local *lp=(struct arcnet_local *)dev->priv; short ioaddr=dev->base_addr; @@ -515,7 +515,7 @@ * FIX ME - do multicast stuff, not just promiscuous. */ static void -arc20020_set_mc_list(struct device *dev) +arc20020_set_mc_list(struct net_device *dev) { struct arcnet_local *lp=dev->priv; int ioaddr=dev->base_addr; @@ -550,7 +550,7 @@ } -static void arc20020_en_dis_able_TX(struct device *dev, int enable) +static void arc20020_en_dis_able_TX(struct net_device *dev, int enable) { struct arcnet_local *lp=(struct arcnet_local *)dev->priv; int ioaddr=dev->base_addr; @@ -560,7 +560,7 @@ } -static void arc20020_setmask(struct device *dev, u_char mask) +static void arc20020_setmask(struct net_device *dev, u_char mask) { short ioaddr=dev->base_addr; @@ -568,7 +568,7 @@ } -static u_char arc20020_status(struct device *dev) +static u_char arc20020_status(struct net_device *dev) { short ioaddr=dev->base_addr; @@ -576,7 +576,7 @@ } -static void arc20020_command(struct device *dev, u_char cmd) +static void arc20020_command(struct net_device *dev, u_char cmd) { short ioaddr=dev->base_addr; @@ -588,7 +588,7 @@ * by the card. */ static void -arc20020_inthandler(struct device *dev) +arc20020_inthandler(struct net_device *dev) { struct arcnet_local *lp=(struct arcnet_local *)dev->priv; int ioaddr=dev->base_addr, status, boguscount = 3, didsomething, @@ -828,7 +828,7 @@ */ static void -arc20020_rx(struct device *dev,int recbuf) +arc20020_rx(struct net_device *dev,int recbuf) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; int ioaddr=dev->base_addr; @@ -885,7 +885,7 @@ * by arcnet_go_tx. */ static void -arc20020_prepare_tx(struct device *dev,u_char *hdr,int hdrlen, +arc20020_prepare_tx(struct net_device *dev,u_char *hdr,int hdrlen, char *data,int length,int daddr,int exceptA, int offset) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -957,19 +957,19 @@ #ifdef MODULE -static struct device *cards[16]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +static struct net_device *cards[16]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; int init_module(void) { - struct device *dev; + struct net_device *dev; - cards[0]=dev=(struct device *)kmalloc(sizeof(struct device), GFP_KERNEL); + cards[0]=dev=(struct net_device *)kmalloc(sizeof(struct net_device), GFP_KERNEL); if (!dev) return -ENOMEM; - memset(dev, 0, sizeof(struct device)); + memset(dev, 0, sizeof(struct net_device)); dev->name=(char *)kmalloc(9, GFP_KERNEL); if (!dev->name) @@ -1006,7 +1006,7 @@ void cleanup_module(void) { - struct device *dev=cards[0]; + struct net_device *dev=cards[0]; int ioaddr=dev->base_addr; if (dev->start) (*dev->stop)(dev); @@ -1037,7 +1037,7 @@ void __init com20020_setup (char *str, int *ints) { - struct device *dev; + struct net_device *dev; if (arcnet_num_devs == MAX_ARCNET_DEVS) { diff -u --recursive --new-file v2.3.13/linux/drivers/net/com90io.c linux/drivers/net/com90io.c --- v2.3.13/linux/drivers/net/com90io.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/com90io.c Wed Aug 18 11:36:41 1999 @@ -58,22 +58,22 @@ /* Internal function declarations */ -static int arc90io_probe(struct device *dev); -static void arc90io_rx(struct device *dev,int recbuf); -static int arc90io_found(struct device *dev,int ioaddr,int airq); -static void arc90io_inthandler (struct device *dev); -static int arc90io_reset (struct device *dev, int reset_delay); -static void arc90io_setmask (struct device *dev, u_char mask); -static void arc90io_command (struct device *dev, u_char command); -static u_char arc90io_status (struct device *dev); -static void arc90io_prepare_tx(struct device *dev,u_char *hdr,int hdrlen, +static int arc90io_probe(struct net_device *dev); +static void arc90io_rx(struct net_device *dev,int recbuf); +static int arc90io_found(struct net_device *dev,int ioaddr,int airq); +static void arc90io_inthandler (struct net_device *dev); +static int arc90io_reset (struct net_device *dev, int reset_delay); +static void arc90io_setmask (struct net_device *dev, u_char mask); +static void arc90io_command (struct net_device *dev, u_char command); +static u_char arc90io_status (struct net_device *dev); +static void arc90io_prepare_tx(struct net_device *dev,u_char *hdr,int hdrlen, char *data,int length,int daddr,int exceptA, int offset); static void arc90io_openclose(int open); -static u_char get_buffer_byte (struct device *dev, unsigned offset); -static void put_buffer_byte (struct device *dev, unsigned offset, u_char datum); -static void get_whole_buffer (struct device *dev, unsigned offset, unsigned length, char *dest); -static void put_whole_buffer (struct device *dev, unsigned offset, unsigned length, char *dest); +static u_char get_buffer_byte (struct net_device *dev, unsigned offset); +static void put_buffer_byte (struct net_device *dev, unsigned offset, u_char datum); +static void get_whole_buffer (struct net_device *dev, unsigned offset, unsigned length, char *dest); +static void put_whole_buffer (struct net_device *dev, unsigned offset, unsigned length, char *dest); /* Module parameters */ @@ -88,7 +88,7 @@ MODULE_PARM(device, "s"); #else void __init com90io_setup (char *str, int *ints); -extern struct device arcnet_devs[]; +extern struct net_device arcnet_devs[]; extern char arcnet_dev_names[][10]; extern int arcnet_num_devs; #endif @@ -124,7 +124,7 @@ * * ****************************************************************************/ -u_char get_buffer_byte (struct device *dev, unsigned offset) +u_char get_buffer_byte (struct net_device *dev, unsigned offset) { int ioaddr=dev->base_addr; @@ -134,7 +134,7 @@ return inb(_MEMDATA); } -void put_buffer_byte (struct device *dev, unsigned offset, u_char datum) +void put_buffer_byte (struct net_device *dev, unsigned offset, u_char datum) { int ioaddr=dev->base_addr; @@ -148,7 +148,7 @@ #undef ONE_AT_A_TIME_TX #undef ONE_AT_A_TIME_RX -void get_whole_buffer (struct device *dev, unsigned offset, unsigned length, char *dest) +void get_whole_buffer (struct net_device *dev, unsigned offset, unsigned length, char *dest) { int ioaddr=dev->base_addr; @@ -163,7 +163,7 @@ #endif } -void put_whole_buffer (struct device *dev, unsigned offset, unsigned length, char *dest) +void put_whole_buffer (struct net_device *dev, unsigned offset, unsigned length, char *dest) { int ioaddr=dev->base_addr; @@ -193,7 +193,7 @@ * it's where we were told it was, and even autoirq */ -int __init arc90io_probe(struct device *dev) +int __init arc90io_probe(struct net_device *dev) { int ioaddr=dev->base_addr,status,delayval; unsigned long airqmask; @@ -284,10 +284,10 @@ } -/* Set up the struct device associated with this card. Called after +/* Set up the struct net_device associated with this card. Called after * probing succeeds. */ -int __init arc90io_found(struct device *dev,int ioaddr,int airq) +int __init arc90io_found(struct net_device *dev,int ioaddr,int airq) { struct arcnet_local *lp; @@ -381,7 +381,7 @@ * * However, it does make sure the card is in a defined state. */ -int arc90io_reset(struct device *dev,int reset_delay) +int arc90io_reset(struct net_device *dev,int reset_delay) { struct arcnet_local *lp=(struct arcnet_local *)dev->priv; short ioaddr=dev->base_addr; @@ -453,21 +453,21 @@ } -static void arc90io_setmask(struct device *dev, u_char mask) +static void arc90io_setmask(struct net_device *dev, u_char mask) { short ioaddr=dev->base_addr; AINTMASK(mask); } -static u_char arc90io_status(struct device *dev) +static u_char arc90io_status(struct net_device *dev) { short ioaddr=dev->base_addr; return ARCSTATUS; } -static void arc90io_command(struct device *dev, u_char cmd) +static void arc90io_command(struct net_device *dev, u_char cmd) { short ioaddr=dev->base_addr; @@ -479,7 +479,7 @@ * by the card. */ static void -arc90io_inthandler(struct device *dev) +arc90io_inthandler(struct net_device *dev) { struct arcnet_local *lp=(struct arcnet_local *)dev->priv; int ioaddr=dev->base_addr, status, boguscount = 3, didsomething; @@ -711,7 +711,7 @@ */ static void -arc90io_rx(struct device *dev,int recbuf) +arc90io_rx(struct net_device *dev,int recbuf) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; int ioaddr=dev->base_addr; @@ -768,7 +768,7 @@ * by arcnet_go_tx. */ static void -arc90io_prepare_tx(struct device *dev,u_char *hdr,int hdrlen, +arc90io_prepare_tx(struct net_device *dev,u_char *hdr,int hdrlen, char *data,int length,int daddr,int exceptA, int offset) { struct arcnet_local *lp = (struct arcnet_local *)dev->priv; @@ -840,19 +840,19 @@ #ifdef MODULE -static struct device *cards[16]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +static struct net_device *cards[16]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; int init_module(void) { - struct device *dev=cards[0]; + struct net_device *dev=cards[0]; - cards[0]=dev=(struct device *)kmalloc(sizeof(struct device), GFP_KERNEL); + cards[0]=dev=(struct net_device *)kmalloc(sizeof(struct net_device), GFP_KERNEL); if (!dev) return -ENOMEM; - memset(dev, 0, sizeof(struct device)); + memset(dev, 0, sizeof(struct net_device)); dev->name=(char *)kmalloc(9, GFP_KERNEL); if (!dev->name) @@ -881,7 +881,7 @@ void cleanup_module(void) { - struct device *dev=cards[0]; + struct net_device *dev=cards[0]; int ioaddr=dev->base_addr; if (dev->start) (*dev->stop)(dev); @@ -916,7 +916,7 @@ void __init com90io_setup (char *str, int *ints) { - struct device *dev; + struct net_device *dev; if (arcnet_num_devs == MAX_ARCNET_DEVS) { diff -u --recursive --new-file v2.3.13/linux/drivers/net/com90xx.c linux/drivers/net/com90xx.c --- v2.3.13/linux/drivers/net/com90xx.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/com90xx.c Wed Aug 18 11:36:41 1999 @@ -91,15 +91,15 @@ #ifdef MODULE static #endif -int arc90xx_probe(struct device *dev); -static void arc90xx_rx(struct device *dev, int recbuf); -static int arc90xx_found(struct device *dev, int ioaddr, int airq, u_long shmem, int more); -static void arc90xx_inthandler(struct device *dev); -static int arc90xx_reset(struct device *dev, int reset_delay); -static void arc90xx_setmask(struct device *dev, u_char mask); -static void arc90xx_command(struct device *dev, u_char command); -static u_char arc90xx_status(struct device *dev); -static void arc90xx_prepare_tx(struct device *dev, u_char * hdr, int hdrlen, +int arc90xx_probe(struct net_device *dev); +static void arc90xx_rx(struct net_device *dev, int recbuf); +static int arc90xx_found(struct net_device *dev, int ioaddr, int airq, u_long shmem, int more); +static void arc90xx_inthandler(struct net_device *dev); +static int arc90xx_reset(struct net_device *dev, int reset_delay); +static void arc90xx_setmask(struct net_device *dev, u_char mask); +static void arc90xx_command(struct net_device *dev, u_char command); +static u_char arc90xx_status(struct net_device *dev); +static void arc90xx_prepare_tx(struct net_device *dev, u_char * hdr, int hdrlen, char *data, int length, int daddr, int exceptA, int offset); static void arc90xx_openclose(int open); @@ -120,7 +120,7 @@ void __init com90xx_setup(char *str, int *ints); char __initdata com90xx_explicit = 0; -extern struct device arcnet_devs[]; +extern struct net_device arcnet_devs[]; extern char arcnet_dev_names[][10]; extern int arcnet_num_devs; #endif @@ -179,7 +179,7 @@ 0 }; -int __init arc90xx_probe(struct device *dev) +int __init arc90xx_probe(struct net_device *dev) { static int init_once = 0; static int numports = sizeof(ports) / sizeof(ports[0]), numshmems = sizeof(shmems) / sizeof(shmems[0]); @@ -490,10 +490,10 @@ return retval; } -/* Set up the struct device associated with this card. Called after +/* Set up the struct net_device associated with this card. Called after * probing succeeds. */ -static int __init arc90xx_found(struct device *dev, int ioaddr, int airq, u_long shmem, int more) +static int __init arc90xx_found(struct net_device *dev, int ioaddr, int airq, u_long shmem, int more) { struct arcnet_local *lp; u_long first_mirror, last_mirror; @@ -623,7 +623,7 @@ * * However, it does make sure the card is in a defined state. */ -int arc90xx_reset(struct device *dev, int reset_delay) +int arc90xx_reset(struct net_device *dev, int reset_delay) { struct arcnet_local *lp = (struct arcnet_local *) dev->priv; short ioaddr = dev->base_addr; @@ -690,7 +690,7 @@ } -static void arc90xx_setmask(struct device *dev, u_char mask) +static void arc90xx_setmask(struct net_device *dev, u_char mask) { short ioaddr = dev->base_addr; @@ -698,7 +698,7 @@ } -static u_char arc90xx_status(struct device *dev) +static u_char arc90xx_status(struct net_device *dev) { short ioaddr = dev->base_addr; @@ -706,7 +706,7 @@ } -static void arc90xx_command(struct device *dev, u_char cmd) +static void arc90xx_command(struct net_device *dev, u_char cmd) { short ioaddr = dev->base_addr; @@ -717,7 +717,7 @@ /* The actual interrupt handler routine - handle various IRQ's generated * by the card. */ -static void arc90xx_inthandler(struct device *dev) +static void arc90xx_inthandler(struct net_device *dev) { struct arcnet_local *lp = (struct arcnet_local *) dev->priv; int ioaddr = dev->base_addr, status, boguscount = 3, didsomething; @@ -909,7 +909,7 @@ * arcnet_rx routing to deal with it. */ -static void arc90xx_rx(struct device *dev, int recbuf) +static void arc90xx_rx(struct net_device *dev, int recbuf) { struct arcnet_local *lp = (struct arcnet_local *) dev->priv; int ioaddr = dev->base_addr; @@ -962,7 +962,7 @@ /* Given an skb, copy a packet into the ARCnet buffers for later transmission * by arcnet_go_tx. */ -static void arc90xx_prepare_tx(struct device *dev, u_char * hdr, int hdrlen, +static void arc90xx_prepare_tx(struct net_device *dev, u_char * hdr, int hdrlen, char *data, int length, int daddr, int exceptA, int offset) { struct arcnet_local *lp = (struct arcnet_local *) dev->priv; @@ -1053,7 +1053,7 @@ #ifdef MODULE static char devicename[9] = ""; -static struct device thiscard = +static struct net_device thiscard = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, @@ -1064,7 +1064,7 @@ int init_module(void) { - struct device *dev = &thiscard; + struct net_device *dev = &thiscard; if (device) strcpy(dev->name, device); else @@ -1090,7 +1090,7 @@ void cleanup_module(void) { - struct device *dev = &thiscard; + struct net_device *dev = &thiscard; int ioaddr = dev->mem_start; if (dev->start) @@ -1123,7 +1123,7 @@ void __init com90xx_setup(char *str, int *ints) { - struct device *dev; + struct net_device *dev; if (arcnet_num_devs == MAX_ARCNET_DEVS) { printk("com90xx: Too many ARCnet devices registered (max %d).\n", diff -u --recursive --new-file v2.3.13/linux/drivers/net/cops.c linux/drivers/net/cops.c --- v2.3.13/linux/drivers/net/cops.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/cops.c Wed Aug 18 11:36:41 1999 @@ -188,28 +188,28 @@ }; /* Index to functions, as function prototypes. */ -extern int cops_probe (struct device *dev); -static int cops_probe1 (struct device *dev, int ioaddr); +extern int cops_probe (struct net_device *dev); +static int cops_probe1 (struct net_device *dev, int ioaddr); static int cops_irq (int ioaddr, int board); -static int cops_open (struct device *dev); -static int cops_jumpstart (struct device *dev); -static void cops_reset (struct device *dev, int sleep); -static void cops_load (struct device *dev); -static int cops_nodeid (struct device *dev, int nodeid); +static int cops_open (struct net_device *dev); +static int cops_jumpstart (struct net_device *dev); +static void cops_reset (struct net_device *dev, int sleep); +static void cops_load (struct net_device *dev); +static int cops_nodeid (struct net_device *dev, int nodeid); static void cops_interrupt (int irq, void *dev_id, struct pt_regs *regs); static void cops_poll (unsigned long ltdev); -static void cops_rx (struct device *dev); -static int cops_send_packet (struct sk_buff *skb, struct device *dev); -static void set_multicast_list (struct device *dev); -static int cops_hard_header (struct sk_buff *skb, struct device *dev, +static void cops_rx (struct net_device *dev); +static int cops_send_packet (struct sk_buff *skb, struct net_device *dev); +static void set_multicast_list (struct net_device *dev); +static int cops_hard_header (struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); -static int cops_ioctl (struct device *dev, struct ifreq *rq, int cmd); -static int cops_close (struct device *dev); -static struct enet_statistics *cops_get_stats (struct device *dev); +static int cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static int cops_close (struct net_device *dev); +static struct enet_statistics *cops_get_stats (struct net_device *dev); /* @@ -218,7 +218,7 @@ * If dev->base_addr in [1..0x1ff], always return failure. * otherwise go with what we pass in. */ -int __init cops_probe(struct device *dev) +int __init cops_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -252,7 +252,7 @@ * probes on the ISA bus. A good device probes avoids doing writes, and * verifies that the correct device exists and functions. */ -static int __init cops_probe1(struct device *dev, int ioaddr) +static int __init cops_probe1(struct net_device *dev, int ioaddr) { struct cops_local *lp; static unsigned version_printed = 0; @@ -397,7 +397,7 @@ * Open/initialize the board. This is called (in the current kernel) * sometime after booting when the 'ifconfig' program is run. */ -static int cops_open(struct device *dev) +static int cops_open(struct net_device *dev) { struct cops_local *lp = (struct cops_local *)dev->priv; @@ -438,7 +438,7 @@ /* * This allows for a dynamic start/restart of the entire card. */ -static int cops_jumpstart(struct device *dev) +static int cops_jumpstart(struct net_device *dev) { struct cops_local *lp = (struct cops_local *)dev->priv; @@ -472,7 +472,7 @@ /* * Reset the LocalTalk board. */ -static void cops_reset(struct device *dev, int sleep) +static void cops_reset(struct net_device *dev, int sleep) { struct cops_local *lp = (struct cops_local *)dev->priv; int ioaddr=dev->base_addr; @@ -506,7 +506,7 @@ return; } -static void cops_load (struct device *dev) +static void cops_load (struct net_device *dev) { struct ifreq ifr; struct ltfirmware *ltf= (struct ltfirmware *)&ifr.ifr_data; @@ -601,7 +601,7 @@ * address else we can specify 0 as the nodeid and the card * will autoprobe for a nodeid. */ -static int cops_nodeid (struct device *dev, int nodeid) +static int cops_nodeid (struct net_device *dev, int nodeid) { struct cops_local *lp = (struct cops_local *) dev->priv; int ioaddr = dev->base_addr; @@ -678,7 +678,7 @@ int ioaddr, status; int boguscount = 0; - struct device *dev = (struct device *)ltdev; + struct net_device *dev = (struct net_device *)ltdev; del_timer(&cops_timer); @@ -707,7 +707,7 @@ */ static void cops_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct cops_local *lp; int ioaddr, status; int boguscount = 0; @@ -754,7 +754,7 @@ /* * We have a good packet(s), get it/them out of the buffers. */ -static void cops_rx(struct device *dev) +static void cops_rx(struct net_device *dev) { int pkt_len = 0; int rsp_type = 0; @@ -860,7 +860,7 @@ /* * Make the card transmit a LocalTalk packet. */ -static int cops_send_packet(struct sk_buff *skb, struct device *dev) +static int cops_send_packet(struct sk_buff *skb, struct net_device *dev) { struct cops_local *lp = (struct cops_local *)dev->priv; int ioaddr = dev->base_addr; @@ -937,7 +937,7 @@ * Dummy function to keep the Appletalk layer happy. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { if(cops_debug >= 3) printk("%s: set_multicast_list executed\n", dev->name); @@ -947,7 +947,7 @@ * Another Dummy function to keep the Appletalk layer happy. */ -static int cops_hard_header(struct sk_buff *skb, struct device *dev, +static int cops_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { @@ -960,7 +960,7 @@ * System ioctls for the COPS LocalTalk card. */ -static int cops_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int cops_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct cops_local *lp = (struct cops_local *)dev->priv; struct sockaddr_at *sa=(struct sockaddr_at *)&ifr->ifr_addr; @@ -996,7 +996,7 @@ * The inverse routine to cops_open(). */ -static int cops_close(struct device *dev) +static int cops_close(struct net_device *dev) { struct cops_local *lp = (struct cops_local *)dev->priv; @@ -1019,7 +1019,7 @@ * Get the current statistics. * This may be called with the card open or closed. */ -static struct enet_statistics *cops_get_stats(struct device *dev) +static struct enet_statistics *cops_get_stats(struct net_device *dev) { struct cops_local *lp = (struct cops_local *)dev->priv; return &lp->stats; @@ -1028,7 +1028,7 @@ #ifdef MODULE static char lt_name[16]; -static struct device cops0_dev = +static struct net_device cops0_dev = { lt_name, /* device name */ 0, 0, 0, 0, diff -u --recursive --new-file v2.3.13/linux/drivers/net/cosa.c linux/drivers/net/cosa.c --- v2.3.13/linux/drivers/net/cosa.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/cosa.c Wed Aug 18 11:36:41 1999 @@ -274,14 +274,14 @@ /* SPPP/HDLC stuff */ static void sppp_channel_init(struct channel_data *chan); static void sppp_channel_delete(struct channel_data *chan); -static int cosa_sppp_open(struct device *d); -static int cosa_sppp_close(struct device *d); -static int cosa_sppp_tx(struct sk_buff *skb, struct device *d); +static int cosa_sppp_open(struct net_device *d); +static int cosa_sppp_close(struct net_device *d); +static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *d); static char *sppp_setup_rx(struct channel_data *channel, int size); static int sppp_rx_done(struct channel_data *channel); static int sppp_tx_done(struct channel_data *channel, int size); -static int cosa_sppp_ioctl(struct device *dev, struct ifreq *ifr, int cmd); -static struct net_device_stats *cosa_net_stats(struct device *dev); +static int cosa_sppp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static struct net_device_stats *cosa_net_stats(struct net_device *dev); /* Character device */ static void chardev_channel_init(struct channel_data *chan); @@ -568,7 +568,7 @@ static void sppp_channel_init(struct channel_data *chan) { - struct device *d; + struct net_device *d; sppp_attach(&chan->pppdev); d=&chan->pppdev.dev; d->name = chan->name; @@ -597,7 +597,7 @@ } -static int cosa_sppp_open(struct device *d) +static int cosa_sppp_open(struct net_device *d) { struct channel_data *chan = d->priv; int err, flags; @@ -633,7 +633,7 @@ return 0; } -static int cosa_sppp_tx(struct sk_buff *skb, struct device *dev) +static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev) { struct channel_data *chan = dev->priv; @@ -665,7 +665,7 @@ return 0; } -static int cosa_sppp_close(struct device *d) +static int cosa_sppp_close(struct net_device *d) { struct channel_data *chan = d->priv; int flags; @@ -747,7 +747,7 @@ return 1; } -static struct net_device_stats *cosa_net_stats(struct device *dev) +static struct net_device_stats *cosa_net_stats(struct net_device *dev) { struct channel_data *chan = dev->priv; return &chan->stats; @@ -1166,7 +1166,7 @@ return -ENOIOCTLCMD; } -static int cosa_sppp_ioctl(struct device *dev, struct ifreq *ifr, +static int cosa_sppp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { int rv; diff -u --recursive --new-file v2.3.13/linux/drivers/net/cs89x0.c linux/drivers/net/cs89x0.c --- v2.3.13/linux/drivers/net/cs89x0.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/cs89x0.c Wed Aug 18 11:36:41 1999 @@ -113,20 +113,20 @@ /* Index to functions, as function prototypes. */ -extern int cs89x0_probe(struct device *dev); +extern int cs89x0_probe(struct net_device *dev); -static int cs89x0_probe1(struct device *dev, int ioaddr); -static int net_open(struct device *dev); -static int net_send_packet(struct sk_buff *skb, struct device *dev); +static int cs89x0_probe1(struct net_device *dev, int ioaddr); +static int net_open(struct net_device *dev); +static int net_send_packet(struct sk_buff *skb, struct net_device *dev); static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void set_multicast_list(struct device *dev); -static void net_rx(struct device *dev); -static int net_close(struct device *dev); -static struct net_device_stats *net_get_stats(struct device *dev); -static void reset_chip(struct device *dev); -static int get_eeprom_data(struct device *dev, int off, int len, int *buffer); +static void set_multicast_list(struct net_device *dev); +static void net_rx(struct net_device *dev); +static int net_close(struct net_device *dev); +static struct net_device_stats *net_get_stats(struct net_device *dev); +static void reset_chip(struct net_device *dev); +static int get_eeprom_data(struct net_device *dev, int off, int len, int *buffer); static int get_eeprom_cksum(int off, int len, int *buffer); -static int set_mac_address(struct device *dev, void *addr); +static int set_mac_address(struct net_device *dev, void *addr); /* Example routines you must write ;->. */ @@ -146,7 +146,7 @@ {"netcard", cs89x0_probe1, NETCARD_IO_EXTENT, netcard_portlist}; #else int __init -cs89x0_probe(struct device *dev) +cs89x0_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -169,14 +169,14 @@ #endif static int inline -readreg(struct device *dev, int portno) +readreg(struct net_device *dev, int portno) { outw(portno, dev->base_addr + ADD_PORT); return inw(dev->base_addr + DATA_PORT); } static void inline -writereg(struct device *dev, int portno, int value) +writereg(struct net_device *dev, int portno, int value) { outw(portno, dev->base_addr + ADD_PORT); outw(value, dev->base_addr + DATA_PORT); @@ -184,19 +184,19 @@ static int inline -readword(struct device *dev, int portno) +readword(struct net_device *dev, int portno) { return inw(dev->base_addr + portno); } static void inline -writeword(struct device *dev, int portno, int value) +writeword(struct net_device *dev, int portno, int value) { outw(value, dev->base_addr + portno); } static int __init -wait_eeprom_ready(struct device *dev) +wait_eeprom_ready(struct net_device *dev) { int timeout = jiffies; /* check to see if the EEPROM is ready, a timeout is used - @@ -209,7 +209,7 @@ } static int __init -get_eeprom_data(struct device *dev, int off, int len, int *buffer) +get_eeprom_data(struct net_device *dev, int off, int len, int *buffer) { int i; @@ -244,7 +244,7 @@ probes on the ISA bus. A good device probes avoids doing writes, and verifies that the correct device exists and functions. */ -static int __init cs89x0_probe1(struct device *dev, int ioaddr) +static int __init cs89x0_probe1(struct net_device *dev, int ioaddr) { struct net_local *lp; static unsigned version_printed = 0; @@ -391,7 +391,7 @@ } void __init -reset_chip(struct device *dev) +reset_chip(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -421,7 +421,7 @@ static void -control_dc_dc(struct device *dev, int on_not_off) +control_dc_dc(struct net_device *dev, int on_not_off) { struct net_local *lp = (struct net_local *)dev->priv; unsigned int selfcontrol; @@ -442,7 +442,7 @@ } static int -detect_tp(struct device *dev) +detect_tp(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int timenow = jiffies; @@ -487,7 +487,7 @@ /* send a test packet - return true if carrier bits are ok */ static int -send_test_pkt(struct device *dev) +send_test_pkt(struct net_device *dev) { int ioaddr = dev->base_addr; char test_packet[] = { 0,0,0,0,0,0, 0,0,0,0,0,0, @@ -532,7 +532,7 @@ static int -detect_aui(struct device *dev) +detect_aui(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -548,7 +548,7 @@ } static int -detect_bnc(struct device *dev) +detect_bnc(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -565,7 +565,7 @@ static void -write_irq(struct device *dev, int chip_type, int irq) +write_irq(struct net_device *dev, int chip_type, int irq) { int i; @@ -591,7 +591,7 @@ there is non-reboot way to recover if something goes wrong. */ static int -net_open(struct device *dev) +net_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int result = 0; @@ -728,7 +728,7 @@ } static int -net_send_packet(struct sk_buff *skb, struct device *dev) +net_send_packet(struct sk_buff *skb, struct net_device *dev) { if (dev->tbusy) { /* If we get here, some higher level has decided we are broken. @@ -787,7 +787,7 @@ Handle the network interface interrupts. */ static void net_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *lp; int ioaddr, status; @@ -857,7 +857,7 @@ /* We have a good packet(s), get it/them out of the buffers. */ static void -net_rx(struct device *dev) +net_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -904,7 +904,7 @@ /* The inverse routine to net_open(). */ static int -net_close(struct device *dev) +net_close(struct net_device *dev) { writereg(dev, PP_RxCFG, 0); @@ -926,7 +926,7 @@ /* Get the current statistics. This may be called with the card open or closed. */ static struct net_device_stats * -net_get_stats(struct device *dev) +net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -939,7 +939,7 @@ return &lp->stats; } -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -964,7 +964,7 @@ } -static int set_mac_address(struct device *dev, void *addr) +static int set_mac_address(struct net_device *dev, void *addr) { int i; if (dev->start) @@ -983,7 +983,7 @@ #ifdef MODULE static char namespace[16] = ""; -static struct device dev_cs89x0 = { +static struct net_device dev_cs89x0 = { NULL, 0, 0, 0, 0, 0, 0, diff -u --recursive --new-file v2.3.13/linux/drivers/net/cycx_drv.c linux/drivers/net/cycx_drv.c --- v2.3.13/linux/drivers/net/cycx_drv.c Wed Jun 30 13:38:20 1999 +++ linux/drivers/net/cycx_drv.c Thu Aug 12 09:46:13 1999 @@ -57,7 +57,7 @@ #include /* for inb(), outb(), etc. */ #define MOD_VERSION 0 -#define MOD_RELEASE 1 +#define MOD_RELEASE 2 #ifdef MODULE MODULE_AUTHOR("Arnaldo Carvalho de Melo"); @@ -122,7 +122,6 @@ { printk(KERN_INFO "%s v%u.%u %s\n", fullname, MOD_VERSION, MOD_RELEASE, copyright); - printk(KERN_INFO "version=0x%X\n", LINUX_VERSION_CODE); return 0; } /* Module 'remove' entry point. diff -u --recursive --new-file v2.3.13/linux/drivers/net/cycx_main.c linux/drivers/net/cycx_main.c --- v2.3.13/linux/drivers/net/cycx_main.c Wed Jun 2 14:40:22 1999 +++ linux/drivers/net/cycx_main.c Thu Aug 12 09:46:13 1999 @@ -13,12 +13,15 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ +* 1999/08/09 acme removed references to enable_tx_int +* use spinlocks instead of cli/sti in +* cyclomx_set_state * 1999/05/19 acme works directly linked into the kernel * init_waitqueue_head for 2.3.* kernel * 1999/05/18 acme major cleanup (polling not needed), etc -* Aug 28, 1998 Arnaldo minor cleanup (ioctls for firmware deleted) +* 1998/08/28 acme minor cleanup (ioctls for firmware deleted) * queue_task activated -* Aug 08, 1998 Arnaldo Initial version. +* 1998/08/08 acme Initial version. */ #include /* OS configuration options */ @@ -43,7 +46,7 @@ /* Defines & Macros */ #define DRV_VERSION 0 /* version number */ -#define DRV_RELEASE 3 /* release (minor version) number */ +#define DRV_RELEASE 4 /* release (minor version) number */ #define MAX_CARDS 1 /* max number of adapters */ #ifndef CONFIG_CYCLOMX_CARDS /* configurable option */ @@ -118,7 +121,6 @@ wandev->magic = ROUTER_MAGIC; wandev->name = card->devname; wandev->private = card; - wandev->enable_tx_int = 0; wandev->setup = &setup; wandev->shutdown = &shutdown; wandev->ioctl = &ioctl; @@ -239,7 +241,7 @@ /* Protocol-specific initialization */ switch (card->hw.fwid) { -#ifdef CONFIG_CYCLOMX_X25 +#ifdef CONFIG_CYCLOMX_X25 case CFID_X25_2X: err = cyx_init(card, conf); break; #endif default: @@ -254,7 +256,6 @@ return err; } - wandev->critical = 0; return 0; } @@ -280,7 +281,6 @@ cycx_down(&card->hw); printk(KERN_INFO "%s: irq %d being freed!\n", wandev->name,wandev->irq); free_irq(wandev->irq, card); - wandev->critical = 0; return 0; } @@ -306,7 +306,8 @@ static void cycx_isr (int irq, void *dev_id, struct pt_regs *regs) { #define card ((cycx_t*)dev_id) - if (!card || card->wandev.state == WAN_UNCONFIGURED) return; + if (!card || card->wandev.state == WAN_UNCONFIGURED) + return; if (card->in_isr) { printk(KERN_WARNING "%s: interrupt re-entrancy on IRQ %d!\n", @@ -314,7 +315,8 @@ return; } - if (card->isr) card->isr(card); + if (card->isr) + card->isr(card); #undef card } @@ -345,9 +347,9 @@ /* Set WAN device state. */ void cyclomx_set_state (cycx_t *card, int state) { - unsigned long flags; + unsigned long host_cpu_flags; - save_flags(flags); cli(); + spin_lock_irqsave(&card->lock, host_cpu_flags); if (card->wandev.state != state) { switch (state) { @@ -371,7 +373,7 @@ } card->state_tick = jiffies; - restore_flags(flags); + spin_unlock_irqrestore(&card->lock, host_cpu_flags); } /* End */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/cycx_x25.c linux/drivers/net/cycx_x25.c --- v2.3.13/linux/drivers/net/cycx_x25.c Wed Jun 2 14:40:22 1999 +++ linux/drivers/net/cycx_x25.c Wed Aug 18 11:36:41 1999 @@ -11,6 +11,10 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ +* 1999/08/10 acme serialized access to the card thru a spinlock +* in x25_exec +* 1999/08/09 acme removed per channel spinlocks +* removed references to enable_tx_int * 1999/05/28 acme fixed nibble_to_byte, ackvc now properly treated * if_send simplified * 1999/05/25 acme fixed t1, t2, t21 & t23 configuration @@ -70,11 +74,9 @@ /* Defines & Macros */ #define MAX_CMD_RETRY 5 #define X25_CHAN_MTU 2048 /* unfragmented logical channel MTU */ -#define OUT_INTR 1 -#define IN_INTR 0 /* Data Structures */ -/* This is an extention of the 'struct device' we create for each network +/* This is an extention of the 'struct net_device' we create for each network interface to keep the rest of X.25 channel-specific data. */ typedef struct x25_channel { char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */ @@ -84,7 +86,6 @@ s16 lcn; /* logical channel number/conn.req.key*/ u8 link; struct timer_list timer; /* timer used for svc channel disc. */ - spinlock_t lock; u16 protocol; /* ethertype, 0 - multiplexed */ u8 svc; /* 0 - permanent, 1 - switched */ u8 state; /* channel state */ @@ -98,19 +99,19 @@ /* Function Prototypes */ /* WAN link driver entry points. These are called by the WAN router module. */ static int update (wan_device_t *wandev), - new_if (wan_device_t *wandev, struct device *dev,wanif_conf_t *conf), - del_if (wan_device_t *wandev, struct device *dev); + new_if (wan_device_t *wandev, struct net_device *dev,wanif_conf_t *conf), + del_if (wan_device_t *wandev, struct net_device *dev); /* Network device interface */ -static int if_init (struct device *dev), - if_open (struct device *dev), - if_close (struct device *dev), - if_header (struct sk_buff *skb, struct device *dev, +static int if_init (struct net_device *dev), + if_open (struct net_device *dev), + if_close (struct net_device *dev), + if_header (struct sk_buff *skb, struct net_device *dev, u16 type, void *daddr, void *saddr, unsigned len), if_rebuild_hdr (struct sk_buff *skb), - if_send (struct sk_buff *skb, struct device *dev); + if_send (struct sk_buff *skb, struct net_device *dev); -static struct net_device_stats * if_stats (struct device *dev); +static struct net_device_stats * if_stats (struct net_device *dev); /* Interrupt handlers */ static void cyx_isr (cycx_t *card), @@ -132,22 +133,22 @@ x25_disconnect_response (cycx_t *card, u8 link, u8 lcn); /* Miscellaneous functions */ -static int chan_connect (struct device *dev), - chan_send (struct device *dev, struct sk_buff *skb); +static int chan_connect (struct net_device *dev), + chan_send (struct net_device *dev, struct sk_buff *skb); -static void set_chan_state (struct device *dev, u8 state, u8 outside_intr), +static void set_chan_state (struct net_device *dev, u8 state), nibble_to_byte (u8 *s, u8 *d, u8 len, u8 nibble), - reset_timer (struct device *dev), - chan_disc (struct device *dev), - chan_timer (unsigned long data); + reset_timer (struct net_device *dev), + chan_disc (struct net_device *dev), + chan_timer (unsigned long d); static u8 bps_to_speed_code (u32 bps); static u8 log2 (u32 n); static unsigned dec_to_uint (u8 *str, int len); -static struct device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn); -static struct device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte); +static struct net_device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn); +static struct net_device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte); #ifdef CYCLOMX_X25_DEBUG static void hex_dump(char *msg, unsigned char *p, int len); @@ -187,8 +188,8 @@ /* Initialize protocol-specific fields */ card->mbox = card->hw.dpmbase + X25_MBOX_OFFS; - card->u.x.critical = 0; /* critical section flag */ card->u.x.connection_keys = 0; + card->u.x.lock = SPIN_LOCK_UNLOCKED; /* Configure adapter. Here we set resonable defaults, then parse * device configuration structure and set configuration options. @@ -286,7 +287,6 @@ card->wandev.new_if = &new_if; card->wandev.del_if = &del_if; card->wandev.state = WAN_DISCONNECTED; - card->wandev.enable_tx_int = card->irq_dis_if_send_count = 0; return 0; } @@ -315,7 +315,7 @@ * * Return: 0 o.k. * < 0 failure (channel will not be created) */ -static int new_if (wan_device_t *wandev, struct device *dev, wanif_conf_t *conf) +static int new_if (wan_device_t *wandev, struct net_device *dev, wanif_conf_t *conf) { cycx_t *card = wandev->private; x25_channel_t *chan; @@ -338,21 +338,23 @@ chan->rx_skb = NULL; /* only used in svc connected thru crossover cable */ chan->local_addr = NULL; - chan->lock = SPIN_LOCK_UNLOCKED; if (conf->addr[0] == '@') { /* SVC */ - int local_len = strlen(conf->local_addr); + int len = strlen(conf->local_addr); - if (local_len) { - if (local_len > WAN_ADDRESS_SZ) { + if (len) { + if (len > WAN_ADDRESS_SZ) { printk(KERN_ERR "%s: %s local addr too long!\n", wandev->name, chan->name); kfree(chan); return -EINVAL; - } else if ((chan->local_addr = kmalloc(local_len + 1, - GFP_KERNEL)) == NULL) { - kfree(chan); - return ENOMEM; + } else { + chan->local_addr = kmalloc(len + 1, GFP_KERNEL); + + if (!chan->local_addr) { + kfree(chan); + return ENOMEM; + } } strncpy(chan->local_addr, conf->local_addr, @@ -387,6 +389,7 @@ if (err) { if (chan->local_addr) kfree(chan->local_addr); + kfree(chan); return err; } @@ -399,7 +402,7 @@ } /* Delete logical channel. */ -static int del_if (wan_device_t *wandev, struct device *dev) +static int del_if (wan_device_t *wandev, struct net_device *dev) { if (!dev) { printk(KERN_ERR "cycx_x25:del_if:dev == NULL!\n"); @@ -408,6 +411,7 @@ if (dev->priv) { x25_channel_t *chan = dev->priv; + if (chan->svc) { if (chan->local_addr) kfree(chan->local_addr); @@ -415,6 +419,7 @@ if (chan->state == WAN_CONNECTED) del_timer(&chan->timer); } + kfree(chan); dev->priv = NULL; } @@ -428,7 +433,7 @@ * This routine is called only once for each interface, during Linux network * interface registration. Returning anything but zero will fail interface * registration. */ -static int if_init (struct device *dev) +static int if_init (struct net_device *dev) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; @@ -464,7 +469,7 @@ /* Initialize socket buffers */ dev_init_buffers(dev); - set_chan_state(dev, WAN_DISCONNECTED, OUT_INTR); + set_chan_state(dev, WAN_DISCONNECTED); return 0; } @@ -473,7 +478,7 @@ * o if link is disconnected then initiate connection * * Return 0 if O.k. or errno. */ -static int if_open (struct device *dev) +static int if_open (struct net_device *dev) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; @@ -481,37 +486,28 @@ if (dev->start) return -EBUSY; /* only one open is allowed */ - if (test_and_set_bit(0, (void*)&card->wandev.critical)) - return -EAGAIN; - dev->interrupt = 0; dev->tbusy = 0; dev->start = 1; cyclomx_open(card); - card->wandev.critical = 0; return 0; } /* Close network interface. * o reset flags. * o if there's no more open channels then disconnect physical link. */ -static int if_close (struct device *dev) +static int if_close (struct net_device *dev) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; - if (test_and_set_bit(0, (void*)&card->wandev.critical)) - return -EAGAIN; - dev->start = 0; if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING) chan_disc(dev); cyclomx_close(card); - - card->wandev.critical = 0; return 0; } @@ -523,7 +519,7 @@ * set skb->protocol to 0 and discard packet later. * * Return: media header length. */ -static int if_header (struct sk_buff *skb, struct device *dev, +static int if_header (struct sk_buff *skb, struct net_device *dev, u16 type, void *daddr, void *saddr, unsigned len) { skb->protocol = type; @@ -553,7 +549,7 @@ * bottom half" (with interrupts enabled). * 2. Setting tbusy flag will inhibit further transmit requests from the * protocol stack and can be used for flow control with protocol layer. */ -static int if_send (struct sk_buff *skb, struct device *dev) +static int if_send (struct sk_buff *skb, struct net_device *dev) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; @@ -563,10 +559,6 @@ return -EBUSY; } - dev->tbusy = 1; - - reset_timer(dev); - if (!chan->svc) chan->protocol = skb->protocol; @@ -580,13 +572,17 @@ ++chan->ifstats.tx_errors; } else switch (chan->state) { case WAN_DISCONNECTED: - if (chan_connect(dev)) + if (chan_connect(dev)) { + dev->tbusy = 1; return -EBUSY; + } /* fall thru */ case WAN_CONNECTED: + reset_timer(dev); dev->trans_start = jiffies; + dev->tbusy = 1; + if (chan_send(dev, skb)) { - dev->tbusy = 1; return -EBUSY; } break; @@ -601,7 +597,7 @@ /* Get Ethernet-style interface statistics. * Return a pointer to struct net_device_stats */ -static struct net_device_stats *if_stats (struct device *dev) +static struct net_device_stats *if_stats (struct net_device *dev) { x25_channel_t *chan = dev->priv; @@ -612,25 +608,13 @@ /* X.25 Interrupt Service Routine. */ static void cyx_isr (cycx_t *card) { - unsigned long host_cpu_flags; TX25Cmd cmd; u16 z = 0; card->in_isr = 1; card->buff_int_mode_unbusy = 0; - - if (test_and_set_bit(0, (void*)&card->wandev.critical)) { - printk(KERN_INFO "cyx_isr: %s, wandev.critical set to 0x%02X\n", - card->devname, card->wandev.critical); - card->in_isr = 0; - return; - } - - /* For all interrupts set the critical flag to CRITICAL_RX_INTR. - * If the if_send routine is called with this flag set it will set - * the enable transmit flag to 1. (for a delayed interrupt) */ - card->wandev.critical = CRITICAL_IN_ISR; cycx_peek(&card->hw, X25_RXMBOX_OFFS, &cmd, sizeof(cmd)); + switch (cmd.command) { case X25_DATA_INDICATION: rx_intr(card, &cmd); @@ -668,16 +652,7 @@ cycx_poke(&card->hw, 0, &z, sizeof(z)); cycx_poke(&card->hw, X25_RXMBOX_OFFS, &z, sizeof(z)); - - card->wandev.critical = CRITICAL_INTR_HANDLED; - - if (card->wandev.enable_tx_int) - card->wandev.enable_tx_int = 0; - - spin_lock_irqsave(&card->lock, host_cpu_flags); card->in_isr = 0; - card->wandev.critical = 0; - spin_unlock_irqrestore(&card->lock, host_cpu_flags); if (card->buff_int_mode_unbusy) mark_bh(NET_BH); @@ -688,7 +663,7 @@ * o Clear 'tbusy' flag */ static void tx_intr (cycx_t *card, TX25Cmd *cmd) { - struct device *dev; + struct net_device *dev; wan_device_t *wandev = &card->wandev; u8 lcn; @@ -720,7 +695,7 @@ static void rx_intr (cycx_t *card, TX25Cmd *cmd) { wan_device_t *wandev = &card->wandev; - struct device *dev; + struct net_device *dev; x25_channel_t *chan; struct sk_buff *skb; u8 bitm, lcn; @@ -740,11 +715,12 @@ chan = dev->priv; reset_timer(dev); - if (chan->drop_sequence) + if (chan->drop_sequence) { if (!bitm) chan->drop_sequence = 0; else return; + } if ((skb = chan->rx_skb) == NULL) { /* Allocate new socket buffer */ @@ -799,29 +775,30 @@ static void connect_intr (cycx_t *card, TX25Cmd *cmd) { wan_device_t *wandev = &card->wandev; - struct device *dev = NULL; + struct net_device *dev = NULL; x25_channel_t *chan; - u8 data[32], - local[24], + u8 d[32], + loc[24], rem[24]; - u8 lcn, sizelocal, sizerem; + u8 lcn, sizeloc, sizerem; cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn)); - cycx_peek(&card->hw, cmd->buf + 5, &sizelocal, sizeof(sizelocal)); - cycx_peek(&card->hw, cmd->buf + 6, data, cmd->len - 6); + cycx_peek(&card->hw, cmd->buf + 5, &sizeloc, sizeof(sizeloc)); + cycx_peek(&card->hw, cmd->buf + 6, d, cmd->len - 6); - sizerem = sizelocal >> 4; - sizelocal &= 0x0F; + sizerem = sizeloc >> 4; + sizeloc &= 0x0F; - local[0] = rem[0] = '\0'; + loc[0] = rem[0] = '\0'; - if (sizelocal) - nibble_to_byte(data, local, sizelocal, 0); + if (sizeloc) + nibble_to_byte(d, loc, sizeloc, 0); if (sizerem) - nibble_to_byte(data + (sizelocal >> 1), rem, sizerem, sizelocal & 1); + nibble_to_byte(d + (sizeloc >> 1), rem, sizerem, sizeloc & 1); + dprintk(KERN_INFO "connect_intr:lcn=%d, local=%s, remote=%s\n", - lcn, local, rem); + lcn, loc, rem); if ((dev = get_dev_by_dte_addr(wandev, rem)) == NULL) { /* Invalid channel, discard packet */ printk(KERN_INFO "%s: connect not expected: remote %s!\n", @@ -832,14 +809,14 @@ chan = dev->priv; chan->lcn = lcn; x25_connect_response(card, chan); - set_chan_state(dev, WAN_CONNECTED, IN_INTR); + set_chan_state(dev, WAN_CONNECTED); } /* Connect confirm interrupt handler. */ static void connect_confirm_intr (cycx_t *card, TX25Cmd *cmd) { wan_device_t *wandev = &card->wandev; - struct device *dev; + struct net_device *dev; x25_channel_t *chan; u8 lcn, key; @@ -858,14 +835,14 @@ clear_bit(--key, (void*)&card->u.x.connection_keys); chan = dev->priv; chan->lcn = lcn; - set_chan_state(dev, WAN_CONNECTED, IN_INTR); + set_chan_state(dev, WAN_CONNECTED); } /* Disonnect confirm interrupt handler. */ static void disconnect_confirm_intr (cycx_t *card, TX25Cmd *cmd) { wan_device_t *wandev = &card->wandev; - struct device *dev; + struct net_device *dev; u8 lcn; cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn)); @@ -878,22 +855,26 @@ return; } - set_chan_state(dev, WAN_DISCONNECTED, IN_INTR); + set_chan_state(dev, WAN_DISCONNECTED); } /* disconnect interrupt handler. */ static void disconnect_intr (cycx_t *card, TX25Cmd *cmd) { wan_device_t *wandev = &card->wandev; - struct device *dev; + struct net_device *dev; u8 lcn; cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn)); dprintk(KERN_INFO "disconnect_intr:lcn=%d\n", lcn); - x25_disconnect_response(card, 0, lcn); - if ((dev = get_dev_by_lcn(wandev, lcn)) != NULL) - set_chan_state(dev, WAN_DISCONNECTED, IN_INTR); + if ((dev = get_dev_by_lcn(wandev, lcn)) != NULL) { + x25_channel_t *chan = dev->priv; + + x25_disconnect_response(card, chan->link, lcn); + set_chan_state(dev, WAN_DISCONNECTED); + } else + x25_disconnect_response(card, 0, lcn); } /* LOG interrupt handler. */ @@ -960,55 +941,51 @@ printk(KERN_INFO "%s: %s\n", msg, hex); } #endif -/* CYCLOM X Firmware-Specific Functions - * - * Almost all X.25 commands can unexpetedly fail due to so called 'X.25 - * asynchronous events' such as restart, interrupt, incoming call request, - * call clear request, etc. They can't be ignored and have to be dealt with - * immediately. To tackle with this problem we execute each interface command - * in a loop until good return code is received or maximum number of retries - * is reached. Each interface command returns non-zero return code, an - * asynchronous event/error handler x25_error() is called. - */ +/* CYCLOM X Firmware-Specific Functions */ /* Exec x25 command. */ static int x25_exec (cycx_t *card, int command, int link, - void *data1, int len1, void *data2, int len2) + void *d1, int len1, void *d2, int len2) { TX25Cmd c; + unsigned long flags; u32 addr = 0x1200 + 0x2E0 * link + 0x1E2; + u8 retry = MAX_CMD_RETRY; int err = 0; c.command = command; c.link = link; c.len = len1 + len2; - if (test_and_set_bit(0, (void*)&card->u.x.critical)) - return -EAGAIN; + spin_lock_irqsave(&card->u.x.lock, flags); /* write command */ cycx_poke(&card->hw, X25_MBOX_OFFS, &c, sizeof(c) - sizeof(c.buf)); /* write x25 data */ - if (data1) { - cycx_poke(&card->hw, addr, data1, len1); + if (d1) { + cycx_poke(&card->hw, addr, d1, len1); - if (data2) + if (d2) { if (len2 > 254) { u32 addr1 = 0xA00 + 0x400 * link; - cycx_poke(&card->hw, addr + len1, data2, 249); - cycx_poke(&card->hw, addr1, ((u8*) data2) + 249, + cycx_poke(&card->hw, addr + len1, d2, 249); + cycx_poke(&card->hw, addr1, ((u8*) d2) + 249, len2 - 249); } else - cycx_poke(&card->hw, addr + len1, data2, len2); + cycx_poke(&card->hw, addr + len1, d2, len2); + } } /* generate interruption, executing command */ cycx_intr(&card->hw); /* wait till card->mbox == 0 */ - err = cycx_exec(card->mbox); - card->u.x.critical = 0; + do { + err = cycx_exec(card->mbox); + } while (retry-- && err); + + spin_unlock_irqrestore(&card->u.x.lock, flags); return err; } @@ -1110,6 +1087,7 @@ while (len) { *d++ = '0' + (*s >> 4); + if (--len) { *d++ = '0' + (*s & 0x0F); --len; @@ -1125,9 +1103,8 @@ static int x25_place_call (cycx_t *card, x25_channel_t *chan) { int err = 0, - retry = MAX_CMD_RETRY, len; - char data[64], + char d[64], nibble = 0, mylen = chan->local_addr ? strlen(chan->local_addr) : 0, remotelen = strlen(chan->addr); @@ -1143,24 +1120,24 @@ set_bit(key, (void*)&card->u.x.connection_keys); ++key; dprintk(KERN_INFO "%s:x25_place_call:key=%d\n", card->devname, key); - memset(data, 0, sizeof(data)); - data[1] = key; /* user key */ - data[2] = 0x10; - data[4] = 0x0B; - - len = byte_to_nibble(chan->addr, data + 6, &nibble); - len += chan->local_addr ? byte_to_nibble(chan->local_addr, - data + 6 + len, &nibble) : 0; + memset(d, 0, sizeof(d)); + d[1] = key; /* user key */ + d[2] = 0x10; + d[4] = 0x0B; + + len = byte_to_nibble(chan->addr, d + 6, &nibble); + + if (chan->local_addr) + len += byte_to_nibble(chan->local_addr, d + 6 + len, &nibble); + if (nibble) ++len; - data[5] = mylen << 4 | remotelen; - data[6 + len + 1] = 0xCC; /* TCP/IP over X.25, thanx to Daniela :) */ - - do err = x25_exec(card, X25_CONNECT_REQUEST, chan->link, - &data, 7 + len + 1, NULL, 0); - while (err && retry--); - if (err) + d[5] = mylen << 4 | remotelen; + d[6 + len + 1] = 0xCC; /* TCP/IP over X.25, thanx to Daniela :) */ + + if ((err = x25_exec(card, X25_CONNECT_REQUEST, chan->link, + &d, 7 + len + 1, NULL, 0)) != 0) clear_bit(--key, (void*)&card->u.x.connection_keys); else { chan->lcn = -key; @@ -1173,82 +1150,60 @@ /* Place X.25 CONNECT RESPONSE. */ static int x25_connect_response (cycx_t *card, x25_channel_t *chan) { - int err = 0, - retry = MAX_CMD_RETRY; - char data[32]; + u8 d[8]; - memset(data, 0, sizeof(data)); - data[0] = data[3] = chan->lcn; - data[2] = 0x10; - data[4] = 0x0F; - data[7] = 0xCC; /* TCP/IP over X.25, thanx Daniela */ - - do err = x25_exec(card, X25_CONNECT_RESPONSE, chan->link, - &data, 8, NULL, 0); - while (err && retry--); + memset(d, 0, sizeof(d)); + d[0] = d[3] = chan->lcn; + d[2] = 0x10; + d[4] = 0x0F; + d[7] = 0xCC; /* TCP/IP over X.25, thanx Daniela */ - return err; + return x25_exec(card, X25_CONNECT_RESPONSE, chan->link, &d, 8, NULL, 0); } /* Place X.25 DISCONNECT RESPONSE. */ static int x25_disconnect_response (cycx_t *card, u8 link, u8 lcn) { - int err = 0, - retry = MAX_CMD_RETRY; - char data[5]; + char d[5]; - memset(data, 0, sizeof(data)); - data[0] = data[3] = lcn; - data[2] = 0x10; - data[4] = 0x17; - do err = x25_exec(card, X25_DISCONNECT_RESPONSE, link, - &data, 5, NULL, 0); - while (err && retry--); - - return err; + memset(d, 0, sizeof(d)); + d[0] = d[3] = lcn; + d[2] = 0x10; + d[4] = 0x17; + return x25_exec(card, X25_DISCONNECT_RESPONSE, link, &d, 5, NULL, 0); } /* Clear X.25 call. */ static int x25_clear_call (cycx_t *card, u8 link, u8 lcn, u8 cause, u8 diagn) { - int retry = MAX_CMD_RETRY, - err; - u8 data[7]; - - memset(data, 0, sizeof(data)); - data[0] = data[3] = lcn; - data[2] = 0x10; - data[4] = 0x13; - data[5] = cause; - data[6] = diagn; + u8 d[7]; - do err = x25_exec(card, X25_DISCONNECT_REQUEST, link, data, 7, NULL, 0); - while (err && retry--); + memset(d, 0, sizeof(d)); + d[0] = d[3] = lcn; + d[2] = 0x10; + d[4] = 0x13; + d[5] = cause; + d[6] = diagn; - return err; + return x25_exec(card, X25_DISCONNECT_REQUEST, link, d, 7, NULL, 0); } /* Send X.25 data packet. */ static int x25_send (cycx_t *card, u8 link, u8 lcn, u8 bitm, int len, void *buf) { - int err = 0, - retry = MAX_CMD_RETRY; - u8 data[] = "?\xFF\x10??"; - - data[0] = data[3] = lcn; - data[4] = bitm; + u8 d[] = "?\xFF\x10??"; - do err = x25_exec(card, X25_DATA_REQUEST, link, &data, 5, buf, len); - while (err && retry--); + d[0] = d[3] = lcn; + d[4] = bitm; - return err; + return x25_exec(card, X25_DATA_REQUEST, link, &d, 5, buf, len); } /* Miscellaneous */ /* Find network device by its channel number. */ -static struct device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn) +static struct net_device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn) { - struct device *dev = wandev->dev; + struct net_device *dev = wandev->dev; for (; dev; dev = dev->slave) if (((x25_channel_t*)dev->priv)->lcn == lcn) @@ -1257,9 +1212,9 @@ } /* Find network device by its remote dte address. */ -static struct device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte) +static struct net_device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte) { - struct device *dev = wandev->dev; + struct net_device *dev = wandev->dev; for (; dev; dev = dev->slave) if (!strcmp (((x25_channel_t*)dev->priv)->addr, dte)) @@ -1274,7 +1229,7 @@ * Return: 0 connected * >0 connection in progress * <0 failure */ -static int chan_connect (struct device *dev) +static int chan_connect (struct net_device *dev) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; @@ -1286,31 +1241,31 @@ card->devname, chan->addr); if (x25_place_call(card, chan)) return -EIO; - set_chan_state(dev, WAN_CONNECTING, OUT_INTR); + set_chan_state(dev, WAN_CONNECTING); return 1; } else - set_chan_state(dev, WAN_CONNECTED, OUT_INTR); + set_chan_state(dev, WAN_CONNECTED); return 0; } /* Disconnect logical channel. * o if SVC then clear X.25 call */ -static void chan_disc (struct device *dev) +static void chan_disc (struct net_device *dev) { x25_channel_t *chan = dev->priv; if (chan->svc) { x25_clear_call(chan->card, chan->link, chan->lcn, 0, 0); - set_chan_state(dev, WAN_DISCONNECTING, OUT_INTR); + set_chan_state(dev, WAN_DISCONNECTING); } else - set_chan_state(dev, WAN_DISCONNECTED, OUT_INTR); + set_chan_state(dev, WAN_DISCONNECTED); } /* Called by kernel timer */ -static void chan_timer (unsigned long data) +static void chan_timer (unsigned long d) { - struct device *dev = (struct device*) data; + struct net_device *dev = (struct net_device*) d; x25_channel_t *chan = dev->priv; switch (chan->state) { @@ -1325,16 +1280,13 @@ } /* Set logical channel state. */ -static void set_chan_state (struct device *dev, u8 state, u8 outside_intr) +static void set_chan_state (struct net_device *dev, u8 state) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; u32 flags = 0; - if (outside_intr) - spin_lock(&card->lock); - else - spin_lock_irqsave(&card->lock, flags); + spin_lock_irqsave(&card->lock, flags); if (chan->state != state) { if (chan->svc && chan->state == WAN_CONNECTED) @@ -1370,16 +1322,14 @@ *(unsigned short*)dev->dev_addr = 0; chan->lcn = 0; } + dev->tbusy = 0; break; } chan->state = state; } - if (outside_intr) - spin_unlock(&card->lock); - else - spin_unlock_irqrestore(&card->lock, flags); + spin_unlock_irqrestore(&card->lock, flags); } /* Send packet on a logical channel. @@ -1395,7 +1345,7 @@ * the packet into 'complete sequence' using M-bit. * 2. When transmission is complete, an event notification should be issued * to the router. */ -static int chan_send (struct device *dev, struct sk_buff *skb) +static int chan_send (struct net_device *dev, struct sk_buff *skb) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; @@ -1468,7 +1418,7 @@ return val; } -static void reset_timer(struct device *dev) +static void reset_timer(struct net_device *dev) { x25_channel_t *chan = dev->priv; @@ -1520,7 +1470,7 @@ static void x25_dump_devs(wan_device_t *wandev) { - struct device *dev = wandev->dev; + struct net_device *dev = wandev->dev; printk (KERN_INFO "x25 dev states\n"); printk (KERN_INFO "name: addr: tbusy:\n"); diff -u --recursive --new-file v2.3.13/linux/drivers/net/daynaport.c linux/drivers/net/daynaport.c --- v2.3.13/linux/drivers/net/daynaport.c Thu Dec 17 09:04:49 1998 +++ linux/drivers/net/daynaport.c Wed Aug 18 11:36:41 1999 @@ -37,33 +37,33 @@ #include #include "8390.h" -int ns8390_probe1(struct device *dev, int word16, char *name, int id, int prom); +int ns8390_probe1(struct net_device *dev, int word16, char *name, int id, int prom); -static int ns8390_open(struct device *dev); -static void ns8390_no_reset(struct device *dev); -static int ns8390_close_card(struct device *dev); +static int ns8390_open(struct net_device *dev); +static void ns8390_no_reset(struct net_device *dev); +static int ns8390_close_card(struct net_device *dev); -static void interlan_reset(struct device *dev); +static void interlan_reset(struct net_device *dev); -static void dayna_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void dayna_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void dayna_block_input(struct device *dev, int count, +static void dayna_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void dayna_block_output(struct device *dev, int count, +static void dayna_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); -static void sane_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void sane_block_input(struct device *dev, int count, +static void sane_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void sane_block_output(struct device *dev, int count, +static void sane_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); -static void slow_sane_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void slow_sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void slow_sane_block_input(struct device *dev, int count, +static void slow_sane_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void slow_sane_block_output(struct device *dev, int count, +static void slow_sane_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); @@ -199,7 +199,7 @@ int ns8390_probe(struct nubus_device_specifier *d, int slot, struct nubus_type *match) { - struct device *dev; + struct net_device *dev; volatile unsigned short *i; volatile unsigned char *p; int plen; @@ -336,7 +336,7 @@ return -ENODEV; } -int ns8390_probe1(struct device *dev, int word16, char *model_name, int type, int promoff) +int ns8390_probe1(struct net_device *dev, int word16, char *model_name, int type, int promoff) { static unsigned version_printed = 0; @@ -469,14 +469,14 @@ return 0; } -static int ns8390_open(struct device *dev) +static int ns8390_open(struct net_device *dev) { ei_open(dev); MOD_INC_USE_COUNT; return 0; } -static void ns8390_no_reset(struct device *dev) +static void ns8390_no_reset(struct net_device *dev) { if (ei_debug > 1) printk("Need to reset the NS8390 t=%lu...", jiffies); @@ -485,7 +485,7 @@ return; } -static int ns8390_close_card(struct device *dev) +static int ns8390_close_card(struct net_device *dev) { if (ei_debug > 1) printk("%s: Shutting down ethercard.\n", dev->name); @@ -504,7 +504,7 @@ * Interlan Specific Code Starts Here */ -static void interlan_reset(struct device *dev) +static void interlan_reset(struct net_device *dev) { unsigned char *target=nubus_slot_addr(dev->irq); if (ei_debug > 1) @@ -531,7 +531,7 @@ The only complications are that the ring buffer wraps. */ -static void dayna_cpu_memcpy(struct device *dev, void *to, int from, int count) +static void dayna_cpu_memcpy(struct net_device *dev, void *to, int from, int count) { volatile unsigned short *ptr; unsigned short *target=to; @@ -554,7 +554,7 @@ } } -static void cpu_dayna_memcpy(struct device *dev, int to, const void *from, int count) +static void cpu_dayna_memcpy(struct net_device *dev, int to, const void *from, int count) { volatile unsigned short *ptr; const unsigned short *src=from; @@ -577,7 +577,7 @@ } } -static void dayna_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +static void dayna_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = (ring_page - WD_START_PG)<<8; dayna_cpu_memcpy(dev, (void *)hdr, hdr_start, 4); @@ -585,7 +585,7 @@ hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8); } -static void dayna_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +static void dayna_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned long xfer_base = ring_offset - (WD_START_PG<<8); unsigned long xfer_start = xfer_base+dev->mem_start; @@ -610,7 +610,7 @@ } } -static void dayna_block_output(struct device *dev, int count, const unsigned char *buf, +static void dayna_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { long shmem = (start_page - WD_START_PG)<<8; @@ -623,7 +623,7 @@ */ -static void sane_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +static void sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = (ring_page - WD_START_PG)<<8; memcpy((void *)hdr, (char *)dev->mem_start+hdr_start, 4); @@ -631,7 +631,7 @@ hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8); } -static void sane_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +static void sane_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned long xfer_base = ring_offset - (WD_START_PG<<8); unsigned long xfer_start = xfer_base+dev->mem_start; @@ -652,7 +652,7 @@ } -static void sane_block_output(struct device *dev, int count, const unsigned char *buf, +static void sane_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { long shmem = (start_page - WD_START_PG)<<8; @@ -684,7 +684,7 @@ *to++=*from++; } -static void slow_sane_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +static void slow_sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = (ring_page - WD_START_PG)<<8; word_memcpy_fromcard((void *)hdr, (char *)dev->mem_start+hdr_start, 4); @@ -692,7 +692,7 @@ hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8); } -static void slow_sane_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +static void slow_sane_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned long xfer_base = ring_offset - (WD_START_PG<<8); unsigned long xfer_start = xfer_base+dev->mem_start; @@ -712,7 +712,7 @@ } } -static void slow_sane_block_output(struct device *dev, int count, const unsigned char *buf, +static void slow_sane_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { long shmem = (start_page - WD_START_PG)<<8; diff -u --recursive --new-file v2.3.13/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c --- v2.3.13/linux/drivers/net/de4x5.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/de4x5.c Wed Aug 18 11:36:41 1999 @@ -826,7 +826,7 @@ struct sk_buff *skb; /* Save the (re-ordered) skb's */ } cache; struct de4x5_srom srom; /* A copy of the SROM */ - struct device *next_module; /* Link to the next module */ + struct net_device *next_module; /* Link to the next module */ int rx_ovf; /* Check for 'RX overflow' tag */ int useSROM; /* For non-DEC card use SROM */ int useMII; /* Infoblock using the MII */ @@ -839,7 +839,7 @@ int infoleaf_offset; /* SROM infoleaf for controller */ s32 infoblock_csr6; /* csr6 value in SROM infoblock */ int infoblock_media; /* infoblock media */ - int (*infoleaf_fn)(struct device *); /* Pointer to infoleaf function */ + int (*infoleaf_fn)(struct net_device *); /* Pointer to infoleaf function */ u_char *rst; /* Pointer to Type 5 reset info */ u_char ibn; /* Infoblock number */ struct parameters params; /* Command line/ #defined params */ @@ -895,63 +895,63 @@ /* ** Public Functions */ -static int de4x5_open(struct device *dev); -static int de4x5_queue_pkt(struct sk_buff *skb, struct device *dev); +static int de4x5_open(struct net_device *dev); +static int de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev); static void de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int de4x5_close(struct device *dev); -static struct net_device_stats *de4x5_get_stats(struct device *dev); -static void de4x5_local_stats(struct device *dev, char *buf, int pkt_len); -static void set_multicast_list(struct device *dev); -static int de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd); +static int de4x5_close(struct net_device *dev); +static struct net_device_stats *de4x5_get_stats(struct net_device *dev); +static void de4x5_local_stats(struct net_device *dev, char *buf, int pkt_len); +static void set_multicast_list(struct net_device *dev); +static int de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); /* ** Private functions */ -static int de4x5_hw_init(struct device *dev, u_long iobase); -static int de4x5_init(struct device *dev); -static int de4x5_sw_reset(struct device *dev); -static int de4x5_rx(struct device *dev); -static int de4x5_tx(struct device *dev); -static int de4x5_ast(struct device *dev); -static int de4x5_txur(struct device *dev); -static int de4x5_rx_ovfc(struct device *dev); +static int de4x5_hw_init(struct net_device *dev, u_long iobase); +static int de4x5_init(struct net_device *dev); +static int de4x5_sw_reset(struct net_device *dev); +static int de4x5_rx(struct net_device *dev); +static int de4x5_tx(struct net_device *dev); +static int de4x5_ast(struct net_device *dev); +static int de4x5_txur(struct net_device *dev); +static int de4x5_rx_ovfc(struct net_device *dev); -static int autoconf_media(struct device *dev); -static void create_packet(struct device *dev, char *frame, int len); +static int autoconf_media(struct net_device *dev); +static void create_packet(struct net_device *dev, char *frame, int len); static void de4x5_us_delay(u32 usec); static void de4x5_ms_delay(u32 msec); -static void load_packet(struct device *dev, char *buf, u32 flags, struct sk_buff *skb); -static int dc21040_autoconf(struct device *dev); -static int dc21041_autoconf(struct device *dev); -static int dc21140m_autoconf(struct device *dev); -static int dc2114x_autoconf(struct device *dev); -static int srom_autoconf(struct device *dev); -static int de4x5_suspect_state(struct device *dev, int timeout, int prev_state, int (*fn)(struct device *, int), int (*asfn)(struct device *)); -static int dc21040_state(struct device *dev, int csr13, int csr14, int csr15, int timeout, int next_state, int suspect_state, int (*fn)(struct device *, int)); -static int test_media(struct device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec); -static int test_for_100Mb(struct device *dev, int msec); -static int wait_for_link(struct device *dev); -static int test_mii_reg(struct device *dev, int reg, int mask, int pol, long msec); -static int is_spd_100(struct device *dev); -static int is_100_up(struct device *dev); -static int is_10_up(struct device *dev); -static int is_anc_capable(struct device *dev); -static int ping_media(struct device *dev, int msec); -static struct sk_buff *de4x5_alloc_rx_buff(struct device *dev, int index, int len); -static void de4x5_free_rx_buffs(struct device *dev); -static void de4x5_free_tx_buffs(struct device *dev); -static void de4x5_save_skbs(struct device *dev); -static void de4x5_rst_desc_ring(struct device *dev); -static void de4x5_cache_state(struct device *dev, int flag); -static void de4x5_put_cache(struct device *dev, struct sk_buff *skb); -static void de4x5_putb_cache(struct device *dev, struct sk_buff *skb); -static struct sk_buff *de4x5_get_cache(struct device *dev); -static void de4x5_setup_intr(struct device *dev); -static void de4x5_init_connection(struct device *dev); -static int de4x5_reset_phy(struct device *dev); -static void reset_init_sia(struct device *dev, s32 sicr, s32 strr, s32 sigr); -static int test_ans(struct device *dev, s32 irqs, s32 irq_mask, s32 msec); -static int test_tp(struct device *dev, s32 msec); +static void load_packet(struct net_device *dev, char *buf, u32 flags, struct sk_buff *skb); +static int dc21040_autoconf(struct net_device *dev); +static int dc21041_autoconf(struct net_device *dev); +static int dc21140m_autoconf(struct net_device *dev); +static int dc2114x_autoconf(struct net_device *dev); +static int srom_autoconf(struct net_device *dev); +static int de4x5_suspect_state(struct net_device *dev, int timeout, int prev_state, int (*fn)(struct net_device *, int), int (*asfn)(struct net_device *)); +static int dc21040_state(struct net_device *dev, int csr13, int csr14, int csr15, int timeout, int next_state, int suspect_state, int (*fn)(struct net_device *, int)); +static int test_media(struct net_device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec); +static int test_for_100Mb(struct net_device *dev, int msec); +static int wait_for_link(struct net_device *dev); +static int test_mii_reg(struct net_device *dev, int reg, int mask, int pol, long msec); +static int is_spd_100(struct net_device *dev); +static int is_100_up(struct net_device *dev); +static int is_10_up(struct net_device *dev); +static int is_anc_capable(struct net_device *dev); +static int ping_media(struct net_device *dev, int msec); +static struct sk_buff *de4x5_alloc_rx_buff(struct net_device *dev, int index, int len); +static void de4x5_free_rx_buffs(struct net_device *dev); +static void de4x5_free_tx_buffs(struct net_device *dev); +static void de4x5_save_skbs(struct net_device *dev); +static void de4x5_rst_desc_ring(struct net_device *dev); +static void de4x5_cache_state(struct net_device *dev, int flag); +static void de4x5_put_cache(struct net_device *dev, struct sk_buff *skb); +static void de4x5_putb_cache(struct net_device *dev, struct sk_buff *skb); +static struct sk_buff *de4x5_get_cache(struct net_device *dev); +static void de4x5_setup_intr(struct net_device *dev); +static void de4x5_init_connection(struct net_device *dev); +static int de4x5_reset_phy(struct net_device *dev); +static void reset_init_sia(struct net_device *dev, s32 sicr, s32 strr, s32 sigr); +static int test_ans(struct net_device *dev, s32 irqs, s32 irq_mask, s32 msec); +static int test_tp(struct net_device *dev, s32 msec); static int EISA_signature(char *name, s32 eisa_id); static int PCI_signature(char *name, struct bus_type *lp); static void DevicePresent(u_long iobase); @@ -965,10 +965,10 @@ /*static void srom_busy(u_int command, u_long address);*/ static void sendto_srom(u_int command, u_long addr); static int getfrom_srom(u_long addr); -static int srom_map_media(struct device *dev); -static int srom_infoleaf_info(struct device *dev); -static void srom_init(struct device *dev); -static void srom_exec(struct device *dev, u_char *p); +static int srom_map_media(struct net_device *dev); +static int srom_infoleaf_info(struct net_device *dev); +static void srom_init(struct net_device *dev); +static void srom_exec(struct net_device *dev, u_char *p); static int mii_rd(u_char phyreg, u_char phyaddr, u_long ioaddr); static void mii_wr(int data, u_char phyreg, u_char phyaddr, u_long ioaddr); static int mii_rdata(u_long ioaddr); @@ -979,51 +979,51 @@ static void sendto_mii(u32 command, int data, u_long ioaddr); static int getfrom_mii(u32 command, u_long ioaddr); static int mii_get_oui(u_char phyaddr, u_long ioaddr); -static int mii_get_phy(struct device *dev); -static void SetMulticastFilter(struct device *dev); -static int get_hw_addr(struct device *dev); -static void srom_repair(struct device *dev, int card); -static int test_bad_enet(struct device *dev, int status); +static int mii_get_phy(struct net_device *dev); +static void SetMulticastFilter(struct net_device *dev); +static int get_hw_addr(struct net_device *dev); +static void srom_repair(struct net_device *dev, int card); +static int test_bad_enet(struct net_device *dev, int status); static int an_exception(struct bus_type *lp); #if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__) -static void eisa_probe(struct device *dev, u_long iobase); +static void eisa_probe(struct net_device *dev, u_long iobase); #endif -static void pci_probe(struct device *dev, u_long iobase); +static void pci_probe(struct net_device *dev, u_long iobase); static void srom_search(struct pci_dev *pdev); -static char *build_setup_frame(struct device *dev, int mode); -static void disable_ast(struct device *dev); -static void enable_ast(struct device *dev, u32 time_out); -static long de4x5_switch_mac_port(struct device *dev); -static int gep_rd(struct device *dev); -static void gep_wr(s32 data, struct device *dev); -static void timeout(struct device *dev, void (*fn)(u_long data), u_long data, u_long msec); -static void yawn(struct device *dev, int state); -static void link_modules(struct device *dev, struct device *tmp); -static void de4x5_parse_params(struct device *dev); -static void de4x5_dbg_open(struct device *dev); -static void de4x5_dbg_mii(struct device *dev, int k); -static void de4x5_dbg_media(struct device *dev); +static char *build_setup_frame(struct net_device *dev, int mode); +static void disable_ast(struct net_device *dev); +static void enable_ast(struct net_device *dev, u32 time_out); +static long de4x5_switch_mac_port(struct net_device *dev); +static int gep_rd(struct net_device *dev); +static void gep_wr(s32 data, struct net_device *dev); +static void timeout(struct net_device *dev, void (*fn)(u_long data), u_long data, u_long msec); +static void yawn(struct net_device *dev, int state); +static void link_modules(struct net_device *dev, struct net_device *tmp); +static void de4x5_parse_params(struct net_device *dev); +static void de4x5_dbg_open(struct net_device *dev); +static void de4x5_dbg_mii(struct net_device *dev, int k); +static void de4x5_dbg_media(struct net_device *dev); static void de4x5_dbg_srom(struct de4x5_srom *p); static void de4x5_dbg_rx(struct sk_buff *skb, int len); static int de4x5_strncmp(char *a, char *b, int n); -static int dc21041_infoleaf(struct device *dev); -static int dc21140_infoleaf(struct device *dev); -static int dc21142_infoleaf(struct device *dev); -static int dc21143_infoleaf(struct device *dev); -static int type0_infoblock(struct device *dev, u_char count, u_char *p); -static int type1_infoblock(struct device *dev, u_char count, u_char *p); -static int type2_infoblock(struct device *dev, u_char count, u_char *p); -static int type3_infoblock(struct device *dev, u_char count, u_char *p); -static int type4_infoblock(struct device *dev, u_char count, u_char *p); -static int type5_infoblock(struct device *dev, u_char count, u_char *p); -static int compact_infoblock(struct device *dev, u_char count, u_char *p); +static int dc21041_infoleaf(struct net_device *dev); +static int dc21140_infoleaf(struct net_device *dev); +static int dc21142_infoleaf(struct net_device *dev); +static int dc21143_infoleaf(struct net_device *dev); +static int type0_infoblock(struct net_device *dev, u_char count, u_char *p); +static int type1_infoblock(struct net_device *dev, u_char count, u_char *p); +static int type2_infoblock(struct net_device *dev, u_char count, u_char *p); +static int type3_infoblock(struct net_device *dev, u_char count, u_char *p); +static int type4_infoblock(struct net_device *dev, u_char count, u_char *p); +static int type5_infoblock(struct net_device *dev, u_char count, u_char *p); +static int compact_infoblock(struct net_device *dev, u_char count, u_char *p); #ifdef MODULE int init_module(void); void cleanup_module(void); -static struct device *unlink_modules(struct device *p); -static struct device *insert_device(struct device *dev, u_long iobase, - int (*init)(struct device *)); +static struct net_device *unlink_modules(struct net_device *p); +static struct net_device *insert_device(struct net_device *dev, u_long iobase, + int (*init)(struct net_device *)); static int count_adapters(void); static int loading_module = 1; MODULE_PARM(de4x5_debug, "i"); @@ -1046,7 +1046,7 @@ static int num_de4x5s = 0; static int cfrv = 0, useSROM = 0; static int lastPCI = -1; -static struct device *lastModule = NULL; +static struct net_device *lastModule = NULL; static struct pci_dev *pdev = NULL; /* @@ -1054,7 +1054,7 @@ */ struct InfoLeaf { int chipset; - int (*fn)(struct device *); + int (*fn)(struct net_device *); }; static struct InfoLeaf infoleaf_array[] = { {DC21041, dc21041_infoleaf}, @@ -1067,7 +1067,7 @@ /* ** List the SROM info block functions */ -static int (*dc_infoblock[])(struct device *dev, u_char, u_char *) = { +static int (*dc_infoblock[])(struct net_device *dev, u_char, u_char *) = { type0_infoblock, type1_infoblock, type2_infoblock, @@ -1107,7 +1107,7 @@ ** more info. */ int __init -de4x5_probe(struct device *dev) +de4x5_probe(struct net_device *dev) { u_long iobase = dev->base_addr; @@ -1122,7 +1122,7 @@ } static int __init -de4x5_hw_init(struct device *dev, u_long iobase) +de4x5_hw_init(struct net_device *dev, u_long iobase) { struct bus_type *lp = &bus; int i, status=0; @@ -1339,7 +1339,7 @@ static int -de4x5_open(struct device *dev) +de4x5_open(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1419,7 +1419,7 @@ ** ttcp source). */ static int -de4x5_init(struct device *dev) +de4x5_init(struct net_device *dev) { /* Lock out other processes whilst setting up the hardware */ test_and_set_bit(0, (void *)&dev->tbusy); @@ -1433,7 +1433,7 @@ } static int -de4x5_sw_reset(struct device *dev) +de4x5_sw_reset(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1510,7 +1510,7 @@ ** Writes a socket buffer address to the next available transmit descriptor. */ static int -de4x5_queue_pkt(struct sk_buff *skb, struct device *dev) +de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1590,7 +1590,7 @@ static void de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct de4x5_private *lp; s32 imr, omr, sts, limit; u_long iobase; @@ -1654,7 +1654,7 @@ } static int -de4x5_rx(struct device *dev) +de4x5_rx(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1733,7 +1733,7 @@ ** Buffer sent - check for TX buffer errors. */ static int -de4x5_tx(struct device *dev) +de4x5_tx(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1784,7 +1784,7 @@ } static int -de4x5_ast(struct device *dev) +de4x5_ast(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int next_tick = DE4X5_AUTOSENSE_MS; @@ -1807,7 +1807,7 @@ } static int -de4x5_txur(struct device *dev) +de4x5_txur(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1830,7 +1830,7 @@ } static int -de4x5_rx_ovfc(struct device *dev) +de4x5_rx_ovfc(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1851,7 +1851,7 @@ } static int -de4x5_close(struct device *dev) +de4x5_close(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1889,7 +1889,7 @@ } static struct net_device_stats * -de4x5_get_stats(struct device *dev) +de4x5_get_stats(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1900,7 +1900,7 @@ } static void -de4x5_local_stats(struct device *dev, char *buf, int pkt_len) +de4x5_local_stats(struct net_device *dev, char *buf, int pkt_len) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int i; @@ -1939,7 +1939,7 @@ ** the descriptor register is read only to the hardware. */ static void -load_packet(struct device *dev, char *buf, u32 flags, struct sk_buff *skb) +load_packet(struct net_device *dev, char *buf, u32 flags, struct sk_buff *skb) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int entry = (lp->tx_new ? lp->tx_new-1 : lp->txRingSize-1); @@ -1961,7 +1961,7 @@ ** Set or clear the multicast filter for this adaptor. */ static void -set_multicast_list(struct device *dev) +set_multicast_list(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -1993,7 +1993,7 @@ ** Little endian crc one liner from Matt Thomas, DEC. */ static void -SetMulticastFilter(struct device *dev) +SetMulticastFilter(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; struct dev_mc_list *dmi=dev->mc_list; @@ -2055,7 +2055,7 @@ ** the motherboard. Upto 15 EISA devices are supported. */ static void __init -eisa_probe(struct device *dev, u_long ioaddr) +eisa_probe(struct net_device *dev, u_long ioaddr) { int i, maxSlots, status, device; u_char irq; @@ -2137,7 +2137,7 @@ #define PCI_LAST_DEV 32 static void __init -pci_probe(struct device *dev, u_long ioaddr) +pci_probe(struct net_device *dev, u_long ioaddr) { u_char pb, pbus, dev_num, dnum, timer; u_short vendor, index, status; @@ -2308,9 +2308,9 @@ } static void __init -link_modules(struct device *dev, struct device *tmp) +link_modules(struct net_device *dev, struct net_device *tmp) { - struct device *p=dev; + struct net_device *p=dev; if (p) { while (((struct de4x5_private *)(p->priv))->next_module) { @@ -2335,7 +2335,7 @@ ** sneaky and changed the port on us. */ static int -autoconf_media(struct device *dev) +autoconf_media(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -2376,7 +2376,7 @@ ** timeouts don't effectively duplicate packets on the network. */ static int -dc21040_autoconf(struct device *dev) +dc21040_autoconf(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -2447,9 +2447,9 @@ } static int -dc21040_state(struct device *dev, int csr13, int csr14, int csr15, int timeout, +dc21040_state(struct net_device *dev, int csr13, int csr14, int csr15, int timeout, int next_state, int suspect_state, - int (*fn)(struct device *, int)) + int (*fn)(struct net_device *, int)) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int next_tick = DE4X5_AUTOSENSE_MS; @@ -2486,9 +2486,9 @@ } static int -de4x5_suspect_state(struct device *dev, int timeout, int prev_state, - int (*fn)(struct device *, int), - int (*asfn)(struct device *)) +de4x5_suspect_state(struct net_device *dev, int timeout, int prev_state, + int (*fn)(struct net_device *, int), + int (*asfn)(struct net_device *)) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int next_tick = DE4X5_AUTOSENSE_MS; @@ -2530,7 +2530,7 @@ ** when the media is found. */ static int -dc21041_autoconf(struct device *dev) +dc21041_autoconf(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -2732,7 +2732,7 @@ ** register, except at the first power up negotiation. */ static int -dc21140m_autoconf(struct device *dev) +dc21140m_autoconf(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int ana, anlpa, cap, cr, slnk, sr; @@ -2916,7 +2916,7 @@ ** Only _10Mb and _100Mb are tested here. */ static int -dc2114x_autoconf(struct device *dev) +dc2114x_autoconf(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3167,7 +3167,7 @@ } static int -srom_autoconf(struct device *dev) +srom_autoconf(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; @@ -3180,7 +3180,7 @@ ** The early return avoids a media state / SROM media space clash. */ static int -srom_map_media(struct device *dev) +srom_map_media(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; @@ -3244,7 +3244,7 @@ } static void -de4x5_init_connection(struct device *dev) +de4x5_init_connection(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3273,7 +3273,7 @@ ** on the signal pin use. Do a double reset to ensure a reset. */ static int -de4x5_reset_phy(struct device *dev) +de4x5_reset_phy(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3307,7 +3307,7 @@ } static int -test_media(struct device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec) +test_media(struct net_device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3345,7 +3345,7 @@ } static int -test_tp(struct device *dev, s32 msec) +test_tp(struct net_device *dev, s32 msec) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3374,7 +3374,7 @@ #define SAMPLE_INTERVAL 500 /* ms */ #define SAMPLE_DELAY 2000 /* ms */ static int -test_for_100Mb(struct device *dev, int msec) +test_for_100Mb(struct net_device *dev, int msec) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int gep = 0, ret = ((lp->chipset & ~0x00ff)==DC2114x? -1 :GEP_SLNK); @@ -3405,7 +3405,7 @@ } static int -wait_for_link(struct device *dev) +wait_for_link(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; @@ -3427,7 +3427,7 @@ ** */ static int -test_mii_reg(struct device *dev, int reg, int mask, int pol, long msec) +test_mii_reg(struct net_device *dev, int reg, int mask, int pol, long msec) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int test; @@ -3451,7 +3451,7 @@ } static int -is_spd_100(struct device *dev) +is_spd_100(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3475,7 +3475,7 @@ } static int -is_100_up(struct device *dev) +is_100_up(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3496,7 +3496,7 @@ } static int -is_10_up(struct device *dev) +is_10_up(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3519,7 +3519,7 @@ } static int -is_anc_capable(struct device *dev) +is_anc_capable(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3538,7 +3538,7 @@ ** media is bad or unconnected. */ static int -ping_media(struct device *dev, int msec) +ping_media(struct net_device *dev, int msec) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3579,7 +3579,7 @@ ** into which the packet is copied. */ static struct sk_buff * -de4x5_alloc_rx_buff(struct device *dev, int index, int len) +de4x5_alloc_rx_buff(struct net_device *dev, int index, int len) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; struct sk_buff *p; @@ -3630,7 +3630,7 @@ } static void -de4x5_free_rx_buffs(struct device *dev) +de4x5_free_rx_buffs(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int i; @@ -3647,7 +3647,7 @@ } static void -de4x5_free_tx_buffs(struct device *dev) +de4x5_free_tx_buffs(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int i; @@ -3676,7 +3676,7 @@ ** packet meaningful. */ static void -de4x5_save_skbs(struct device *dev) +de4x5_save_skbs(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3697,7 +3697,7 @@ } static void -de4x5_rst_desc_ring(struct device *dev) +de4x5_rst_desc_ring(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3729,7 +3729,7 @@ } static void -de4x5_cache_state(struct device *dev, int flag) +de4x5_cache_state(struct net_device *dev, int flag) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3759,7 +3759,7 @@ } static void -de4x5_put_cache(struct device *dev, struct sk_buff *skb) +de4x5_put_cache(struct net_device *dev, struct sk_buff *skb) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; struct sk_buff *p; @@ -3776,7 +3776,7 @@ } static void -de4x5_putb_cache(struct device *dev, struct sk_buff *skb) +de4x5_putb_cache(struct net_device *dev, struct sk_buff *skb) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; struct sk_buff *p = lp->cache.skb; @@ -3788,7 +3788,7 @@ } static struct sk_buff * -de4x5_get_cache(struct device *dev) +de4x5_get_cache(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; struct sk_buff *p = lp->cache.skb; @@ -3806,7 +3806,7 @@ ** is received and the auto-negotiation status is NWAY OK. */ static int -test_ans(struct device *dev, s32 irqs, s32 irq_mask, s32 msec) +test_ans(struct net_device *dev, s32 irqs, s32 irq_mask, s32 msec) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3834,7 +3834,7 @@ } static void -de4x5_setup_intr(struct device *dev) +de4x5_setup_intr(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3855,7 +3855,7 @@ ** */ static void -reset_init_sia(struct device *dev, s32 csr13, s32 csr14, s32 csr15) +reset_init_sia(struct net_device *dev, s32 csr13, s32 csr14, s32 csr15) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -3889,7 +3889,7 @@ ** Create a loopback ethernet packet */ static void -create_packet(struct device *dev, char *frame, int len) +create_packet(struct net_device *dev, char *frame, int len) { int i; char *buf = frame; @@ -4098,7 +4098,7 @@ ** as the first three are invariant - assigned to an organisation. */ static int -get_hw_addr(struct device *dev) +get_hw_addr(struct net_device *dev) { u_long iobase = dev->base_addr; int broken, i, k, tmp, status = 0; @@ -4212,7 +4212,7 @@ } static void -srom_repair(struct device *dev, int card) +srom_repair(struct net_device *dev, int card) { struct bus_type *lp = &bus; @@ -4233,7 +4233,7 @@ ** to be true so far (2 for 2). */ static int -test_bad_enet(struct device *dev, int status) +test_bad_enet(struct net_device *dev, int status) { struct bus_type *lp = &bus; int i, tmp; @@ -4387,7 +4387,7 @@ } static int -srom_infoleaf_info(struct device *dev) +srom_infoleaf_info(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int i, count; @@ -4435,7 +4435,7 @@ ** will follow the discovery process from MII address 1-31 then 0. */ static void -srom_init(struct device *dev) +srom_init(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char *p = (u_char *)&lp->srom + lp->infoleaf_offset; @@ -4480,7 +4480,7 @@ ** to the GEP register (21140) or csr15 GEP portion (2114[23]). */ static void -srom_exec(struct device *dev, u_char *p) +srom_exec(struct net_device *dev, u_char *p) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -4511,13 +4511,13 @@ ** since the existing code will be satisfactory for all boards. */ static int -dc21041_infoleaf(struct device *dev) +dc21041_infoleaf(struct net_device *dev) { return DE4X5_AUTOSENSE_MS; } static int -dc21140_infoleaf(struct device *dev) +dc21140_infoleaf(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char count = 0; @@ -4555,7 +4555,7 @@ } static int -dc21142_infoleaf(struct device *dev) +dc21142_infoleaf(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char count = 0; @@ -4590,7 +4590,7 @@ } static int -dc21143_infoleaf(struct device *dev) +dc21143_infoleaf(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char count = 0; @@ -4628,7 +4628,7 @@ ** we'll reuse the dc21140m_autoconf function. Non MII media only. */ static int -compact_infoblock(struct device *dev, u_char count, u_char *p) +compact_infoblock(struct net_device *dev, u_char count, u_char *p) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char flags, csr6; @@ -4668,7 +4668,7 @@ ** This block describes non MII media for the DC21140[A] only. */ static int -type0_infoblock(struct device *dev, u_char count, u_char *p) +type0_infoblock(struct net_device *dev, u_char count, u_char *p) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char flags, csr6, len = (*p & BLOCK_LEN)+1; @@ -4708,7 +4708,7 @@ /* These functions are under construction! */ static int -type1_infoblock(struct device *dev, u_char count, u_char *p) +type1_infoblock(struct net_device *dev, u_char count, u_char *p) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char len = (*p & BLOCK_LEN)+1; @@ -4747,7 +4747,7 @@ } static int -type2_infoblock(struct device *dev, u_char count, u_char *p) +type2_infoblock(struct net_device *dev, u_char count, u_char *p) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char len = (*p & BLOCK_LEN)+1; @@ -4788,7 +4788,7 @@ } static int -type3_infoblock(struct device *dev, u_char count, u_char *p) +type3_infoblock(struct net_device *dev, u_char count, u_char *p) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char len = (*p & BLOCK_LEN)+1; @@ -4829,7 +4829,7 @@ } static int -type4_infoblock(struct device *dev, u_char count, u_char *p) +type4_infoblock(struct net_device *dev, u_char count, u_char *p) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char flags, csr6, len = (*p & BLOCK_LEN)+1; @@ -4874,7 +4874,7 @@ ** (chips) through the General Purpose Register. */ static int -type5_infoblock(struct device *dev, u_char count, u_char *p) +type5_infoblock(struct net_device *dev, u_char count, u_char *p) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_char len = (*p & BLOCK_LEN)+1; @@ -5074,7 +5074,7 @@ ** The SROM spec forces us to search addresses [1-31 0]. Bummer. */ static int -mii_get_phy(struct device *dev) +mii_get_phy(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -5138,7 +5138,7 @@ } static char * -build_setup_frame(struct device *dev, int mode) +build_setup_frame(struct net_device *dev, int mode) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int i; @@ -5170,7 +5170,7 @@ } static void -enable_ast(struct device *dev, u32 time_out) +enable_ast(struct net_device *dev, u32 time_out) { timeout(dev, (void *)&de4x5_ast, (u_long)dev, time_out); @@ -5178,7 +5178,7 @@ } static void -disable_ast(struct device *dev) +disable_ast(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; @@ -5188,7 +5188,7 @@ } static long -de4x5_switch_mac_port(struct device *dev) +de4x5_switch_mac_port(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -5224,7 +5224,7 @@ } static void -gep_wr(s32 data, struct device *dev) +gep_wr(s32 data, struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -5239,7 +5239,7 @@ } static int -gep_rd(struct device *dev) +gep_rd(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -5254,7 +5254,7 @@ } static void -timeout(struct device *dev, void (*fn)(u_long data), u_long data, u_long msec) +timeout(struct net_device *dev, void (*fn)(u_long data), u_long data, u_long msec) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int dt; @@ -5276,7 +5276,7 @@ } static void -yawn(struct device *dev, int state) +yawn(struct net_device *dev, int state) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -5324,7 +5324,7 @@ } static void -de4x5_parse_params(struct device *dev) +de4x5_parse_params(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; char *p, *q, t; @@ -5370,7 +5370,7 @@ } static void -de4x5_dbg_open(struct device *dev) +de4x5_dbg_open(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; int i; @@ -5421,7 +5421,7 @@ } static void -de4x5_dbg_mii(struct device *dev, int k) +de4x5_dbg_mii(struct net_device *dev, int k) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; @@ -5449,7 +5449,7 @@ } static void -de4x5_dbg_media(struct device *dev) +de4x5_dbg_media(struct net_device *dev) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; @@ -5542,7 +5542,7 @@ ** this function is only used for my testing. */ static int -de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd) +de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct de4x5_private *lp = (struct de4x5_private *)dev->priv; struct de4x5_ioctl *ioc = (struct de4x5_ioctl *) &rq->ifr_data; @@ -5751,7 +5751,7 @@ ** to "do the right thing". */ #define LP(a) ((struct de4x5_private *)(a)) -static struct device *mdev = NULL; +static struct net_device *mdev = NULL; static int io=0x0;/* EDIT THIS LINE FOR YOUR CONFIGURATION IF NEEDED */ MODULE_PARM(io, "i"); @@ -5759,7 +5759,7 @@ init_module(void) { int i, num, status = -EIO; - struct device *p; + struct net_device *p; num = count_adapters(); @@ -5802,10 +5802,10 @@ return; } -static struct device * -unlink_modules(struct device *p) +static struct net_device * +unlink_modules(struct net_device *p) { - struct device *next = NULL; + struct net_device *next = NULL; if (p->priv) { /* Private areas allocated? */ struct de4x5_private *lp = (struct de4x5_private *)p->priv; @@ -5856,17 +5856,17 @@ ** If at end of eth device list and can't use current entry, malloc ** one up. If memory could not be allocated, print an error message. */ -static struct device * __init -insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)) +static struct net_device * __init +insert_device(struct net_device *dev, u_long iobase, int (*init)(struct net_device *)) { - struct device *new; + struct net_device *new; - new = (struct device *)kmalloc(sizeof(struct device)+8, GFP_KERNEL); + new = (struct net_device *)kmalloc(sizeof(struct net_device)+8, GFP_KERNEL); if (new == NULL) { printk("de4x5.c: Device not initialised, insufficient memory\n"); return NULL; } else { - memset((char *)new, 0, sizeof(struct device)+8); + memset((char *)new, 0, sizeof(struct net_device)+8); new->name = (char *)(new + 1); new->base_addr = iobase; /* assign the io address */ new->init = init; /* initialisation routine */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/de600.c linux/drivers/net/de600.c --- v2.3.13/linux/drivers/net/de600.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/de600.c Wed Aug 18 11:36:41 1999 @@ -243,24 +243,24 @@ * Index to functions, as function prototypes. */ /* Routines used internally. (See "convenience macros") */ -static byte de600_read_status(struct device *dev); -static byte de600_read_byte(unsigned char type, struct device *dev); +static byte de600_read_status(struct net_device *dev); +static byte de600_read_byte(unsigned char type, struct net_device *dev); /* Put in the device structure. */ -static int de600_open(struct device *dev); -static int de600_close(struct device *dev); -static struct net_device_stats *get_stats(struct device *dev); -static int de600_start_xmit(struct sk_buff *skb, struct device *dev); +static int de600_open(struct net_device *dev); +static int de600_close(struct net_device *dev); +static struct net_device_stats *get_stats(struct net_device *dev); +static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev); /* Dispatch from interrupts. */ static void de600_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int de600_tx_intr(struct device *dev, int irq_status); -static void de600_rx_intr(struct device *dev); +static int de600_tx_intr(struct net_device *dev, int irq_status); +static void de600_rx_intr(struct net_device *dev); /* Initialization */ -static void trigger_interrupt(struct device *dev); -int de600_probe(struct device *dev); -static int adapter_init(struct device *dev); +static void trigger_interrupt(struct net_device *dev); +int de600_probe(struct net_device *dev); +static int adapter_init(struct net_device *dev); /* * D-Link driver variables: @@ -310,7 +310,7 @@ #define tx_page_adr(a) (((a) + 1) * MEM_2K) static inline byte -de600_read_status(struct device *dev) +de600_read_status(struct net_device *dev) { byte status; @@ -322,7 +322,7 @@ } static inline byte -de600_read_byte(unsigned char type, struct device *dev) { /* dev used by macros */ +de600_read_byte(unsigned char type, struct net_device *dev) { /* dev used by macros */ byte lo; (void)outb_p((type), DATA_PORT); @@ -340,7 +340,7 @@ * there is a non-reboot way to recover if something goes wrong. */ static int -de600_open(struct device *dev) +de600_open(struct net_device *dev) { if (request_irq(DE600_IRQ, de600_interrupt, 0, "de600", dev)) { printk ("%s: unable to get IRQ %d\n", dev->name, DE600_IRQ); @@ -360,7 +360,7 @@ * The inverse routine to de600_open(). */ static int -de600_close(struct device *dev) +de600_close(struct net_device *dev) { select_nic(); rx_page = 0; @@ -378,13 +378,13 @@ } static struct net_device_stats * -get_stats(struct device *dev) +get_stats(struct net_device *dev) { return (struct net_device_stats *)(dev->priv); } static inline void -trigger_interrupt(struct device *dev) +trigger_interrupt(struct net_device *dev) { de600_put_command(FLIP_IRQ); select_prn(); @@ -398,7 +398,7 @@ * Start sending. */ static int -de600_start_xmit(struct sk_buff *skb, struct device *dev) +de600_start_xmit(struct sk_buff *skb, struct net_device *dev) { int transmit_from; int len; @@ -483,7 +483,7 @@ static void de600_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; byte irq_status; int retrig = 0; int boguscount = 0; @@ -532,7 +532,7 @@ } static int -de600_tx_intr(struct device *dev, int irq_status) +de600_tx_intr(struct net_device *dev, int irq_status) { /* * Returns 1 if tx still not done @@ -568,7 +568,7 @@ * We have a good packet, get it out of the adapter. */ static void -de600_rx_intr(struct device *dev) +de600_rx_intr(struct net_device *dev) { struct sk_buff *skb; int i; @@ -628,7 +628,7 @@ } int __init -de600_probe(struct device *dev) +de600_probe(struct net_device *dev) { int i; static struct net_device_stats de600_netstats; @@ -707,7 +707,7 @@ } static int -adapter_init(struct device *dev) +adapter_init(struct net_device *dev) { int i; long flags; @@ -818,7 +818,7 @@ #ifdef MODULE static char nullname[8]; -static struct device de600_dev = { +static struct net_device de600_dev = { nullname, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, de600_probe }; int diff -u --recursive --new-file v2.3.13/linux/drivers/net/de620.c linux/drivers/net/de620.c --- v2.3.13/linux/drivers/net/de620.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/de620.c Wed Aug 18 11:36:41 1999 @@ -209,20 +209,20 @@ */ /* Put in the device structure. */ -static int de620_open(struct device *); -static int de620_close(struct device *); -static struct net_device_stats *get_stats(struct device *); -static void de620_set_multicast_list(struct device *); -static int de620_start_xmit(struct sk_buff *, struct device *); +static int de620_open(struct net_device *); +static int de620_close(struct net_device *); +static struct net_device_stats *get_stats(struct net_device *); +static void de620_set_multicast_list(struct net_device *); +static int de620_start_xmit(struct sk_buff *, struct net_device *); /* Dispatch from interrupts. */ static void de620_interrupt(int, void *, struct pt_regs *); -static int de620_rx_intr(struct device *); +static int de620_rx_intr(struct net_device *); /* Initialization */ -static int adapter_init(struct device *); -int de620_probe(struct device *); -static int read_eeprom(struct device *); +static int adapter_init(struct net_device *); +int de620_probe(struct net_device *); +static int read_eeprom(struct net_device *); /* @@ -260,7 +260,7 @@ static int tot_cnt; #endif static inline byte -de620_ready(struct device *dev) +de620_ready(struct net_device *dev) { byte value; register short int cnt = 0; @@ -275,7 +275,7 @@ } static inline void -de620_send_command(struct device *dev, byte cmd) +de620_send_command(struct net_device *dev, byte cmd) { de620_ready(dev); if (cmd == W_DUMMY) @@ -289,7 +289,7 @@ } static inline void -de620_put_byte(struct device *dev, byte value) +de620_put_byte(struct net_device *dev, byte value) { /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */ de620_ready(dev); @@ -298,7 +298,7 @@ } static inline byte -de620_read_byte(struct device *dev) +de620_read_byte(struct net_device *dev) { byte value; @@ -310,7 +310,7 @@ } static inline void -de620_write_block(struct device *dev, byte *buffer, int count) +de620_write_block(struct net_device *dev, byte *buffer, int count) { #ifndef LOWSPEED byte uflip = NIC_Cmd ^ (DS0 | DS1); @@ -346,7 +346,7 @@ } static inline void -de620_read_block(struct device *dev, byte *data, int count) +de620_read_block(struct net_device *dev, byte *data, int count) { #ifndef LOWSPEED byte value; @@ -381,7 +381,7 @@ } static inline void -de620_set_delay(struct device *dev) +de620_set_delay(struct net_device *dev) { de620_ready(dev); outb(W_DFR, DATA_PORT); @@ -405,7 +405,7 @@ } static inline void -de620_set_register(struct device *dev, byte reg, byte value) +de620_set_register(struct net_device *dev, byte reg, byte value) { de620_ready(dev); outb(reg, DATA_PORT); @@ -415,7 +415,7 @@ } static inline byte -de620_get_register(struct device *dev, byte reg) +de620_get_register(struct net_device *dev, byte reg) { byte value; @@ -436,7 +436,7 @@ * */ static int -de620_open(struct device *dev) +de620_open(struct net_device *dev) { if (request_irq(dev->irq, de620_interrupt, 0, "de620", dev)) { printk ("%s: unable to get IRQ %d\n", dev->name, dev->irq); @@ -457,7 +457,7 @@ * */ static int -de620_close(struct device *dev) +de620_close(struct net_device *dev) { /* disable recv */ de620_set_register(dev, W_TCR, RXOFF); @@ -474,7 +474,7 @@ * Return current statistics * */ -static struct net_device_stats *get_stats(struct device *dev) +static struct net_device_stats *get_stats(struct net_device *dev) { return (struct net_device_stats *)(dev->priv); } @@ -486,7 +486,7 @@ * */ -static void de620_set_multicast_list(struct device *dev) +static void de620_set_multicast_list(struct net_device *dev) { if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) { /* Enable promiscuous mode */ @@ -511,7 +511,7 @@ * Start sending. */ static int -de620_start_xmit(struct sk_buff *skb, struct device *dev) +de620_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned long flags; int len; @@ -592,7 +592,7 @@ static void de620_interrupt(int irq_in, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; byte irq_status; int bogus_count = 0; int again = 0; @@ -634,7 +634,7 @@ * */ static int -de620_rx_intr(struct device *dev) +de620_rx_intr(struct net_device *dev) { struct header_buf { byte status; @@ -733,7 +733,7 @@ * */ static int -adapter_init(struct device *dev) +adapter_init(struct net_device *dev) { int i; static int was_down = 0; @@ -821,7 +821,7 @@ * Check if there is a DE-620 connected */ int __init -de620_probe(struct device *dev) +de620_probe(struct net_device *dev) { static struct net_device_stats de620_netstats; int i; @@ -914,7 +914,7 @@ #define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister); static unsigned short __init -ReadAWord(struct device *dev, int from) +ReadAWord(struct net_device *dev, int from) { unsigned short data; int nbits; @@ -957,7 +957,7 @@ } static int __init -read_eeprom(struct device *dev) +read_eeprom(struct net_device *dev) { unsigned short wrd; @@ -1000,7 +1000,7 @@ */ #ifdef MODULE static char nullname[8] = ""; -static struct device de620_dev = { +static struct net_device de620_dev = { nullname, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, de620_probe }; int diff -u --recursive --new-file v2.3.13/linux/drivers/net/declance.c linux/drivers/net/declance.c --- v2.3.13/linux/drivers/net/declance.c Wed Jun 30 13:38:20 1999 +++ linux/drivers/net/declance.c Wed Aug 18 11:36:41 1999 @@ -262,7 +262,7 @@ unsigned short busmaster_regval; - struct device *dev; /* Backpointer */ + struct net_device *dev; /* Backpointer */ struct lance_private *next_module; /* Pointers to the ring buffers as seen from the CPU */ @@ -441,7 +441,7 @@ /* Setup the Lance Rx and Tx rings */ /* Sets dev->tbusy */ -static void lance_init_ring(struct device *dev) +static void lance_init_ring(struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib; @@ -544,7 +544,7 @@ return 0; } -static int lance_rx(struct device *dev) +static int lance_rx(struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib; @@ -626,7 +626,7 @@ return 0; } -static int lance_tx(struct device *dev) +static int lance_tx(struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib; @@ -703,7 +703,7 @@ static void lance_interrupt(const int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_regs *ll = lp->ll; int csr0; @@ -765,9 +765,9 @@ dev->interrupt = 0; } -struct device *last_dev = 0; +struct net_device *last_dev = 0; -static int lance_open(struct device *dev) +static int lance_open(struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -801,7 +801,7 @@ return status; } -static int lance_close(struct device *dev) +static int lance_close(struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -820,7 +820,7 @@ return 0; } -static inline int lance_reset(struct device *dev) +static inline int lance_reset(struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -843,7 +843,7 @@ return status; } -static int lance_start_xmit(struct sk_buff *skb, struct device *dev) +static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -912,14 +912,14 @@ return status; } -static struct net_device_stats *lance_get_stats(struct device *dev) +static struct net_device_stats *lance_get_stats(struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; return &lp->stats; } -static void lance_load_multicast(struct device *dev) +static void lance_load_multicast(struct net_device *dev) { volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start); volatile u16 *mcast_table = (u16 *) & ib->filter; @@ -970,7 +970,7 @@ return; } -static void lance_set_multicast(struct device *dev) +static void lance_set_multicast(struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib; @@ -1000,7 +1000,7 @@ dev->tbusy = 0; } -__initfunc(static int dec_lance_init(struct device *dev, const int type)) +__initfunc(static int dec_lance_init(struct net_device *dev, const int type)) { static unsigned version_printed = 0; struct lance_private *lp; @@ -1194,7 +1194,7 @@ /* Find all the lance cards on the system and initialize them */ -__initfunc(int dec_lance_probe(struct device *dev)) +__initfunc(int dec_lance_probe(struct net_device *dev)) { static int called = 0; diff -u --recursive --new-file v2.3.13/linux/drivers/net/defxx.c linux/drivers/net/defxx.c --- v2.3.13/linux/drivers/net/defxx.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/defxx.c Wed Aug 18 11:36:41 1999 @@ -236,29 +236,29 @@ /* Define global routines */ -int dfx_probe(struct device *dev); +int dfx_probe(struct net_device *dev); /* Define module-wide (static) routines */ -static struct device *dfx_alloc_device(struct device *dev, u16 iobase); +static struct net_device *dfx_alloc_device(struct net_device *dev, u16 iobase); -static void dfx_bus_init(struct device *dev); +static void dfx_bus_init(struct net_device *dev); static void dfx_bus_config_check(DFX_board_t *bp); -static int dfx_driver_init(struct device *dev); +static int dfx_driver_init(struct net_device *dev); static int dfx_adap_init(DFX_board_t *bp); -static int dfx_open(struct device *dev); -static int dfx_close(struct device *dev); +static int dfx_open(struct net_device *dev); +static int dfx_close(struct net_device *dev); static void dfx_int_pr_halt_id(DFX_board_t *bp); static void dfx_int_type_0_process(DFX_board_t *bp); static void dfx_int_common(DFX_board_t *bp); static void dfx_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static struct net_device_stats *dfx_ctl_get_stats(struct device *dev); -static void dfx_ctl_set_multicast_list(struct device *dev); -static int dfx_ctl_set_mac_address(struct device *dev, void *addr); +static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev); +static void dfx_ctl_set_multicast_list(struct net_device *dev); +static int dfx_ctl_set_mac_address(struct net_device *dev, void *addr); static int dfx_ctl_update_cam(DFX_board_t *bp); static int dfx_ctl_update_filters(DFX_board_t *bp); @@ -271,7 +271,7 @@ static void dfx_rcv_init(DFX_board_t *bp); static void dfx_rcv_queue_process(DFX_board_t *bp); -static int dfx_xmt_queue_pkt(struct sk_buff *skb, struct device *dev); +static int dfx_xmt_queue_pkt(struct sk_buff *skb, struct net_device *dev); static void dfx_xmt_done(DFX_board_t *bp); static void dfx_xmt_flush(DFX_board_t *bp); @@ -446,7 +446,7 @@ * the device structure. */ -int __init dfx_probe(struct device *dev) +int __init dfx_probe(struct net_device *dev) { int i; /* used in for loops */ int version_disp; /* was version info string already displayed? */ @@ -638,9 +638,9 @@ * None */ -struct device __init *dfx_alloc_device( struct device *dev, u16 iobase) +struct net_device __init *dfx_alloc_device( struct net_device *dev, u16 iobase) { - struct device *tmp_dev; /* pointer to a device structure */ + struct net_device *tmp_dev; /* pointer to a device structure */ DBG_printk("In dfx_alloc_device...\n"); @@ -729,7 +729,7 @@ * enabled yet. */ -void __init dfx_bus_init(struct device *dev) +void __init dfx_bus_init(struct net_device *dev) { DFX_board_t *bp = (DFX_board_t *)dev->priv; u8 val; /* used for I/O read/writes */ @@ -962,7 +962,7 @@ * returning from this routine. */ -int __init dfx_driver_init(struct device *dev) +int __init dfx_driver_init(struct net_device *dev) { DFX_board_t *bp = (DFX_board_t *)dev->priv; int alloc_size; /* total buffer size needed */ @@ -1370,7 +1370,7 @@ */ int dfx_open( - struct device *dev + struct net_device *dev ) { @@ -1462,7 +1462,7 @@ */ int dfx_close( - struct device *dev + struct net_device *dev ) { @@ -1882,7 +1882,7 @@ ) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; DFX_board_t *bp; /* private board structure pointer */ u8 tmp; /* used for disabling/enabling ints */ @@ -1990,7 +1990,7 @@ */ struct net_device_stats *dfx_ctl_get_stats( - struct device *dev + struct net_device *dev ) { @@ -2178,7 +2178,7 @@ */ void dfx_ctl_set_multicast_list( - struct device *dev + struct net_device *dev ) { @@ -2296,7 +2296,7 @@ */ int dfx_ctl_set_mac_address( - struct device *dev, + struct net_device *dev, void *addr ) @@ -3188,7 +3188,7 @@ int dfx_xmt_queue_pkt( struct sk_buff *skb, - struct device *dev + struct net_device *dev ) { diff -u --recursive --new-file v2.3.13/linux/drivers/net/defxx.h linux/drivers/net/defxx.h --- v2.3.13/linux/drivers/net/defxx.h Fri Apr 16 13:58:46 1999 +++ linux/drivers/net/defxx.h Wed Aug 18 11:36:45 1999 @@ -1755,7 +1755,7 @@ /* Store device, bus-specific, and parameter information for this adapter */ - struct device *dev; /* pointer to device structure */ + struct net_device *dev; /* pointer to device structure */ u32 bus_type; /* bus type (0 == PCI, 1 == EISA) */ u16 base_addr; /* base I/O address (same as dev->base_addr) */ struct pci_dev * pci_dev; diff -u --recursive --new-file v2.3.13/linux/drivers/net/depca.c linux/drivers/net/depca.c --- v2.3.13/linux/drivers/net/depca.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/depca.c Wed Aug 18 11:36:41 1999 @@ -416,39 +416,39 @@ /* ** Public Functions */ -static int depca_open(struct device *dev); -static int depca_start_xmit(struct sk_buff *skb, struct device *dev); +static int depca_open(struct net_device *dev); +static int depca_start_xmit(struct sk_buff *skb, struct net_device *dev); static void depca_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int depca_close(struct device *dev); -static int depca_ioctl(struct device *dev, struct ifreq *rq, int cmd); -static struct net_device_stats *depca_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static int depca_close(struct net_device *dev); +static int depca_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct net_device_stats *depca_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); /* ** Private functions */ -static int depca_hw_init(struct device *dev, u_long ioaddr, int mca_slot); -static void depca_init_ring(struct device *dev); -static int depca_rx(struct device *dev); -static int depca_tx(struct device *dev); +static int depca_hw_init(struct net_device *dev, u_long ioaddr, int mca_slot); +static void depca_init_ring(struct net_device *dev); +static int depca_rx(struct net_device *dev); +static int depca_tx(struct net_device *dev); -static void LoadCSRs(struct device *dev); -static int InitRestartDepca(struct device *dev); +static void LoadCSRs(struct net_device *dev); +static int InitRestartDepca(struct net_device *dev); static void DepcaSignature(char *name, u_long paddr); static int DevicePresent(u_long ioaddr); -static int get_hw_addr(struct device *dev); +static int get_hw_addr(struct net_device *dev); static int EISA_signature(char *name, s32 eisa_id); -static void SetMulticastFilter(struct device *dev); -static void isa_probe(struct device *dev, u_long iobase); -static void eisa_probe(struct device *dev, u_long iobase); +static void SetMulticastFilter(struct net_device *dev); +static void isa_probe(struct net_device *dev, u_long iobase); +static void eisa_probe(struct net_device *dev, u_long iobase); #ifdef CONFIG_MCA -static void mca_probe(struct device *dev, u_long iobase); +static void mca_probe(struct net_device *dev, u_long iobase); #endif -static struct device *alloc_device(struct device *dev, u_long iobase); +static struct net_device *alloc_device(struct net_device *dev, u_long iobase); static int depca_dev_index(char *s); -static struct device *insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)); -static int load_packet(struct device *dev, struct sk_buff *skb); -static void depca_dbg_open(struct device *dev); +static struct net_device *insert_device(struct net_device *dev, u_long iobase, int (*init)(struct net_device *)); +static int load_packet(struct net_device *dev, struct sk_buff *skb); +static void depca_dbg_open(struct net_device *dev); #ifdef MODULE int init_module(void); @@ -477,7 +477,7 @@ outw(STOP, DEPCA_DATA) int __init -depca_probe(struct device *dev) +depca_probe(struct net_device *dev) { int tmp = num_depcas, status = -ENODEV; u_long iobase = dev->base_addr; @@ -511,7 +511,7 @@ } static int __init -depca_hw_init(struct device *dev, u_long ioaddr, int mca_slot) +depca_hw_init(struct net_device *dev, u_long ioaddr, int mca_slot) { struct depca_private *lp; int i, j, offset, netRAM, mem_len, status=0; @@ -723,7 +723,7 @@ static int -depca_open(struct device *dev) +depca_open(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; u_long ioaddr = dev->base_addr; @@ -774,7 +774,7 @@ /* Initialize the lance Rx and Tx descriptor rings. */ static void -depca_init_ring(struct device *dev) +depca_init_ring(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; u_int i; @@ -817,7 +817,7 @@ ** Writes a socket buffer to TX descriptor ring and starts transmission */ static int -depca_start_xmit(struct sk_buff *skb, struct device *dev) +depca_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; u_long ioaddr = dev->base_addr; @@ -877,7 +877,7 @@ static void depca_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct depca_private *lp; s16 csr0, nicsr; u_long ioaddr; @@ -926,7 +926,7 @@ } static int -depca_rx(struct device *dev) +depca_rx(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; int i, entry; @@ -1026,7 +1026,7 @@ ** Buffer sent - check for buffer errors. */ static int -depca_tx(struct device *dev) +depca_tx(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; int entry; @@ -1064,7 +1064,7 @@ } static int -depca_close(struct device *dev) +depca_close(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; s16 nicsr; @@ -1105,7 +1105,7 @@ return 0; } -static void LoadCSRs(struct device *dev) +static void LoadCSRs(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; u_long ioaddr = dev->base_addr; @@ -1122,7 +1122,7 @@ return; } -static int InitRestartDepca(struct device *dev) +static int InitRestartDepca(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; u_long ioaddr = dev->base_addr; @@ -1154,7 +1154,7 @@ } static struct net_device_stats * -depca_get_stats(struct device *dev) +depca_get_stats(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; @@ -1167,7 +1167,7 @@ ** Set or clear the multicast filter for this adaptor. */ static void -set_multicast_list(struct device *dev) +set_multicast_list(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; u_long ioaddr = dev->base_addr; @@ -1199,7 +1199,7 @@ ** Big endian crc one liner is mine, all mine, ha ha ha ha! ** LANCE calculates its hash codes big endian. */ -static void SetMulticastFilter(struct device *dev) +static void SetMulticastFilter(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; struct dev_mc_list *dmi=dev->mc_list; @@ -1249,7 +1249,7 @@ ** Microchannel bus I/O device probe */ static void __init -mca_probe(struct device *dev, u_long ioaddr) +mca_probe(struct net_device *dev, u_long ioaddr) { unsigned char pos[2]; unsigned char where; @@ -1398,7 +1398,7 @@ ** ISA bus I/O device probe */ static void __init -isa_probe(struct device *dev, u_long ioaddr) +isa_probe(struct net_device *dev, u_long ioaddr) { int i = num_depcas, maxSlots; s32 ports[] = DEPCA_IO_PORTS; @@ -1437,7 +1437,7 @@ ** the motherboard. Upto 15 EISA devices are supported. */ static void __init -eisa_probe(struct device *dev, u_long ioaddr) +eisa_probe(struct net_device *dev, u_long ioaddr) { int i, maxSlots; u_long iobase; @@ -1483,10 +1483,10 @@ ** are not available then insert a new device structure at the end of ** the current list. */ -static struct device * __init -alloc_device(struct device *dev, u_long iobase) +static struct net_device * __init +alloc_device(struct net_device *dev, u_long iobase) { - struct device *adev = NULL; + struct net_device *adev = NULL; int fixed = 0, new_dev = 0; num_eth = depca_dev_index(dev->name); @@ -1528,12 +1528,12 @@ ** If at end of eth device list and can't use current entry, malloc ** one up. If memory could not be allocated, print an error message. */ -static struct device * __init -insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)) +static struct net_device * __init +insert_device(struct net_device *dev, u_long iobase, int (*init)(struct net_device *)) { - struct device *new; + struct net_device *new; - new = (struct device *)kmalloc(sizeof(struct device)+8, GFP_KERNEL); + new = (struct net_device *)kmalloc(sizeof(struct net_device)+8, GFP_KERNEL); if (new == NULL) { printk("eth%d: Device not initialised, insufficient memory\n",num_eth); return NULL; @@ -1681,7 +1681,7 @@ ** with x=1. */ static int __init -get_hw_addr(struct device *dev) +get_hw_addr(struct net_device *dev) { u_long ioaddr = dev->base_addr; int i, k, tmp, status = 0; @@ -1712,7 +1712,7 @@ /* ** Load a packet into the shared memory */ -static int load_packet(struct device *dev, struct sk_buff *skb) +static int load_packet(struct net_device *dev, struct sk_buff *skb) { struct depca_private *lp = (struct depca_private *)dev->priv; int i, entry, end, len, status = 0; @@ -1801,7 +1801,7 @@ return status; } -static void depca_dbg_open(struct device *dev) +static void depca_dbg_open(struct net_device *dev) { struct depca_private *lp = (struct depca_private *)dev->priv; u_long ioaddr = dev->base_addr; @@ -1880,7 +1880,7 @@ ** effective uid is checked in those cases. ** All multicast IOCTLs will not work here and are for testing purposes only. */ -static int depca_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int depca_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct depca_private *lp = (struct depca_private *)dev->priv; struct depca_ioctl *ioc = (struct depca_ioctl *) &rq->ifr_data; @@ -2015,7 +2015,7 @@ #ifdef MODULE static char devicename[9] = {0,}; -static struct device thisDepca = { +static struct net_device thisDepca = { devicename, /* device name is inserted by /linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0x200, 7, /* I/O address, IRQ */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/dgrs.c linux/drivers/net/dgrs.c --- v2.3.13/linux/drivers/net/dgrs.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/dgrs.c Wed Aug 18 11:36:41 1999 @@ -183,7 +183,7 @@ * Chain of device structures */ #ifdef MODULE - static struct device *dgrs_root_dev = NULL; + static struct net_device *dgrs_root_dev = NULL; #endif /* @@ -195,7 +195,7 @@ * Stuff for generic ethercard I/F */ char devname[8]; /* "ethN" string */ - struct device *next_dev; + struct net_device *next_dev; struct net_device_stats stats; /* @@ -240,7 +240,7 @@ */ int nports; /* Number of physical ports (4 or 6) */ int chan; /* Channel # (1-6) for this device */ - struct device *devtbl[6]; /* Ptrs to N device structs */ + struct net_device *devtbl[6]; /* Ptrs to N device structs */ } DGRS_PRIV; @@ -249,7 +249,7 @@ * reset or un-reset the IDT processor */ static void -proc_reset(struct device *dev0, int reset) +proc_reset(struct net_device *dev0, int reset) { DGRS_PRIV *priv0 = (DGRS_PRIV *) dev0->priv; @@ -273,7 +273,7 @@ * See if the board supports bus master DMA */ static int -check_board_dma(struct device *dev0) +check_board_dma(struct net_device *dev0) { DGRS_PRIV *priv0 = (DGRS_PRIV *) dev0->priv; ulong x; @@ -347,7 +347,7 @@ */ static int do_plx_dma( - struct device *dev, + struct net_device *dev, ulong pciaddr, ulong lcladdr, int len, @@ -453,7 +453,7 @@ */ void dgrs_rcv_frame( - struct device *dev0, + struct net_device *dev0, DGRS_PRIV *priv0, I596_CB *cbp ) @@ -463,7 +463,7 @@ struct sk_buff *skb; uchar *putp; uchar *p; - struct device *devN; + struct net_device *devN; DGRS_PRIV *privN; /* @@ -689,10 +689,10 @@ * end of the traditional 82596 RFD structure. */ -static int dgrs_start_xmit(struct sk_buff *skb, struct device *devN) +static int dgrs_start_xmit(struct sk_buff *skb, struct net_device *devN) { DGRS_PRIV *privN = (DGRS_PRIV *) devN->priv; - struct device *dev0; + struct net_device *dev0; DGRS_PRIV *priv0; I596_RBD *rbdp; int count; @@ -788,7 +788,7 @@ * Open the interface */ static int -dgrs_open( struct device *dev ) +dgrs_open( struct net_device *dev ) { dev->tbusy = 0; dev->interrupt = 0; @@ -804,7 +804,7 @@ /* * Close the interface */ -static int dgrs_close( struct device *dev ) +static int dgrs_close( struct net_device *dev ) { dev->start = 0; dev->tbusy = 1; @@ -819,7 +819,7 @@ /* * Get statistics */ -static struct net_device_stats *dgrs_get_stats( struct device *dev ) +static struct net_device_stats *dgrs_get_stats( struct net_device *dev ) { DGRS_PRIV *priv = (DGRS_PRIV *) dev->priv; @@ -830,7 +830,7 @@ * Set multicast list and/or promiscuous mode */ -static void dgrs_set_multicast_list( struct device *dev) +static void dgrs_set_multicast_list( struct net_device *dev) { DGRS_PRIV *priv = (DGRS_PRIV *) dev->priv; @@ -840,7 +840,7 @@ /* * Unique ioctl's */ -static int dgrs_ioctl(struct device *devN, struct ifreq *ifr, int cmd) +static int dgrs_ioctl(struct net_device *devN, struct ifreq *ifr, int cmd) { DGRS_PRIV *privN = (DGRS_PRIV *) devN->priv; DGRS_IOCTL ioc; @@ -905,7 +905,7 @@ static void dgrs_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev0 = (struct device *) dev_id; + struct net_device *dev0 = (struct net_device *) dev_id; DGRS_PRIV *priv0 = (DGRS_PRIV *) dev0->priv; I596_CB *cbp; int cmd; @@ -992,7 +992,7 @@ * Download the board firmware */ static int __init -dgrs_download(struct device *dev0) +dgrs_download(struct net_device *dev0) { DGRS_PRIV *priv0 = (DGRS_PRIV *) dev0->priv; int is; @@ -1151,7 +1151,7 @@ * Probe (init) a board */ int __init -dgrs_probe1(struct device *dev) +dgrs_probe1(struct net_device *dev) { DGRS_PRIV *priv = (DGRS_PRIV *) dev->priv; int i; @@ -1225,7 +1225,7 @@ } int __init -dgrs_initclone(struct device *dev) +dgrs_initclone(struct net_device *dev) { DGRS_PRIV *priv = (DGRS_PRIV *) dev->priv; int i; @@ -1241,7 +1241,7 @@ static int __init dgrs_found_device( - struct device *dev, + struct net_device *dev, int io, ulong mem, int irq, @@ -1254,12 +1254,12 @@ #ifdef MODULE { /* Allocate and fill new device structure. */ - int dev_size = sizeof(struct device) + sizeof(DGRS_PRIV); + int dev_size = sizeof(struct net_device) + sizeof(DGRS_PRIV); int i; - dev = (struct device *) kmalloc(dev_size, GFP_KERNEL); + dev = (struct net_device *) kmalloc(dev_size, GFP_KERNEL); memset(dev, 0, dev_size); - dev->priv = ((void *)dev) + sizeof(struct device); + dev->priv = ((void *)dev) + sizeof(struct net_device); priv = (DGRS_PRIV *)dev->priv; dev->name = priv->devname; /* An empty string. */ @@ -1291,15 +1291,15 @@ priv->nports = priv->bcomm->bc_nports; for (i = 1; i < priv->nports; ++i) { - struct device *devN; + struct net_device *devN; DGRS_PRIV *privN; /* Allocate new dev and priv structures */ - devN = (struct device *) kmalloc(dev_size, GFP_KERNEL); + devN = (struct net_device *) kmalloc(dev_size, GFP_KERNEL); /* Make it an exact copy of dev[0]... */ memcpy(devN, dev, dev_size); - devN->priv = ((void *)devN) + sizeof(struct device); + devN->priv = ((void *)devN) + sizeof(struct net_device); privN = (DGRS_PRIV *)devN->priv; /* ... but seset devname to a NULL string */ @@ -1361,7 +1361,7 @@ static int is2iv[8] __initdata = { 0, 3, 5, 7, 10, 11, 12, 15 }; static int __init -dgrs_scan(struct device *dev) +dgrs_scan(struct net_device *dev) { int cards_found = 0; uint io; @@ -1574,7 +1574,7 @@ { while (dgrs_root_dev) { - struct device *next_dev; + struct net_device *next_dev; DGRS_PRIV *priv; priv = (DGRS_PRIV *) dgrs_root_dev->priv; @@ -1601,7 +1601,7 @@ #else int __init -dgrs_probe(struct device *dev) +dgrs_probe(struct net_device *dev) { int cards_found; diff -u --recursive --new-file v2.3.13/linux/drivers/net/dlci.c linux/drivers/net/dlci.c --- v2.3.13/linux/drivers/net/dlci.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/dlci.c Wed Aug 18 11:36:42 1999 @@ -60,11 +60,11 @@ static const char *devname = "dlci"; static const char *version = "DLCI driver v0.35, 4 Jan 1997, mike.mclagan@linux.org"; -static struct device *open_dev[CONFIG_DLCI_COUNT]; +static struct net_device *open_dev[CONFIG_DLCI_COUNT]; static char *basename[16]; -int dlci_init(struct device *dev); +int dlci_init(struct net_device *dev); /* allow FRAD's to register their name as a valid FRAD */ int register_frad(const char *name) @@ -122,7 +122,7 @@ * the upper network layers */ -static int dlci_header(struct sk_buff *skb, struct device *dev, +static int dlci_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { @@ -161,7 +161,7 @@ return(hlen); } -static void dlci_receive(struct sk_buff *skb, struct device *dev) +static void dlci_receive(struct sk_buff *skb, struct net_device *dev) { struct dlci_local *dlp; struct frhdr *hdr; @@ -234,7 +234,7 @@ dev_kfree_skb(skb); } -static int dlci_transmit(struct sk_buff *skb, struct device *dev) +static int dlci_transmit(struct sk_buff *skb, struct net_device *dev) { struct dlci_local *dlp; int ret; @@ -284,7 +284,7 @@ return(ret); } -int dlci_config(struct device *dev, struct dlci_conf *conf, int get) +int dlci_config(struct net_device *dev, struct dlci_conf *conf, int get) { struct dlci_conf config; struct dlci_local *dlp; @@ -318,7 +318,7 @@ return(0); } -int dlci_dev_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct dlci_local *dlp; @@ -350,7 +350,7 @@ return(0); } -static int dlci_change_mtu(struct device *dev, int new_mtu) +static int dlci_change_mtu(struct net_device *dev, int new_mtu) { struct dlci_local *dlp; @@ -359,7 +359,7 @@ return((*dlp->slave->change_mtu)(dlp->slave, new_mtu)); } -static int dlci_open(struct device *dev) +static int dlci_open(struct net_device *dev) { struct dlci_local *dlp; struct frad_local *flp; @@ -386,7 +386,7 @@ return 0; } -static int dlci_close(struct device *dev) +static int dlci_close(struct net_device *dev) { struct dlci_local *dlp; struct frad_local *flp; @@ -403,7 +403,7 @@ return 0; } -static struct net_device_stats *dlci_get_stats(struct device *dev) +static struct net_device_stats *dlci_get_stats(struct net_device *dev) { struct dlci_local *dlp; @@ -414,7 +414,7 @@ int dlci_add(struct dlci_add *dlci) { - struct device *master, *slave; + struct net_device *master, *slave; struct dlci_local *dlp; struct frad_local *flp; int err, i; @@ -500,7 +500,7 @@ { struct dlci_local *dlp; struct frad_local *flp; - struct device *master, *slave; + struct net_device *master, *slave; int i, err; /* validate slave device */ @@ -569,7 +569,7 @@ return(err); } -int dlci_init(struct device *dev) +int dlci_init(struct net_device *dev) { struct dlci_local *dlp; diff -u --recursive --new-file v2.3.13/linux/drivers/net/dummy.c linux/drivers/net/dummy.c --- v2.3.13/linux/drivers/net/dummy.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/dummy.c Wed Aug 18 11:36:42 1999 @@ -53,34 +53,34 @@ #include #include -static int dummy_xmit(struct sk_buff *skb, struct device *dev); -static struct net_device_stats *dummy_get_stats(struct device *dev); +static int dummy_xmit(struct sk_buff *skb, struct net_device *dev); +static struct net_device_stats *dummy_get_stats(struct net_device *dev); -static int dummy_open(struct device *dev) +static int dummy_open(struct net_device *dev) { MOD_INC_USE_COUNT; return 0; } -static int dummy_close(struct device *dev) +static int dummy_close(struct net_device *dev) { MOD_DEC_USE_COUNT; return 0; } /* fake multicast ability */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { } #ifdef CONFIG_NET_FASTROUTE -static int dummy_accept_fastpath(struct device *dev, struct dst_entry *dst) +static int dummy_accept_fastpath(struct net_device *dev, struct dst_entry *dst) { return -1; } #endif -int __init dummy_init(struct device *dev) +int __init dummy_init(struct net_device *dev) { /* Initialize the device structure. */ dev->hard_start_xmit = dummy_xmit; @@ -107,7 +107,7 @@ return 0; } -static int dummy_xmit(struct sk_buff *skb, struct device *dev) +static int dummy_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_device_stats *stats; dev_kfree_skb(skb); @@ -119,7 +119,7 @@ return 0; } -static struct net_device_stats *dummy_get_stats(struct device *dev) +static struct net_device_stats *dummy_get_stats(struct net_device *dev) { struct net_device_stats *stats = (struct net_device_stats *) dev->priv; return stats; @@ -127,7 +127,7 @@ #ifdef MODULE -static int __init dummy_probe(struct device *dev) +static int __init dummy_probe(struct net_device *dev) { dummy_init(dev); return 0; @@ -135,7 +135,7 @@ static char dummy_name[16]; -static struct device dev_dummy = { +static struct net_device dev_dummy = { dummy_name, /* Needs to be writeable */ 0, 0, 0, 0, 0x0, 0, diff -u --recursive --new-file v2.3.13/linux/drivers/net/e2100.c linux/drivers/net/e2100.c --- v2.3.13/linux/drivers/net/e2100.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/e2100.c Wed Aug 18 11:36:42 1999 @@ -95,19 +95,19 @@ #define E21_BIG_RX_STOP_PG 0xF0 /* Last page +1 of RX ring */ #define E21_TX_START_PG E21_RX_STOP_PG /* First page of TX buffer */ -int e2100_probe(struct device *dev); -int e21_probe1(struct device *dev, int ioaddr); +int e2100_probe(struct net_device *dev); +int e21_probe1(struct net_device *dev, int ioaddr); -static int e21_open(struct device *dev); -static void e21_reset_8390(struct device *dev); -static void e21_block_input(struct device *dev, int count, +static int e21_open(struct net_device *dev); +static void e21_reset_8390(struct net_device *dev); +static void e21_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void e21_block_output(struct device *dev, int count, +static void e21_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page); -static void e21_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void e21_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static int e21_close(struct device *dev); +static int e21_close(struct net_device *dev); /* Probe for the E2100 series ethercards. These cards have an 8390 at the @@ -117,7 +117,7 @@ station address). */ -int __init e2100_probe(struct device *dev) +int __init e2100_probe(struct net_device *dev) { int *port; int base_addr = dev->base_addr; @@ -137,7 +137,7 @@ return ENODEV; } -int __init e21_probe1(struct device *dev, int ioaddr) +int __init e21_probe1(struct net_device *dev, int ioaddr) { int i, status; unsigned char *station_addr = dev->dev_addr; @@ -254,7 +254,7 @@ } static int -e21_open(struct device *dev) +e21_open(struct net_device *dev) { short ioaddr = dev->base_addr; @@ -277,7 +277,7 @@ } static void -e21_reset_8390(struct device *dev) +e21_reset_8390(struct net_device *dev) { short ioaddr = dev->base_addr; @@ -295,7 +295,7 @@ appears at the start of the shared memory. */ static void -e21_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +e21_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { short ioaddr = dev->base_addr; @@ -319,7 +319,7 @@ The E21xx makes block_input() especially easy by wrapping the top ring buffer to the bottom automatically. */ static void -e21_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +e21_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { short ioaddr = dev->base_addr; char *shared_mem = (char *)dev->mem_start; @@ -333,7 +333,7 @@ } static void -e21_block_output(struct device *dev, int count, const unsigned char *buf, +e21_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { short ioaddr = dev->base_addr; @@ -349,7 +349,7 @@ } static int -e21_close(struct device *dev) +e21_close(struct net_device *dev) { short ioaddr = dev->base_addr; @@ -386,7 +386,7 @@ #define MAX_E21_CARDS 4 /* Max number of E21 cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_E21_CARDS] = { 0, }; -static struct device dev_e21[MAX_E21_CARDS] = { +static struct net_device dev_e21[MAX_E21_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -413,7 +413,7 @@ int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) { - struct device *dev = &dev_e21[this_dev]; + struct net_device *dev = &dev_e21[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -444,7 +444,7 @@ int this_dev; for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) { - struct device *dev = &dev_e21[this_dev]; + struct net_device *dev = &dev_e21[this_dev]; if (dev->priv != NULL) { void *priv = dev->priv; /* NB: e21_close() handles free_irq */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/eepro.c linux/drivers/net/eepro.c --- v2.3.13/linux/drivers/net/eepro.c Thu Jan 7 08:47:54 1999 +++ linux/drivers/net/eepro.c Wed Aug 18 11:36:42 1999 @@ -303,21 +303,21 @@ /* Index to functions, as function prototypes. */ -extern int eepro_probe(struct device *dev); +extern int eepro_probe(struct net_device *dev); -static int eepro_probe1(struct device *dev, short ioaddr); -static int eepro_open(struct device *dev); -static int eepro_send_packet(struct sk_buff *skb, struct device *dev); +static int eepro_probe1(struct net_device *dev, short ioaddr); +static int eepro_open(struct net_device *dev); +static int eepro_send_packet(struct sk_buff *skb, struct net_device *dev); static void eepro_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void eepro_rx(struct device *dev); -static void eepro_transmit_interrupt(struct device *dev); -static int eepro_close(struct device *dev); -static struct enet_statistics *eepro_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static void eepro_rx(struct net_device *dev); +static void eepro_transmit_interrupt(struct net_device *dev); +static int eepro_close(struct net_device *dev); +static struct enet_statistics *eepro_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); static int read_eeprom(int ioaddr, int location); -static void hardware_send_packet(struct device *dev, void *buf, short length); -static int eepro_grab_irq(struct device *dev); +static void hardware_send_packet(struct net_device *dev, void *buf, short length); +static int eepro_grab_irq(struct net_device *dev); /* Details of the i82595. @@ -461,7 +461,7 @@ struct netdev_entry netcard_drv = {"eepro", eepro_probe1, EEPRO_IO_EXTENT, eepro_portlist}; #else -compat_init_func(int eepro_probe(struct device *dev)) +compat_init_func(int eepro_probe(struct net_device *dev)) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -575,7 +575,7 @@ probes on the ISA bus. A good device probe avoids doing writes, and verifies that the correct device exists and functions. */ -int eepro_probe1(struct device *dev, short ioaddr) +int eepro_probe1(struct net_device *dev, short ioaddr) { unsigned short station_addr[6], id, counter; int i,j, irqMask; @@ -746,7 +746,7 @@ static char irqrmap[] = {-1,-1,0,1,-1,2,-1,-1,-1,0,3,4,-1,-1,-1,-1}; static char irqrmap2[] = {-1,-1,4,0,1,2,-1,3,-1,4,5,6,7,-1,-1,-1}; -static int eepro_grab_irq(struct device *dev) +static int eepro_grab_irq(struct net_device *dev) { int irqlist[] = { 3, 4, 5, 7, 9, 10, 11, 12 }; int *irqp = irqlist, temp_reg, ioaddr = dev->base_addr; @@ -804,7 +804,7 @@ return dev->irq; } -static int eepro_open(struct device *dev) +static int eepro_open(struct net_device *dev) { unsigned short temp_reg, old8, old9; int irqMask; @@ -984,7 +984,7 @@ return 0; } -static int eepro_send_packet(struct sk_buff *skb, struct device *dev) +static int eepro_send_packet(struct sk_buff *skb, struct net_device *dev) { struct eepro_local *lp = (struct eepro_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1087,8 +1087,8 @@ static void eepro_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = (struct device *)dev_id; - /* (struct device *)(irq2dev_map[irq]);*/ + struct net_device *dev = (struct net_device *)dev_id; + /* (struct net_device *)(irq2dev_map[irq]);*/ struct eepro_local *lp = (struct eepro_local *)dev->priv; int ioaddr, status, boguscount = 20; @@ -1155,7 +1155,7 @@ return; } -static int eepro_close(struct device *dev) +static int eepro_close(struct net_device *dev) { struct eepro_local *lp = (struct eepro_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1207,7 +1207,7 @@ /* Get the current statistics. This may be called with the card open or closed. */ static struct enet_statistics * -eepro_get_stats(struct device *dev) +eepro_get_stats(struct net_device *dev) { struct eepro_local *lp = (struct eepro_local *)dev->priv; @@ -1217,7 +1217,7 @@ /* Set or clear the multicast filter for this adaptor. */ static void -set_multicast_list(struct device *dev) +set_multicast_list(struct net_device *dev) { struct eepro_local *lp = (struct eepro_local *)dev->priv; short ioaddr = dev->base_addr; @@ -1386,7 +1386,7 @@ } static void -hardware_send_packet(struct device *dev, void *buf, short length) +hardware_send_packet(struct net_device *dev, void *buf, short length) { struct eepro_local *lp = (struct eepro_local *)dev->priv; short ioaddr = dev->base_addr; @@ -1503,7 +1503,7 @@ } static void -eepro_rx(struct device *dev) +eepro_rx(struct net_device *dev) { struct eepro_local *lp = (struct eepro_local *)dev->priv; short ioaddr = dev->base_addr, rcv_ram = dev->mem_end; @@ -1597,7 +1597,7 @@ } static void -eepro_transmit_interrupt(struct device *dev) +eepro_transmit_interrupt(struct net_device *dev) { struct eepro_local *lp = (struct eepro_local *)dev->priv; short ioaddr = dev->base_addr; @@ -1655,7 +1655,7 @@ #define MAX_EEPRO 8 static char devicename[MAX_EEPRO][9]; -static struct device dev_eepro[MAX_EEPRO]; +static struct net_device dev_eepro[MAX_EEPRO]; static int io[MAX_EEPRO] = { #ifdef PnPWakeup @@ -1693,7 +1693,7 @@ printk("eepro_init_module: You should not use auto-probing with insmod!\n"); while (n_eepro < MAX_EEPRO && io[n_eepro] >= 0) { - struct device *d = &dev_eepro[n_eepro]; + struct net_device *d = &dev_eepro[n_eepro]; d->name = devicename[n_eepro]; /* inserted by drivers/net/net_init.c */ d->mem_end = mem[n_eepro]; d->base_addr = io[n_eepro]; @@ -1713,7 +1713,7 @@ int i; for (i=0; ipriv,sizeof(struct eepro_local)); diff -u --recursive --new-file v2.3.13/linux/drivers/net/eepro100.c linux/drivers/net/eepro100.c --- v2.3.13/linux/drivers/net/eepro100.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/eepro100.c Wed Aug 18 11:36:42 1999 @@ -79,9 +79,6 @@ #include #endif -#if LINUX_VERSION_CODE < 0x20200 && defined(MODVERSIONS) -#include -#endif #include #include #include @@ -287,8 +284,8 @@ */ /* This table drives the PCI probe routines. */ -static struct device * -speedo_found1(int pci_bus, int pci_devfn, struct device *dev, +static struct net_device * +speedo_found1(int pci_bus, int pci_devfn, struct net_device *dev, long ioaddr, int irq, int chip_idx, int fnd_cnt); #ifdef USE_IO @@ -315,7 +312,7 @@ const char *name; u16 vendor_id, device_id, device_id_mask, flags; int io_size; - struct device *(*probe1)(int pci_bus, int pci_devfn, struct device *dev, + struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, long ioaddr, int irq, int chip_idx, int fnd_cnt); } static pci_tbl[] = { { "Intel PCI EtherExpress Pro100", @@ -458,7 +455,7 @@ unsigned int cur_rx, dirty_rx; /* The next free ring entry */ long last_rx_time; /* Last Rx, in jiffies, to handle Rx hang. */ const char *product_name; - struct device *next_module; + struct net_device *next_module; void *priv_addr; /* Unaligned address for kfree */ struct enet_statistics stats; struct speedo_stats lstats; @@ -511,18 +508,18 @@ static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len); static int mdio_read(long ioaddr, int phy_id, int location); static int mdio_write(long ioaddr, int phy_id, int location, int value); -static int speedo_open(struct device *dev); -static void speedo_resume(struct device *dev); +static int speedo_open(struct net_device *dev); +static void speedo_resume(struct net_device *dev); static void speedo_timer(unsigned long data); -static void speedo_init_rx_ring(struct device *dev); -static void speedo_tx_timeout(struct device *dev); -static int speedo_start_xmit(struct sk_buff *skb, struct device *dev); -static int speedo_rx(struct device *dev); +static void speedo_init_rx_ring(struct net_device *dev); +static void speedo_tx_timeout(struct net_device *dev); +static int speedo_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int speedo_rx(struct net_device *dev); static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs); -static int speedo_close(struct device *dev); -static struct enet_statistics *speedo_get_stats(struct device *dev); -static int speedo_ioctl(struct device *dev, struct ifreq *rq, int cmd); -static void set_rx_mode(struct device *dev); +static int speedo_close(struct net_device *dev); +static struct enet_statistics *speedo_get_stats(struct net_device *dev); +static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static void set_rx_mode(struct net_device *dev); @@ -534,10 +531,10 @@ #endif /* A list of all installed Speedo devices, for removing the driver module. */ -static struct device *root_speedo_dev = NULL; +static struct net_device *root_speedo_dev = NULL; #if ! defined(HAS_PCI_NETIF) -int eepro100_init(struct device *dev) +int eepro100_init(struct net_device *dev) { int cards_found = 0; static int pci_index = 0; @@ -628,8 +625,8 @@ } #endif -static struct device * -speedo_found1(int pci_bus, int pci_devfn, struct device *dev, +static struct net_device * +speedo_found1(int pci_bus, int pci_devfn, struct net_device *dev, long ioaddr, int irq, int chip_idx, int card_idx) { struct speedo_private *sp; @@ -899,7 +896,7 @@ static int -speedo_open(struct device *dev) +speedo_open(struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; long ioaddr = dev->base_addr; @@ -987,7 +984,7 @@ } /* Start the chip hardware after a full reset. */ -static void speedo_resume(struct device *dev) +static void speedo_resume(struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1043,7 +1040,7 @@ /* Media monitoring and control. */ static void speedo_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct speedo_private *sp = (struct speedo_private *)dev->priv; long ioaddr = dev->base_addr; int phy_num = sp->phy[0] & 0x1f; @@ -1090,7 +1087,7 @@ add_timer(&sp->timer); } -static void speedo_show_state(struct device *dev) +static void speedo_show_state(struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1125,7 +1122,7 @@ /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ static void -speedo_init_rx_ring(struct device *dev) +speedo_init_rx_ring(struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; struct RxFD *rxf, *last_rxf = NULL; @@ -1162,7 +1159,7 @@ sp->last_rxf = last_rxf; } -static void speedo_tx_timeout(struct device *dev) +static void speedo_tx_timeout(struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1210,7 +1207,7 @@ } static int -speedo_start_xmit(struct sk_buff *skb, struct device *dev) +speedo_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1281,7 +1278,7 @@ after the Tx thread. */ static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_instance; + struct net_device *dev = (struct net_device *)dev_instance; struct speedo_private *sp; long ioaddr, boguscnt = max_interrupt_work; unsigned short status; @@ -1404,7 +1401,7 @@ } static int -speedo_rx(struct device *dev) +speedo_rx(struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; int entry = sp->cur_rx % RX_RING_SIZE; @@ -1515,7 +1512,7 @@ } static int -speedo_close(struct device *dev) +speedo_close(struct net_device *dev) { long ioaddr = dev->base_addr; struct speedo_private *sp = (struct speedo_private *)dev->priv; @@ -1588,7 +1585,7 @@ Oh, and incoming frames are dropped while executing dump-stats! */ static struct enet_statistics * -speedo_get_stats(struct device *dev) +speedo_get_stats(struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1615,7 +1612,7 @@ return &sp->stats; } -static int speedo_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct speedo_private *sp = (struct speedo_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1662,7 +1659,7 @@ loaded the link -- we convert the current command block, normally a Tx command, into a no-op and link it to the new command. */ -static void set_rx_mode(struct device *dev) +static void set_rx_mode(struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1856,7 +1853,7 @@ void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ while (root_speedo_dev) { @@ -1880,7 +1877,7 @@ #else /* not MODULE */ -int eepro100_probe(struct device *dev) +int eepro100_probe(struct net_device *dev) { int cards_found = 0; diff -u --recursive --new-file v2.3.13/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c --- v2.3.13/linux/drivers/net/eexpress.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/eexpress.c Wed Aug 18 11:36:42 1999 @@ -236,34 +236,34 @@ * Prototypes for Linux interface */ -extern int express_probe(struct device *dev); -static int eexp_open(struct device *dev); -static int eexp_close(struct device *dev); -static struct net_device_stats *eexp_stats(struct device *dev); -static int eexp_xmit(struct sk_buff *buf, struct device *dev); +extern int express_probe(struct net_device *dev); +static int eexp_open(struct net_device *dev); +static int eexp_close(struct net_device *dev); +static struct net_device_stats *eexp_stats(struct net_device *dev); +static int eexp_xmit(struct sk_buff *buf, struct net_device *dev); static void eexp_irq(int irq, void *dev_addr, struct pt_regs *regs); -static void eexp_set_multicast(struct device *dev); +static void eexp_set_multicast(struct net_device *dev); /* * Prototypes for hardware access functions */ -static void eexp_hw_rx_pio(struct device *dev); -static void eexp_hw_tx_pio(struct device *dev, unsigned short *buf, +static void eexp_hw_rx_pio(struct net_device *dev); +static void eexp_hw_tx_pio(struct net_device *dev, unsigned short *buf, unsigned short len); -static int eexp_hw_probe(struct device *dev,unsigned short ioaddr); +static int eexp_hw_probe(struct net_device *dev,unsigned short ioaddr); static unsigned short eexp_hw_readeeprom(unsigned short ioaddr, unsigned char location); -static unsigned short eexp_hw_lasttxstat(struct device *dev); -static void eexp_hw_txrestart(struct device *dev); +static unsigned short eexp_hw_lasttxstat(struct net_device *dev); +static void eexp_hw_txrestart(struct net_device *dev); -static void eexp_hw_txinit (struct device *dev); -static void eexp_hw_rxinit (struct device *dev); +static void eexp_hw_txinit (struct net_device *dev); +static void eexp_hw_rxinit (struct net_device *dev); -static void eexp_hw_init586 (struct device *dev); -static void eexp_setup_filter (struct device *dev); +static void eexp_hw_init586 (struct net_device *dev); +static void eexp_setup_filter (struct net_device *dev); static char *eexp_ifmap[]={"AUI", "BNC", "RJ45"}; enum eexp_iftype {AUI=0, BNC=1, TPE=2}; @@ -275,37 +275,37 @@ * Primitive hardware access functions. */ -static inline unsigned short scb_status(struct device *dev) +static inline unsigned short scb_status(struct net_device *dev) { return inw(dev->base_addr + 0xc008); } -static inline unsigned short scb_rdcmd(struct device *dev) +static inline unsigned short scb_rdcmd(struct net_device *dev) { return inw(dev->base_addr + 0xc00a); } -static inline void scb_command(struct device *dev, unsigned short cmd) +static inline void scb_command(struct net_device *dev, unsigned short cmd) { outw(cmd, dev->base_addr + 0xc00a); } -static inline void scb_wrcbl(struct device *dev, unsigned short val) +static inline void scb_wrcbl(struct net_device *dev, unsigned short val) { outw(val, dev->base_addr + 0xc00c); } -static inline void scb_wrrfa(struct device *dev, unsigned short val) +static inline void scb_wrrfa(struct net_device *dev, unsigned short val) { outw(val, dev->base_addr + 0xc00e); } -static inline void set_loopback(struct device *dev) +static inline void set_loopback(struct net_device *dev) { outb(inb(dev->base_addr + Config) | 2, dev->base_addr + Config); } -static inline void clear_loopback(struct device *dev) +static inline void clear_loopback(struct net_device *dev) { outb(inb(dev->base_addr + Config) & ~2, dev->base_addr + Config); } @@ -325,7 +325,7 @@ * checks for presence of EtherExpress card */ -int __init express_probe(struct device *dev) +int __init express_probe(struct net_device *dev) { unsigned short *port; static unsigned short ports[] = { 0x300,0x310,0x270,0x320,0x340,0 }; @@ -356,7 +356,7 @@ * open and initialize the adapter, ready for use */ -static int eexp_open(struct device *dev) +static int eexp_open(struct net_device *dev) { int irq = dev->irq; unsigned short ioaddr = dev->base_addr; @@ -397,7 +397,7 @@ * close and disable the interface, leaving the 586 in reset. */ -static int eexp_close(struct device *dev) +static int eexp_close(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; struct net_local *lp = dev->priv; @@ -426,7 +426,7 @@ * Return interface stats */ -static struct net_device_stats *eexp_stats(struct device *dev) +static struct net_device_stats *eexp_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -438,7 +438,7 @@ * nothing has become jammed in the CU. */ -static void unstick_cu(struct device *dev) +static void unstick_cu(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned short ioaddr = dev->base_addr; @@ -519,7 +519,7 @@ * Called to transmit a packet, or to allow us to right ourselves * if the kernel thinks we've died. */ -static int eexp_xmit(struct sk_buff *buf, struct device *dev) +static int eexp_xmit(struct sk_buff *buf, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned long flags; @@ -601,7 +601,7 @@ * check to make sure we've not become wedged. */ -static unsigned short eexp_start_irq(struct device *dev, +static unsigned short eexp_start_irq(struct net_device *dev, unsigned short status) { unsigned short ack_cmd = SCB_ack(status); @@ -659,7 +659,7 @@ return ack_cmd; } -static void eexp_cmd_clear(struct device *dev) +static void eexp_cmd_clear(struct net_device *dev) { unsigned long int oldtime = jiffies; while (scb_rdcmd(dev) && ((jiffies-oldtime)<10)); @@ -670,7 +670,7 @@ static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs) { - struct device *dev = dev_info; + struct net_device *dev = dev_info; struct net_local *lp; unsigned short ioaddr,status,ack_cmd; unsigned short old_read_ptr, old_write_ptr; @@ -781,7 +781,7 @@ * Set the cable type to use. */ -static void eexp_hw_set_interface(struct device *dev) +static void eexp_hw_set_interface(struct net_device *dev) { unsigned char oldval = inb(dev->base_addr + 0x300e); oldval &= ~0x82; @@ -802,7 +802,7 @@ * descriptor, though we don't bother trying to fix broken ones. */ -static void eexp_hw_rx_pio(struct device *dev) +static void eexp_hw_rx_pio(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned short rx_block = lp->rx_ptr; @@ -897,7 +897,7 @@ * buffer region. */ -static void eexp_hw_tx_pio(struct device *dev, unsigned short *buf, +static void eexp_hw_tx_pio(struct net_device *dev, unsigned short *buf, unsigned short len) { struct net_local *lp = (struct net_local *)dev->priv; @@ -961,7 +961,7 @@ * than one card in a machine. */ -static int __init eexp_hw_probe(struct device *dev, unsigned short ioaddr) +static int __init eexp_hw_probe(struct net_device *dev, unsigned short ioaddr) { unsigned short hw_addr[3]; unsigned char buswidth; @@ -1134,7 +1134,7 @@ * again */ -static unsigned short eexp_hw_lasttxstat(struct device *dev) +static unsigned short eexp_hw_lasttxstat(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned short tx_block = lp->tx_reap; @@ -1205,7 +1205,7 @@ * we were working on, or the idle loop if we had finished for the time. */ -static void eexp_hw_txrestart(struct device *dev) +static void eexp_hw_txrestart(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned short ioaddr = dev->base_addr; @@ -1251,7 +1251,7 @@ * the 586 command unit is continuously active. */ -static void eexp_hw_txinit(struct device *dev) +static void eexp_hw_txinit(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned short tx_block = TX_BUF_START; @@ -1293,7 +1293,7 @@ * "out of resources" messages). */ -static void eexp_hw_rxinit(struct device *dev) +static void eexp_hw_rxinit(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned short rx_block = lp->rx_buf_start; @@ -1352,7 +1352,7 @@ * the hardware is configured correctly. */ -static void eexp_hw_init586(struct device *dev) +static void eexp_hw_init586(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; unsigned short ioaddr = dev->base_addr; @@ -1475,7 +1475,7 @@ return; } -static void eexp_setup_filter(struct device *dev) +static void eexp_setup_filter(struct net_device *dev) { struct dev_mc_list *dmi = dev->mc_list; unsigned short ioaddr = dev->base_addr; @@ -1512,7 +1512,7 @@ * Set or clear the multicast filter for this adaptor. */ static void -eexp_set_multicast(struct device *dev) +eexp_set_multicast(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; struct net_local *lp = (struct net_local *)dev->priv; @@ -1564,7 +1564,7 @@ static char namelist[NAMELEN * EEXP_MAX_CARDS] = { 0, }; -static struct device dev_eexp[EEXP_MAX_CARDS] = +static struct net_device dev_eexp[EEXP_MAX_CARDS] = { { NULL, /* will allocate dynamically */ 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, express_probe }, @@ -1585,7 +1585,7 @@ int this_dev, found = 0; for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) { - struct device *dev = &dev_eexp[this_dev]; + struct net_device *dev = &dev_eexp[this_dev]; dev->name = namelist + (NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -1608,7 +1608,7 @@ int this_dev; for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) { - struct device *dev = &dev_eexp[this_dev]; + struct net_device *dev = &dev_eexp[this_dev]; if (dev->priv != NULL) { unregister_netdev(dev); kfree(dev->priv); diff -u --recursive --new-file v2.3.13/linux/drivers/net/epic100.c linux/drivers/net/epic100.c --- v2.3.13/linux/drivers/net/epic100.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/epic100.c Wed Aug 18 11:36:42 1999 @@ -151,8 +151,8 @@ /* The rest of these values should never change. */ -static struct device *epic_probe1(int pci_bus, int pci_devfn, - struct device *dev, long ioaddr, int irq, +static struct net_device *epic_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, int irq, int chip_id, int card_idx); enum pci_flags_bit { @@ -164,7 +164,7 @@ const char *name; u16 vendor_id, device_id, device_id_mask, pci_flags; int io_size, min_latency; - struct device *(*probe1)(int pci_bus, int pci_devfn, struct device *dev, + struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, long ioaddr, int irq, int chip_idx, int fnd_cnt); } chip_tbl[] = { {"SMSC EPIC/100 83c170", 0x10B8, 0x0005, 0x7fff, @@ -217,7 +217,7 @@ struct epic_private { char devname[8]; /* Used only for kernel debugging. */ const char *product_name; - struct device *next_module; + struct net_device *next_module; /* Tx and Rx rings here so that they remain paragraph aligned. */ struct epic_rx_desc rx_ring[RX_RING_SIZE]; @@ -253,28 +253,28 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; -static int epic_open(struct device *dev); +static int epic_open(struct net_device *dev); static int read_eeprom(long ioaddr, int location); static int mdio_read(long ioaddr, int phy_id, int location); static void mdio_write(long ioaddr, int phy_id, int location, int value); -static void epic_restart(struct device *dev); +static void epic_restart(struct net_device *dev); static void epic_timer(unsigned long data); -static void epic_tx_timeout(struct device *dev); -static void epic_init_ring(struct device *dev); -static int epic_start_xmit(struct sk_buff *skb, struct device *dev); -static int epic_rx(struct device *dev); +static void epic_tx_timeout(struct net_device *dev); +static void epic_init_ring(struct net_device *dev); +static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int epic_rx(struct net_device *dev); static void epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs); -static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd); -static int epic_close(struct device *dev); -static struct net_device_stats *epic_get_stats(struct device *dev); -static void set_rx_mode(struct device *dev); +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static int epic_close(struct net_device *dev); +static struct net_device_stats *epic_get_stats(struct net_device *dev); +static void set_rx_mode(struct net_device *dev); /* A list of all installed EPIC devices, for removing the driver module. */ -static struct device *root_epic_dev = NULL; +static struct net_device *root_epic_dev = NULL; #ifndef CARDBUS -int epic100_probe(struct device *dev) +int epic100_probe(struct net_device *dev) { int cards_found = 0; int chip_idx, irq; @@ -381,8 +381,8 @@ } #endif /* not CARDBUS */ -static struct device *epic_probe1(int pci_bus, int pci_devfn, - struct device *dev, long ioaddr, int irq, +static struct net_device *epic_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, int irq, int chip_idx, int card_idx) { struct epic_private *ep; @@ -589,7 +589,7 @@ static int -epic_open(struct device *dev) +epic_open(struct net_device *dev) { struct epic_private *ep = (struct epic_private *)dev->priv; long ioaddr = dev->base_addr; @@ -680,7 +680,7 @@ /* Reset the chip to recover from a PCI transaction error. This may occur at interrupt time. */ -static void epic_pause(struct device *dev) +static void epic_pause(struct net_device *dev) { long ioaddr = dev->base_addr; struct epic_private *ep = (struct epic_private *)dev->priv; @@ -701,7 +701,7 @@ epic_rx(dev); } -static void epic_restart(struct device *dev) +static void epic_restart(struct net_device *dev) { long ioaddr = dev->base_addr; struct epic_private *ep = (struct epic_private *)dev->priv; @@ -752,7 +752,7 @@ static void epic_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct epic_private *ep = (struct epic_private *)dev->priv; long ioaddr = dev->base_addr; int next_tick = 0; @@ -784,7 +784,7 @@ } } -static void epic_tx_timeout(struct device *dev) +static void epic_tx_timeout(struct net_device *dev) { struct epic_private *ep = (struct epic_private *)dev->priv; long ioaddr = dev->base_addr; @@ -815,7 +815,7 @@ /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ static void -epic_init_ring(struct device *dev) +epic_init_ring(struct net_device *dev) { struct epic_private *ep = (struct epic_private *)dev->priv; int i; @@ -856,7 +856,7 @@ } static int -epic_start_xmit(struct sk_buff *skb, struct device *dev) +epic_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct epic_private *ep = (struct epic_private *)dev->priv; int entry; @@ -920,7 +920,7 @@ after the Tx thread. */ static void epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_instance; + struct net_device *dev = (struct net_device *)dev_instance; struct epic_private *ep = (struct epic_private *)dev->priv; long ioaddr = dev->base_addr; int status, boguscnt = max_interrupt_work; @@ -1063,7 +1063,7 @@ return; } -static int epic_rx(struct device *dev) +static int epic_rx(struct net_device *dev) { struct epic_private *ep = (struct epic_private *)dev->priv; int entry = ep->cur_rx % RX_RING_SIZE; @@ -1139,7 +1139,7 @@ return work_done; } -static int epic_close(struct device *dev) +static int epic_close(struct net_device *dev) { long ioaddr = dev->base_addr; struct epic_private *ep = (struct epic_private *)dev->priv; @@ -1195,7 +1195,7 @@ return 0; } -static struct net_device_stats *epic_get_stats(struct device *dev) +static struct net_device_stats *epic_get_stats(struct net_device *dev) { struct epic_private *ep = (struct epic_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1237,7 +1237,7 @@ } -static void set_rx_mode(struct device *dev) +static void set_rx_mode(struct net_device *dev) { long ioaddr = dev->base_addr; struct epic_private *ep = (struct epic_private *)dev->priv; @@ -1276,7 +1276,7 @@ return; } -static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { long ioaddr = dev->base_addr; u16 *data = (u16 *)&rq->ifr_data; @@ -1325,7 +1325,7 @@ static dev_node_t *epic_attach(dev_locator_t *loc) { - struct device *dev; + struct net_device *dev; u16 dev_id; u32 io; u8 bus, devfn, irq; @@ -1357,7 +1357,7 @@ static void epic_suspend(dev_node_t *node) { - struct device **devp, **next; + struct net_device **devp, **next; printk(KERN_INFO "epic_suspend(%s)\n", node->dev_name); for (devp = &root_epic_dev; *devp; devp = next) { next = &((struct epic_private *)(*devp)->priv)->next_module; @@ -1372,7 +1372,7 @@ } static void epic_resume(dev_node_t *node) { - struct device **devp, **next; + struct net_device **devp, **next; printk(KERN_INFO "epic_resume(%s)\n", node->dev_name); for (devp = &root_epic_dev; *devp; devp = next) { next = &((struct epic_private *)(*devp)->priv)->next_module; @@ -1384,7 +1384,7 @@ } static void epic_detach(dev_node_t *node) { - struct device **devp, **next; + struct net_device **devp, **next; printk(KERN_INFO "epic_detach(%s)\n", node->dev_name); for (devp = &root_epic_dev; *devp; devp = next) { next = &((struct epic_private *)(*devp)->priv)->next_module; @@ -1423,7 +1423,7 @@ void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; #ifdef CARDBUS unregister_driver(&epic_ops); diff -u --recursive --new-file v2.3.13/linux/drivers/net/eql.c linux/drivers/net/eql.c --- v2.3.13/linux/drivers/net/eql.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/eql.c Wed Aug 18 11:36:42 1999 @@ -150,27 +150,27 @@ #endif static unsigned int eql_debug = EQL_DEBUG; -int eql_init(struct device *dev); /* */ -static int eql_open(struct device *dev); /* */ -static int eql_close(struct device *dev); /* */ -static int eql_ioctl(struct device *dev, struct ifreq *ifr, int cmd); /* */ -static int eql_slave_xmit(struct sk_buff *skb, struct device *dev); /* */ +int eql_init(struct net_device *dev); /* */ +static int eql_open(struct net_device *dev); /* */ +static int eql_close(struct net_device *dev); /* */ +static int eql_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); /* */ +static int eql_slave_xmit(struct sk_buff *skb, struct net_device *dev); /* */ -static struct net_device_stats *eql_get_stats(struct device *dev); /* */ +static struct net_device_stats *eql_get_stats(struct net_device *dev); /* */ /* ioctl() handlers ---------------- */ -static int eql_enslave(struct device *dev, slaving_request_t *srq); /* */ -static int eql_emancipate(struct device *dev, slaving_request_t *srq); /* */ +static int eql_enslave(struct net_device *dev, slaving_request_t *srq); /* */ +static int eql_emancipate(struct net_device *dev, slaving_request_t *srq); /* */ -static int eql_g_slave_cfg(struct device *dev, slave_config_t *sc); /* */ -static int eql_s_slave_cfg(struct device *dev, slave_config_t *sc); /* */ +static int eql_g_slave_cfg(struct net_device *dev, slave_config_t *sc); /* */ +static int eql_s_slave_cfg(struct net_device *dev, slave_config_t *sc); /* */ -static int eql_g_master_cfg(struct device *dev, master_config_t *mc); /* */ -static int eql_s_master_cfg(struct device *dev, master_config_t *mc); /* */ +static int eql_g_master_cfg(struct net_device *dev, master_config_t *mc); /* */ +static int eql_s_master_cfg(struct net_device *dev, master_config_t *mc); /* */ -static inline int eql_is_slave(struct device *dev); /* */ -static inline int eql_is_master(struct device *dev); /* */ +static inline int eql_is_slave(struct net_device *dev); /* */ +static inline int eql_is_master(struct net_device *dev); /* */ static slave_t *eql_new_slave(void); /* */ static void eql_delete_slave(slave_t *slave); /* */ @@ -181,16 +181,16 @@ static inline int eql_is_empty(slave_queue_t *queue); /* */ static inline int eql_is_full(slave_queue_t *queue); /* */ -static slave_queue_t *eql_new_slave_queue(struct device *dev); /* */ +static slave_queue_t *eql_new_slave_queue(struct net_device *dev); /* */ static void eql_delete_slave_queue(slave_queue_t *queue); /* */ static int eql_insert_slave(slave_queue_t *queue, slave_t *slave); /* */ static slave_t *eql_remove_slave(slave_queue_t *queue, slave_t *slave); /* */ -/* static int eql_insert_slave_dev(slave_queue_t *queue, struct device *dev); -* */ -static int eql_remove_slave_dev(slave_queue_t *queue, struct device *dev); /* */ +/* static int eql_insert_slave_dev(slave_queue_t *queue, struct net_device *dev); -* */ +static int eql_remove_slave_dev(slave_queue_t *queue, struct net_device *dev); /* */ -static inline struct device *eql_best_slave_dev(slave_queue_t *queue); /* */ +static inline struct net_device *eql_best_slave_dev(slave_queue_t *queue); /* */ static inline slave_t *eql_best_slave(slave_queue_t *queue); /* */ static inline slave_t *eql_first_slave(slave_queue_t *queue); /* */ static inline slave_t *eql_next_slave(slave_queue_t *queue, slave_t *slave); /* */ @@ -198,18 +198,18 @@ static inline void eql_set_best_slave(slave_queue_t *queue, slave_t *slave); /* */ static inline void eql_schedule_slaves(slave_queue_t *queue); /* */ -static slave_t *eql_find_slave_dev(slave_queue_t *queue, struct device *dev); /* */ +static slave_t *eql_find_slave_dev(slave_queue_t *queue, struct net_device *dev); /* */ /* static inline eql_lock_slave_queue(slave_queue_t *queue); -* */ /* static inline eql_unlock_slave_queue(slave_queue_t *queue); -* */ static void eql_timer(unsigned long param); /* */ -/* struct device * interface functions +/* struct net_device * interface functions --------------------------------------------------------- */ -int __init eql_init(struct device *dev) +int __init eql_init(struct net_device *dev) { static unsigned version_printed = 0; /* static unsigned num_masters = 0; */ @@ -268,7 +268,7 @@ return 0; } -static int eql_open(struct device *dev) +static int eql_open(struct net_device *dev) { equalizer_t *eql = (equalizer_t *) dev->priv; slave_queue_t *new_queue; @@ -301,7 +301,7 @@ } -static int eql_close(struct device *dev) +static int eql_close(struct net_device *dev) { equalizer_t *eql = (equalizer_t *) dev->priv; @@ -327,7 +327,7 @@ } -static int eql_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int eql_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { if(cmd!=EQL_GETMASTRCFG && cmd!=EQL_GETSLAVECFG && !capable(CAP_NET_ADMIN)) @@ -352,10 +352,10 @@ } -static int eql_slave_xmit(struct sk_buff *skb, struct device *dev) +static int eql_slave_xmit(struct sk_buff *skb, struct net_device *dev) { equalizer_t *eql = (equalizer_t *) dev->priv; - struct device *slave_dev = 0; + struct net_device *slave_dev = 0; slave_t *slave; if (skb == NULL) @@ -394,7 +394,7 @@ } -static struct net_device_stats * eql_get_stats(struct device *dev) +static struct net_device_stats * eql_get_stats(struct net_device *dev) { equalizer_t *eql = (equalizer_t *) dev->priv; return eql->stats; @@ -404,10 +404,10 @@ * Private ioctl functions */ -static int eql_enslave(struct device *dev, slaving_request_t *srqp) +static int eql_enslave(struct net_device *dev, slaving_request_t *srqp) { - struct device *master_dev; - struct device *slave_dev; + struct net_device *master_dev; + struct net_device *slave_dev; slaving_request_t srq; int err; @@ -465,10 +465,10 @@ return -EINVAL; } -static int eql_emancipate(struct device *dev, slaving_request_t *srqp) +static int eql_emancipate(struct net_device *dev, slaving_request_t *srqp) { - struct device *master_dev; - struct device *slave_dev; + struct net_device *master_dev; + struct net_device *slave_dev; slaving_request_t srq; int err; @@ -494,11 +494,11 @@ } -static int eql_g_slave_cfg(struct device *dev, slave_config_t *scp) +static int eql_g_slave_cfg(struct net_device *dev, slave_config_t *scp) { slave_t *slave; equalizer_t *eql; - struct device *slave_dev; + struct net_device *slave_dev; slave_config_t sc; int err; @@ -530,11 +530,11 @@ } -static int eql_s_slave_cfg(struct device *dev, slave_config_t *scp) +static int eql_s_slave_cfg(struct net_device *dev, slave_config_t *scp) { slave_t *slave; equalizer_t *eql; - struct device *slave_dev; + struct net_device *slave_dev; slave_config_t sc; int err; @@ -566,7 +566,7 @@ } -static int eql_g_master_cfg(struct device *dev, master_config_t *mcp) +static int eql_g_master_cfg(struct net_device *dev, master_config_t *mcp) { equalizer_t *eql; master_config_t mc; @@ -591,7 +591,7 @@ } -static int eql_s_master_cfg(struct device *dev, master_config_t *mcp) +static int eql_s_master_cfg(struct net_device *dev, master_config_t *mcp) { equalizer_t *eql; master_config_t mc; @@ -618,7 +618,7 @@ * Private device support functions */ -static inline int eql_is_slave(struct device *dev) +static inline int eql_is_slave(struct net_device *dev) { if (dev) { @@ -629,7 +629,7 @@ } -static inline int eql_is_master(struct device *dev) +static inline int eql_is_master(struct net_device *dev) { if (dev) { @@ -695,7 +695,7 @@ return 0; } -static slave_queue_t *eql_new_slave_queue(struct device *dev) +static slave_queue_t *eql_new_slave_queue(struct net_device *dev) { slave_queue_t *queue; slave_t *head_slave; @@ -804,7 +804,7 @@ } -static int eql_remove_slave_dev(slave_queue_t *queue, struct device *dev) +static int eql_remove_slave_dev(slave_queue_t *queue, struct net_device *dev) { slave_t *prev; slave_t *curr; @@ -832,7 +832,7 @@ } -static inline struct device *eql_best_slave_dev(slave_queue_t *queue) +static inline struct net_device *eql_best_slave_dev(slave_queue_t *queue) { if (queue->best_slave != 0) { @@ -853,7 +853,7 @@ static inline void eql_schedule_slaves(slave_queue_t *queue) { - struct device *master_dev = queue->master_dev; + struct net_device *master_dev = queue->master_dev; slave_t *best_slave = 0; slave_t *slave_corpse = 0; @@ -937,7 +937,7 @@ } -static slave_t * eql_find_slave_dev(slave_queue_t *queue, struct device *dev) +static slave_t * eql_find_slave_dev(slave_queue_t *queue, struct net_device *dev) { slave_t *slave = 0; slave = eql_first_slave(queue); @@ -1014,7 +1014,7 @@ } #ifdef MODULE -static struct device dev_eql = +static struct net_device dev_eql = { "eql", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, eql_init }; diff -u --recursive --new-file v2.3.13/linux/drivers/net/es3210.c linux/drivers/net/es3210.c --- v2.3.13/linux/drivers/net/es3210.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/es3210.c Wed Aug 18 11:36:42 1999 @@ -61,17 +61,17 @@ #include #include "8390.h" -int es_probe(struct device *dev); -int es_probe1(struct device *dev, int ioaddr); +int es_probe(struct net_device *dev); +int es_probe1(struct net_device *dev, int ioaddr); -static int es_open(struct device *dev); -static int es_close(struct device *dev); +static int es_open(struct net_device *dev); +static int es_close(struct net_device *dev); -static void es_reset_8390(struct device *dev); +static void es_reset_8390(struct net_device *dev); -static void es_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void es_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset); -static void es_block_output(struct device *dev, int count, const unsigned char *buf, int start_page); +static void es_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); +static void es_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); +static void es_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page); #define ES_START_PG 0x00 /* First page of TX buffer */ #define ES_STOP_PG 0x40 /* Last page +1 of RX ring */ @@ -124,7 +124,7 @@ * PROM for a match against the Racal-Interlan assigned value. */ -int __init es_probe(struct device *dev) +int __init es_probe(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; @@ -151,7 +151,7 @@ return ENODEV; } -int __init es_probe1(struct device *dev, int ioaddr) +int __init es_probe1(struct net_device *dev, int ioaddr) { int i; unsigned long eisa_id; @@ -284,7 +284,7 @@ * file, this just toggles the "Board Enable" bits (bit 2 and 0). */ -static void es_reset_8390(struct device *dev) +static void es_reset_8390(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; unsigned long end; @@ -318,7 +318,7 @@ */ static void -es_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +es_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = dev->mem_start + ((ring_page - ES_START_PG)<<8); memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); @@ -331,7 +331,7 @@ * be rounded up to a doubleword value via es_get_8390_hdr() above. */ -static void es_block_input(struct device *dev, int count, struct sk_buff *skb, +static void es_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned long xfer_start = dev->mem_start + ring_offset - (ES_START_PG<<8); @@ -348,7 +348,7 @@ } } -static void es_block_output(struct device *dev, int count, +static void es_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { unsigned long shmem = dev->mem_start + ((start_page - ES_START_PG)<<8); @@ -357,7 +357,7 @@ memcpy_toio(shmem, buf, count); } -static int es_open(struct device *dev) +static int es_open(struct net_device *dev) { ei_open(dev); @@ -366,7 +366,7 @@ return 0; } -static int es_close(struct device *dev) +static int es_close(struct net_device *dev) { if (ei_debug > 1) @@ -383,7 +383,7 @@ #define MAX_ES_CARDS 4 /* Max number of ES3210 cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_ES_CARDS] = { 0, }; -static struct device dev_es3210[MAX_ES_CARDS] = { +static struct net_device dev_es3210[MAX_ES_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -406,7 +406,7 @@ int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) { - struct device *dev = &dev_es3210[this_dev]; + struct net_device *dev = &dev_es3210[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -434,7 +434,7 @@ int this_dev; for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) { - struct device *dev = &dev_es3210[this_dev]; + struct net_device *dev = &dev_es3210[this_dev]; if (dev->priv != NULL) { void *priv = dev->priv; free_irq(dev->irq, dev); diff -u --recursive --new-file v2.3.13/linux/drivers/net/eth16i.c linux/drivers/net/eth16i.c --- v2.3.13/linux/drivers/net/eth16i.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/eth16i.c Wed Aug 18 11:36:42 1999 @@ -407,9 +407,9 @@ /* Function prototypes */ -extern int eth16i_probe(struct device *dev); +extern int eth16i_probe(struct net_device *dev); -static int eth16i_probe1(struct device *dev, int ioaddr); +static int eth16i_probe1(struct net_device *dev, int ioaddr); static int eth16i_check_signature(int ioaddr); static int eth16i_probe_port(int ioaddr); static void eth16i_set_port(int ioaddr, int porttype); @@ -419,26 +419,26 @@ static int eth16i_read_eeprom(int ioaddr, int offset); static int eth16i_read_eeprom_word(int ioaddr); static void eth16i_eeprom_cmd(int ioaddr, unsigned char command); -static int eth16i_open(struct device *dev); -static int eth16i_close(struct device *dev); -static int eth16i_tx(struct sk_buff *skb, struct device *dev); -static void eth16i_rx(struct device *dev); +static int eth16i_open(struct net_device *dev); +static int eth16i_close(struct net_device *dev); +static int eth16i_tx(struct sk_buff *skb, struct net_device *dev); +static void eth16i_rx(struct net_device *dev); static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void eth16i_reset(struct device *dev); -static void eth16i_skip_packet(struct device *dev); -static void eth16i_multicast(struct device *dev); +static void eth16i_reset(struct net_device *dev); +static void eth16i_skip_packet(struct net_device *dev); +static void eth16i_multicast(struct net_device *dev); static void eth16i_select_regbank(unsigned char regbank, int ioaddr); -static void eth16i_initialize(struct device *dev); +static void eth16i_initialize(struct net_device *dev); #if 0 -static int eth16i_set_irq(struct device *dev); +static int eth16i_set_irq(struct net_device *dev); #endif #ifdef MODULE static ushort eth16i_parse_mediatype(const char* s); #endif -static struct enet_statistics *eth16i_get_stats(struct device *dev); +static struct enet_statistics *eth16i_get_stats(struct net_device *dev); static char *cardname = "ICL EtherTeam 16i/32"; @@ -450,7 +450,7 @@ #else /* Not HAVE_DEVLIST */ -int __init eth16i_probe(struct device *dev) +int __init eth16i_probe(struct net_device *dev) { int i; int ioaddr; @@ -484,7 +484,7 @@ } #endif /* Not HAVE_DEVLIST */ -static int __init eth16i_probe1(struct device *dev, int ioaddr) +static int __init eth16i_probe1(struct net_device *dev, int ioaddr) { static unsigned version_printed = 0; boot = 1; /* To inform initilization that we are in boot probe */ @@ -593,7 +593,7 @@ } -static void eth16i_initialize(struct device *dev) +static void eth16i_initialize(struct net_device *dev) { int ioaddr = dev->base_addr; int i, node_w = 0; @@ -824,7 +824,7 @@ } #if 0 -static int eth16i_set_irq(struct device* dev) +static int eth16i_set_irq(struct net_device* dev) { const int ioaddr = dev->base_addr; const int irq = dev->irq; @@ -966,7 +966,7 @@ } } -static int eth16i_open(struct device *dev) +static int eth16i_open(struct net_device *dev) { struct eth16i_local *lp = (struct eth16i_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1007,7 +1007,7 @@ return 0; } -static int eth16i_close(struct device *dev) +static int eth16i_close(struct net_device *dev) { struct eth16i_local *lp = (struct eth16i_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1036,7 +1036,7 @@ return 0; } -static int eth16i_tx(struct sk_buff *skb, struct device *dev) +static int eth16i_tx(struct sk_buff *skb, struct net_device *dev) { struct eth16i_local *lp = (struct eth16i_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1185,7 +1185,7 @@ return status; } -static void eth16i_rx(struct device *dev) +static void eth16i_rx(struct net_device *dev) { struct eth16i_local *lp = (struct eth16i_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1300,7 +1300,7 @@ static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct eth16i_local *lp; int ioaddr = 0, status; @@ -1406,7 +1406,7 @@ return; } -static void eth16i_skip_packet(struct device *dev) +static void eth16i_skip_packet(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -1418,7 +1418,7 @@ while( inb( ioaddr + FILTER_SELF_RX_REG ) != 0); } -static void eth16i_reset(struct device *dev) +static void eth16i_reset(struct net_device *dev) { struct eth16i_local *lp = (struct eth16i_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1441,7 +1441,7 @@ BITCLR(ioaddr + CONFIG_REG_0, DLC_EN); } -static void eth16i_multicast(struct device *dev) +static void eth16i_multicast(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -1454,7 +1454,7 @@ } } -static struct enet_statistics *eth16i_get_stats(struct device *dev) +static struct enet_statistics *eth16i_get_stats(struct net_device *dev) { struct eth16i_local *lp = (struct eth16i_local *)dev->priv; @@ -1492,7 +1492,7 @@ #define NAMELEN 8 /* number of chars for storing dev->name */ static char namelist[NAMELEN * MAX_ETH16I_CARDS] = { 0, }; -static struct device dev_eth16i[MAX_ETH16I_CARDS] = { +static struct net_device dev_eth16i[MAX_ETH16I_CARDS] = { { NULL, 0, 0, 0, 0, @@ -1533,7 +1533,7 @@ for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) { - struct device *dev = &dev_eth16i[this_dev]; + struct net_device *dev = &dev_eth16i[this_dev]; dev->name = namelist + (NAMELEN*this_dev); dev->irq = 0; /* irq[this_dev]; */ @@ -1575,7 +1575,7 @@ for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) { - struct device* dev = &dev_eth16i[this_dev]; + struct net_device* dev = &dev_eth16i[this_dev]; if(dev->priv != NULL) { diff -u --recursive --new-file v2.3.13/linux/drivers/net/ethertap.c linux/drivers/net/ethertap.c --- v2.3.13/linux/drivers/net/ethertap.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/ethertap.c Wed Aug 18 11:36:42 1999 @@ -33,19 +33,19 @@ * Index to functions. */ -int ethertap_probe(struct device *dev); -static int ethertap_open(struct device *dev); -static int ethertap_start_xmit(struct sk_buff *skb, struct device *dev); -static int ethertap_close(struct device *dev); -static struct net_device_stats *ethertap_get_stats(struct device *dev); +int ethertap_probe(struct net_device *dev); +static int ethertap_open(struct net_device *dev); +static int ethertap_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int ethertap_close(struct net_device *dev); +static struct net_device_stats *ethertap_get_stats(struct net_device *dev); static void ethertap_rx(struct sock *sk, int len); #ifdef CONFIG_ETHERTAP_MC -static void set_multicast_list(struct device *dev); +static void set_multicast_list(struct net_device *dev); #endif static int ethertap_debug = 0; -static struct device *tap_map[32]; /* Returns the tap device for a given netlink */ +static struct net_device *tap_map[32]; /* Returns the tap device for a given netlink */ /* * Board-specific info in dev->priv. @@ -65,7 +65,7 @@ * hardware it would have to check what was present. */ -int __init ethertap_probe(struct device *dev) +int __init ethertap_probe(struct net_device *dev) { memcpy(dev->dev_addr, "\xFE\xFD\x00\x00\x00\x00", 6); if (dev->mem_start & 0xf) @@ -109,7 +109,7 @@ * Open/initialize the board. */ -static int ethertap_open(struct device *dev) +static int ethertap_open(struct net_device *dev) { struct net_local *lp = (struct net_local*)dev->priv; @@ -142,7 +142,7 @@ return 1U << (idx&0x1F); } -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { unsigned groups = ~0; struct net_local *lp = (struct net_local *)dev->priv; @@ -169,7 +169,7 @@ * it for 2.0 so that we dev_kfree_skb() the locked original. */ -static int ethertap_start_xmit(struct sk_buff *skb, struct device *dev) +static int ethertap_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; #ifdef CONFIG_ETHERTAP_MC @@ -227,7 +227,7 @@ return 0; } -static __inline__ int ethertap_rx_skb(struct sk_buff *skb, struct device *dev) +static __inline__ int ethertap_rx_skb(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; #ifdef CONFIG_ETHERTAP_MC @@ -295,7 +295,7 @@ static void ethertap_rx(struct sock *sk, int len) { - struct device *dev = tap_map[sk->protocol]; + struct net_device *dev = tap_map[sk->protocol]; struct sk_buff *skb; if (dev==NULL) { @@ -311,7 +311,7 @@ ethertap_rx_skb(skb, dev); } -static int ethertap_close(struct device *dev) +static int ethertap_close(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; struct sock *sk = lp->nl; @@ -331,7 +331,7 @@ return 0; } -static struct net_device_stats *ethertap_get_stats(struct device *dev) +static struct net_device_stats *ethertap_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; return &lp->stats; @@ -344,7 +344,7 @@ static char devicename[9] = { 0, }; -static struct device dev_ethertap = +static struct net_device dev_ethertap = { devicename, 0, 0, 0, 0, diff -u --recursive --new-file v2.3.13/linux/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c --- v2.3.13/linux/drivers/net/ewrk3.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/ewrk3.c Wed Aug 18 11:36:42 1999 @@ -288,36 +288,36 @@ /* ** Public Functions */ -static int ewrk3_open(struct device *dev); -static int ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev); +static int ewrk3_open(struct net_device *dev); +static int ewrk3_queue_pkt(struct sk_buff *skb, struct net_device *dev); static void ewrk3_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int ewrk3_close(struct device *dev); -static struct net_device_stats *ewrk3_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); -static int ewrk3_ioctl(struct device *dev, struct ifreq *rq, int cmd); +static int ewrk3_close(struct net_device *dev); +static struct net_device_stats *ewrk3_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); +static int ewrk3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); /* ** Private functions */ -static int ewrk3_hw_init(struct device *dev, u_long iobase); -static void ewrk3_init(struct device *dev); -static int ewrk3_rx(struct device *dev); -static int ewrk3_tx(struct device *dev); +static int ewrk3_hw_init(struct net_device *dev, u_long iobase); +static void ewrk3_init(struct net_device *dev); +static int ewrk3_rx(struct net_device *dev); +static int ewrk3_tx(struct net_device *dev); static void EthwrkSignature(char *name, char *eeprom_image); static int DevicePresent(u_long iobase); -static void SetMulticastFilter(struct device *dev); +static void SetMulticastFilter(struct net_device *dev); static int EISA_signature(char *name, s32 eisa_id); static int Read_EEPROM(u_long iobase, u_char eaddr); static int Write_EEPROM(short data, u_long iobase, u_char eaddr); -static u_char get_hw_addr(struct device *dev, u_char * eeprom_image, char chipType); +static u_char get_hw_addr(struct net_device *dev, u_char * eeprom_image, char chipType); -static void isa_probe(struct device *dev, u_long iobase); -static void eisa_probe(struct device *dev, u_long iobase); -static struct device *alloc_device(struct device *dev, u_long iobase); +static void isa_probe(struct net_device *dev, u_long iobase); +static void eisa_probe(struct net_device *dev, u_long iobase); +static struct net_device *alloc_device(struct net_device *dev, u_long iobase); static int ewrk3_dev_index(char *s); -static struct device *insert_device(struct device *dev, u_long iobase, int (*init) (struct device *)); +static struct net_device *insert_device(struct net_device *dev, u_long iobase, int (*init) (struct net_device *)); #ifdef MODULE @@ -343,7 +343,7 @@ mdelay(1);\ } -int __init ewrk3_probe(struct device *dev) +int __init ewrk3_probe(struct net_device *dev) { int tmp = num_ewrk3s, status = -ENODEV; u_long iobase = dev->base_addr; @@ -376,7 +376,7 @@ } static int __init -ewrk3_hw_init(struct device *dev, u_long iobase) +ewrk3_hw_init(struct net_device *dev, u_long iobase) { struct ewrk3_private *lp; int i, status = 0; @@ -621,7 +621,7 @@ } -static int ewrk3_open(struct device *dev) +static int ewrk3_open(struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; u_long iobase = dev->base_addr; @@ -690,7 +690,7 @@ /* ** Initialize the EtherWORKS 3 operating conditions */ -static void ewrk3_init(struct device *dev) +static void ewrk3_init(struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; u_char csr, page; @@ -724,7 +724,7 @@ /* ** Writes a socket buffer to the free page queue */ -static int ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev) +static int ewrk3_queue_pkt(struct sk_buff *skb, struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; u_long iobase = dev->base_addr; @@ -873,7 +873,7 @@ */ static void ewrk3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct ewrk3_private *lp; u_long iobase; u_char icr, cr, csr; @@ -934,7 +934,7 @@ return; } -static int ewrk3_rx(struct device *dev) +static int ewrk3_rx(struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; u_long iobase = dev->base_addr; @@ -1078,7 +1078,7 @@ /* ** Buffer sent - check for TX buffer errors. */ -static int ewrk3_tx(struct device *dev) +static int ewrk3_tx(struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; u_long iobase = dev->base_addr; @@ -1114,7 +1114,7 @@ return 0; } -static int ewrk3_close(struct device *dev) +static int ewrk3_close(struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; u_long iobase = dev->base_addr; @@ -1152,7 +1152,7 @@ return 0; } -static struct net_device_stats *ewrk3_get_stats(struct device *dev) +static struct net_device_stats *ewrk3_get_stats(struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; @@ -1163,7 +1163,7 @@ /* ** Set or clear the multicast filter for this adapter. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; u_long iobase = dev->base_addr; @@ -1196,7 +1196,7 @@ ** Note that when clearing the table, the broadcast bit must remain asserted ** to receive broadcast messages. */ -static void SetMulticastFilter(struct device *dev) +static void SetMulticastFilter(struct net_device *dev) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; struct dev_mc_list *dmi = dev->mc_list; @@ -1282,7 +1282,7 @@ /* ** ISA bus I/O device probe */ -static void __init isa_probe(struct device *dev, u_long ioaddr) +static void __init isa_probe(struct net_device *dev, u_long ioaddr) { int i = num_ewrk3s, maxSlots; u_long iobase; @@ -1322,7 +1322,7 @@ ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually ** the motherboard. */ -static void __init eisa_probe(struct device *dev, u_long ioaddr) +static void __init eisa_probe(struct net_device *dev, u_long ioaddr) { int i, maxSlots; u_long iobase; @@ -1369,10 +1369,10 @@ ** are not available then insert a new device structure at the end of ** the current list. */ -static struct device * __init -alloc_device(struct device *dev, u_long iobase) +static struct net_device * __init +alloc_device(struct net_device *dev, u_long iobase) { - struct device *adev = NULL; + struct net_device *adev = NULL; int fixed = 0, new_dev = 0; num_eth = ewrk3_dev_index(dev->name); @@ -1414,12 +1414,12 @@ ** If at end of eth device list and can't use current entry, malloc ** one up. If memory could not be allocated, print an error message. */ -static __init struct device * -insert_device(struct device *dev, u_long iobase, int (*init) (struct device *)) +static __init struct net_device * +insert_device(struct net_device *dev, u_long iobase, int (*init) (struct net_device *)) { - struct device *new; + struct net_device *new; - new = (struct device *) kmalloc(sizeof(struct device) + 8, GFP_KERNEL); + new = (struct net_device *) kmalloc(sizeof(struct net_device) + 8, GFP_KERNEL); if (new == NULL) { printk("eth%d: Device not initialised, insufficient memory\n", num_eth); return NULL; @@ -1570,7 +1570,7 @@ return status; } -static u_char __init get_hw_addr(struct device *dev, u_char * eeprom_image, char chipType) +static u_char __init get_hw_addr(struct net_device *dev, u_char * eeprom_image, char chipType) { int i, j, k; u_short chksum; @@ -1658,7 +1658,7 @@ ** Perform IOCTL call functions here. Some are privileged operations and the ** effective uid is checked in those cases. */ -static int ewrk3_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int ewrk3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv; struct ewrk3_ioctl *ioc = (struct ewrk3_ioctl *) &rq->ifr_data; @@ -1879,7 +1879,7 @@ #ifdef MODULE static char devicename[9] = {0,}; -static struct device thisEthwrk = +static struct net_device thisEthwrk = { devicename, /* device name is inserted by /linux/drivers/net/net_init.c */ 0, 0, 0, 0, diff -u --recursive --new-file v2.3.13/linux/drivers/net/fmv18x.c linux/drivers/net/fmv18x.c --- v2.3.13/linux/drivers/net/fmv18x.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/fmv18x.c Wed Aug 18 11:36:42 1999 @@ -108,16 +108,16 @@ /* Index to functions, as function prototypes. */ -extern int fmv18x_probe(struct device *dev); +extern int fmv18x_probe(struct net_device *dev); -static int fmv18x_probe1(struct device *dev, short ioaddr); -static int net_open(struct device *dev); -static int net_send_packet(struct sk_buff *skb, struct device *dev); +static int fmv18x_probe1(struct net_device *dev, short ioaddr); +static int net_open(struct net_device *dev); +static int net_send_packet(struct sk_buff *skb, struct net_device *dev); static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void net_rx(struct device *dev); -static int net_close(struct device *dev); -static struct net_device_stats *net_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static void net_rx(struct net_device *dev); +static int net_close(struct net_device *dev); +static struct net_device_stats *net_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); /* Check for a network adaptor of this type, and return '0' iff one exists. @@ -133,7 +133,7 @@ {"fmv18x", fmv18x_probe1, FMV18X_IO_EXTENT, fmv18x_probe_list}; #else int __init -fmv18x_probe(struct device *dev) +fmv18x_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -163,7 +163,7 @@ that can be done is checking a few bits and then diving right into MAC address check. */ -int __init fmv18x_probe1(struct device *dev, short ioaddr) +int __init fmv18x_probe1(struct net_device *dev, short ioaddr) { char irqmap[4] = {3, 7, 10, 15}; char irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15}; @@ -287,7 +287,7 @@ } -static int net_open(struct device *dev) +static int net_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -326,7 +326,7 @@ } static int -net_send_packet(struct sk_buff *skb, struct device *dev) +net_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -420,7 +420,7 @@ static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *lp; int ioaddr, status; @@ -483,7 +483,7 @@ /* We have a good packet(s), get it/them out of the buffers. */ static void -net_rx(struct device *dev) +net_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -572,7 +572,7 @@ } /* The inverse routine to net_open(). */ -static int net_close(struct device *dev) +static int net_close(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -599,7 +599,7 @@ /* Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *net_get_stats(struct device *dev) +static struct net_device_stats *net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -617,7 +617,7 @@ best-effort filtering. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { short ioaddr = dev->base_addr; if (dev->mc_count || dev->flags&(IFF_PROMISC|IFF_ALLMULTI)) @@ -637,7 +637,7 @@ #ifdef MODULE static char devicename[9] = { 0, }; -static struct device dev_fmv18x = { +static struct net_device dev_fmv18x = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0, 0, diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/6pack.c linux/drivers/net/hamradio/6pack.c --- v2.3.13/linux/drivers/net/hamradio/6pack.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/hamradio/6pack.c Wed Aug 18 11:38:51 1999 @@ -53,7 +53,7 @@ typedef struct sixpack_ctrl { char if_name[8]; /* "sp0\0" .. "sp99999\0" */ struct sixpack ctrl; /* 6pack things */ - struct device dev; /* the device */ + struct net_device dev; /* the device */ } sixpack_ctrl_t; static sixpack_ctrl_t **sixpack_ctrls = NULL; int sixpack_maxdev = SIXP_NRUNIT; /* Can be overridden with insmod! */ @@ -327,7 +327,7 @@ /* Encapsulate an IP datagram and kick it into a TTY queue. */ static int -sp_xmit(struct sk_buff *skb, struct device *dev) +sp_xmit(struct sk_buff *skb, struct net_device *dev) { struct sixpack *sp = (struct sixpack*)(dev->priv); @@ -382,7 +382,7 @@ /* #if defined(CONFIG_6PACK) || defined(CONFIG_6PACK_MODULE) */ /* Return the frame type ID */ -static int sp_header(struct sk_buff *skb, struct device *dev, unsigned short type, +static int sp_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { #ifdef CONFIG_INET @@ -406,7 +406,7 @@ /* Open the low-level part of the 6pack channel. */ static int -sp_open(struct device *dev) +sp_open(struct net_device *dev) { struct sixpack *sp = (struct sixpack*)(dev->priv); unsigned long len; @@ -469,7 +469,7 @@ /* Close the low-level part of the 6pack channel. */ static int -sp_close(struct device *dev) +sp_close(struct net_device *dev) { struct sixpack *sp = (struct sixpack*)(dev->priv); @@ -612,7 +612,7 @@ static struct net_device_stats * -sp_get_stats(struct device *dev) +sp_get_stats(struct net_device *dev) { static struct net_device_stats stats; struct sixpack *sp = (struct sixpack*)(dev->priv); @@ -633,7 +633,7 @@ int -sp_set_mac_address(struct device *dev, void *addr) +sp_set_mac_address(struct net_device *dev, void *addr) { int err; @@ -648,7 +648,7 @@ } static int -sp_set_dev_mac_address(struct device *dev, void *addr) +sp_set_dev_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa=addr; memcpy(dev->dev_addr, sa->sa_data, AX25_ADDR_LEN); @@ -713,7 +713,7 @@ } } -static int sp_open_dev(struct device *dev) +static int sp_open_dev(struct net_device *dev) { struct sixpack *sp = (struct sixpack*)(dev->priv); if(sp->tty==NULL) @@ -726,7 +726,7 @@ #ifdef MODULE static int sixpack_init_ctrl_dev(void) #else /* !MODULE */ -int __init sixpack_init_ctrl_dev(struct device *dummy) +int __init sixpack_init_ctrl_dev(struct net_device *dummy) #endif /* !MODULE */ { int status; @@ -778,7 +778,7 @@ /* Initialize the 6pack driver. Called by DDI. */ int -sixpack_init(struct device *dev) +sixpack_init(struct net_device *dev) { struct sixpack *sp = (struct sixpack*)(dev->priv); diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/6pack.h linux/drivers/net/hamradio/6pack.h --- v2.3.13/linux/drivers/net/hamradio/6pack.h Wed Apr 8 17:31:27 1998 +++ linux/drivers/net/hamradio/6pack.h Wed Aug 18 11:38:51 1999 @@ -70,7 +70,7 @@ /* Various fields. */ struct tty_struct *tty; /* ptr to TTY structure */ - struct device *dev; /* easy for intr handling */ + struct net_device *dev; /* easy for intr handling */ /* These are pointers to the malloc()ed frame buffers. */ unsigned char *rbuff; /* receiver buffer */ @@ -128,7 +128,7 @@ #define AX25_6PACK_HEADER_LEN 0 #define SIXPACK_MAGIC 0x5304 -extern int sixpack_init(struct device *dev); +extern int sixpack_init(struct net_device *dev); #endif diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/Config.in linux/drivers/net/hamradio/Config.in --- v2.3.13/linux/drivers/net/hamradio/Config.in Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/hamradio/Config.in Thu Aug 12 12:18:32 1999 @@ -11,12 +11,13 @@ bool ' support for TRX that feedback the tx signal to rx' CONFIG_SCC_TRXECHO fi -tristate 'BAYCOM ser12 fullduplex driver for AX.25' CONFIG_BAYCOM_SER_FDX -tristate 'BAYCOM ser12 halfduplex driver for AX.25' CONFIG_BAYCOM_SER_HDX -dep_tristate 'BAYCOM picpar and par96 driver for AX.25' CONFIG_BAYCOM_PAR $CONFIG_PARPORT -dep_tristate 'BAYCOM epp driver for AX.25' CONFIG_BAYCOM_EPP $CONFIG_PARPORT +dep_tristate 'BAYCOM ser12 fullduplex driver for AX.25' CONFIG_BAYCOM_SER_FDX $CONFIG_AX25 +dep_tristate 'BAYCOM ser12 halfduplex driver for AX.25' CONFIG_BAYCOM_SER_HDX $CONFIG_AX25 +dep_tristate 'BAYCOM picpar and par96 driver for AX.25' CONFIG_BAYCOM_PAR $CONFIG_PARPORT $CONFIG_AX25 +dep_tristate 'BAYCOM epp driver for AX.25' CONFIG_BAYCOM_EPP $CONFIG_PARPORT $CONFIG_AX25 +dep_tristate 'BAYCOM eppflex driver for AX.25' CONFIG_BAYCOM_EPPFLEX $CONFIG_PARPORT $CONFIG_AX25 -dep_tristate 'Soundcard modem driver' CONFIG_SOUNDMODEM $CONFIG_PARPORT +dep_tristate 'Soundcard modem driver' CONFIG_SOUNDMODEM $CONFIG_PARPORT $CONFIG_AX25 if [ "$CONFIG_SOUNDMODEM" != "n" ]; then bool ' soundmodem support for Soundblaster and compatible cards' CONFIG_SOUNDMODEM_SBC bool ' soundmodem support for WSS and Crystal cards' CONFIG_SOUNDMODEM_WSS diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/Makefile linux/drivers/net/hamradio/Makefile --- v2.3.13/linux/drivers/net/hamradio/Makefile Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/hamradio/Makefile Thu Aug 12 12:19:41 1999 @@ -11,8 +11,8 @@ MOD_SUB_DIRS := $(SUB_DIRS) ALL_SUB_DIRS := $(SUB_DIRS) -L_TARGET := hamradio.a -L_OBJS := +O_TARGET := hamradio.o +O_OBJS := M_OBJS := MOD_LIST_NAME := HAM_MODULES @@ -22,7 +22,7 @@ CONFIG_HDLCDRV_MODULE := ifeq ($(CONFIG_DMASCC),y) -L_OBJS += dmascc.o +O_OBJS += dmascc.o else ifeq ($(CONFIG_DMASCC),m) M_OBJS += dmascc.o @@ -30,7 +30,7 @@ endif ifeq ($(CONFIG_SCC),y) -L_OBJS += scc.o +O_OBJS += scc.o else ifeq ($(CONFIG_SCC),m) M_OBJS += scc.o @@ -38,7 +38,7 @@ endif ifeq ($(CONFIG_MKISS),y) -L_OBJS += mkiss.o +O_OBJS += mkiss.o else ifeq ($(CONFIG_MKISS),m) M_OBJS += mkiss.o @@ -46,7 +46,7 @@ endif ifeq ($(CONFIG_6PACK),y) -L_OBJS += 6pack.o +O_OBJS += 6pack.o else ifeq ($(CONFIG_6PACK),m) M_OBJS += 6pack.o @@ -54,7 +54,7 @@ endif ifeq ($(CONFIG_YAM),y) -L_OBJS += yam.o +O_OBJS += yam.o else ifeq ($(CONFIG_YAM),m) M_OBJS += yam.o @@ -62,7 +62,7 @@ endif ifeq ($(CONFIG_PI),y) -L_OBJS += pi2.o +O_OBJS += pi2.o else ifeq ($(CONFIG_PI),m) M_OBJS += pi2.o @@ -70,7 +70,7 @@ endif ifeq ($(CONFIG_PT),y) -L_OBJS += pt.o +O_OBJS += pt.o else ifeq ($(CONFIG_PT),m) M_OBJS += pt.o @@ -78,7 +78,7 @@ endif ifeq ($(CONFIG_BPQETHER),y) -L_OBJS += bpqether.o +O_OBJS += bpqether.o else ifeq ($(CONFIG_BPQETHER),m) M_OBJS += bpqether.o @@ -86,7 +86,7 @@ endif ifeq ($(CONFIG_BAYCOM_SER_FDX),y) -L_OBJS += baycom_ser_fdx.o +O_OBJS += baycom_ser_fdx.o CONFIG_HDLCDRV_BUILTIN = y else ifeq ($(CONFIG_BAYCOM_SER_FDX),m) @@ -96,7 +96,7 @@ endif ifeq ($(CONFIG_BAYCOM_SER_HDX),y) -L_OBJS += baycom_ser_hdx.o +O_OBJS += baycom_ser_hdx.o CONFIG_HDLCDRV_BUILTIN = y else ifeq ($(CONFIG_BAYCOM_SER_HDX),m) @@ -106,7 +106,7 @@ endif ifeq ($(CONFIG_BAYCOM_PAR),y) -L_OBJS += baycom_par.o +O_OBJS += baycom_par.o CONFIG_HDLCDRV_BUILTIN = y else ifeq ($(CONFIG_BAYCOM_PAR),m) @@ -116,7 +116,7 @@ endif ifeq ($(CONFIG_BAYCOM_EPP),y) -L_OBJS += baycom_epp.o +O_OBJS += baycom_epp.o CONFIG_HDLCDRV_BUILTIN = y else ifeq ($(CONFIG_BAYCOM_EPP),m) @@ -128,7 +128,7 @@ ifeq ($(CONFIG_SOUNDMODEM),y) ALL_SUB_DIRS += soundmodem SUB_DIRS += soundmodem -L_OBJS += soundmodem/soundmodem.o +O_OBJS += soundmodem/soundmodem.o CONFIG_HDLCDRV_BUILTIN = y else ifeq ($(CONFIG_SOUNDMODEM),m) @@ -141,7 +141,7 @@ # If anything built-in uses the hdlcdrv, then build it into the kernel also. # If not, but a module uses it, build as a module. ifdef CONFIG_HDLCDRV_BUILTIN -LX_OBJS += hdlcdrv.o +OX_OBJS += hdlcdrv.o else ifdef CONFIG_HDLCDRV_MODULE MX_OBJS += hdlcdrv.o diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/baycom_epp.c linux/drivers/net/hamradio/baycom_epp.c --- v2.3.13/linux/drivers/net/hamradio/baycom_epp.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/hamradio/baycom_epp.c Wed Aug 18 11:38:51 1999 @@ -95,7 +95,7 @@ #define NR_PORTS 4 -static struct device baycom_device[NR_PORTS]; +static struct net_device baycom_device[NR_PORTS]; /* --------------------------------------------------------------------- */ @@ -698,7 +698,7 @@ /* ---------------------------------------------------------------------- */ -static void do_rxpacket(struct device *dev) +static void do_rxpacket(struct net_device *dev) { struct baycom_state *bc = (struct baycom_state *)dev->priv; struct sk_buff *skb; @@ -756,7 +756,7 @@ goto enditer##j; \ }) -static int receive(struct device *dev, int cnt) +static int receive(struct net_device *dev, int cnt) { struct baycom_state *bc = (struct baycom_state *)dev->priv; struct parport *pp = bc->pdev->port; @@ -832,7 +832,7 @@ #define GETTICK(x) #endif /* __i386__ */ -static void epp_bh(struct device *dev) +static void epp_bh(struct net_device *dev) { struct baycom_state *bc; struct parport *pp; @@ -953,7 +953,7 @@ * ===================== network driver interface ========================= */ -static int baycom_send_packet(struct sk_buff *skb, struct device *dev) +static int baycom_send_packet(struct sk_buff *skb, struct net_device *dev) { struct baycom_state *bc; @@ -966,7 +966,7 @@ /* --------------------------------------------------------------------- */ -static int baycom_set_mac_address(struct device *dev, void *addr) +static int baycom_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = (struct sockaddr *)addr; @@ -977,7 +977,7 @@ /* --------------------------------------------------------------------- */ -static struct net_device_stats *baycom_get_stats(struct device *dev) +static struct net_device_stats *baycom_get_stats(struct net_device *dev) { struct baycom_state *bc; @@ -994,7 +994,7 @@ static void epp_wakeup(void *handle) { - struct device *dev = (struct device *)handle; + struct net_device *dev = (struct net_device *)handle; struct baycom_state *bc; baycom_paranoia_check_void(dev, "epp_wakeup"); @@ -1015,7 +1015,7 @@ * there is non-reboot way to recover if something goes wrong. */ -static int epp_open(struct device *dev) +static int epp_open(struct net_device *dev) { struct baycom_state *bc; struct parport *pp; @@ -1141,7 +1141,7 @@ /* --------------------------------------------------------------------- */ -static int epp_close(struct device *dev) +static int epp_close(struct net_device *dev) { struct baycom_state *bc; struct parport *pp; @@ -1209,7 +1209,7 @@ /* --------------------------------------------------------------------- */ -static int baycom_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct baycom_state *bc; struct baycom_ioctl bi; @@ -1348,7 +1348,7 @@ * If dev->base_addr == 2, allocate space for the device and return success * (detachable devices only). */ -static int baycom_probe(struct device *dev) +static int baycom_probe(struct net_device *dev) { static char ax25_bcast[AX25_ADDR_LEN] = { 'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1 @@ -1425,7 +1425,7 @@ #endif int __init init_module(void) { - struct device *dev; + struct net_device *dev; int i, found = 0; char set_hw = 1; struct baycom_state *bc; @@ -1440,7 +1440,7 @@ set_hw = 0; if (!set_hw) iobase[i] = 0; - memset(dev, 0, sizeof(struct device)); + memset(dev, 0, sizeof(struct net_device)); if (!(bc = dev->priv = kmalloc(sizeof(struct baycom_state), GFP_KERNEL))) return -ENOMEM; /* @@ -1490,7 +1490,7 @@ void cleanup_module(void) { - struct device *dev; + struct net_device *dev; struct baycom_state *bc; int i; diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/baycom_par.c linux/drivers/net/hamradio/baycom_par.c --- v2.3.13/linux/drivers/net/hamradio/baycom_par.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/hamradio/baycom_par.c Wed Aug 18 11:38:50 1999 @@ -105,7 +105,7 @@ #define NR_PORTS 4 -static struct device baycom_device[NR_PORTS]; +static struct net_device baycom_device[NR_PORTS]; /* --------------------------------------------------------------------- */ @@ -202,7 +202,7 @@ /* --------------------------------------------------------------------- */ -static __inline__ void par96_tx(struct device *dev, struct baycom_state *bc) +static __inline__ void par96_tx(struct net_device *dev, struct baycom_state *bc) { int i; unsigned int data = hdlcdrv_getbits(&bc->hdrv); @@ -225,7 +225,7 @@ /* --------------------------------------------------------------------- */ -static __inline__ void par96_rx(struct device *dev, struct baycom_state *bc) +static __inline__ void par96_rx(struct net_device *dev, struct baycom_state *bc) { int i; unsigned int data, mask, mask2, descx; @@ -279,7 +279,7 @@ static void par96_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct baycom_state *bc = (struct baycom_state *)dev->priv; if (!dev || !bc || bc->hdrv.magic != HDLCDRV_MAGIC) @@ -309,7 +309,7 @@ static void par96_wakeup(void *handle) { - struct device *dev = (struct device *)handle; + struct net_device *dev = (struct net_device *)handle; struct baycom_state *bc = (struct baycom_state *)dev->priv; printk(KERN_DEBUG "baycom_par: %s: why am I being woken up?\n", dev->name); @@ -319,7 +319,7 @@ /* --------------------------------------------------------------------- */ -static int par96_open(struct device *dev) +static int par96_open(struct net_device *dev) { struct baycom_state *bc = (struct baycom_state *)dev->priv; struct parport *pp = parport_enumerate(); @@ -363,7 +363,7 @@ /* --------------------------------------------------------------------- */ -static int par96_close(struct device *dev) +static int par96_close(struct net_device *dev) { struct baycom_state *bc = (struct baycom_state *)dev->priv; @@ -387,7 +387,7 @@ * ===================== hdlcdrv driver interface ========================= */ -static int baycom_ioctl(struct device *dev, struct ifreq *ifr, +static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd); /* --------------------------------------------------------------------- */ @@ -415,7 +415,7 @@ /* --------------------------------------------------------------------- */ -static int baycom_ioctl(struct device *dev, struct ifreq *ifr, +static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd) { struct baycom_state *bc; @@ -506,7 +506,7 @@ * register net devices */ for (i = 0; i < NR_PORTS; i++) { - struct device *dev = baycom_device+i; + struct net_device *dev = baycom_device+i; sprintf(ifname, "bcp%d", i); if (!mode[i]) @@ -547,7 +547,7 @@ int i; for(i = 0; i < NR_PORTS; i++) { - struct device *dev = baycom_device+i; + struct net_device *dev = baycom_device+i; struct baycom_state *bc = (struct baycom_state *)dev->priv; if (bc) { diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/baycom_ser_fdx.c linux/drivers/net/hamradio/baycom_ser_fdx.c --- v2.3.13/linux/drivers/net/hamradio/baycom_ser_fdx.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/hamradio/baycom_ser_fdx.c Wed Aug 18 11:38:50 1999 @@ -94,7 +94,7 @@ #define NR_PORTS 4 -static struct device baycom_device[NR_PORTS]; +static struct net_device baycom_device[NR_PORTS]; /* --------------------------------------------------------------------- */ @@ -181,7 +181,7 @@ /* --------------------------------------------------------------------- */ -static inline void ser12_set_divisor(struct device *dev, +static inline void ser12_set_divisor(struct net_device *dev, unsigned int divisor) { outb(0x81, LCR(dev->base_addr)); /* DLAB = 1 */ @@ -228,7 +228,7 @@ /* --------------------------------------------------------------------- */ -static __inline__ void ser12_rx(struct device *dev, struct baycom_state *bc, struct timeval *tv, unsigned char curs) +static __inline__ void ser12_rx(struct net_device *dev, struct baycom_state *bc, struct timeval *tv, unsigned char curs) { int timediff; int bdus8 = bc->baud_us >> 3; @@ -285,7 +285,7 @@ static void ser12_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct baycom_state *bc = (struct baycom_state *)dev->priv; struct timeval tv; unsigned char iir, msr; @@ -409,7 +409,7 @@ /* --------------------------------------------------------------------- */ -static int ser12_open(struct device *dev) +static int ser12_open(struct net_device *dev) { struct baycom_state *bc = (struct baycom_state *)dev->priv; enum uart u; @@ -464,7 +464,7 @@ /* --------------------------------------------------------------------- */ -static int ser12_close(struct device *dev) +static int ser12_close(struct net_device *dev) { struct baycom_state *bc = (struct baycom_state *)dev->priv; @@ -490,7 +490,7 @@ /* --------------------------------------------------------------------- */ -static int baycom_ioctl(struct device *dev, struct ifreq *ifr, +static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd); /* --------------------------------------------------------------------- */ @@ -520,7 +520,7 @@ /* --------------------------------------------------------------------- */ -static int baycom_ioctl(struct device *dev, struct ifreq *ifr, +static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd) { struct baycom_state *bc; @@ -616,7 +616,7 @@ * register net devices */ for (i = 0; i < NR_PORTS; i++) { - struct device *dev = baycom_device+i; + struct net_device *dev = baycom_device+i; sprintf(ifname, "bcsf%d", i); if (!mode[i]) @@ -662,7 +662,7 @@ int i; for(i = 0; i < NR_PORTS; i++) { - struct device *dev = baycom_device+i; + struct net_device *dev = baycom_device+i; struct baycom_state *bc = (struct baycom_state *)dev->priv; if (bc) { diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/baycom_ser_hdx.c linux/drivers/net/hamradio/baycom_ser_hdx.c --- v2.3.13/linux/drivers/net/hamradio/baycom_ser_hdx.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/hamradio/baycom_ser_hdx.c Wed Aug 18 11:38:50 1999 @@ -83,7 +83,7 @@ #define NR_PORTS 4 -static struct device baycom_device[NR_PORTS]; +static struct net_device baycom_device[NR_PORTS]; /* --------------------------------------------------------------------- */ @@ -169,7 +169,7 @@ * ===================== SER12 specific routines ========================= */ -static void inline ser12_set_divisor(struct device *dev, +static void inline ser12_set_divisor(struct net_device *dev, unsigned char divisor) { outb(0x81, LCR(dev->base_addr)); /* DLAB = 1 */ @@ -200,7 +200,7 @@ #define SER12_DCD_INTERVAL(bc) ((bc->options & BAYCOM_OPTIONS_SOFTDCD) ? \ 240 : 12) -static inline void ser12_tx(struct device *dev, struct baycom_state *bc) +static inline void ser12_tx(struct net_device *dev, struct baycom_state *bc) { /* one interrupt per channel bit */ ser12_set_divisor(dev, 12); @@ -218,7 +218,7 @@ /* --------------------------------------------------------------------- */ -static inline void ser12_rx(struct device *dev, struct baycom_state *bc) +static inline void ser12_rx(struct net_device *dev, struct baycom_state *bc) { unsigned char cur_s; /* @@ -376,7 +376,7 @@ static void ser12_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct baycom_state *bc = (struct baycom_state *)dev->priv; unsigned char iir; @@ -467,7 +467,7 @@ /* --------------------------------------------------------------------- */ -static int ser12_open(struct device *dev) +static int ser12_open(struct net_device *dev) { struct baycom_state *bc = (struct baycom_state *)dev->priv; enum uart u; @@ -509,7 +509,7 @@ /* --------------------------------------------------------------------- */ -static int ser12_close(struct device *dev) +static int ser12_close(struct net_device *dev) { struct baycom_state *bc = (struct baycom_state *)dev->priv; @@ -535,7 +535,7 @@ /* --------------------------------------------------------------------- */ -static int baycom_ioctl(struct device *dev, struct ifreq *ifr, +static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd); /* --------------------------------------------------------------------- */ @@ -558,7 +558,7 @@ /* --------------------------------------------------------------------- */ -static int baycom_ioctl(struct device *dev, struct ifreq *ifr, +static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd) { struct baycom_state *bc; @@ -653,7 +653,7 @@ * register net devices */ for (i = 0; i < NR_PORTS; i++) { - struct device *dev = baycom_device+i; + struct net_device *dev = baycom_device+i; sprintf(ifname, "bcsh%d", i); if (!mode[i]) @@ -696,7 +696,7 @@ int i; for(i = 0; i < NR_PORTS; i++) { - struct device *dev = baycom_device+i; + struct net_device *dev = baycom_device+i; struct baycom_state *bc = (struct baycom_state *)dev->priv; if (bc) { diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/bpqether.c linux/drivers/net/hamradio/bpqether.c --- v2.3.13/linux/drivers/net/hamradio/bpqether.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/hamradio/bpqether.c Wed Aug 18 11:38:50 1999 @@ -95,7 +95,7 @@ static char bpq_eth_addr[6]; -static int bpq_rcv(struct sk_buff *, struct device *, struct packet_type *); +static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *); static int bpq_device_event(struct notifier_block *, unsigned long, void *); static char *bpq_print_ethaddr(unsigned char *); @@ -118,8 +118,8 @@ static struct bpqdev { struct bpqdev *next; char ethname[14]; /* ether device name */ - struct device *ethdev; /* link to ethernet device */ - struct device axdev; /* bpq device (bpq#) */ + struct net_device *ethdev; /* link to ethernet device */ + struct net_device axdev; /* bpq device (bpq#) */ struct net_device_stats stats; /* some statistics */ char dest_addr[6]; /* ether destination address */ char acpt_addr[6]; /* accept ether frames from this address only */ @@ -132,7 +132,7 @@ /* * Get the ethernet device for a BPQ device */ -static __inline__ struct device *bpq_get_ether_dev(struct device *dev) +static __inline__ struct net_device *bpq_get_ether_dev(struct net_device *dev) { struct bpqdev *bpq; @@ -144,7 +144,7 @@ /* * Get the BPQ device for the ethernet device */ -static __inline__ struct device *bpq_get_ax25_dev(struct device *dev) +static __inline__ struct net_device *bpq_get_ax25_dev(struct net_device *dev) { struct bpqdev *bpq; @@ -155,7 +155,7 @@ return NULL; } -static __inline__ int dev_is_ethdev(struct device *dev) +static __inline__ int dev_is_ethdev(struct net_device *dev) { return ( dev->type == ARPHRD_ETHER @@ -167,7 +167,7 @@ * Sanity check: remove all devices that ceased to exists and * return '1' if the given BPQ device was affected. */ -static int bpq_check_devices(struct device *dev) +static int bpq_check_devices(struct net_device *dev) { struct bpqdev *bpq, *bpq_prev; int result = 0; @@ -211,7 +211,7 @@ /* * Receive an AX.25 frame via an ethernet interface. */ -static int bpq_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *ptype) +static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype) { int len; char * ptr; @@ -264,7 +264,7 @@ /* * Send an AX.25 frame via an ethernet interface */ -static int bpq_xmit(struct sk_buff *skb, struct device *dev) +static int bpq_xmit(struct sk_buff *skb, struct net_device *dev) { struct sk_buff *newskb; unsigned char *ptr; @@ -331,7 +331,7 @@ /* * Statistics */ -static struct net_device_stats *bpq_get_stats(struct device *dev) +static struct net_device_stats *bpq_get_stats(struct net_device *dev) { struct bpqdev *bpq; @@ -343,7 +343,7 @@ /* * Set AX.25 callsign */ -static int bpq_set_mac_address(struct device *dev, void *addr) +static int bpq_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = (struct sockaddr *)addr; @@ -359,7 +359,7 @@ * source ethernet address (broadcast * or multicast: accept all) */ -static int bpq_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int bpq_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { int err; struct bpq_ethaddr *ethaddr = (struct bpq_ethaddr *)ifr->ifr_data; @@ -403,7 +403,7 @@ /* * open/close a device */ -static int bpq_open(struct device *dev) +static int bpq_open(struct net_device *dev) { if (bpq_check_devices(dev)) return -ENODEV; /* oops, it's gone */ @@ -416,7 +416,7 @@ return 0; } -static int bpq_close(struct device *dev) +static int bpq_close(struct net_device *dev) { dev->tbusy = 1; dev->start = 0; @@ -429,7 +429,7 @@ /* * currently unused */ -static int bpq_dev_init(struct device *dev) +static int bpq_dev_init(struct net_device *dev) { return 0; } @@ -498,7 +498,7 @@ /* * Setup a new device. */ -static int bpq_new_device(struct device *dev) +static int bpq_new_device(struct net_device *dev) { int k; unsigned char *buf; @@ -521,7 +521,7 @@ buf = kmalloc(14, GFP_KERNEL); for (k = 0; k < MAXBPQDEV; k++) { - struct device *odev; + struct net_device *odev; sprintf(buf, "bpq%d", k); @@ -589,7 +589,7 @@ */ static int bpq_device_event(struct notifier_block *this,unsigned long event, void *ptr) { - struct device *dev = (struct device *)ptr; + struct net_device *dev = (struct net_device *)ptr; if (!dev_is_ethdev(dev)) return NOTIFY_DONE; @@ -623,7 +623,7 @@ */ int __init bpq_init(void) { - struct device *dev; + struct net_device *dev; bpq_packet_type.type = htons(ETH_P_BPQ); dev_add_pack(&bpq_packet_type); diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/dmascc.c linux/drivers/net/hamradio/dmascc.c --- v2.3.13/linux/drivers/net/hamradio/dmascc.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/hamradio/dmascc.c Wed Aug 18 11:38:51 1999 @@ -71,12 +71,12 @@ #define RXFIFOH 0x08 #define TXFIFOE 0x20 -static int dmascc_dev_init(struct device *dev) +static int dmascc_dev_init(struct net_device *dev) { return 0; } -static void dev_init_buffers(struct device *dev) +static void dev_init_buffers(struct net_device *dev) { int i; @@ -239,7 +239,7 @@ int scc_base; int tmr_base; int twin_serial_cfg; - struct device dev[2]; + struct net_device dev[2]; struct scc_priv priv[2]; struct scc_info *next; }; @@ -252,21 +252,21 @@ static inline void write_scc(int ctl, int reg, int val); static inline int read_scc(int ctl, int reg); -static int scc_open(struct device *dev); -static int scc_close(struct device *dev); -static int scc_ioctl(struct device *dev, struct ifreq *ifr, int cmd); -static int scc_send_packet(struct sk_buff *skb, struct device *dev); -static struct enet_statistics *scc_get_stats(struct device *dev); -static int scc_set_mac_address(struct device *dev, void *sa); +static int scc_open(struct net_device *dev); +static int scc_close(struct net_device *dev); +static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static int scc_send_packet(struct sk_buff *skb, struct net_device *dev); +static struct enet_statistics *scc_get_stats(struct net_device *dev); +static int scc_set_mac_address(struct net_device *dev, void *sa); static void scc_isr(int irq, void *dev_id, struct pt_regs * regs); static inline void z8530_isr(struct scc_info *info); -static void rx_isr(struct device *dev); -static void special_condition(struct device *dev, int rc); +static void rx_isr(struct net_device *dev); +static void special_condition(struct net_device *dev, int rc); static void rx_bh(void *arg); -static void tx_isr(struct device *dev); -static void es_isr(struct device *dev); -static void tm_isr(struct device *dev); -static inline void delay(struct device *dev, int t); +static void tx_isr(struct net_device *dev); +static void es_isr(struct net_device *dev); +static void tm_isr(struct net_device *dev); +static inline void delay(struct net_device *dev, int t); static inline unsigned char random(void); @@ -457,7 +457,7 @@ { int i, irq, chip; struct scc_info *info; - struct device *dev; + struct net_device *dev; struct scc_priv *priv; unsigned long time; unsigned int irqs; @@ -623,7 +623,7 @@ } -static int scc_open(struct device *dev) +static int scc_open(struct net_device *dev) { struct scc_priv *priv = dev->priv; struct scc_info *info = priv->info; @@ -740,7 +740,7 @@ } -static int scc_close(struct device *dev) +static int scc_close(struct net_device *dev) { struct scc_priv *priv = dev->priv; struct scc_info *info = priv->info; @@ -772,7 +772,7 @@ } -static int scc_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { int rc; struct scc_priv *priv = dev->priv; @@ -797,7 +797,7 @@ } -static int scc_send_packet(struct sk_buff *skb, struct device *dev) +static int scc_send_packet(struct sk_buff *skb, struct net_device *dev) { struct scc_priv *priv = dev->priv; struct scc_info *info = priv->info; @@ -851,7 +851,7 @@ } -static struct enet_statistics *scc_get_stats(struct device *dev) +static struct enet_statistics *scc_get_stats(struct net_device *dev) { struct scc_priv *priv = dev->priv; @@ -859,7 +859,7 @@ } -static int scc_set_mac_address(struct device *dev, void *sa) +static int scc_set_mac_address(struct net_device *dev, void *sa) { memcpy(dev->dev_addr, ((struct sockaddr *)sa)->sa_data, dev->addr_len); return 0; @@ -934,7 +934,7 @@ } -static void rx_isr(struct device *dev) +static void rx_isr(struct net_device *dev) { struct scc_priv *priv = dev->priv; int cmd = priv->cmd; @@ -961,7 +961,7 @@ } -static void special_condition(struct device *dev, int rc) +static void special_condition(struct net_device *dev, int rc) { struct scc_priv *priv = dev->priv; int cb, cmd = priv->cmd; @@ -1032,7 +1032,7 @@ static void rx_bh(void *arg) { - struct device *dev = arg; + struct net_device *dev = arg; struct scc_priv *priv = dev->priv; struct scc_info *info = priv->info; int cmd = priv->cmd; @@ -1081,7 +1081,7 @@ } -static void tx_isr(struct device *dev) +static void tx_isr(struct net_device *dev) { struct scc_priv *priv = dev->priv; int cmd = priv->cmd; @@ -1103,7 +1103,7 @@ } -static void es_isr(struct device *dev) +static void es_isr(struct net_device *dev) { struct scc_priv *priv = dev->priv; struct scc_info *info = priv->info; @@ -1261,7 +1261,7 @@ } -static void tm_isr(struct device *dev) +static void tm_isr(struct net_device *dev) { struct scc_priv *priv = dev->priv; struct scc_info *info = priv->info; @@ -1326,7 +1326,7 @@ } -static inline void delay(struct device *dev, int t) +static inline void delay(struct net_device *dev, int t) { struct scc_priv *priv = dev->priv; int tmr = priv->tmr; diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/hdlcdrv.c linux/drivers/net/hamradio/hdlcdrv.c --- v2.3.13/linux/drivers/net/hamradio/hdlcdrv.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/hamradio/hdlcdrv.c Wed Aug 18 11:38:50 1999 @@ -204,7 +204,7 @@ return added; } -static void hdlc_rx_flag(struct device *dev, struct hdlcdrv_state *s) +static void hdlc_rx_flag(struct net_device *dev, struct hdlcdrv_state *s) { struct sk_buff *skb; int pkt_len; @@ -231,7 +231,7 @@ s->stats.rx_packets++; } -void hdlcdrv_receiver(struct device *dev, struct hdlcdrv_state *s) +void hdlcdrv_receiver(struct net_device *dev, struct hdlcdrv_state *s) { int i; unsigned int mask1, mask2, mask3, mask4, mask5, mask6, word; @@ -328,7 +328,7 @@ /* ---------------------------------------------------------------------- */ -void hdlcdrv_transmitter(struct device *dev, struct hdlcdrv_state *s) +void hdlcdrv_transmitter(struct net_device *dev, struct hdlcdrv_state *s) { unsigned int mask1, mask2, mask3; int i; @@ -430,7 +430,7 @@ /* ---------------------------------------------------------------------- */ -static void start_tx(struct device *dev, struct hdlcdrv_state *s) +static void start_tx(struct net_device *dev, struct hdlcdrv_state *s) { s->hdlctx.tx_state = 0; s->hdlctx.numflags = tenms_to_2flags(s, s->ch_params.tx_delay); @@ -452,7 +452,7 @@ /* ---------------------------------------------------------------------- */ -void hdlcdrv_arbitrate(struct device *dev, struct hdlcdrv_state *s) +void hdlcdrv_arbitrate(struct net_device *dev, struct hdlcdrv_state *s) { if (!s || s->magic != HDLCDRV_MAGIC || s->hdlctx.ptt || skb_queue_empty(&s->send_queue)) @@ -478,7 +478,7 @@ * ===================== network driver interface ========================= */ -static inline int hdlcdrv_paranoia_check(struct device *dev, +static inline int hdlcdrv_paranoia_check(struct net_device *dev, const char *routine) { if (!dev || !dev->priv || @@ -492,7 +492,7 @@ /* --------------------------------------------------------------------- */ -static int hdlcdrv_send_packet(struct sk_buff *skb, struct device *dev) +static int hdlcdrv_send_packet(struct sk_buff *skb, struct net_device *dev) { struct hdlcdrv_state *sm; @@ -506,7 +506,7 @@ /* --------------------------------------------------------------------- */ -static int hdlcdrv_set_mac_address(struct device *dev, void *addr) +static int hdlcdrv_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = (struct sockaddr *)addr; @@ -517,7 +517,7 @@ /* --------------------------------------------------------------------- */ -static struct net_device_stats *hdlcdrv_get_stats(struct device *dev) +static struct net_device_stats *hdlcdrv_get_stats(struct net_device *dev) { struct hdlcdrv_state *sm; @@ -541,7 +541,7 @@ * there is non-reboot way to recover if something goes wrong. */ -static int hdlcdrv_open(struct device *dev) +static int hdlcdrv_open(struct net_device *dev) { struct hdlcdrv_state *s; int i; @@ -589,7 +589,7 @@ * The inverse routine to hdlcdrv_open(). */ -static int hdlcdrv_close(struct device *dev) +static int hdlcdrv_close(struct net_device *dev) { struct hdlcdrv_state *s; struct sk_buff *skb; @@ -614,7 +614,7 @@ /* --------------------------------------------------------------------- */ -static int hdlcdrv_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct hdlcdrv_state *s; struct hdlcdrv_ioctl bi; @@ -749,7 +749,7 @@ * If dev->base_addr == 2, allocate space for the device and return success * (detachable devices only). */ -static int hdlcdrv_probe(struct device *dev) +static int hdlcdrv_probe(struct net_device *dev) { const struct hdlcdrv_channel_params dflt_ch_params = { 20, 2, 10, 40, 0 @@ -830,7 +830,7 @@ /* --------------------------------------------------------------------- */ -int hdlcdrv_register_hdlcdrv(struct device *dev, const struct hdlcdrv_ops *ops, +int hdlcdrv_register_hdlcdrv(struct net_device *dev, const struct hdlcdrv_ops *ops, unsigned int privsize, char *ifname, unsigned int baseaddr, unsigned int irq, unsigned int dma) @@ -841,7 +841,7 @@ return -EACCES; if (privsize < sizeof(struct hdlcdrv_state)) privsize = sizeof(struct hdlcdrv_state); - memset(dev, 0, sizeof(struct device)); + memset(dev, 0, sizeof(struct net_device)); if (!(s = dev->priv = kmalloc(privsize, GFP_KERNEL))) return -ENOMEM; /* @@ -874,7 +874,7 @@ /* --------------------------------------------------------------------- */ -int hdlcdrv_unregister_hdlcdrv(struct device *dev) +int hdlcdrv_unregister_hdlcdrv(struct net_device *dev) { struct hdlcdrv_state *s; diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/mkiss.c linux/drivers/net/hamradio/mkiss.c --- v2.3.13/linux/drivers/net/hamradio/mkiss.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/hamradio/mkiss.c Wed Aug 18 11:38:50 1999 @@ -75,7 +75,7 @@ typedef struct ax25_ctrl { char if_name[8]; /* "ax0\0" .. "ax99999\0" */ struct ax_disp ctrl; /* */ - struct device dev; /* the device */ + struct net_device dev; /* the device */ } ax25_ctrl_t; static ax25_ctrl_t **ax25_ctrls = NULL; @@ -90,7 +90,7 @@ static struct termios *mkiss_termios_locked[NR_MKISS]; struct mkiss_channel MKISS_Info[NR_MKISS]; -static int ax25_init(struct device *); +static int ax25_init(struct net_device *); static int mkiss_init(void); static int mkiss_write(struct tty_struct *, int, const unsigned char *, int); static int kiss_esc(unsigned char *, unsigned char *, int); @@ -247,7 +247,7 @@ static void ax_changedmtu(struct ax_disp *ax) { - struct device *dev = ax->dev; + struct net_device *dev = ax->dev; unsigned char *xbuff, *rbuff, *oxbuff, *orbuff; int len; unsigned long flags; @@ -460,7 +460,7 @@ } /* Encapsulate an AX.25 packet and kick it into a TTY queue. */ -static int ax_xmit(struct sk_buff *skb, struct device *dev) +static int ax_xmit(struct sk_buff *skb, struct net_device *dev) { struct ax_disp *ax = (struct ax_disp*)dev->priv; struct mkiss_channel *mkiss = ax->tty->driver_data; @@ -523,7 +523,7 @@ #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) /* Return the frame type ID */ -static int ax_header(struct sk_buff *skb, struct device *dev, unsigned short type, +static int ax_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { #ifdef CONFIG_INET @@ -546,7 +546,7 @@ #endif /* CONFIG_{AX25,AX25_MODULE} */ /* Open the low-level part of the AX25 channel. Easy! */ -static int ax_open(struct device *dev) +static int ax_open(struct net_device *dev) { struct ax_disp *ax = (struct ax_disp*)dev->priv; unsigned long len; @@ -600,7 +600,7 @@ /* Close the low-level part of the AX25 channel. Easy! */ -static int ax_close(struct device *dev) +static int ax_close(struct net_device *dev) { struct ax_disp *ax = (struct ax_disp*)dev->priv; @@ -737,7 +737,7 @@ } -static struct net_device_stats *ax_get_stats(struct device *dev) +static struct net_device_stats *ax_get_stats(struct net_device *dev) { static struct net_device_stats stats; struct ax_disp *ax = (struct ax_disp*)dev->priv; @@ -873,14 +873,14 @@ } -int ax_set_mac_address(struct device *dev, void *addr) +int ax_set_mac_address(struct net_device *dev, void *addr) { if (copy_from_user(dev->dev_addr, addr, AX25_ADDR_LEN)) return -EFAULT; return 0; } -static int ax_set_dev_mac_address(struct device *dev, void *addr) +static int ax_set_dev_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = addr; @@ -926,7 +926,7 @@ } } -static int ax_open_dev(struct device *dev) +static int ax_open_dev(struct net_device *dev) { struct ax_disp *ax = (struct ax_disp*)dev->priv; @@ -986,7 +986,7 @@ /* Initialize the driver. Called by network startup. */ -static int ax25_init(struct device *dev) +static int ax25_init(struct net_device *dev) { struct ax_disp *ax = (struct ax_disp*)dev->priv; diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/mkiss.h linux/drivers/net/hamradio/mkiss.h --- v2.3.13/linux/drivers/net/hamradio/mkiss.h Wed Jul 22 13:45:52 1998 +++ linux/drivers/net/hamradio/mkiss.h Wed Aug 18 11:38:50 1999 @@ -18,7 +18,7 @@ /* Various fields. */ struct tty_struct *tty; /* ptr to TTY structure */ - struct device *dev; /* easy for intr handling */ + struct net_device *dev; /* easy for intr handling */ struct ax_disp *mkiss; /* mkiss txport if mkiss channel*/ /* These are pointers to the malloc()ed frame buffers. */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/pi2.c linux/drivers/net/hamradio/pi2.c --- v2.3.13/linux/drivers/net/hamradio/pi2.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/hamradio/pi2.c Wed Aug 18 11:38:50 1999 @@ -130,9 +130,9 @@ * PI device declarations. */ -static int pi0_preprobe(struct device *dev){return 0;} /* Dummy probe function */ -static struct device pi0a = { "pi0a", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pi0_preprobe }; -static struct device pi0b = { "pi0b", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pi0_preprobe }; +static int pi0_preprobe(struct net_device *dev){return 0;} /* Dummy probe function */ +static struct net_device pi0a = { "pi0a", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pi0_preprobe }; +static struct net_device pi0b = { "pi0b", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pi0_preprobe }; /* The number of low I/O ports used by the card. */ @@ -141,18 +141,18 @@ /* Index to functions, as function prototypes. */ -static int pi_probe(struct device *dev, int card_type); -static int pi_open(struct device *dev); -static int pi_send_packet(struct sk_buff *skb, struct device *dev); +static int pi_probe(struct net_device *dev, int card_type); +static int pi_open(struct net_device *dev); +static int pi_send_packet(struct sk_buff *skb, struct net_device *dev); static void pi_interrupt(int reg_ptr, void *dev_id, struct pt_regs *regs); -static int pi_close(struct device *dev); -static int pi_ioctl(struct device *dev, struct ifreq *ifr, int cmd); -static struct net_device_stats *pi_get_stats(struct device *dev); +static int pi_close(struct net_device *dev); +static int pi_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static struct net_device_stats *pi_get_stats(struct net_device *dev); static void rts(struct pi_local *lp, int x); -static void b_rxint(struct device *dev, struct pi_local *lp); +static void b_rxint(struct net_device *dev, struct pi_local *lp); static void b_txint(struct pi_local *lp); static void b_exint(struct pi_local *lp); -static void a_rxint(struct device *dev, struct pi_local *lp); +static void a_rxint(struct net_device *dev, struct pi_local *lp); static void a_txint(struct pi_local *lp); static void a_exint(struct pi_local *lp); static char *get_dma_buffer(unsigned long *mem_ptr); @@ -493,7 +493,7 @@ /* Receive interrupt handler for the A channel */ -static void a_rxint(struct device *dev, struct pi_local *lp) +static void a_rxint(struct net_device *dev, struct pi_local *lp) { unsigned long flags; int cmd; @@ -568,7 +568,7 @@ restore_flags(flags); } -static void b_rxint(struct device *dev, struct pi_local *lp) +static void b_rxint(struct net_device *dev, struct pi_local *lp) { unsigned long flags; int cmd; @@ -1063,7 +1063,7 @@ } } -static void scc_init(struct device *dev) +static void scc_init(struct net_device *dev) { unsigned long flags; struct pi_local *lp = (struct pi_local *) dev->priv; @@ -1165,7 +1165,7 @@ restore_flags(flags); } -static void chipset_init(struct device *dev) +static void chipset_init(struct net_device *dev) { int cardbase; unsigned long flags; @@ -1251,7 +1251,7 @@ return 0; } -static int pi_set_mac_address(struct device *dev, void *addr) +static int pi_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = (struct sockaddr *)addr; memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); /* addr is an AX.25 shifted ASCII */ @@ -1274,7 +1274,7 @@ return (ret); } -static int pi_probe(struct device *dev, int card_type) +static int pi_probe(struct net_device *dev, int card_type) { short ioaddr; struct pi_local *lp; @@ -1423,7 +1423,7 @@ 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 pi_open(struct device *dev) +static int pi_open(struct net_device *dev) { unsigned long flags; static first_time = 1; @@ -1464,7 +1464,7 @@ return 0; } -static int pi_send_packet(struct sk_buff *skb, struct device *dev) +static int pi_send_packet(struct sk_buff *skb, struct net_device *dev) { struct pi_local *lp = (struct pi_local *) dev->priv; @@ -1531,7 +1531,7 @@ } /* The inverse routine to pi_open(). */ -static int pi_close(struct device *dev) +static int pi_close(struct net_device *dev) { unsigned long flags; struct pi_local *lp; @@ -1562,7 +1562,7 @@ return 0; } -static int pi_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int pi_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { unsigned long flags; struct pi_req rq; @@ -1643,7 +1643,7 @@ /* Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *pi_get_stats(struct device *dev) +static struct net_device_stats *pi_get_stats(struct net_device *dev) { struct pi_local *lp = (struct pi_local *) dev->priv; diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/pt.c linux/drivers/net/hamradio/pt.c --- v2.3.13/linux/drivers/net/hamradio/pt.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/hamradio/pt.c Wed Aug 18 11:38:50 1999 @@ -105,9 +105,9 @@ /* * The actual PT devices we will use */ -static int pt0_preprobe(struct device *dev) {return 0;} /* Dummy probe function */ -static struct device pt0a = { "pt0a", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pt0_preprobe }; -static struct device pt0b = { "pt0b", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pt0_preprobe }; +static int pt0_preprobe(struct net_device *dev) {return 0;} /* Dummy probe function */ +static struct net_device pt0a = { "pt0a", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pt0_preprobe }; +static struct net_device pt0b = { "pt0b", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pt0_preprobe }; /* Ok, they shouldn't be here, but both channels share them */ /* The Images of the Serial and DMA config registers */ @@ -119,15 +119,15 @@ /* Index to functions, as function prototypes. */ -static int pt_probe(struct device *dev); -static int pt_open(struct device *dev); -static int pt_send_packet(struct sk_buff *skb, struct device *dev); +static int pt_probe(struct net_device *dev); +static int pt_open(struct net_device *dev); +static int pt_send_packet(struct sk_buff *skb, struct net_device *dev); static void pt_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int pt_close(struct device *dev); -static int pt_ioctl(struct device *dev, struct ifreq *ifr, int cmd); -static struct net_device_stats *pt_get_stats(struct device *dev); +static int pt_close(struct net_device *dev); +static int pt_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static struct net_device_stats *pt_get_stats(struct net_device *dev); static void pt_rts(struct pt_local *lp, int x); -static void pt_rxisr(struct device *dev); +static void pt_rxisr(struct net_device *dev); static void pt_txisr(struct pt_local *lp); static void pt_exisr(struct pt_local *lp); static void pt_tmrisr(struct pt_local *lp); @@ -135,7 +135,7 @@ static int valid_dma_page(unsigned long addr, unsigned long dev_buffsize); static int hw_probe(int ioaddr); static void tdelay(struct pt_local *lp, int time); -static void chipset_init(struct device *dev); +static void chipset_init(struct net_device *dev); static char ax25_bcast[7] = {'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1}; @@ -179,7 +179,7 @@ char kickflag; unsigned long flags; char *ptr; - struct device *dev; + struct net_device *dev; /* First, let's see if this packet is actually a KISS packet */ ptr = skb->data; @@ -322,7 +322,7 @@ * This sets up all the registers in the SCC for the given channel * based upon tsync_hwint() */ -static void scc_init(struct device *dev) +static void scc_init(struct net_device *dev) { unsigned long flags; struct pt_local *lp = (struct pt_local*) dev->priv; @@ -443,7 +443,7 @@ } /* scc_init() */ /* Resets the given channel and whole SCC if both channels off */ -static void chipset_init(struct device *dev) +static void chipset_init(struct net_device *dev) { struct pt_local *lp = (struct pt_local*) dev->priv; @@ -699,7 +699,7 @@ return 0; } -static int pt_set_mac_address(struct device *dev, void *addr) +static int pt_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = (struct sockaddr *)addr; memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); /* addr is an AX.25 shifted ASCII */ @@ -726,7 +726,7 @@ /* * Sets up all the structures for the PT device */ -static int pt_probe(struct device *dev) +static int pt_probe(struct net_device *dev) { short ioaddr; struct pt_local *lp; @@ -878,7 +878,7 @@ * a non-reboot way to recover if something goes wrong. * derived from last half of tsync_attach() */ -static int pt_open(struct device *dev) +static int pt_open(struct net_device *dev) { unsigned long flags; struct pt_local *lp = dev->priv; @@ -928,7 +928,7 @@ return 0; } /* pt_open() */ -static int pt_send_packet(struct sk_buff *skb, struct device *dev) +static int pt_send_packet(struct sk_buff *skb, struct net_device *dev) { struct pt_local *lp = (struct pt_local *) dev->priv; @@ -944,7 +944,7 @@ /* The inverse routine to pt_open() */ -static int pt_close(struct device *dev) +static int pt_close(struct net_device *dev) { unsigned long flags; struct pt_local *lp = dev->priv; @@ -980,7 +980,7 @@ } /* pt_close() */ -static int pt_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int pt_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { unsigned long flags; struct pt_req rq; @@ -1064,7 +1064,7 @@ * This may be called with the card open or closed. */ -static struct net_device_stats *pt_get_stats(struct device *dev) +static struct net_device_stats *pt_get_stats(struct net_device *dev) { struct pt_local *lp = (struct pt_local *) dev->priv; return &lp->stats; @@ -1219,7 +1219,7 @@ restore_flags(flags); } -static void pt_rxisr(struct device *dev) +static void pt_rxisr(struct net_device *dev) { struct pt_local *lp = (struct pt_local*) dev->priv; int cmd = lp->base + CTL; @@ -1432,7 +1432,7 @@ static void pt_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* It's a tad dodgy here, but we assume pt0a until proven otherwise */ - struct device *dev = &pt0a; + struct net_device *dev = &pt0a; struct pt_local *lp = dev->priv; unsigned char intreg; unsigned char st; diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/scc.c linux/drivers/net/hamradio/scc.c --- v2.3.13/linux/drivers/net/hamradio/scc.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/hamradio/scc.c Wed Aug 18 11:38:50 1999 @@ -210,15 +210,15 @@ static void scc_init_timer(struct scc_channel *scc); static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev); -static int scc_net_init(struct device *dev); -static int scc_net_open(struct device *dev); -static int scc_net_close(struct device *dev); +static int scc_net_init(struct net_device *dev); +static int scc_net_open(struct net_device *dev); +static int scc_net_close(struct net_device *dev); static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb); -static int scc_net_tx(struct sk_buff *skb, struct device *dev); -static int scc_net_ioctl(struct device *dev, struct ifreq *ifr, int cmd); -static int scc_net_set_mac_address(struct device *dev, void *addr); -static int scc_net_header(struct sk_buff *skb, struct device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); -static struct net_device_stats * scc_net_get_stats(struct device *dev); +static int scc_net_tx(struct sk_buff *skb, struct net_device *dev); +static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static int scc_net_set_mac_address(struct net_device *dev, void *addr); +static int scc_net_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); +static struct net_device_stats * scc_net_get_stats(struct net_device *dev); static unsigned char *SCC_DriverName = "scc"; @@ -1569,7 +1569,7 @@ static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev) { unsigned char *buf; - struct device *dev; + struct net_device *dev; if (dev_get(name) != NULL) { @@ -1577,11 +1577,11 @@ return -EEXIST; } - if ((scc->dev = (struct device *) kmalloc(sizeof(struct device), GFP_KERNEL)) == NULL) + if ((scc->dev = (struct net_device *) kmalloc(sizeof(struct net_device), GFP_KERNEL)) == NULL) return -ENOMEM; dev = scc->dev; - memset(dev, 0, sizeof(struct device)); + memset(dev, 0, sizeof(struct net_device)); buf = (unsigned char *) kmalloc(10, GFP_KERNEL); strcpy(buf, name); @@ -1612,7 +1612,7 @@ /* ----> Initialize device <----- */ -static int scc_net_init(struct device *dev) +static int scc_net_init(struct net_device *dev) { dev_init_buffers(dev); @@ -1643,7 +1643,7 @@ /* ----> open network device <---- */ -static int scc_net_open(struct device *dev) +static int scc_net_open(struct net_device *dev) { struct scc_channel *scc = (struct scc_channel *) dev->priv; @@ -1668,7 +1668,7 @@ /* ----> close network device <---- */ -static int scc_net_close(struct device *dev) +static int scc_net_close(struct net_device *dev) { struct scc_channel *scc = (struct scc_channel *) dev->priv; unsigned long flags; @@ -1721,7 +1721,7 @@ /* ----> transmit frame <---- */ -static int scc_net_tx(struct sk_buff *skb, struct device *dev) +static int scc_net_tx(struct sk_buff *skb, struct net_device *dev) { struct scc_channel *scc = (struct scc_channel *) dev->priv; unsigned long flags; @@ -1799,7 +1799,7 @@ * SIOCSCCCAL - send calib. pattern arg: (struct scc_calibrate *) arg */ -static int scc_net_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct scc_kiss_cmd kiss_cmd; struct scc_mem_config memcfg; @@ -2031,7 +2031,7 @@ /* ----> set interface callsign <---- */ -static int scc_net_set_mac_address(struct device *dev, void *addr) +static int scc_net_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = (struct sockaddr *) addr; memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); @@ -2040,7 +2040,7 @@ /* ----> "hard" header <---- */ -static int scc_net_header(struct sk_buff *skb, struct device *dev, +static int scc_net_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { return ax25_encapsulate(skb, dev, type, daddr, saddr, len); @@ -2048,7 +2048,7 @@ /* ----> get statistics <---- */ -static struct net_device_stats *scc_net_get_stats(struct device *dev) +static struct net_device_stats *scc_net_get_stats(struct net_device *dev) { struct scc_channel *scc = (struct scc_channel *) dev->priv; diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/soundmodem/sm.c linux/drivers/net/hamradio/soundmodem/sm.c --- v2.3.13/linux/drivers/net/hamradio/soundmodem/sm.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/hamradio/soundmodem/sm.c Wed Aug 18 11:38:50 1999 @@ -140,7 +140,7 @@ #define NR_PORTS 4 -static struct device sm_device[NR_PORTS]; +static struct net_device sm_device[NR_PORTS]; /* --------------------------------------------------------------------- */ @@ -357,9 +357,9 @@ /* --------------------------------------------------------------------- */ -static int sm_open(struct device *dev); -static int sm_close(struct device *dev); -static int sm_ioctl(struct device *dev, struct ifreq *ifr, +static int sm_open(struct net_device *dev); +static int sm_close(struct net_device *dev); +static int sm_ioctl(struct net_device *dev, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd); /* --------------------------------------------------------------------- */ @@ -370,7 +370,7 @@ /* --------------------------------------------------------------------- */ -static int sm_open(struct device *dev) +static int sm_open(struct net_device *dev) { struct sm_state *sm; int err; @@ -398,7 +398,7 @@ /* --------------------------------------------------------------------- */ -static int sm_close(struct device *dev) +static int sm_close(struct net_device *dev) { struct sm_state *sm; int err = -ENODEV; @@ -422,7 +422,7 @@ /* --------------------------------------------------------------------- */ -static int sethw(struct device *dev, struct sm_state *sm, char *mode) +static int sethw(struct net_device *dev, struct sm_state *sm, char *mode) { char *cp = strchr(mode, ':'); const struct hardware_info **hwp = sm_hardware_table; @@ -451,7 +451,7 @@ /* --------------------------------------------------------------------- */ -static int sm_ioctl(struct device *dev, struct ifreq *ifr, +static int sm_ioctl(struct net_device *dev, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd) { struct sm_state *sm; @@ -626,7 +626,7 @@ * register net devices */ for (i = 0; i < NR_PORTS; i++) { - struct device *dev = sm_device+i; + struct net_device *dev = sm_device+i; sprintf(ifname, "sm%d", i); if (!mode[i]) @@ -700,7 +700,7 @@ printk(KERN_INFO "sm: cleanup_module called\n"); for(i = 0; i < NR_PORTS; i++) { - struct device *dev = sm_device+i; + struct net_device *dev = sm_device+i; struct sm_state *sm = (struct sm_state *)dev->priv; if (sm) { diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/soundmodem/sm.h linux/drivers/net/hamradio/soundmodem/sm.h --- v2.3.13/linux/drivers/net/hamradio/soundmodem/sm.h Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/hamradio/soundmodem/sm.h Wed Aug 18 11:38:50 1999 @@ -141,11 +141,11 @@ /* * mode specific open/close */ - int (*open)(struct device *, struct sm_state *); - int (*close)(struct device *, struct sm_state *); - int (*ioctl)(struct device *, struct sm_state *, struct ifreq *, + int (*open)(struct net_device *, struct sm_state *); + int (*close)(struct net_device *, struct sm_state *); + int (*ioctl)(struct net_device *, struct sm_state *, struct ifreq *, struct hdlcdrv_ioctl *, int); - int (*sethw)(struct device *, struct sm_state *, char *); + int (*sethw)(struct net_device *, struct sm_state *, char *); }; /* --------------------------------------------------------------------- */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/soundmodem/sm_sbc.c linux/drivers/net/hamradio/soundmodem/sm_sbc.c --- v2.3.13/linux/drivers/net/hamradio/soundmodem/sm_sbc.c Tue Dec 9 09:49:58 1997 +++ linux/drivers/net/hamradio/soundmodem/sm_sbc.c Wed Aug 18 11:38:50 1999 @@ -140,7 +140,7 @@ /* --------------------------------------------------------------------- */ -static int inline reset_dsp(struct device *dev) +static int inline reset_dsp(struct net_device *dev) { int i; @@ -156,7 +156,7 @@ /* --------------------------------------------------------------------- */ -static void inline write_dsp(struct device *dev, unsigned char data) +static void inline write_dsp(struct net_device *dev, unsigned char data) { int i; @@ -169,7 +169,7 @@ /* --------------------------------------------------------------------- */ -static int inline read_dsp(struct device *dev, unsigned char *data) +static int inline read_dsp(struct net_device *dev, unsigned char *data) { int i; @@ -185,7 +185,7 @@ /* --------------------------------------------------------------------- */ -static int config_resources(struct device *dev, struct sm_state *sm, int fdx) +static int config_resources(struct net_device *dev, struct sm_state *sm, int fdx) { unsigned char irqreg = 0, dmareg = 0, realirq, realdma; unsigned long flags; @@ -266,21 +266,21 @@ /* --------------------------------------------------------------------- */ -static void inline sbc_int_ack_8bit(struct device *dev) +static void inline sbc_int_ack_8bit(struct net_device *dev) { inb(DSP_DATA_AVAIL(dev->base_addr)); } /* --------------------------------------------------------------------- */ -static void inline sbc_int_ack_16bit(struct device *dev) +static void inline sbc_int_ack_16bit(struct net_device *dev) { inb(DSP_INTACK_16BIT(dev->base_addr)); } /* --------------------------------------------------------------------- */ -static void setup_dma_dsp(struct device *dev, struct sm_state *sm, int send) +static void setup_dma_dsp(struct net_device *dev, struct sm_state *sm, int send) { unsigned long flags; static const unsigned char sbcmode[2][2] = { @@ -323,7 +323,7 @@ static void sbc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct sm_state *sm = (struct sm_state *)dev->priv; unsigned int curfrag; @@ -364,7 +364,7 @@ /* --------------------------------------------------------------------- */ -static int sbc_open(struct device *dev, struct sm_state *sm) +static int sbc_open(struct net_device *dev, struct sm_state *sm) { int err; unsigned int dmasz, u; @@ -449,7 +449,7 @@ /* --------------------------------------------------------------------- */ -static int sbc_close(struct device *dev, struct sm_state *sm) +static int sbc_close(struct net_device *dev, struct sm_state *sm) { if (!dev || !sm) return -EINVAL; @@ -467,7 +467,7 @@ /* --------------------------------------------------------------------- */ -static int sbc_sethw(struct device *dev, struct sm_state *sm, char *mode) +static int sbc_sethw(struct net_device *dev, struct sm_state *sm, char *mode) { char *cp = strchr(mode, '.'); const struct modem_tx_info **mtp = sm_modem_tx_table; @@ -524,7 +524,7 @@ /* --------------------------------------------------------------------- */ -static int sbc_ioctl(struct device *dev, struct sm_state *sm, struct ifreq *ifr, +static int sbc_ioctl(struct net_device *dev, struct sm_state *sm, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd) { struct sm_ioctl bi; @@ -619,7 +619,7 @@ /* --------------------------------------------------------------------- */ -static void setup_dma_fdx_dsp(struct device *dev, struct sm_state *sm) +static void setup_dma_fdx_dsp(struct net_device *dev, struct sm_state *sm) { unsigned long flags; unsigned int isamps, osamps; @@ -684,7 +684,7 @@ static void sbcfdx_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct sm_state *sm = (struct sm_state *)dev->priv; unsigned char intsrc, pbint = 0, captint = 0; unsigned int ocfrag, icfrag; @@ -747,7 +747,7 @@ /* --------------------------------------------------------------------- */ -static int sbcfdx_open(struct device *dev, struct sm_state *sm) +static int sbcfdx_open(struct net_device *dev, struct sm_state *sm) { int err; @@ -830,7 +830,7 @@ /* --------------------------------------------------------------------- */ -static int sbcfdx_close(struct device *dev, struct sm_state *sm) +static int sbcfdx_close(struct net_device *dev, struct sm_state *sm) { if (!dev || !sm) return -EINVAL; @@ -851,7 +851,7 @@ /* --------------------------------------------------------------------- */ -static int sbcfdx_sethw(struct device *dev, struct sm_state *sm, char *mode) +static int sbcfdx_sethw(struct net_device *dev, struct sm_state *sm, char *mode) { char *cp = strchr(mode, '.'); const struct modem_tx_info **mtp = sm_modem_tx_table; @@ -917,7 +917,7 @@ /* --------------------------------------------------------------------- */ -static int sbcfdx_ioctl(struct device *dev, struct sm_state *sm, struct ifreq *ifr, +static int sbcfdx_ioctl(struct net_device *dev, struct sm_state *sm, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd) { if (cmd != SIOCDEVPRIVATE) diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/soundmodem/sm_wss.c linux/drivers/net/hamradio/soundmodem/sm_wss.c --- v2.3.13/linux/drivers/net/hamradio/soundmodem/sm_wss.c Tue Aug 5 09:49:51 1997 +++ linux/drivers/net/hamradio/soundmodem/sm_wss.c Wed Aug 18 11:38:51 1999 @@ -102,7 +102,7 @@ /* --------------------------------------------------------------------- */ -static void write_codec(struct device *dev, unsigned char idx, +static void write_codec(struct net_device *dev, unsigned char idx, unsigned char data) { int timeout = 900000; @@ -117,7 +117,7 @@ /* --------------------------------------------------------------------- */ -static unsigned char read_codec(struct device *dev, unsigned char idx) +static unsigned char read_codec(struct net_device *dev, unsigned char idx) { int timeout = 900000; @@ -130,7 +130,7 @@ /* --------------------------------------------------------------------- */ -extern void inline wss_ack_int(struct device *dev) +extern void inline wss_ack_int(struct net_device *dev) { outb(0, WSS_CODEC_STATUS(dev->base_addr)); } @@ -154,7 +154,7 @@ /* --------------------------------------------------------------------- */ -static int wss_set_codec_fmt(struct device *dev, struct sm_state *sm, unsigned char fmt, +static int wss_set_codec_fmt(struct net_device *dev, struct sm_state *sm, unsigned char fmt, unsigned char fmt2, char fdx, char fullcalib) { unsigned long time; @@ -202,7 +202,7 @@ /* --------------------------------------------------------------------- */ -static int wss_init_codec(struct device *dev, struct sm_state *sm, char fdx, +static int wss_init_codec(struct net_device *dev, struct sm_state *sm, char fdx, unsigned char src_l, unsigned char src_r, int igain_l, int igain_r, int ogain_l, int ogain_r) @@ -341,7 +341,7 @@ /* --------------------------------------------------------------------- */ -static void setup_dma_wss(struct device *dev, struct sm_state *sm, int send) +static void setup_dma_wss(struct net_device *dev, struct sm_state *sm, int send) { unsigned long flags; static const unsigned char codecmode[2] = { 0x0e, 0x0d }; @@ -383,7 +383,7 @@ static void wss_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct sm_state *sm = (struct sm_state *)dev->priv; unsigned int curfrag; unsigned int nums; @@ -426,7 +426,7 @@ /* --------------------------------------------------------------------- */ -static int wss_open(struct device *dev, struct sm_state *sm) +static int wss_open(struct net_device *dev, struct sm_state *sm) { unsigned int dmasz, u; @@ -484,7 +484,7 @@ /* --------------------------------------------------------------------- */ -static int wss_close(struct device *dev, struct sm_state *sm) +static int wss_close(struct net_device *dev, struct sm_state *sm) { if (!dev || !sm) return -EINVAL; @@ -502,7 +502,7 @@ /* --------------------------------------------------------------------- */ -static int wss_sethw(struct device *dev, struct sm_state *sm, char *mode) +static int wss_sethw(struct net_device *dev, struct sm_state *sm, char *mode) { char *cp = strchr(mode, '.'); const struct modem_tx_info **mtp = sm_modem_tx_table; @@ -600,7 +600,7 @@ /* --------------------------------------------------------------------- */ -static int wss_ioctl(struct device *dev, struct sm_state *sm, struct ifreq *ifr, +static int wss_ioctl(struct net_device *dev, struct sm_state *sm, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd) { struct sm_ioctl bi; @@ -665,7 +665,7 @@ /* --------------------------------------------------------------------- */ -static void setup_fdx_dma_wss(struct device *dev, struct sm_state *sm) +static void setup_fdx_dma_wss(struct net_device *dev, struct sm_state *sm) { unsigned long flags; unsigned char oldcodecmode, codecdma; @@ -703,7 +703,7 @@ static void wssfdx_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct sm_state *sm = (struct sm_state *)dev->priv; unsigned long flags; unsigned char cry_int_src; @@ -781,7 +781,7 @@ /* --------------------------------------------------------------------- */ -static int wssfdx_open(struct device *dev, struct sm_state *sm) +static int wssfdx_open(struct net_device *dev, struct sm_state *sm) { if (!dev || !sm || !sm->mode_rx || !sm->mode_tx) return -ENXIO; @@ -840,7 +840,7 @@ /* --------------------------------------------------------------------- */ -static int wssfdx_close(struct device *dev, struct sm_state *sm) +static int wssfdx_close(struct net_device *dev, struct sm_state *sm) { if (!dev || !sm) return -EINVAL; @@ -861,7 +861,7 @@ /* --------------------------------------------------------------------- */ -static int wssfdx_sethw(struct device *dev, struct sm_state *sm, char *mode) +static int wssfdx_sethw(struct net_device *dev, struct sm_state *sm, char *mode) { char *cp = strchr(mode, '.'); const struct modem_tx_info **mtp = sm_modem_tx_table; @@ -938,7 +938,7 @@ /* --------------------------------------------------------------------- */ -static int wssfdx_ioctl(struct device *dev, struct sm_state *sm, struct ifreq *ifr, +static int wssfdx_ioctl(struct net_device *dev, struct sm_state *sm, struct ifreq *ifr, struct hdlcdrv_ioctl *hi, int cmd) { if (cmd != SIOCDEVPRIVATE) diff -u --recursive --new-file v2.3.13/linux/drivers/net/hamradio/yam.c linux/drivers/net/hamradio/yam.c --- v2.3.13/linux/drivers/net/hamradio/yam.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/hamradio/yam.c Wed Aug 18 11:38:51 1999 @@ -117,7 +117,7 @@ #endif #if LINUX_VERSION_CODE < 0x20115 -extern __inline__ void dev_init_buffers(struct device *dev) +extern __inline__ void dev_init_buffers(struct net_device *dev) { int i; for (i = 0; i < DEV_NUMBUFFS; i++) { @@ -174,7 +174,7 @@ int dupmode; char name[16]; - struct device dev; + struct net_device dev; /* Stats section */ @@ -515,7 +515,7 @@ * Serial port init ************************************************************************/ -static void yam_set_uart(struct device *dev) +static void yam_set_uart(struct net_device *dev) { struct yam_port *yp = (struct yam_port *) dev->priv; int divisor = 115200 / yp->baudrate; @@ -584,7 +584,7 @@ * Rx Section ******************************************************************************/ static void inline - yam_rx_flag(struct device *dev, struct yam_port *yp) + yam_rx_flag(struct net_device *dev, struct yam_port *yp) { if (yp->dcd && yp->rx_len >= 3 && yp->rx_len < YAM_MAX_FRAME) { int pkt_len = yp->rx_len - 2 + 1; /* -CRC + kiss */ @@ -615,7 +615,7 @@ } static void inline - yam_rx_byte(struct device *dev, struct yam_port *yp, unsigned char rxb) + yam_rx_byte(struct net_device *dev, struct yam_port *yp, unsigned char rxb) { if (yp->rx_len < YAM_MAX_FRAME) { unsigned char c = yp->rx_crcl; @@ -629,17 +629,17 @@ * TX Section ********************************************************************************/ -static void ptt_on(struct device *dev) +static void ptt_on(struct net_device *dev) { outb(PTT_ON, MCR(dev->base_addr)); } -static void ptt_off(struct device *dev) +static void ptt_off(struct net_device *dev) { outb(PTT_OFF, MCR(dev->base_addr)); } -static int yam_send_packet(struct sk_buff *skb, struct device *dev) +static int yam_send_packet(struct sk_buff *skb, struct net_device *dev) { struct yam_port *yp = dev->priv; @@ -651,7 +651,7 @@ return 0; } -static void yam_start_tx(struct device *dev, struct yam_port *yp) +static void yam_start_tx(struct net_device *dev, struct yam_port *yp) { if ((yp->tx_state == TX_TAIL) || (yp->txd == 0)) yp->tx_count = 1; @@ -669,7 +669,7 @@ return random_seed; } -static void yam_arbitrate(struct device *dev) +static void yam_arbitrate(struct net_device *dev) { struct yam_port *yp = dev->priv; @@ -707,7 +707,7 @@ int i; for (i = 0; i < NR_PORTS; i++) { - struct device *dev = &yam_ports[i].dev; + struct net_device *dev = &yam_ports[i].dev; if (dev->start) yam_arbitrate(dev); } @@ -715,7 +715,7 @@ add_timer(&yam_timer); } -static void yam_tx_byte(struct device *dev, struct yam_port *yp) +static void yam_tx_byte(struct net_device *dev, struct yam_port *yp) { struct sk_buff *skb; unsigned char b, temp; @@ -795,7 +795,7 @@ static void yam_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev; + struct net_device *dev; struct yam_port *yp; unsigned char iir; int counter = 100; @@ -915,10 +915,10 @@ #if LINUX_VERSION_CODE >= 0x20119 static struct net_device_stats * - yam_get_stats(struct device *dev) + yam_get_stats(struct net_device *dev) #else static struct enet_statistics * - yam_get_stats(struct device *dev) + yam_get_stats(struct net_device *dev) #endif { struct yam_port *yp; @@ -939,7 +939,7 @@ /* --------------------------------------------------------------------- */ -static int yam_open(struct device *dev) +static int yam_open(struct net_device *dev) { struct yam_port *yp = (struct yam_port *) dev->priv; enum uart u; @@ -990,7 +990,7 @@ /* --------------------------------------------------------------------- */ -static int yam_close(struct device *dev) +static int yam_close(struct net_device *dev) { struct sk_buff *skb; struct yam_port *yp = (struct yam_port *) dev->priv; @@ -1018,7 +1018,7 @@ /* --------------------------------------------------------------------- */ -static int yam_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int yam_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct yam_port *yp = (struct yam_port *) dev->priv; struct yamdrv_ioctl_cfg yi; @@ -1147,7 +1147,7 @@ /* --------------------------------------------------------------------- */ -static int yam_set_mac_address(struct device *dev, void *addr) +static int yam_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = (struct sockaddr *) addr; @@ -1158,7 +1158,7 @@ /* --------------------------------------------------------------------- */ -static int yam_probe(struct device *dev) +static int yam_probe(struct net_device *dev) { struct yam_port *yp; @@ -1201,7 +1201,7 @@ /* --------------------------------------------------------------------- */ -__initfunc(int yam_init(struct device *dev)) +__initfunc(int yam_init(struct net_device *dev)) { int i; @@ -1282,7 +1282,7 @@ del_timer(&yam_timer); for (i = 0; i < NR_PORTS; i++) { - struct device *dev = &yam_ports[i].dev; + struct net_device *dev = &yam_ports[i].dev; if (!dev->priv) continue; if (dev->start) diff -u --recursive --new-file v2.3.13/linux/drivers/net/hostess_sv11.c linux/drivers/net/hostess_sv11.c --- v2.3.13/linux/drivers/net/hostess_sv11.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/hostess_sv11.c Wed Aug 18 11:36:42 1999 @@ -73,7 +73,7 @@ * We've been placed in the UP state */ -static int hostess_open(struct device *d) +static int hostess_open(struct net_device *d) { struct sv11_device *sv11=d->priv; int err = -1; @@ -126,7 +126,7 @@ return 0; } -static int hostess_close(struct device *d) +static int hostess_close(struct net_device *d) { struct sv11_device *sv11=d->priv; /* @@ -158,14 +158,14 @@ return 0; } -static int hostess_ioctl(struct device *d, struct ifreq *ifr, int cmd) +static int hostess_ioctl(struct net_device *d, struct ifreq *ifr, int cmd) { /* struct sv11_device *sv11=d->priv; z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */ return sppp_do_ioctl(d, ifr,cmd); } -static struct enet_statistics *hostess_get_stats(struct device *d) +static struct enet_statistics *hostess_get_stats(struct net_device *d) { struct sv11_device *sv11=d->priv; if(sv11) @@ -178,7 +178,7 @@ * Passed PPP frames, fire them downwind. */ -static int hostess_queue_xmit(struct sk_buff *skb, struct device *d) +static int hostess_queue_xmit(struct sk_buff *skb, struct net_device *d) { struct sv11_device *sv11=d->priv; return z8530_queue_xmit(&sv11->sync.chanA, skb); @@ -194,7 +194,7 @@ return 0; } -static int hostess_neigh_setup_dev(struct device *dev, struct neigh_parms *p) +static int hostess_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p) { if (p->tbl->family == AF_INET) { p->neigh_setup = hostess_neigh_setup; @@ -206,7 +206,7 @@ #else -static int return_0(struct device *d) +static int return_0(struct net_device *d) { return 0; } @@ -322,7 +322,7 @@ sprintf(sv->name,"hdlc%d", i); if(dev_get(sv->name)==NULL) { - struct device *d=dev->chanA.netdevice; + struct net_device *d=dev->chanA.netdevice; /* * Initialise the PPP components diff -u --recursive --new-file v2.3.13/linux/drivers/net/hp-plus.c linux/drivers/net/hp-plus.c --- v2.3.13/linux/drivers/net/hp-plus.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/hp-plus.c Wed Aug 18 11:36:42 1999 @@ -94,23 +94,23 @@ EnableIRQ = 4, FakeIntr = 8, BootROMEnb = 0x10, IOEnb = 0x20, MemEnable = 0x40, ZeroWait = 0x80, MemDisable = 0x1000, }; -int hp_plus_probe(struct device *dev); -int hpp_probe1(struct device *dev, int ioaddr); +int hp_plus_probe(struct net_device *dev); +int hpp_probe1(struct net_device *dev, int ioaddr); -static void hpp_reset_8390(struct device *dev); -static int hpp_open(struct device *dev); -static int hpp_close(struct device *dev); -static void hpp_mem_block_input(struct device *dev, int count, +static void hpp_reset_8390(struct net_device *dev); +static int hpp_open(struct net_device *dev); +static int hpp_close(struct net_device *dev); +static void hpp_mem_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void hpp_mem_block_output(struct device *dev, int count, +static void hpp_mem_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page); -static void hpp_mem_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void hpp_mem_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void hpp_io_block_input(struct device *dev, int count, +static void hpp_io_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void hpp_io_block_output(struct device *dev, int count, +static void hpp_io_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page); -static void hpp_io_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void hpp_io_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); @@ -123,7 +123,7 @@ {"hpplus", hpp_probe1, HP_IO_EXTENT, hpplus_portlist}; #else -int __init hp_plus_probe(struct device *dev) +int __init hp_plus_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -146,7 +146,7 @@ #endif /* Do the interesting part of the probe at a single address. */ -int __init hpp_probe1(struct device *dev, int ioaddr) +int __init hpp_probe1(struct net_device *dev, int ioaddr) { int i; unsigned char checksum = 0; @@ -258,7 +258,7 @@ } static int -hpp_open(struct device *dev) +hpp_open(struct net_device *dev) { int ioaddr = dev->base_addr - NIC_OFFSET; int option_reg; @@ -287,7 +287,7 @@ } static int -hpp_close(struct device *dev) +hpp_close(struct net_device *dev) { int ioaddr = dev->base_addr - NIC_OFFSET; int option_reg = inw(ioaddr + HPP_OPTION); @@ -302,7 +302,7 @@ } static void -hpp_reset_8390(struct device *dev) +hpp_reset_8390(struct net_device *dev) { int ioaddr = dev->base_addr - NIC_OFFSET; int option_reg = inw(ioaddr + HPP_OPTION); @@ -329,7 +329,7 @@ Note that transfer with the EtherTwist+ must be on word boundaries. */ static void -hpp_io_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +hpp_io_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int ioaddr = dev->base_addr - NIC_OFFSET; @@ -340,7 +340,7 @@ /* Block input and output, similar to the Crynwr packet driver. */ static void -hpp_io_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +hpp_io_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int ioaddr = dev->base_addr - NIC_OFFSET; char *buf = skb->data; @@ -354,7 +354,7 @@ /* The corresponding shared memory versions of the above 2 functions. */ static void -hpp_mem_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +hpp_mem_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int ioaddr = dev->base_addr - NIC_OFFSET; int option_reg = inw(ioaddr + HPP_OPTION); @@ -367,7 +367,7 @@ } static void -hpp_mem_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +hpp_mem_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int ioaddr = dev->base_addr - NIC_OFFSET; int option_reg = inw(ioaddr + HPP_OPTION); @@ -387,7 +387,7 @@ /* A special note: we *must* always transfer >=16 bit words. It's always safe to round up, so we do. */ static void -hpp_io_block_output(struct device *dev, int count, +hpp_io_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { int ioaddr = dev->base_addr - NIC_OFFSET; @@ -397,7 +397,7 @@ } static void -hpp_mem_block_output(struct device *dev, int count, +hpp_mem_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { int ioaddr = dev->base_addr - NIC_OFFSET; @@ -416,7 +416,7 @@ #define MAX_HPP_CARDS 4 /* Max number of HPP cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_HPP_CARDS] = { 0, }; -static struct device dev_hpp[MAX_HPP_CARDS] = { +static struct net_device dev_hpp[MAX_HPP_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -439,7 +439,7 @@ int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) { - struct device *dev = &dev_hpp[this_dev]; + struct net_device *dev = &dev_hpp[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -468,7 +468,7 @@ int this_dev; for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) { - struct device *dev = &dev_hpp[this_dev]; + struct net_device *dev = &dev_hpp[this_dev]; if (dev->priv != NULL) { int ioaddr = dev->base_addr - NIC_OFFSET; void *priv = dev->priv; diff -u --recursive --new-file v2.3.13/linux/drivers/net/hp.c linux/drivers/net/hp.c --- v2.3.13/linux/drivers/net/hp.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/hp.c Wed Aug 18 11:36:42 1999 @@ -56,20 +56,20 @@ #define HP_8BSTOP_PG 0x80 /* Last page +1 of RX ring */ #define HP_16BSTOP_PG 0xFF /* Same, for 16 bit cards. */ -int hp_probe(struct device *dev); -int hp_probe1(struct device *dev, int ioaddr); +int hp_probe(struct net_device *dev); +int hp_probe1(struct net_device *dev, int ioaddr); -static int hp_open(struct device *dev); -static int hp_close(struct device *dev); -static void hp_reset_8390(struct device *dev); -static void hp_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static int hp_open(struct net_device *dev); +static int hp_close(struct net_device *dev); +static void hp_reset_8390(struct net_device *dev); +static void hp_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void hp_block_input(struct device *dev, int count, +static void hp_block_input(struct net_device *dev, int count, struct sk_buff *skb , int ring_offset); -static void hp_block_output(struct device *dev, int count, +static void hp_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page); -static void hp_init_card(struct device *dev); +static void hp_init_card(struct net_device *dev); /* The map from IRQ number to HP_CONFIGURE register setting. */ /* My default is IRQ5 0 1 2 3 4 5 6 7 8 9 10 11 */ @@ -84,7 +84,7 @@ {"hp", hp_probe1, HP_IO_EXTENT, hppclan_portlist}; #else -int __init hp_probe(struct device *dev) +int __init hp_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -106,7 +106,7 @@ } #endif -int __init hp_probe1(struct device *dev, int ioaddr) +int __init hp_probe1(struct net_device *dev, int ioaddr) { int i, board_id, wordmode; const char *name; @@ -215,7 +215,7 @@ } static int -hp_open(struct device *dev) +hp_open(struct net_device *dev) { ei_open(dev); MOD_INC_USE_COUNT; @@ -223,7 +223,7 @@ } static int -hp_close(struct device *dev) +hp_close(struct net_device *dev) { ei_close(dev); MOD_DEC_USE_COUNT; @@ -231,7 +231,7 @@ } static void -hp_reset_8390(struct device *dev) +hp_reset_8390(struct net_device *dev) { int hp_base = dev->base_addr - NIC_OFFSET; int saved_config = inb_p(hp_base + HP_CONFIGURE); @@ -253,7 +253,7 @@ } static void -hp_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +hp_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int nic_base = dev->base_addr; int saved_config = inb_p(nic_base - NIC_OFFSET + HP_CONFIGURE); @@ -280,7 +280,7 @@ out through the "remote DMA" dataport. */ static void -hp_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +hp_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int nic_base = dev->base_addr; int saved_config = inb_p(nic_base - NIC_OFFSET + HP_CONFIGURE); @@ -315,7 +315,7 @@ } static void -hp_block_output(struct device *dev, int count, +hp_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { int nic_base = dev->base_addr; @@ -374,7 +374,7 @@ /* This function resets the ethercard if something screws up. */ static void -hp_init_card(struct device *dev) +hp_init_card(struct net_device *dev) { int irq = dev->irq; NS8390_init(dev, 0); @@ -387,7 +387,7 @@ #define MAX_HP_CARDS 4 /* Max number of HP cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_HP_CARDS] = { 0, }; -static struct device dev_hp[MAX_HP_CARDS] = { +static struct net_device dev_hp[MAX_HP_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -410,7 +410,7 @@ int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_HP_CARDS; this_dev++) { - struct device *dev = &dev_hp[this_dev]; + struct net_device *dev = &dev_hp[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -439,7 +439,7 @@ int this_dev; for (this_dev = 0; this_dev < MAX_HP_CARDS; this_dev++) { - struct device *dev = &dev_hp[this_dev]; + struct net_device *dev = &dev_hp[this_dev]; if (dev->priv != NULL) { int ioaddr = dev->base_addr - NIC_OFFSET; void *priv = dev->priv; diff -u --recursive --new-file v2.3.13/linux/drivers/net/hp100.c linux/drivers/net/hp100.c --- v2.3.13/linux/drivers/net/hp100.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/hp100.c Wed Aug 18 11:36:42 1999 @@ -300,38 +300,38 @@ */ #ifdef LINUX_2_1 -static int hp100_probe1( struct device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev ); +static int hp100_probe1( struct net_device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev ); #else -static int hp100_probe1( struct device *dev, int ioaddr, u_char bus, u_char pci_bus, u_char pci_device_fn ); +static int hp100_probe1( struct net_device *dev, int ioaddr, u_char bus, u_char pci_bus, u_char pci_device_fn ); #endif -static int hp100_open( struct device *dev ); -static int hp100_close( struct device *dev ); -static int hp100_start_xmit( struct sk_buff *skb, struct device *dev ); -static int hp100_start_xmit_bm (struct sk_buff *skb, struct device *dev ); -static void hp100_rx( struct device *dev ); -static hp100_stats_t *hp100_get_stats( struct device *dev ); -static void hp100_misc_interrupt( struct device *dev ); -static void hp100_update_stats( struct device *dev ); +static int hp100_open( struct net_device *dev ); +static int hp100_close( struct net_device *dev ); +static int hp100_start_xmit( struct sk_buff *skb, struct net_device *dev ); +static int hp100_start_xmit_bm (struct sk_buff *skb, struct net_device *dev ); +static void hp100_rx( struct net_device *dev ); +static hp100_stats_t *hp100_get_stats( struct net_device *dev ); +static void hp100_misc_interrupt( struct net_device *dev ); +static void hp100_update_stats( struct net_device *dev ); static void hp100_clear_stats( int ioaddr ); -static void hp100_set_multicast_list( struct device *dev); +static void hp100_set_multicast_list( struct net_device *dev); static void hp100_interrupt( int irq, void *dev_id, struct pt_regs *regs ); -static void hp100_start_interface( struct device *dev ); -static void hp100_stop_interface( struct device *dev ); -static void hp100_load_eeprom( struct device *dev, u_short ioaddr ); -static int hp100_sense_lan( struct device *dev ); -static int hp100_login_to_vg_hub( struct device *dev, u_short force_relogin ); -static int hp100_down_vg_link( struct device *dev ); -static void hp100_cascade_reset( struct device *dev, u_short enable ); -static void hp100_BM_shutdown( struct device *dev ); -static void hp100_mmuinit( struct device *dev ); -static void hp100_init_pdls( struct device *dev ); -static int hp100_init_rxpdl( struct device *dev, register hp100_ring_t *ringptr, register u_int *pdlptr); -static int hp100_init_txpdl( struct device *dev, register hp100_ring_t *ringptr, register u_int *pdlptr); -static void hp100_rxfill( struct device *dev ); -static void hp100_hwinit( struct device *dev ); -static void hp100_clean_txring( struct device *dev ); +static void hp100_start_interface( struct net_device *dev ); +static void hp100_stop_interface( struct net_device *dev ); +static void hp100_load_eeprom( struct net_device *dev, u_short ioaddr ); +static int hp100_sense_lan( struct net_device *dev ); +static int hp100_login_to_vg_hub( struct net_device *dev, u_short force_relogin ); +static int hp100_down_vg_link( struct net_device *dev ); +static void hp100_cascade_reset( struct net_device *dev, u_short enable ); +static void hp100_BM_shutdown( struct net_device *dev ); +static void hp100_mmuinit( struct net_device *dev ); +static void hp100_init_pdls( struct net_device *dev ); +static int hp100_init_rxpdl( struct net_device *dev, register hp100_ring_t *ringptr, register u_int *pdlptr); +static int hp100_init_txpdl( struct net_device *dev, register hp100_ring_t *ringptr, register u_int *pdlptr); +static void hp100_rxfill( struct net_device *dev ); +static void hp100_hwinit( struct net_device *dev ); +static void hp100_clean_txring( struct net_device *dev ); #ifdef HP100_DEBUG -static void hp100_RegisterDump( struct device *dev ); +static void hp100_RegisterDump( struct net_device *dev ); #endif /* TODO: This function should not really be needed in a good design... */ @@ -346,7 +346,7 @@ * since this could cause problems when the card is not installed. */ -int __init hp100_probe( struct device *dev ) +int __init hp100_probe( struct net_device *dev ) { int base_addr = dev ? dev -> base_addr : 0; int ioaddr = 0; @@ -523,9 +523,9 @@ #ifdef LINUX_2_1 -static int __init hp100_probe1( struct device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev ) +static int __init hp100_probe1( struct net_device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev ) #else -static int __init hp100_probe1( struct device *dev, int ioaddr, u_char bus, u_char pci_bus, u_char pci_device_fn ) +static int __init hp100_probe1( struct net_device *dev, int ioaddr, u_char bus, u_char pci_bus, u_char pci_device_fn ) #endif { int i; @@ -941,7 +941,7 @@ /* This procedure puts the card into a stable init state */ -static void hp100_hwinit( struct device *dev ) +static void hp100_hwinit( struct net_device *dev ) { int ioaddr = dev->base_addr; struct hp100_private *lp = (struct hp100_private *)dev->priv; @@ -1037,7 +1037,7 @@ * mmuinit - Reinitialise Cascade MMU and MAC settings. * Note: Must already be in reset and leaves card in reset. */ -static void hp100_mmuinit( struct device *dev ) +static void hp100_mmuinit( struct net_device *dev ) { int ioaddr = dev->base_addr; struct hp100_private *lp = (struct hp100_private *)dev->priv; @@ -1230,7 +1230,7 @@ * open/close functions */ -static int hp100_open( struct device *dev ) +static int hp100_open( struct net_device *dev ) { struct hp100_private *lp = (struct hp100_private *)dev->priv; #ifdef HP100_DEBUG_B @@ -1274,7 +1274,7 @@ /* The close function is called when the interface is to be brought down */ -static int hp100_close( struct device *dev ) +static int hp100_close( struct net_device *dev ) { int ioaddr = dev->base_addr; struct hp100_private *lp = (struct hp100_private *)dev->priv; @@ -1309,7 +1309,7 @@ /* * Configure the PDL Rx rings and LAN */ -static void hp100_init_pdls( struct device *dev ) +static void hp100_init_pdls( struct net_device *dev ) { struct hp100_private *lp = (struct hp100_private *)dev->priv; hp100_ring_t *ringptr; @@ -1362,7 +1362,7 @@ /* These functions "format" the entries in the pdl structure */ /* They return how much memory the fragments need. */ -static int hp100_init_rxpdl( struct device *dev, register hp100_ring_t *ringptr, register u32 *pdlptr ) +static int hp100_init_rxpdl( struct net_device *dev, register hp100_ring_t *ringptr, register u32 *pdlptr ) { /* pdlptr is starting address for this pdl */ @@ -1388,7 +1388,7 @@ } -static int hp100_init_txpdl( struct device *dev, register hp100_ring_t *ringptr, register u32 *pdlptr ) +static int hp100_init_txpdl( struct net_device *dev, register hp100_ring_t *ringptr, register u32 *pdlptr ) { if( 0!=( ((unsigned)pdlptr) & 0xf) ) printk("hp100: %s: Init txpdl: Unaligned pdlptr 0x%x.\n",dev->name,(unsigned) pdlptr); @@ -1408,7 +1408,7 @@ * Returns: 0 if unable to allocate skb_buff * 1 if successful */ -int hp100_build_rx_pdl( hp100_ring_t *ringptr, struct device *dev ) +int hp100_build_rx_pdl( hp100_ring_t *ringptr, struct net_device *dev ) { #ifdef HP100_DEBUG_B int ioaddr = dev->base_addr; @@ -1492,7 +1492,7 @@ * b. Put the physical address of the buffer into the PDL. * c. Output physical address of PDL to adapter. */ -static void hp100_rxfill( struct device *dev ) +static void hp100_rxfill( struct net_device *dev ) { int ioaddr=dev->base_addr; @@ -1540,7 +1540,7 @@ * BM_shutdown - shutdown bus mastering and leave chip in reset state */ -static void hp100_BM_shutdown( struct device *dev ) +static void hp100_BM_shutdown( struct net_device *dev ) { int ioaddr = dev->base_addr; struct hp100_private *lp = (struct hp100_private *)dev->priv; @@ -1634,7 +1634,7 @@ */ /* tx function for busmaster mode */ -static int hp100_start_xmit_bm( struct sk_buff *skb, struct device *dev ) +static int hp100_start_xmit_bm( struct sk_buff *skb, struct net_device *dev ) { unsigned long flags; int i, ok_flag; @@ -1772,7 +1772,7 @@ * * Needs the PERFORMANCE page selected. */ -static void hp100_clean_txring( struct device *dev ) +static void hp100_clean_txring( struct net_device *dev ) { struct hp100_private *lp = (struct hp100_private *)dev->priv; int ioaddr = dev->base_addr; @@ -1814,7 +1814,7 @@ /* tx function for slave modes */ -static int hp100_start_xmit( struct sk_buff *skb, struct device *dev ) +static int hp100_start_xmit( struct sk_buff *skb, struct net_device *dev ) { int i, ok_flag; int ioaddr = dev->base_addr; @@ -1984,7 +1984,7 @@ * and netif_rx. */ -static void hp100_rx( struct device *dev ) +static void hp100_rx( struct net_device *dev ) { int packets, pkt_len; int ioaddr = dev->base_addr; @@ -2103,7 +2103,7 @@ /* * Receive Function for Busmaster Mode */ -static void hp100_rx_bm( struct device *dev ) +static void hp100_rx_bm( struct net_device *dev ) { int ioaddr = dev->base_addr; struct hp100_private *lp = (struct hp100_private *)dev->priv; @@ -2232,7 +2232,7 @@ /* * statistics */ -static hp100_stats_t *hp100_get_stats( struct device *dev ) +static hp100_stats_t *hp100_get_stats( struct net_device *dev ) { int ioaddr = dev->base_addr; @@ -2246,7 +2246,7 @@ return &((struct hp100_private *)dev->priv)->stats; } -static void hp100_update_stats( struct device *dev ) +static void hp100_update_stats( struct net_device *dev ) { int ioaddr = dev->base_addr; u_short val; @@ -2271,7 +2271,7 @@ hp100_page( PERFORMANCE ); } -static void hp100_misc_interrupt( struct device *dev ) +static void hp100_misc_interrupt( struct net_device *dev ) { struct hp100_private *lp = (struct hp100_private *)dev->priv; @@ -2313,7 +2313,7 @@ * Set or clear the multicast filter for this adapter. */ -static void hp100_set_multicast_list( struct device *dev ) +static void hp100_set_multicast_list( struct net_device *dev ) { unsigned long flags; int ioaddr = dev->base_addr; @@ -2468,7 +2468,7 @@ static void hp100_interrupt( int irq, void *dev_id, struct pt_regs *regs ) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct hp100_private *lp = (struct hp100_private *)dev->priv; int ioaddr; @@ -2609,7 +2609,7 @@ * some misc functions */ -static void hp100_start_interface( struct device *dev ) +static void hp100_start_interface( struct net_device *dev ) { unsigned long flags; int ioaddr = dev->base_addr; @@ -2676,7 +2676,7 @@ } -static void hp100_stop_interface( struct device *dev ) +static void hp100_stop_interface( struct net_device *dev ) { struct hp100_private *lp = (struct hp100_private *)dev->priv; int ioaddr = dev->base_addr; @@ -2714,7 +2714,7 @@ } -static void hp100_load_eeprom( struct device *dev, u_short probe_ioaddr ) +static void hp100_load_eeprom( struct net_device *dev, u_short probe_ioaddr ) { int i; int ioaddr = probe_ioaddr > 0 ? probe_ioaddr : dev->base_addr; @@ -2737,7 +2737,7 @@ * LAN_100 - Connected to 100Mbit/s network * LAN_ERR - not connected or 100Mbit/s Hub down */ -static int hp100_sense_lan( struct device *dev ) +static int hp100_sense_lan( struct net_device *dev ) { int ioaddr = dev->base_addr; u_short val_VG, val_10; @@ -2779,7 +2779,7 @@ -static int hp100_down_vg_link( struct device *dev ) +static int hp100_down_vg_link( struct net_device *dev ) { struct hp100_private *lp = (struct hp100_private *)dev->priv; int ioaddr = dev->base_addr; @@ -2873,7 +2873,7 @@ } -static int hp100_login_to_vg_hub( struct device *dev, u_short force_relogin ) +static int hp100_login_to_vg_hub( struct net_device *dev, u_short force_relogin ) { int ioaddr = dev->base_addr; struct hp100_private *lp = (struct hp100_private *)dev->priv; @@ -3046,7 +3046,7 @@ } -static void hp100_cascade_reset( struct device *dev, u_short enable ) +static void hp100_cascade_reset( struct net_device *dev, u_short enable ) { int ioaddr = dev->base_addr; struct hp100_private *lp = (struct hp100_private *)dev->priv; @@ -3083,7 +3083,7 @@ } #ifdef HP100_DEBUG -void hp100_RegisterDump( struct device *dev ) +void hp100_RegisterDump( struct net_device *dev ) { int ioaddr=dev->base_addr; int Page; @@ -3140,7 +3140,7 @@ #endif /* List of devices */ -static struct device *hp100_devlist[5] = { NULL, NULL, NULL, NULL, NULL }; +static struct net_device *hp100_devlist[5] = { NULL, NULL, NULL, NULL, NULL }; /* * Note: if you have more than five 100vg cards in your pc, feel free to @@ -3166,8 +3166,8 @@ while((hp100_port[++i] != -1) && (i < 5)) { /* Create device and set basics args */ - hp100_devlist[i] = kmalloc(sizeof(struct device), GFP_KERNEL); - memset(hp100_devlist[i], 0x00, sizeof(struct device)); + hp100_devlist[i] = kmalloc(sizeof(struct net_device), GFP_KERNEL); + memset(hp100_devlist[i], 0x00, sizeof(struct net_device)); hp100_devlist[i]->name = hp100_name[i]; hp100_devlist[i]->base_addr = hp100_port[i]; hp100_devlist[i]->init = &hp100_probe; @@ -3177,8 +3177,8 @@ { /* DeAllocate everything */ /* Note: if dev->priv is mallocated, there is no way to fail */ - kfree_s(hp100_devlist[i], sizeof(struct device)); - hp100_devlist[i] = (struct device *) NULL; + kfree_s(hp100_devlist[i], sizeof(struct net_device)); + hp100_devlist[i] = (struct net_device *) NULL; } else cards++; @@ -3193,7 +3193,7 @@ /* TODO: Check if all skb's are released/freed. */ for(i = 0; i < 5; i++) - if(hp100_devlist[i] != (struct device *) NULL) + if(hp100_devlist[i] != (struct net_device *) NULL) { unregister_netdev( hp100_devlist[i] ); release_region( hp100_devlist[i]->base_addr, HP100_REGION_SIZE ); @@ -3203,8 +3203,8 @@ iounmap( ((struct hp100_private *)hp100_devlist[i]->priv) -> mem_ptr_virt ); kfree_s( hp100_devlist[i]->priv, sizeof( struct hp100_private ) ); hp100_devlist[i]->priv = NULL; - kfree_s(hp100_devlist[i], sizeof(struct device)); - hp100_devlist[i] = (struct device *) NULL; + kfree_s(hp100_devlist[i], sizeof(struct net_device)); + hp100_devlist[i] = (struct net_device *) NULL; } } diff -u --recursive --new-file v2.3.13/linux/drivers/net/hplance.c linux/drivers/net/hplance.c --- v2.3.13/linux/drivers/net/hplance.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/hplance.c Wed Aug 18 11:36:42 1999 @@ -54,10 +54,10 @@ * plus board-specific init, open and close actions. * Oh, and we need to tell the generic code how to read and write LANCE registers... */ -int hplance_probe(struct device *dev); -static int hplance_init(struct device *dev, int scode); -static int hplance_open(struct device *dev); -static int hplance_close(struct device *dev); +int hplance_probe(struct net_device *dev); +static int hplance_init(struct net_device *dev, int scode); +static int hplance_open(struct net_device *dev); +static int hplance_close(struct net_device *dev); static void hplance_writerap(struct hplance_private *lp, unsigned short value); static void hplance_writerdp(struct hplance_private *lp, unsigned short value); static unsigned short hplance_readrdp(struct hplance_private *lp); @@ -67,7 +67,7 @@ #endif /* Find all the HP Lance boards and initialise them... */ -int __init hplance_probe(struct device *dev) +int __init hplance_probe(struct net_device *dev) { int cards = 0, called = 0; @@ -98,7 +98,7 @@ } /* Initialise a single lance board at the given select code */ -static int __init hplance_init(struct device *dev, int scode) +static int __init hplance_init(struct net_device *dev, int scode) { /* const char *name = dio_scodetoname(scode); */ static const char name[] = "HP LANCE"; @@ -198,7 +198,7 @@ return val; } -static int hplance_open(struct device *dev) +static int hplance_open(struct net_device *dev) { int status; struct hplance_private *lp = (struct hplance_private *)dev->priv; @@ -214,7 +214,7 @@ return 0; } -static int hplance_close(struct device *dev) +static int hplance_close(struct net_device *dev) { struct hplance_private *lp = (struct hplance_private *)dev->priv; struct hplance_reg *hpregs = (struct hplance_reg *)lp->base; diff -u --recursive --new-file v2.3.13/linux/drivers/net/hydra.c linux/drivers/net/hydra.c --- v2.3.13/linux/drivers/net/hydra.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/hydra.c Wed Aug 18 11:36:42 1999 @@ -90,14 +90,14 @@ unsigned int key; }; -static int hydra_open(struct device *dev); -static int hydra_start_xmit(struct sk_buff *skb, struct device *dev); +static int hydra_open(struct net_device *dev); +static int hydra_start_xmit(struct sk_buff *skb, struct net_device *dev); static void hydra_interrupt(int irq, void *data, struct pt_regs *fp); -static void __inline__ hydra_rx(struct device *dev, struct hydra_private *priv, volatile u8 *nicbase); -static int hydra_close(struct device *dev); -static struct net_device_stats *hydra_get_stats(struct device *dev); +static void __inline__ hydra_rx(struct net_device *dev, struct hydra_private *priv, volatile u8 *nicbase); +static int hydra_close(struct net_device *dev); +static struct net_device_stats *hydra_get_stats(struct net_device *dev); #ifdef HAVE_MULTICAST -static void set_multicast_list(struct device *dev, int num_addrs, void *addrs); +static void set_multicast_list(struct net_device *dev, int num_addrs, void *addrs); #endif @@ -157,7 +157,7 @@ #endif -int __init hydra_probe(struct device *dev) +int __init hydra_probe(struct net_device *dev) { struct hydra_private *priv; u32 board; @@ -210,7 +210,7 @@ } -static int hydra_open(struct device *dev) +static int hydra_open(struct net_device *dev) { struct hydra_private *priv = (struct hydra_private *)dev->priv; volatile u8 *nicbase = priv->hydra_nic_base; @@ -282,7 +282,8 @@ dev->interrupt = 0; dev->start = 1; - if(request_irq(IRQ_AMIGA_PORTS, hydra_interrupt, 0, "Hydra Ethernet", dev)) + if(request_irq(IRQ_AMIGA_PORTS, hydra_interrupt, SA_SHIRQ, + "Hydra Ethernet", dev)) return(-EAGAIN); MOD_INC_USE_COUNT; @@ -291,7 +292,7 @@ } -static int hydra_close(struct device *dev) +static int hydra_close(struct net_device *dev) { struct hydra_private *priv = (struct hydra_private *)dev->priv; volatile u8 *nicbase = priv->hydra_nic_base; @@ -322,7 +323,7 @@ { volatile u8 *nicbase; - struct device *dev = (struct device *) data; + struct net_device *dev = (struct net_device *) data; struct hydra_private *priv; u16 intbits; @@ -433,7 +434,7 @@ * packet transmit routine */ -static int hydra_start_xmit(struct sk_buff *skb, struct device *dev) +static int hydra_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct hydra_private *priv = (struct hydra_private *)dev->priv; volatile u8 *nicbase = priv->hydra_nic_base; @@ -524,7 +525,7 @@ } -static void __inline__ hydra_rx(struct device *dev, struct hydra_private *priv, volatile u8 *nicbase) +static void __inline__ hydra_rx(struct net_device *dev, struct hydra_private *priv, volatile u8 *nicbase) { volatile u16 *board_ram_ptr; struct sk_buff *skb; @@ -633,7 +634,7 @@ } -static struct net_device_stats *hydra_get_stats(struct device *dev) +static struct net_device_stats *hydra_get_stats(struct net_device *dev) { struct hydra_private *priv = (struct hydra_private *)dev->priv; #if 0 @@ -647,7 +648,7 @@ } #ifdef HAVE_MULTICAST -static void set_multicast_list(struct device *dev, int num_addrs, void *addrs) +static void set_multicast_list(struct net_device *dev, int num_addrs, void *addrs) { struct hydra_private *priv = (struct hydra_private *)dev->priv; u8 *board = priv->hydra_base; @@ -662,7 +663,7 @@ #ifdef MODULE static char devicename[9] = { 0, }; -static struct device hydra_dev = +static struct net_device hydra_dev = { devicename, /* filled in by register_netdev() */ 0, 0, 0, 0, /* memory */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c --- v2.3.13/linux/drivers/net/ibmtr.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/ibmtr.c Wed Aug 18 11:36:42 1999 @@ -193,27 +193,27 @@ #define TRC_INIT 0x01 /* Trace initialization & PROBEs */ #define TRC_INITV 0x02 /* verbose init trace points */ -int ibmtr_probe(struct device *dev); -static int ibmtr_probe1(struct device *dev, int ioaddr); +int ibmtr_probe(struct net_device *dev); +static int ibmtr_probe1(struct net_device *dev, int ioaddr); static unsigned char get_sram_size(struct tok_info *adapt_info); #ifdef PCMCIA extern unsigned char pcmcia_reality_check(unsigned char gss); #endif -static int tok_init_card(struct device *dev); +static int tok_init_card(struct net_device *dev); void tok_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int trdev_init(struct device *dev); -static void initial_tok_int(struct device *dev); -static void open_sap(unsigned char type,struct device *dev); +static int trdev_init(struct net_device *dev); +static void initial_tok_int(struct net_device *dev); +static void open_sap(unsigned char type,struct net_device *dev); void tok_open_adapter(unsigned long dev_addr); -static void tr_rx(struct device *dev); -static void tr_tx(struct device *dev); -static int tok_open(struct device *dev); -static int tok_close(struct device *dev); -static int tok_send_packet(struct sk_buff *skb, struct device *dev); -static struct net_device_stats * tok_get_stats(struct device *dev); -void ibmtr_readlog(struct device *dev); -void ibmtr_reset_timer(struct timer_list *tmr, struct device *dev); -int ibmtr_change_mtu(struct device *dev, int mtu); +static void tr_rx(struct net_device *dev); +static void tr_tx(struct net_device *dev); +static int tok_open(struct net_device *dev); +static int tok_close(struct net_device *dev); +static int tok_send_packet(struct sk_buff *skb, struct net_device *dev); +static struct net_device_stats * tok_get_stats(struct net_device *dev); +void ibmtr_readlog(struct net_device *dev); +void ibmtr_reset_timer(struct timer_list *tmr, struct net_device *dev); +int ibmtr_change_mtu(struct net_device *dev, int mtu); static unsigned int ibmtr_portlist[] __initdata = { 0xa20, 0xa24, 0 @@ -250,7 +250,7 @@ * which references it. */ -int __init ibmtr_probe(struct device *dev) +int __init ibmtr_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -293,7 +293,7 @@ return -ENODEV; } -static int __init ibmtr_probe1(struct device *dev, int PIOaddr) +static int __init ibmtr_probe1(struct net_device *dev, int PIOaddr) { unsigned char segment=0, intr=0, irq=0, i=0, j=0, cardpresent=NOTOK,temp=0; __u32 t_mmio=0; @@ -767,7 +767,7 @@ return 1<<((readb(adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)>>2)+4); } -static int __init trdev_init(struct device *dev) +static int __init trdev_init(struct net_device *dev) { struct tok_info *ti=(struct tok_info *)dev->priv; @@ -791,7 +791,7 @@ -static int tok_open(struct device *dev) +static int tok_open(struct net_device *dev) { struct tok_info *ti=(struct tok_info *)dev->priv; @@ -815,7 +815,7 @@ } -static int tok_close(struct device *dev) +static int tok_close(struct net_device *dev) { struct tok_info *ti=(struct tok_info *) dev->priv; @@ -846,7 +846,7 @@ { unsigned char status; struct tok_info *ti; - struct device *dev; + struct net_device *dev; dev = dev_id; #if TR_VERBOSE @@ -1220,7 +1220,7 @@ spin_unlock(&(ti->lock)); } -static void initial_tok_int(struct device *dev) +static void initial_tok_int(struct net_device *dev) { __u32 encoded_addr; @@ -1288,7 +1288,7 @@ tok_open_adapter((unsigned long)dev); } -static int tok_init_card(struct device *dev) +static int tok_init_card(struct net_device *dev) { struct tok_info *ti; short PIOaddr; @@ -1326,7 +1326,7 @@ return 0; } -static void open_sap(unsigned char type,struct device *dev) +static void open_sap(unsigned char type,struct net_device *dev) { int i; struct tok_info *ti=(struct tok_info *) dev->priv; @@ -1351,7 +1351,7 @@ void tok_open_adapter(unsigned long dev_addr) { - struct device *dev=(struct device *)dev_addr; + struct net_device *dev=(struct net_device *)dev_addr; struct tok_info *ti; int i; @@ -1400,7 +1400,7 @@ } -static void tr_tx(struct device *dev) +static void tr_tx(struct net_device *dev) { struct tok_info *ti=(struct tok_info *) dev->priv; struct trh_hdr *trhdr=(struct trh_hdr *)ti->current_skb->data; @@ -1475,7 +1475,7 @@ if (ti->readlog_pending) ibmtr_readlog(dev); } -static void tr_rx(struct device *dev) +static void tr_rx(struct net_device *dev) { struct tok_info *ti=(struct tok_info *) dev->priv; __u32 rbuffer, rbufdata; @@ -1630,7 +1630,7 @@ netif_rx(skb); } -static int tok_send_packet(struct sk_buff *skb, struct device *dev) +static int tok_send_packet(struct sk_buff *skb, struct net_device *dev) { struct tok_info *ti; ti=(struct tok_info *) dev->priv; @@ -1668,7 +1668,7 @@ return 0; } -void ibmtr_reset_timer(struct timer_list *tmr, struct device *dev) { +void ibmtr_reset_timer(struct timer_list *tmr, struct net_device *dev) { tmr->expires = jiffies + TR_RETRY_INTERVAL; tmr->data = (unsigned long) dev; tmr->function = tok_open_adapter; @@ -1676,7 +1676,7 @@ add_timer(tmr); } -void ibmtr_readlog(struct device *dev) { +void ibmtr_readlog(struct net_device *dev) { struct tok_info *ti; ti=(struct tok_info *) dev->priv; @@ -1692,14 +1692,14 @@ this device -- the tr.... structure is an ethnet look-alike so at least for this iteration may suffice. */ -static struct net_device_stats * tok_get_stats(struct device *dev) { +static struct net_device_stats * tok_get_stats(struct net_device *dev) { struct tok_info *toki; toki=(struct tok_info *) dev->priv; return (struct net_device_stats *) &toki->tr_stats; } -int ibmtr_change_mtu(struct device *dev, int mtu) { +int ibmtr_change_mtu(struct net_device *dev, int mtu) { struct tok_info *ti = (struct tok_info *) dev->priv; if (ti->ring_speed == 16 && mtu > ti->maxmtu16) @@ -1713,7 +1713,7 @@ #ifdef MODULE /* 3COM 3C619C supports 8 interrupts, 32 I/O ports */ -static struct device* dev_ibmtr[IBMTR_MAX_ADAPTERS]; +static struct net_device* dev_ibmtr[IBMTR_MAX_ADAPTERS]; static int io[IBMTR_MAX_ADAPTERS] = {0xa20,0xa24}; static int irq[IBMTR_MAX_ADAPTERS] = {0,0}; static int mem[IBMTR_MAX_ADAPTERS] = {0,0}; @@ -1739,7 +1739,7 @@ dev_ibmtr[i]->init = &ibmtr_probe; if (register_trdev(dev_ibmtr[i]) != 0) { - kfree_s(dev_ibmtr[i], sizeof(struct device)); + kfree_s(dev_ibmtr[i], sizeof(struct net_device)); dev_ibmtr[i] = NULL; if (i == 0) { printk("ibmtr: register_trdev() returned non-zero.\n"); @@ -1762,7 +1762,7 @@ free_irq(dev_ibmtr[i]->irq, dev_ibmtr[i]); release_region(dev_ibmtr[i]->base_addr, IBMTR_IO_EXTENT); kfree_s(dev_ibmtr[i]->priv, sizeof(struct tok_info)); - kfree_s(dev_ibmtr[i], sizeof(struct device)); + kfree_s(dev_ibmtr[i], sizeof(struct net_device)); dev_ibmtr[i] = NULL; } } diff -u --recursive --new-file v2.3.13/linux/drivers/net/ipddp.c linux/drivers/net/ipddp.c --- v2.3.13/linux/drivers/net/ipddp.c Sun Nov 8 13:45:07 1998 +++ linux/drivers/net/ipddp.c Wed Aug 18 11:36:42 1999 @@ -75,15 +75,15 @@ static unsigned int ipddp_debug = IPDDP_DEBUG; /* Index to functions, as function prototypes. */ -static int ipddp_xmit(struct sk_buff *skb, struct device *dev); -static struct net_device_stats *ipddp_get_stats(struct device *dev); +static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev); +static struct net_device_stats *ipddp_get_stats(struct net_device *dev); static int ipddp_create(struct ipddp_route *new_rt); static int ipddp_delete(struct ipddp_route *rt); static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt); -static int ipddp_ioctl(struct device *dev, struct ifreq *ifr, int cmd); +static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); -static int ipddp_open(struct device *dev) +static int ipddp_open(struct net_device *dev) { #ifdef MODULE MOD_INC_USE_COUNT; @@ -92,7 +92,7 @@ return 0; } -static int ipddp_close(struct device *dev) +static int ipddp_close(struct net_device *dev) { #ifdef MODULE MOD_DEC_USE_COUNT; @@ -101,7 +101,7 @@ return 0; } -int ipddp_init(struct device *dev) +int ipddp_init(struct net_device *dev) { static unsigned version_printed = 0; @@ -149,7 +149,7 @@ /* * Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *ipddp_get_stats(struct device *dev) +static struct net_device_stats *ipddp_get_stats(struct net_device *dev) { return (struct net_device_stats *)dev->priv; } @@ -157,7 +157,7 @@ /* * Transmit LLAP/ELAP frame using aarp_send_ddp. */ -static int ipddp_xmit(struct sk_buff *skb, struct device *dev) +static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev) { u32 paddr = ((struct rtable*)skb->dst)->rt_gateway; struct ddpehdr *ddp; @@ -297,7 +297,7 @@ return (NULL); } -static int ipddp_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct ipddp_route *rt = (struct ipddp_route *)ifr->ifr_data; @@ -324,7 +324,7 @@ #ifdef MODULE /* Module specific functions for ipddp.c */ -static struct device dev_ipddp= +static struct net_device dev_ipddp= { "ipddp0\0 ", 0, 0, 0, 0, diff -u --recursive --new-file v2.3.13/linux/drivers/net/ipddp.h linux/drivers/net/ipddp.h --- v2.3.13/linux/drivers/net/ipddp.h Thu Mar 12 10:54:12 1998 +++ linux/drivers/net/ipddp.h Wed Aug 18 11:36:45 1999 @@ -13,7 +13,7 @@ struct ipddp_route { - struct device *dev; /* Carrier device */ + struct net_device *dev; /* Carrier device */ __u32 ip; /* IP address */ struct at_addr at; /* Gateway appletalk address */ int flags; diff -u --recursive --new-file v2.3.13/linux/drivers/net/irda/irport.c linux/drivers/net/irda/irport.c --- v2.3.13/linux/drivers/net/irda/irport.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/irda/irport.c Wed Aug 18 11:38:51 1999 @@ -79,9 +79,9 @@ static int irport_write(int iobase, int fifo_size, __u8 *buf, int len); static void irport_receive(struct irda_device *idev); -static int irport_net_init(struct device *dev); -static int irport_net_open(struct device *dev); -static int irport_net_close(struct device *dev); +static int irport_net_init(struct net_device *dev); +static int irport_net_open(struct net_device *dev); +static int irport_net_close(struct net_device *dev); static int irport_is_receiving(struct irda_device *idev); static void irport_set_dtr_rts(struct irda_device *idev, int dtr, int rts); static int irport_raw_write(struct irda_device *idev, __u8 *buf, int len); @@ -413,7 +413,7 @@ * waits until the next transmitt interrupt, and continues until the * frame is transmited. */ -int irport_hard_xmit(struct sk_buff *skb, struct device *dev) +int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct irda_device *idev; unsigned long flags; @@ -555,7 +555,7 @@ spin_unlock(&idev->lock); } -static int irport_net_init(struct device *dev) +static int irport_net_init(struct net_device *dev) { /* Set up to be a normal IrDA network device driver */ irda_device_setup(dev); @@ -571,7 +571,7 @@ * * */ -static int irport_net_open(struct device *dev) +static int irport_net_open(struct net_device *dev) { struct irda_device *idev; int iobase; @@ -607,7 +607,7 @@ * * */ -static int irport_net_close(struct device *dev) +static int irport_net_close(struct net_device *dev) { struct irda_device *idev; int iobase; diff -u --recursive --new-file v2.3.13/linux/drivers/net/irda/irtty.c linux/drivers/net/irda/irtty.c --- v2.3.13/linux/drivers/net/irda/irtty.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/irda/irtty.c Wed Aug 18 11:38:51 1999 @@ -44,14 +44,14 @@ static int qos_mtt_bits = 0x03; /* 5 ms or more */ -static int irtty_hard_xmit(struct sk_buff *skb, struct device *dev); +static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev); static void irtty_wait_until_sent(struct irda_device *driver); static int irtty_is_receiving(struct irda_device *idev); static void irtty_set_dtr_rts(struct irda_device *idev, int dtr, int rts); static int irtty_raw_write(struct irda_device *idev, __u8 *buf, int len); -static int irtty_net_init(struct device *dev); -static int irtty_net_open(struct device *dev); -static int irtty_net_close(struct device *dev); +static int irtty_net_init(struct net_device *dev); +static int irtty_net_open(struct net_device *dev); +static int irtty_net_close(struct net_device *dev); static int irtty_open(struct tty_struct *tty); static void irtty_close(struct tty_struct *tty); @@ -427,7 +427,7 @@ * Transmit frame * */ -static int irtty_hard_xmit(struct sk_buff *skb, struct device *dev) +static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct irtty_cb *self; struct irda_device *idev; @@ -634,7 +634,7 @@ return actual; } -static int irtty_net_init(struct device *dev) +static int irtty_net_init(struct net_device *dev) { /* Set up to be a normal IrDA network device driver */ irda_device_setup(dev); @@ -644,7 +644,7 @@ return 0; } -static int irtty_net_open(struct device *dev) +static int irtty_net_open(struct net_device *dev) { ASSERT(dev != NULL, return -1;); @@ -658,7 +658,7 @@ return 0; } -static int irtty_net_close(struct device *dev) +static int irtty_net_close(struct net_device *dev) { ASSERT(dev != NULL, return -1;); diff -u --recursive --new-file v2.3.13/linux/drivers/net/irda/pc87108.c linux/drivers/net/irda/pc87108.c --- v2.3.13/linux/drivers/net/irda/pc87108.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/irda/pc87108.c Wed Aug 18 11:38:51 1999 @@ -107,7 +107,7 @@ static void pc87108_pio_receive(struct irda_device *idev); static int pc87108_dma_receive(struct irda_device *idev); static int pc87108_dma_receive_complete(struct irda_device *idev, int iobase); -static int pc87108_hard_xmit(struct sk_buff *skb, struct device *dev); +static int pc87108_hard_xmit(struct sk_buff *skb, struct net_device *dev); static int pc87108_pio_write(int iobase, __u8 *buf, int len, int fifo_size); static void pc87108_dma_write(struct irda_device *idev, int iobase); static void pc87108_change_speed(struct irda_device *idev, int baud); @@ -117,9 +117,9 @@ static int pc87108_read_dongle_id (int iobase); static void pc87108_init_dongle_interface (int iobase, int dongle_id); -static int pc87108_net_init(struct device *dev); -static int pc87108_net_open(struct device *dev); -static int pc87108_net_close(struct device *dev); +static int pc87108_net_init(struct net_device *dev); +static int pc87108_net_open(struct net_device *dev); +static int pc87108_net_close(struct net_device *dev); /* * Function pc87108_init () @@ -712,7 +712,7 @@ * Transmit the frame! * */ -static int pc87108_hard_xmit( struct sk_buff *skb, struct device *dev) +static int pc87108_hard_xmit( struct sk_buff *skb, struct net_device *dev) { struct irda_device *idev; int iobase; @@ -1344,7 +1344,7 @@ * Initialize network device * */ -static int pc87108_net_init( struct device *dev) +static int pc87108_net_init( struct net_device *dev) { DEBUG( 4, __FUNCTION__ "()\n"); @@ -1363,7 +1363,7 @@ * Start the device * */ -static int pc87108_net_open( struct device *dev) +static int pc87108_net_open( struct net_device *dev) { struct irda_device *idev; int iobase; @@ -1418,7 +1418,7 @@ * Stop the device * */ -static int pc87108_net_close(struct device *dev) +static int pc87108_net_close(struct net_device *dev) { struct irda_device *idev; int iobase; diff -u --recursive --new-file v2.3.13/linux/drivers/net/irda/smc-ircc.c linux/drivers/net/irda/smc-ircc.c --- v2.3.13/linux/drivers/net/irda/smc-ircc.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/irda/smc-ircc.c Wed Aug 18 11:38:52 1999 @@ -63,16 +63,16 @@ static int ircc_probe( int iobase, int board_addr); static int ircc_dma_receive( struct irda_device *idev); static int ircc_dma_receive_complete(struct irda_device *idev, int iobase); -static int ircc_hard_xmit( struct sk_buff *skb, struct device *dev); +static int ircc_hard_xmit( struct sk_buff *skb, struct net_device *dev); static void ircc_dma_write( struct irda_device *idev, int iobase); static void ircc_change_speed( struct irda_device *idev, int baud); static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void ircc_wait_until_sent( struct irda_device *idev); static int ircc_is_receiving( struct irda_device *idev); -static int ircc_net_init( struct device *dev); -static int ircc_net_open( struct device *dev); -static int ircc_net_close( struct device *dev); +static int ircc_net_init( struct net_device *dev); +static int ircc_net_open( struct net_device *dev); +static int ircc_net_close( struct net_device *dev); static int ircc_debug=3; static int ircc_irq=255; @@ -448,7 +448,7 @@ * Transmit the frame! * */ -static int ircc_hard_xmit( struct sk_buff *skb, struct device *dev) +static int ircc_hard_xmit( struct sk_buff *skb, struct net_device *dev) { struct irda_device *idev; int iobase; @@ -835,7 +835,7 @@ * Initialize network device * */ -static int ircc_net_init( struct device *dev) +static int ircc_net_init( struct net_device *dev) { DEBUG(ircc_debug, __FUNCTION__ " -->\n"); @@ -855,7 +855,7 @@ * Start the device * */ -static int ircc_net_open( struct device *dev) +static int ircc_net_open( struct net_device *dev) { struct irda_device *idev; int iobase; @@ -902,7 +902,7 @@ * Stop the device * */ -static int ircc_net_close(struct device *dev) +static int ircc_net_close(struct net_device *dev) { struct irda_device *idev; int iobase; diff -u --recursive --new-file v2.3.13/linux/drivers/net/irda/toshoboe.c linux/drivers/net/irda/toshoboe.c --- v2.3.13/linux/drivers/net/irda/toshoboe.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/irda/toshoboe.c Wed Aug 18 11:38:51 1999 @@ -267,7 +267,7 @@ /*Transmit something */ static int -toshoboe_hard_xmit (struct sk_buff *skb, struct device *dev) +toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev) { struct irda_device *idev; struct toshoboe_cb *self; @@ -515,7 +515,7 @@ static int -toshoboe_net_init (struct device *dev) +toshoboe_net_init (struct net_device *dev) { DEBUG (4, __FUNCTION__ "()\n"); @@ -530,7 +530,7 @@ static int -toshoboe_net_open (struct device *dev) +toshoboe_net_open (struct net_device *dev) { struct irda_device *idev; struct toshoboe_cb *self; @@ -594,7 +594,7 @@ } static int -toshoboe_net_close (struct device *dev) +toshoboe_net_close (struct net_device *dev) { struct irda_device *idev; struct toshoboe_cb *self; diff -u --recursive --new-file v2.3.13/linux/drivers/net/irda/uircc.c linux/drivers/net/irda/uircc.c --- v2.3.13/linux/drivers/net/irda/uircc.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/irda/uircc.c Wed Aug 18 11:38:51 1999 @@ -71,16 +71,16 @@ static int uircc_probe(int iobase, int board_addr, int irq, int dma); static int uircc_dma_receive(struct irda_device *idev); static int uircc_dma_receive_complete(struct irda_device *idev, int iobase); -static int uircc_hard_xmit(struct sk_buff *skb, struct device *dev); +static int uircc_hard_xmit(struct sk_buff *skb, struct net_device *dev); static void uircc_dma_write(struct irda_device *idev, int iobase); static void uircc_change_speed(struct irda_device *idev, int baud); static void uircc_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void uircc_wait_until_sent(struct irda_device *idev); static int uircc_is_receiving(struct irda_device *idev); static int uircc_toshiba_cmd(int *retval, int arg0, int arg1, int arg2); -static int uircc_net_init(struct device *dev); -static int uircc_net_open(struct device *dev); -static int uircc_net_close(struct device *dev); +static int uircc_net_init(struct net_device *dev); +static int uircc_net_open(struct net_device *dev); +static int uircc_net_close(struct net_device *dev); /* * Function uircc_init () @@ -406,7 +406,7 @@ * Transmit the frame! * */ -static int uircc_hard_xmit(struct sk_buff *skb, struct device *dev) +static int uircc_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct irda_device *idev; int iobase; @@ -798,7 +798,7 @@ * Initialize network device * */ -static int uircc_net_init( struct device *dev) +static int uircc_net_init( struct net_device *dev) { DEBUG( 4, __FUNCTION__ "()\n"); @@ -817,7 +817,7 @@ * Start the device * */ -static int uircc_net_open(struct device *dev) +static int uircc_net_open(struct net_device *dev) { struct irda_device *idev; int iobase; @@ -863,7 +863,7 @@ * Stop the device * */ -static int uircc_net_close(struct device *dev) +static int uircc_net_close(struct net_device *dev) { struct irda_device *idev; int iobase; diff -u --recursive --new-file v2.3.13/linux/drivers/net/irda/w83977af_ir.c linux/drivers/net/irda/w83977af_ir.c --- v2.3.13/linux/drivers/net/irda/w83977af_ir.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/irda/w83977af_ir.c Wed Aug 18 11:38:51 1999 @@ -87,7 +87,7 @@ static int w83977af_probe(int iobase, int irq, int dma); static int w83977af_dma_receive(struct irda_device *idev); static int w83977af_dma_receive_complete(struct irda_device *idev); -static int w83977af_hard_xmit(struct sk_buff *skb, struct device *dev); +static int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev); static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size); static void w83977af_dma_write(struct irda_device *idev, int iobase); static void w83977af_change_speed(struct irda_device *idev, int baud); @@ -95,9 +95,9 @@ static void w83977af_wait_until_sent(struct irda_device *idev); static int w83977af_is_receiving(struct irda_device *idev); -static int w83977af_net_init(struct device *dev); -static int w83977af_net_open(struct device *dev); -static int w83977af_net_close(struct device *dev); +static int w83977af_net_init(struct net_device *dev); +static int w83977af_net_open(struct net_device *dev); +static int w83977af_net_close(struct net_device *dev); /* * Function w83977af_init () @@ -460,7 +460,7 @@ * Sets up a DMA transfer to send the current frame. * */ -int w83977af_hard_xmit(struct sk_buff *skb, struct device *dev) +int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct irda_device *idev; int iobase; @@ -1155,7 +1155,7 @@ * * */ -static int w83977af_net_init(struct device *dev) +static int w83977af_net_init(struct net_device *dev) { DEBUG(0, __FUNCTION__ "()\n"); @@ -1174,7 +1174,7 @@ * Start the device * */ -static int w83977af_net_open(struct device *dev) +static int w83977af_net_open(struct net_device *dev) { struct irda_device *idev; int iobase; @@ -1233,7 +1233,7 @@ * Stop the device * */ -static int w83977af_net_close(struct device *dev) +static int w83977af_net_close(struct net_device *dev) { struct irda_device *idev; int iobase; diff -u --recursive --new-file v2.3.13/linux/drivers/net/jazzsonic.c linux/drivers/net/jazzsonic.c --- v2.3.13/linux/drivers/net/jazzsonic.c Wed Jun 30 13:38:20 1999 +++ linux/drivers/net/jazzsonic.c Wed Aug 18 11:36:42 1999 @@ -82,15 +82,15 @@ /* Index to functions, as function prototypes. */ -extern int sonic_probe(struct device *dev); -static int sonic_probe1(struct device *dev, unsigned int base_addr, unsigned int irq); +extern int sonic_probe(struct net_device *dev); +static int sonic_probe1(struct net_device *dev, unsigned int base_addr, unsigned int irq); /* * Probe for a SONIC ethernet controller on a Mips Jazz board. * Actually probing is superfluous but we're paranoid. */ -__initfunc(int sonic_probe(struct device *dev)) +__initfunc(int sonic_probe(struct net_device *dev)) { unsigned int base_addr = dev ? dev->base_addr : 0; int i; @@ -115,7 +115,7 @@ return -ENODEV; } -__initfunc(static int sonic_probe1(struct device *dev, +__initfunc(static int sonic_probe1(struct net_device *dev, unsigned int base_addr, unsigned int irq)) { static unsigned version_printed = 0; diff -u --recursive --new-file v2.3.13/linux/drivers/net/lance.c linux/drivers/net/lance.c --- v2.3.13/linux/drivers/net/lance.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/lance.c Wed Aug 18 11:36:42 1999 @@ -68,8 +68,8 @@ #include static unsigned int lance_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x360, 0}; -int lance_probe(struct device *dev); -int lance_probe1(struct device *dev, int ioaddr, int irq, int options); +int lance_probe(struct net_device *dev); +int lance_probe1(struct net_device *dev, int ioaddr, int irq, int options); #ifdef LANCE_DEBUG int lance_debug = LANCE_DEBUG; @@ -283,15 +283,15 @@ Assume yes until we know the memory size. */ static unsigned char lance_need_isa_bounce_buffers = 1; -static int lance_open(struct device *dev); -static int lance_open_fail(struct device *dev); -static void lance_init_ring(struct device *dev, int mode); -static int lance_start_xmit(struct sk_buff *skb, struct device *dev); -static int lance_rx(struct device *dev); +static int lance_open(struct net_device *dev); +static int lance_open_fail(struct net_device *dev); +static void lance_init_ring(struct net_device *dev, int mode); +static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int lance_rx(struct net_device *dev); static void lance_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int lance_close(struct device *dev); -static struct net_device_stats *lance_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static int lance_close(struct net_device *dev); +static struct net_device_stats *lance_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); @@ -308,7 +308,7 @@ MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_CARDS) "i"); static char ifnames[MAX_CARDS][IF_NAMELEN] = { {0, }, }; -static struct device dev_lance[MAX_CARDS] = +static struct net_device dev_lance[MAX_CARDS] = {{ 0, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, @@ -320,7 +320,7 @@ int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_CARDS; this_dev++) { - struct device *dev = &dev_lance[this_dev]; + struct net_device *dev = &dev_lance[this_dev]; dev->name = ifnames[this_dev]; dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -347,7 +347,7 @@ int this_dev; for (this_dev = 0; this_dev < MAX_CARDS; this_dev++) { - struct device *dev = &dev_lance[this_dev]; + struct net_device *dev = &dev_lance[this_dev]; if (dev->priv != NULL) { kfree(dev->priv); dev->priv = NULL; @@ -363,7 +363,7 @@ board probes now that kmalloc() can allocate ISA DMA-able regions. This also allows the LANCE driver to be used as a module. */ -int lance_probe(struct device *dev) +int lance_probe(struct net_device *dev) { int *port, result; @@ -420,7 +420,7 @@ return -ENODEV; } -int __init lance_probe1(struct device *dev, int ioaddr, int irq, int options) +int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int options) { struct lance_private *lp; short dma_channels; /* Mark spuriously-busy DMA channels */ @@ -677,7 +677,7 @@ } static int -lance_open_fail(struct device *dev) +lance_open_fail(struct net_device *dev) { return -ENODEV; } @@ -685,7 +685,7 @@ static int -lance_open(struct device *dev) +lance_open(struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; int ioaddr = dev->base_addr; @@ -776,7 +776,7 @@ */ static void -lance_purge_tx_ring(struct device *dev) +lance_purge_tx_ring(struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; int i; @@ -792,7 +792,7 @@ /* Initialize the LANCE Rx and Tx rings. */ static void -lance_init_ring(struct device *dev, int gfp) +lance_init_ring(struct net_device *dev, int gfp) { struct lance_private *lp = (struct lance_private *)dev->priv; int i; @@ -835,7 +835,7 @@ } static void -lance_restart(struct device *dev, unsigned int csr0_bits, int must_reinit) +lance_restart(struct net_device *dev, unsigned int csr0_bits, int must_reinit) { struct lance_private *lp = (struct lance_private *)dev->priv; @@ -848,7 +848,7 @@ outw(csr0_bits, dev->base_addr + LANCE_DATA); } -static int lance_start_xmit(struct sk_buff *skb, struct device *dev) +static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; int ioaddr = dev->base_addr; @@ -967,7 +967,7 @@ static void lance_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct lance_private *lp; int csr0, ioaddr, boguscnt=10; int must_restart; @@ -1093,7 +1093,7 @@ } static int -lance_rx(struct device *dev) +lance_rx(struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; int entry = lp->cur_rx & RX_RING_MOD_MASK; @@ -1171,7 +1171,7 @@ } static int -lance_close(struct device *dev) +lance_close(struct net_device *dev) { int ioaddr = dev->base_addr; struct lance_private *lp = (struct lance_private *)dev->priv; @@ -1220,7 +1220,7 @@ return 0; } -static struct net_device_stats *lance_get_stats(struct device *dev) +static struct net_device_stats *lance_get_stats(struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; short ioaddr = dev->base_addr; @@ -1243,7 +1243,7 @@ /* Set or clear the multicast filter for this adaptor. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { short ioaddr = dev->base_addr; diff -u --recursive --new-file v2.3.13/linux/drivers/net/lapbether.c linux/drivers/net/lapbether.c --- v2.3.13/linux/drivers/net/lapbether.c Tue May 25 13:06:34 1999 +++ linux/drivers/net/lapbether.c Wed Aug 18 11:36:42 1999 @@ -45,7 +45,7 @@ static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; -static int lapbeth_rcv(struct sk_buff *, struct device *, struct packet_type *); +static int lapbeth_rcv(struct sk_buff *, struct net_device *, struct packet_type *); static int lapbeth_device_event(struct notifier_block *, unsigned long, void *); static struct packet_type lapbeth_packet_type = { @@ -67,8 +67,8 @@ static struct lapbethdev { struct lapbethdev *next; char ethname[14]; /* ether device name */ - struct device *ethdev; /* link to ethernet device */ - struct device axdev; /* lapbeth device (lapb#) */ + struct net_device *ethdev; /* link to ethernet device */ + struct net_device axdev; /* lapbeth device (lapb#) */ struct net_device_stats stats; /* some statistics */ } *lapbeth_devices = NULL; @@ -79,7 +79,7 @@ /* * Get the ethernet device for a LAPB device */ -static __inline__ struct device *lapbeth_get_ether_dev(struct device *dev) +static __inline__ struct net_device *lapbeth_get_ether_dev(struct net_device *dev) { struct lapbethdev *lapbeth; @@ -91,7 +91,7 @@ /* * Get the LAPB device for the ethernet device */ -static __inline__ struct device *lapbeth_get_x25_dev(struct device *dev) +static __inline__ struct net_device *lapbeth_get_x25_dev(struct net_device *dev) { struct lapbethdev *lapbeth; @@ -102,7 +102,7 @@ return NULL; } -static __inline__ int dev_is_ethdev(struct device *dev) +static __inline__ int dev_is_ethdev(struct net_device *dev) { return ( dev->type == ARPHRD_ETHER @@ -114,7 +114,7 @@ * Sanity check: remove all devices that ceased to exists and * return '1' if the given LAPB device was affected. */ -static int lapbeth_check_devices(struct device *dev) +static int lapbeth_check_devices(struct net_device *dev) { struct lapbethdev *lapbeth, *lapbeth_prev; int result = 0; @@ -154,7 +154,7 @@ /* * Receive a LAPB frame via an ethernet interface. */ -static int lapbeth_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *ptype) +static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype) { int len, err; struct lapbethdev *lapbeth; @@ -204,7 +204,7 @@ /* * Send a LAPB frame via an ethernet interface */ -static int lapbeth_xmit(struct sk_buff *skb, struct device *dev) +static int lapbeth_xmit(struct sk_buff *skb, struct net_device *dev) { struct lapbethdev *lapbeth; int err; @@ -254,7 +254,7 @@ { struct lapbethdev *lapbeth = (struct lapbethdev *)token; unsigned char *ptr; - struct device *dev; + struct net_device *dev; int size; skb->protocol = htons(ETH_P_X25); @@ -322,7 +322,7 @@ /* * Statistics */ -static struct net_device_stats *lapbeth_get_stats(struct device *dev) +static struct net_device_stats *lapbeth_get_stats(struct net_device *dev) { struct lapbethdev *lapbeth; @@ -334,7 +334,7 @@ /* * Set AX.25 callsign */ -static int lapbeth_set_mac_address(struct device *dev, void *addr) +static int lapbeth_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = (struct sockaddr *)addr; @@ -343,7 +343,7 @@ return 0; } -static int lapbeth_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int lapbeth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { return -EINVAL; } @@ -351,7 +351,7 @@ /* * open/close a device */ -static int lapbeth_open(struct device *dev) +static int lapbeth_open(struct net_device *dev) { struct lapb_register_struct lapbeth_callbacks; struct lapbethdev *lapbeth; @@ -384,7 +384,7 @@ return 0; } -static int lapbeth_close(struct device *dev) +static int lapbeth_close(struct net_device *dev) { struct lapbethdev *lapbeth; int err; @@ -402,7 +402,7 @@ return 0; } -static int lapbeth_dev_init(struct device *dev) +static int lapbeth_dev_init(struct net_device *dev) { return 0; } @@ -412,7 +412,7 @@ /* * Setup a new device. */ -static int lapbeth_new_device(struct device *dev) +static int lapbeth_new_device(struct net_device *dev) { int k; unsigned char *buf; @@ -432,7 +432,7 @@ buf = kmalloc(14, GFP_KERNEL); for (k = 0; k < MAXLAPBDEV; k++) { - struct device *odev; + struct net_device *odev; sprintf(buf, "lapb%d", k); @@ -490,7 +490,7 @@ */ static int lapbeth_device_event(struct notifier_block *this,unsigned long event, void *ptr) { - struct device *dev = (struct device *)ptr; + struct net_device *dev = (struct net_device *)ptr; if (!dev_is_ethdev(dev)) return NOTIFY_DONE; @@ -524,7 +524,7 @@ */ int lapbeth_init(void) { - struct device *dev; + struct net_device *dev; lapbeth_packet_type.type = htons(ETH_P_DEC); dev_add_pack(&lapbeth_packet_type); diff -u --recursive --new-file v2.3.13/linux/drivers/net/lne390.c linux/drivers/net/lne390.c --- v2.3.13/linux/drivers/net/lne390.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/lne390.c Wed Aug 18 11:36:42 1999 @@ -46,17 +46,17 @@ #include #include "8390.h" -int lne390_probe(struct device *dev); -int lne390_probe1(struct device *dev, int ioaddr); +int lne390_probe(struct net_device *dev); +int lne390_probe1(struct net_device *dev, int ioaddr); -static int lne390_open(struct device *dev); -static int lne390_close(struct device *dev); +static int lne390_open(struct net_device *dev); +static int lne390_close(struct net_device *dev); -static void lne390_reset_8390(struct device *dev); +static void lne390_reset_8390(struct net_device *dev); -static void lne390_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void lne390_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset); -static void lne390_block_output(struct device *dev, int count, const unsigned char *buf, const int start_page); +static void lne390_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); +static void lne390_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); +static void lne390_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); #define LNE390_START_PG 0x00 /* First page of TX buffer */ #define LNE390_STOP_PG 0x80 /* Last page +1 of RX ring */ @@ -100,7 +100,7 @@ * PROM for a match against the value assigned to Mylex. */ -int __init lne390_probe(struct device *dev) +int __init lne390_probe(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; @@ -127,7 +127,7 @@ return ENODEV; } -int __init lne390_probe1(struct device *dev, int ioaddr) +int __init lne390_probe1(struct net_device *dev, int ioaddr) { int i, revision; unsigned long eisa_id; @@ -281,7 +281,7 @@ * file, this just toggles the "Board Enable" bits (bit 2 and 0). */ -static void lne390_reset_8390(struct device *dev) +static void lne390_reset_8390(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; @@ -313,7 +313,7 @@ */ static void -lne390_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +lne390_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = dev->mem_start + ((ring_page - LNE390_START_PG)<<8); memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); @@ -326,7 +326,7 @@ * be rounded up to a doubleword value via lne390_get_8390_hdr() above. */ -static void lne390_block_input(struct device *dev, int count, struct sk_buff *skb, +static void lne390_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned long xfer_start = dev->mem_start + ring_offset - (LNE390_START_PG<<8); @@ -343,7 +343,7 @@ } } -static void lne390_block_output(struct device *dev, int count, +static void lne390_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { unsigned long shmem = dev->mem_start + ((start_page - LNE390_START_PG)<<8); @@ -352,14 +352,14 @@ memcpy_toio(shmem, buf, count); } -static int lne390_open(struct device *dev) +static int lne390_open(struct net_device *dev) { ei_open(dev); MOD_INC_USE_COUNT; return 0; } -static int lne390_close(struct device *dev) +static int lne390_close(struct net_device *dev) { if (ei_debug > 1) @@ -374,7 +374,7 @@ #define MAX_LNE_CARDS 4 /* Max number of LNE390 cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_LNE_CARDS] = { 0, }; -static struct device dev_lne[MAX_LNE_CARDS] = { +static struct net_device dev_lne[MAX_LNE_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -396,7 +396,7 @@ int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_LNE_CARDS; this_dev++) { - struct device *dev = &dev_lne[this_dev]; + struct net_device *dev = &dev_lne[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -423,7 +423,7 @@ int this_dev; for (this_dev = 0; this_dev < MAX_LNE_CARDS; this_dev++) { - struct device *dev = &dev_lne[this_dev]; + struct net_device *dev = &dev_lne[this_dev]; if (dev->priv != NULL) { void *priv = dev->priv; free_irq(dev->irq, dev); diff -u --recursive --new-file v2.3.13/linux/drivers/net/loopback.c linux/drivers/net/loopback.c --- v2.3.13/linux/drivers/net/loopback.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/loopback.c Wed Aug 18 11:36:42 1999 @@ -58,7 +58,7 @@ * The higher levels take care of making this non-reentrant (it's * called with bh's disabled). */ -static int loopback_xmit(struct sk_buff *skb, struct device *dev) +static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_device_stats *stats = (struct net_device_stats *)dev->priv; @@ -102,19 +102,19 @@ return(0); } -static struct net_device_stats *get_stats(struct device *dev) +static struct net_device_stats *get_stats(struct net_device *dev) { return (struct net_device_stats *)dev->priv; } -static int loopback_open(struct device *dev) +static int loopback_open(struct net_device *dev) { dev->flags|=IFF_LOOPBACK; return 0; } /* Initialize the rest of the LOOPBACK device. */ -int __init loopback_init(struct device *dev) +int __init loopback_init(struct net_device *dev) { dev->mtu = LOOPBACK_MTU; dev->tbusy = 0; diff -u --recursive --new-file v2.3.13/linux/drivers/net/ltpc.c linux/drivers/net/ltpc.c --- v2.3.13/linux/drivers/net/ltpc.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/ltpc.c Wed Aug 18 11:36:42 1999 @@ -240,9 +240,9 @@ #include "ltpc.h" /* function prototypes */ -static int do_read(struct device *dev, void *cbuf, int cbuflen, +static int do_read(struct net_device *dev, void *cbuf, int cbuflen, void *dbuf, int dbuflen); -static int sendup_buffer (struct device *dev); +static int sendup_buffer (struct net_device *dev); /* Dma Memory related stuff, cribbed directly from 3c505.c */ @@ -348,7 +348,7 @@ static unsigned char mailbox[16]; static unsigned char mboxinuse[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -static int wait_timeout(struct device *dev, int c) +static int wait_timeout(struct net_device *dev, int c) { /* returns true if it stayed c */ /* this uses base+6, but it's ok */ @@ -383,7 +383,7 @@ } /* read a command from the card */ -static void handlefc(struct device *dev) +static void handlefc(struct net_device *dev) { /* called *only* from idle, non-reentrant */ int dma = dev->dma; @@ -407,7 +407,7 @@ } /* read data from the card */ -static void handlefd(struct device *dev) +static void handlefd(struct net_device *dev) { int dma = dev->dma; int base = dev->base_addr; @@ -429,7 +429,7 @@ sendup_buffer(dev); } -static void handlewrite(struct device *dev) +static void handlewrite(struct net_device *dev) { /* called *only* from idle, non-reentrant */ /* on entry, 0xfb and ltdmabuf holds data */ @@ -457,7 +457,7 @@ } } -static void handleread(struct device *dev) +static void handleread(struct net_device *dev) { /* on entry, 0xfb */ /* on exit, ltdmabuf holds data */ @@ -480,7 +480,7 @@ if ( wait_timeout(dev,0xfb) ) printk("timed out in handleread\n"); } -static void handlecommand(struct device *dev) +static void handlecommand(struct net_device *dev) { /* on entry, 0xfa and ltdmacbuf holds command */ int dma = dev->dma; @@ -510,7 +510,7 @@ * an interrupt, or because the line is tri-stated */ -static void idle(struct device *dev) +static void idle(struct net_device *dev) { unsigned long flags; int state; @@ -665,7 +665,7 @@ } -static int do_write(struct device *dev, void *cbuf, int cbuflen, +static int do_write(struct net_device *dev, void *cbuf, int cbuflen, void *dbuf, int dbuflen) { @@ -689,7 +689,7 @@ return -1; } -static int do_read(struct device *dev, void *cbuf, int cbuflen, +static int do_read(struct net_device *dev, void *cbuf, int cbuflen, void *dbuf, int dbuflen) { @@ -717,10 +717,10 @@ static struct timer_list ltpc_timer; -static int ltpc_xmit(struct sk_buff *skb, struct device *dev); -static struct net_device_stats *ltpc_get_stats(struct device *dev); +static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev); +static struct net_device_stats *ltpc_get_stats(struct net_device *dev); -static int ltpc_open(struct device *dev) +static int ltpc_open(struct net_device *dev) { #ifdef MODULE MOD_INC_USE_COUNT; @@ -728,7 +728,7 @@ return 0; } -static int ltpc_close(struct device *dev) +static int ltpc_close(struct net_device *dev) { #ifdef MODULE MOD_DEC_USE_COUNT; @@ -736,14 +736,14 @@ return 0; } -static int read_30 ( struct device *dev) +static int read_30 ( struct net_device *dev) { lt_command c; c.getflags.command = LT_GETFLAGS; return do_read(dev, &c, sizeof(c.getflags),&c,0); } -static int set_30 (struct device *dev,int x) +static int set_30 (struct net_device *dev,int x) { lt_command c; c.setflags.command = LT_SETFLAGS; @@ -753,7 +753,7 @@ /* LLAP to DDP translation */ -static int sendup_buffer (struct device *dev) +static int sendup_buffer (struct net_device *dev) { /* on entry, command is in ltdmacbuf, data in ltdmabuf */ /* called from idle, non-reentrant */ @@ -825,7 +825,7 @@ static void ltpc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; if (dev==NULL) { printk("ltpc_interrupt: unknown device.\n"); @@ -852,7 +852,7 @@ * ***/ -static int ltpc_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int ltpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct sockaddr_at *sa = (struct sockaddr_at *) &ifr->ifr_addr; /* we'll keep the localtalk node address in dev->pa_addr */ @@ -897,13 +897,13 @@ } } -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { /* This needs to be present to keep netatalk happy. */ /* Actually netatalk needs fixing! */ } -static int ltpc_hard_header (struct sk_buff *skb, struct device *dev, +static int ltpc_hard_header (struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { if(debug&DEBUG_VERBOSE) @@ -912,7 +912,7 @@ return 0; } -static int ltpc_init(struct device *dev) +static int ltpc_init(struct net_device *dev) { /* Initialize the device structure. */ @@ -947,7 +947,7 @@ static void ltpc_poll(unsigned long l) { - struct device *dev = (struct device *) l; + struct net_device *dev = (struct net_device *) l; del_timer(<pc_timer); @@ -970,7 +970,7 @@ /* DDP to LLAP translation */ -static int ltpc_xmit(struct sk_buff *skb, struct device *dev) +static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev) { /* in kernel 1.3.xx, on entry skb->data points to ddp header, * and skb->len is the length of the ddp data + ddp header @@ -1010,7 +1010,7 @@ return 0; } -static struct net_device_stats *ltpc_get_stats(struct device *dev) +static struct net_device_stats *ltpc_get_stats(struct net_device *dev) { struct net_device_stats *stats = &((struct ltpc_private *) dev->priv)->stats; return stats; @@ -1088,7 +1088,7 @@ return dma; } -int __init ltpc_probe(struct device *dev) +int __init ltpc_probe(struct net_device *dev) { int err; int x=0,y=0; @@ -1281,7 +1281,7 @@ static char dev_name[8]; -static struct device dev_ltpc = { +static struct net_device dev_ltpc = { dev_name, 0, 0, 0, 0, 0x0, 0, diff -u --recursive --new-file v2.3.13/linux/drivers/net/mace.c linux/drivers/net/mace.c --- v2.3.13/linux/drivers/net/mace.c Wed Jul 21 15:46:48 1999 +++ linux/drivers/net/mace.c Wed Aug 18 11:36:42 1999 @@ -23,7 +23,7 @@ #include "mace.h" #ifdef MODULE -static struct device *mace_devs = NULL; +static struct net_device *mace_devs = NULL; #endif #define N_RX_RING 8 @@ -69,21 +69,21 @@ + (N_RX_RING + NCMDS_TX * N_TX_RING + 3) * sizeof(struct dbdma_cmd)) static int bitrev(int); -static int mace_open(struct device *dev); -static int mace_close(struct device *dev); -static int mace_xmit_start(struct sk_buff *skb, struct device *dev); -static struct net_device_stats *mace_stats(struct device *dev); -static void mace_set_multicast(struct device *dev); -static void mace_reset(struct device *dev); -static int mace_set_address(struct device *dev, void *addr); +static int mace_open(struct net_device *dev); +static int mace_close(struct net_device *dev); +static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev); +static struct net_device_stats *mace_stats(struct net_device *dev); +static void mace_set_multicast(struct net_device *dev); +static void mace_reset(struct net_device *dev); +static int mace_set_address(struct net_device *dev, void *addr); static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void mace_txdma_intr(int irq, void *dev_id, struct pt_regs *regs); static void mace_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs); -static void mace_set_timeout(struct device *dev); +static void mace_set_timeout(struct net_device *dev); static void mace_tx_timeout(unsigned long data); static inline void dbdma_reset(volatile struct dbdma_regs *dma); static inline void mace_clean_rings(struct mace_data *mp); -static void __mace_set_address(struct device *dev, void *addr); +static void __mace_set_address(struct net_device *dev, void *addr); /* * If we can't get a skbuff when we need it, we use this area for DMA. @@ -102,7 +102,7 @@ } int -mace_probe(struct device *dev) +mace_probe(struct net_device *dev) { int j, rev; struct mace_data *mp; @@ -222,7 +222,7 @@ udelay(1); } -static void mace_reset(struct device *dev) +static void mace_reset(struct net_device *dev) { struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; @@ -269,7 +269,7 @@ out_8(&mb->plscc, PORTSEL_GPSI + ENPLSIO); } -static void __mace_set_address(struct device *dev, void *addr) +static void __mace_set_address(struct net_device *dev, void *addr) { volatile struct mace *mb = ((struct mace_data *) dev->priv)->mace; unsigned char *p = addr; @@ -283,7 +283,7 @@ out_8(&mb->padr, dev->dev_addr[i] = p[i]); } -static int mace_set_address(struct device *dev, void *addr) +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; @@ -301,7 +301,7 @@ return 0; } -static int mace_open(struct device *dev) +static int mace_open(struct net_device *dev) { struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; @@ -392,7 +392,7 @@ } } -static int mace_close(struct device *dev) +static int mace_close(struct net_device *dev) { struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; @@ -416,7 +416,7 @@ return 0; } -static inline void mace_set_timeout(struct device *dev) +static inline void mace_set_timeout(struct net_device *dev) { struct mace_data *mp = (struct mace_data *) dev->priv; unsigned long flags; @@ -433,7 +433,7 @@ restore_flags(flags); } -static int mace_xmit_start(struct sk_buff *skb, struct device *dev) +static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev) { struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct dbdma_regs *td = mp->tx_dma; @@ -489,7 +489,7 @@ return 0; } -static struct net_device_stats *mace_stats(struct device *dev) +static struct net_device_stats *mace_stats(struct net_device *dev) { struct mace_data *p = (struct mace_data *) dev->priv; @@ -501,7 +501,7 @@ */ #define CRC_POLY 0xedb88320 -static void mace_set_multicast(struct device *dev) +static void mace_set_multicast(struct net_device *dev) { struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; @@ -579,7 +579,7 @@ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; volatile struct dbdma_regs *td = mp->tx_dma; @@ -722,7 +722,7 @@ static void mace_tx_timeout(unsigned long data) { - struct device *dev = (struct device *) data; + struct net_device *dev = (struct net_device *) data; struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; volatile struct dbdma_regs *td = mp->tx_dma; @@ -794,7 +794,7 @@ static void mace_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct dbdma_regs *rd = mp->rx_dma; volatile struct dbdma_cmd *cp, *np; diff -u --recursive --new-file v2.3.13/linux/drivers/net/macsonic.c linux/drivers/net/macsonic.c --- v2.3.13/linux/drivers/net/macsonic.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/macsonic.c Wed Aug 18 11:36:42 1999 @@ -176,7 +176,7 @@ __initfunc(int mac_onboard_sonic_probe(void)) { - struct device *dev; + struct net_device *dev; unsigned int silicon_revision; unsigned int val; struct sonic_local *lp; diff -u --recursive --new-file v2.3.13/linux/drivers/net/mvme147.c linux/drivers/net/mvme147.c --- v2.3.13/linux/drivers/net/mvme147.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/mvme147.c Wed Aug 18 11:36:42 1999 @@ -54,9 +54,9 @@ * plus board-specific init, open and close actions. * Oh, and we need to tell the generic code how to read and write LANCE registers... */ -int mvme147lance_probe(struct device *dev); -static int m147lance_open(struct device *dev); -static int m147lance_close(struct device *dev); +int mvme147lance_probe(struct net_device *dev); +static int m147lance_open(struct net_device *dev); +static int m147lance_close(struct net_device *dev); static void m147lance_writerap(struct m147lance_private *lp, unsigned short value); static void m147lance_writerdp(struct m147lance_private *lp, unsigned short value); static unsigned short m147lance_readrdp(struct m147lance_private *lp); @@ -70,7 +70,7 @@ #endif /* Initialise the one and only on-board 7990 */ -__initfunc(int mvme147lance_probe(struct device *dev)) +__initfunc(int mvme147lance_probe(struct net_device *dev)) { static int called = 0; static const char name[] = "MVME147 LANCE"; @@ -162,7 +162,7 @@ return lp->lance.ll->rdp; } -static int m147lance_open(struct device *dev) +static int m147lance_open(struct net_device *dev) { int status; @@ -177,7 +177,7 @@ return 0; } -static int m147lance_close(struct device *dev) +static int m147lance_close(struct net_device *dev) { /* disable interrupts at boardlevel */ m147_pcc->lan_cntrl=0x0; /* disable interrupts */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/myri_sbus.c linux/drivers/net/myri_sbus.c --- v2.3.13/linux/drivers/net/myri_sbus.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/myri_sbus.c Wed Aug 18 11:36:42 1999 @@ -176,7 +176,7 @@ static inline int myri_load_lanai(struct myri_eth *mp) { - struct device *dev = mp->dev; + struct net_device *dev = mp->dev; struct myri_shmem *shmem = mp->shmem; unsigned char *rptr; int i; @@ -261,7 +261,7 @@ { struct recvq *rq = mp->rq; struct myri_rxd *rxd = &rq->myri_rxd[0]; - struct device *dev = mp->dev; + struct net_device *dev = mp->dev; int gfp_flags = GFP_KERNEL; int i; @@ -323,7 +323,7 @@ } #endif -static inline void myri_tx(struct myri_eth *mp, struct device *dev) +static inline void myri_tx(struct myri_eth *mp, struct net_device *dev) { struct sendq *sq = mp->sq; int entry = mp->tx_old; @@ -348,7 +348,7 @@ * assume 802.3 if the type field is short enough to be a length. * This is normal practice and works for any 'now in use' protocol. */ -static unsigned short myri_type_trans(struct sk_buff *skb, struct device *dev) +static unsigned short myri_type_trans(struct sk_buff *skb, struct net_device *dev) { struct ethhdr *eth; unsigned char *rawp; @@ -388,7 +388,7 @@ return htons(ETH_P_802_2); } -static inline void myri_rx(struct myri_eth *mp, struct device *dev) +static inline void myri_rx(struct myri_eth *mp, struct net_device *dev) { struct recvq *rq = mp->rq; struct recvq *rqa = mp->rqack; @@ -506,7 +506,7 @@ static void myri_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct myri_eth *mp = (struct myri_eth *) dev->priv; struct lanai_regs *lregs = mp->lregs; struct myri_channel *chan = &mp->shmem->channel; @@ -537,14 +537,14 @@ DIRQ(("\n")); } -static int myri_open(struct device *dev) +static int myri_open(struct net_device *dev) { struct myri_eth *mp = (struct myri_eth *) dev->priv; return myri_init(mp, in_interrupt()); } -static int myri_close(struct device *dev) +static int myri_close(struct net_device *dev) { struct myri_eth *mp = (struct myri_eth *) dev->priv; @@ -552,7 +552,7 @@ return 0; } -static int myri_start_xmit(struct sk_buff *skb, struct device *dev) +static int myri_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct myri_eth *mp = (struct myri_eth *) dev->priv; struct sendq *sq = mp->sq; @@ -656,7 +656,7 @@ * saddr=NULL means use device source address * daddr=NULL means leave destination address (eg unresolved arp) */ -static int myri_header(struct sk_buff *skb, struct device *dev, unsigned short type, +static int myri_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { struct ethhdr *eth = (struct ethhdr *)skb_push(skb,ETH_HLEN); @@ -708,7 +708,7 @@ { unsigned char *pad = (unsigned char *)skb->data; struct ethhdr *eth = (struct ethhdr *)(pad + MYRI_PAD_LEN); - struct device *dev = skb->dev; + struct net_device *dev = skb->dev; #ifdef DEBUG_HEADER DHDR(("myri_rebuild_header: pad[%02x,%02x] ", pad[0], pad[1])); @@ -744,7 +744,7 @@ unsigned short type = hh->hh_type; unsigned char *pad = (unsigned char *)hh->hh_data; struct ethhdr *eth = (struct ethhdr *)(pad + MYRI_PAD_LEN); - struct device *dev = neigh->dev; + struct net_device *dev = neigh->dev; if (type == __constant_htons(ETH_P_802_3)) return -1; @@ -762,12 +762,12 @@ /* Called by Address Resolution module to notify changes in address. */ -void myri_header_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr) +void myri_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr) { memcpy(((u8*)hh->hh_data) + 2, haddr, dev->addr_len); } -static int myri_change_mtu(struct device *dev, int new_mtu) +static int myri_change_mtu(struct net_device *dev, int new_mtu) { if ((new_mtu < (ETH_HLEN + MYRI_PAD_LEN)) || (new_mtu > MYRINET_MTU)) return -EINVAL; @@ -775,13 +775,13 @@ return 0; } -static struct net_device_stats *myri_get_stats(struct device *dev) +static struct net_device_stats *myri_get_stats(struct net_device *dev) { return &(((struct myri_eth *)dev->priv)->enet_stats); } #define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */ #define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */ -static void myri_set_multicast(struct device *dev) +static void myri_set_multicast(struct net_device *dev) { /* Do nothing, all MyriCOM nodes transmit multicast frames * as broadcast packets... @@ -862,7 +862,7 @@ } #endif -static inline int myri_ether_init(struct device *dev, struct linux_sbus_device *sdev, int num) +static inline int myri_ether_init(struct net_device *dev, struct linux_sbus_device *sdev, int num) { static unsigned version_printed = 0; struct myri_eth *mp; @@ -1074,7 +1074,7 @@ return 0; } -int __init myri_sbus_probe(struct device *dev) +int __init myri_sbus_probe(struct net_device *dev) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff -u --recursive --new-file v2.3.13/linux/drivers/net/myri_sbus.h linux/drivers/net/myri_sbus.h --- v2.3.13/linux/drivers/net/myri_sbus.h Fri May 8 00:20:47 1998 +++ linux/drivers/net/myri_sbus.h Wed Aug 18 11:36:45 1999 @@ -273,7 +273,7 @@ struct recvq *rqack; /* Where we ack rx's. */ struct recvq *rq; /* Where we put buffers. */ struct sendq *sq; /* Where we stuff tx's. */ - struct device *dev; /* Linux/NET dev struct. */ + struct net_device *dev; /* Linux/NET dev struct. */ int tx_old; /* To speed up tx cleaning. */ struct lanai_regs *lregs; /* Quick ptr to LANAI regs. */ struct sk_buff *rx_skbs[RX_RING_SIZE+1];/* RX skb's */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/ne.c linux/drivers/net/ne.c --- v2.3.13/linux/drivers/net/ne.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/ne.c Wed Aug 18 11:36:42 1999 @@ -126,21 +126,21 @@ /* Non-zero only if the current card is a PCI with BIOS-set IRQ. */ static unsigned int pci_irq_line = 0; -int ne_probe(struct device *dev); -static int ne_probe1(struct device *dev, int ioaddr); +int ne_probe(struct net_device *dev); +static int ne_probe1(struct net_device *dev, int ioaddr); #ifdef CONFIG_PCI -static int ne_probe_pci(struct device *dev); +static int ne_probe_pci(struct net_device *dev); #endif -static int ne_open(struct device *dev); -static int ne_close(struct device *dev); +static int ne_open(struct net_device *dev); +static int ne_close(struct net_device *dev); -static void ne_reset_8390(struct device *dev); -static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void ne_reset_8390(struct net_device *dev); +static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ne_block_input(struct device *dev, int count, +static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ne_block_output(struct device *dev, const int count, +static void ne_block_output(struct net_device *dev, const int count, const unsigned char *buf, const int start_page); @@ -177,7 +177,7 @@ * the card. */ -int __init ne_probe(struct device *dev) +int __init ne_probe(struct net_device *dev) { int base_addr = dev ? dev->base_addr : 0; @@ -209,7 +209,7 @@ #endif #ifdef CONFIG_PCI -static int __init ne_probe_pci(struct device *dev) +static int __init ne_probe_pci(struct net_device *dev) { int i; @@ -243,7 +243,7 @@ } #endif /* CONFIG_PCI */ -static int __init ne_probe1(struct device *dev, int ioaddr) +static int __init ne_probe1(struct net_device *dev, int ioaddr) { int i; unsigned char SA_prom[32]; @@ -497,14 +497,14 @@ return 0; } -static int ne_open(struct device *dev) +static int ne_open(struct net_device *dev) { ei_open(dev); MOD_INC_USE_COUNT; return 0; } -static int ne_close(struct device *dev) +static int ne_close(struct net_device *dev) { if (ei_debug > 1) printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name); @@ -516,7 +516,7 @@ /* Hard reset the card. This used to pause for the same period that a 8390 reset command required, but that shouldn't be necessary. */ -static void ne_reset_8390(struct device *dev) +static void ne_reset_8390(struct net_device *dev) { unsigned long reset_start_time = jiffies; @@ -542,7 +542,7 @@ we don't need to be concerned with ring wrap as the header will be at the start of a page, so we optimize accordingly. */ -static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int nic_base = dev->base_addr; @@ -579,7 +579,7 @@ The NEx000 doesn't share the on-board packet memory -- you have to put the packet out through the "remote DMA" dataport using outb. */ -static void ne_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { #ifdef NE_SANITY_CHECK int xfer_count = count; @@ -646,7 +646,7 @@ ei_status.dmaing &= ~0x01; } -static void ne_block_output(struct device *dev, int count, +static void ne_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page) { int nic_base = NE_BASE; @@ -756,7 +756,7 @@ #define MAX_NE_CARDS 4 /* Max number of NE cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_NE_CARDS] = { 0, }; -static struct device dev_ne[MAX_NE_CARDS] = { +static struct net_device dev_ne[MAX_NE_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -787,7 +787,7 @@ int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - struct device *dev = &dev_ne[this_dev]; + struct net_device *dev = &dev_ne[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->mem_end = bad[this_dev]; @@ -816,7 +816,7 @@ int this_dev; for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - struct device *dev = &dev_ne[this_dev]; + struct net_device *dev = &dev_ne[this_dev]; if (dev->priv != NULL) { void *priv = dev->priv; free_irq(dev->irq, dev); diff -u --recursive --new-file v2.3.13/linux/drivers/net/ne2.c linux/drivers/net/ne2.c --- v2.3.13/linux/drivers/net/ne2.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/ne2.c Wed Aug 18 11:36:42 1999 @@ -126,19 +126,19 @@ { 0x0000, NULL } }; -extern int netcard_probe(struct device *dev); +extern int netcard_probe(struct net_device *dev); -static int ne2_probe1(struct device *dev, int slot); +static int ne2_probe1(struct net_device *dev, int slot); -static int ne_open(struct device *dev); -static int ne_close(struct device *dev); +static int ne_open(struct net_device *dev); +static int ne_close(struct net_device *dev); -static void ne_reset_8390(struct device *dev); -static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void ne_reset_8390(struct net_device *dev); +static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ne_block_input(struct device *dev, int count, +static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ne_block_output(struct device *dev, const int count, +static void ne_block_output(struct net_device *dev, const int count, const unsigned char *buf, const int start_page); @@ -146,7 +146,7 @@ * Note that at boot, this probe only picks up one card at a time. */ -int __init ne2_probe(struct device *dev) +int __init ne2_probe(struct net_device *dev) { static int current_mca_slot = -1; int i; @@ -175,7 +175,7 @@ } -static int ne2_procinfo(char *buf, int slot, struct device *dev) +static int ne2_procinfo(char *buf, int slot, struct net_device *dev) { int len=0; @@ -198,7 +198,7 @@ return len; } -static int __init ne2_probe1(struct device *dev, int slot) +static int __init ne2_probe1(struct net_device *dev, int slot) { int i, base_addr, irq; unsigned char POS; @@ -370,14 +370,14 @@ return 0; } -static int ne_open(struct device *dev) +static int ne_open(struct net_device *dev) { ei_open(dev); MOD_INC_USE_COUNT; return 0; } -static int ne_close(struct device *dev) +static int ne_close(struct net_device *dev) { if (ei_debug > 1) printk("%s: Shutting down ethercard.\n", dev->name); @@ -388,7 +388,7 @@ /* Hard reset the card. This used to pause for the same period that a 8390 reset command required, but that shouldn't be necessary. */ -static void ne_reset_8390(struct device *dev) +static void ne_reset_8390(struct net_device *dev) { unsigned long reset_start_time = jiffies; @@ -415,7 +415,7 @@ we don't need to be concerned with ring wrap as the header will be at the start of a page, so we optimize accordingly. */ -static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { @@ -455,7 +455,7 @@ hints. The NEx000 doesn't share the on-board packet memory -- you have to put the packet out through the "remote DMA" dataport using outb. */ -static void ne_block_input(struct device *dev, int count, struct sk_buff *skb, +static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { #ifdef NE_SANITY_CHECK @@ -518,7 +518,7 @@ ei_status.dmaing &= ~0x01; } -static void ne_block_output(struct device *dev, int count, +static void ne_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page) { int nic_base = NE_BASE; @@ -624,7 +624,7 @@ #define MAX_NE_CARDS 4 /* Max number of NE cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_NE_CARDS] = { 0, }; -static struct device dev_ne[MAX_NE_CARDS] = { +static struct net_device dev_ne[MAX_NE_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -650,7 +650,7 @@ int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - struct device *dev = &dev_ne[this_dev]; + struct net_device *dev = &dev_ne[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->mem_end = bad[this_dev]; @@ -672,7 +672,7 @@ int this_dev; for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - struct device *dev = &dev_ne[this_dev]; + struct net_device *dev = &dev_ne[this_dev]; if (dev->priv != NULL) { mca_mark_as_unused(ei_status.priv); mca_set_adapter_procfn( ei_status.priv, NULL, NULL); diff -u --recursive --new-file v2.3.13/linux/drivers/net/ne2k-pci.c linux/drivers/net/ne2k-pci.c --- v2.3.13/linux/drivers/net/ne2k-pci.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/ne2k-pci.c Wed Aug 18 11:36:42 1999 @@ -104,19 +104,19 @@ #define NESM_START_PG 0x40 /* First page of TX buffer */ #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ -int ne2k_pci_probe(struct device *dev); -static struct device *ne2k_pci_probe1(struct device *dev, int ioaddr, int irq, +int ne2k_pci_probe(struct net_device *dev); +static struct net_device *ne2k_pci_probe1(struct net_device *dev, int ioaddr, int irq, int chip_idx); -static int ne2k_pci_open(struct device *dev); -static int ne2k_pci_close(struct device *dev); +static int ne2k_pci_open(struct net_device *dev); +static int ne2k_pci_close(struct net_device *dev); -static void ne2k_pci_reset_8390(struct device *dev); -static void ne2k_pci_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void ne2k_pci_reset_8390(struct net_device *dev); +static void ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ne2k_pci_block_input(struct device *dev, int count, +static void ne2k_pci_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ne2k_pci_block_output(struct device *dev, const int count, +static void ne2k_pci_block_output(struct net_device *dev, const int count, const unsigned char *buf, const int start_page); @@ -124,7 +124,7 @@ /* No room in the standard 8390 structure for extra info we need. */ struct ne2k_pci_card { struct ne2k_pci_card *next; - struct device *dev; + struct net_device *dev; struct pci_dev *pci_dev; }; /* A list of all installed devices, for removing the driver module. */ @@ -150,7 +150,7 @@ void cleanup_module(void) { - struct device *dev; + struct net_device *dev; struct ne2k_pci_card *this_card; /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ @@ -186,7 +186,7 @@ {"ne2k_pci", ne2k_pci_probe1, NE_IO_EXTENT, 0}; #endif -int __init ne2k_pci_probe(struct device *dev) +int __init ne2k_pci_probe(struct net_device *dev) { struct pci_dev *pdev = NULL; int cards_found = 0; @@ -263,7 +263,7 @@ return cards_found ? 0 : -ENODEV; } -static struct device __init *ne2k_pci_probe1(struct device *dev, int ioaddr, int irq, int chip_idx) +static struct net_device __init *ne2k_pci_probe1(struct net_device *dev, int ioaddr, int irq, int chip_idx) { int i; unsigned char SA_prom[32]; @@ -397,7 +397,7 @@ } static int -ne2k_pci_open(struct device *dev) +ne2k_pci_open(struct net_device *dev) { if (request_irq(dev->irq, ei_interrupt, SA_SHIRQ, dev->name, dev)) return -EAGAIN; @@ -407,7 +407,7 @@ } static int -ne2k_pci_close(struct device *dev) +ne2k_pci_close(struct net_device *dev) { ei_close(dev); free_irq(dev->irq, dev); @@ -418,7 +418,7 @@ /* Hard reset the card. This used to pause for the same period that a 8390 reset command required, but that shouldn't be necessary. */ static void -ne2k_pci_reset_8390(struct device *dev) +ne2k_pci_reset_8390(struct net_device *dev) { unsigned long reset_start_time = jiffies; @@ -444,7 +444,7 @@ the start of a page, so we optimize accordingly. */ static void -ne2k_pci_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int nic_base = dev->base_addr; @@ -483,7 +483,7 @@ the packet out through the "remote DMA" dataport using outb. */ static void -ne2k_pci_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +ne2k_pci_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int nic_base = dev->base_addr; char *buf = skb->data; @@ -527,7 +527,7 @@ } static void -ne2k_pci_block_output(struct device *dev, int count, +ne2k_pci_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page) { int nic_base = NE_BASE; diff -u --recursive --new-file v2.3.13/linux/drivers/net/ne3210.c linux/drivers/net/ne3210.c --- v2.3.13/linux/drivers/net/ne3210.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/ne3210.c Wed Aug 18 11:36:42 1999 @@ -43,17 +43,17 @@ #include #include "8390.h" -int ne3210_probe(struct device *dev); -int ne3210_probe1(struct device *dev, int ioaddr); +int ne3210_probe(struct net_device *dev); +int ne3210_probe1(struct net_device *dev, int ioaddr); -static int ne3210_open(struct device *dev); -static int ne3210_close(struct device *dev); +static int ne3210_open(struct net_device *dev); +static int ne3210_close(struct net_device *dev); -static void ne3210_reset_8390(struct device *dev); +static void ne3210_reset_8390(struct net_device *dev); -static void ne3210_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ne3210_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ne3210_block_output(struct device *dev, int count, const unsigned char *buf, const int start_page); +static void ne3210_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); +static void ne3210_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); +static void ne3210_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); #define NE3210_START_PG 0x00 /* First page of TX buffer */ #define NE3210_STOP_PG 0x80 /* Last page +1 of RX ring */ @@ -95,7 +95,7 @@ * PROM for a match against the value assigned to Novell. */ -int __init ne3210_probe(struct device *dev) +int __init ne3210_probe(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; @@ -122,7 +122,7 @@ return ENODEV; } -int __init ne3210_probe1(struct device *dev, int ioaddr) +int __init ne3210_probe1(struct net_device *dev, int ioaddr) { int i; unsigned long eisa_id; @@ -272,7 +272,7 @@ * Reset by toggling the "Board Enable" bits (bit 2 and 0). */ -static void ne3210_reset_8390(struct device *dev) +static void ne3210_reset_8390(struct net_device *dev) { unsigned short ioaddr = dev->base_addr; @@ -304,7 +304,7 @@ */ static void -ne3210_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +ne3210_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = dev->mem_start + ((ring_page - NE3210_START_PG)<<8); memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); @@ -317,7 +317,7 @@ * be rounded up to a doubleword value via ne3210_get_8390_hdr() above. */ -static void ne3210_block_input(struct device *dev, int count, struct sk_buff *skb, +static void ne3210_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned long xfer_start = dev->mem_start + ring_offset - (NE3210_START_PG<<8); @@ -334,7 +334,7 @@ } } -static void ne3210_block_output(struct device *dev, int count, +static void ne3210_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { unsigned long shmem = dev->mem_start + ((start_page - NE3210_START_PG)<<8); @@ -343,14 +343,14 @@ memcpy_toio(shmem, buf, count); } -static int ne3210_open(struct device *dev) +static int ne3210_open(struct net_device *dev) { ei_open(dev); MOD_INC_USE_COUNT; return 0; } -static int ne3210_close(struct device *dev) +static int ne3210_close(struct net_device *dev) { if (ei_debug > 1) @@ -365,7 +365,7 @@ #define MAX_NE3210_CARDS 4 /* Max number of NE3210 cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_NE3210_CARDS] = { 0, }; -static struct device dev_ne3210[MAX_NE3210_CARDS] = { +static struct net_device dev_ne3210[MAX_NE3210_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -387,7 +387,7 @@ int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_NE3210_CARDS; this_dev++) { - struct device *dev = &dev_ne3210[this_dev]; + struct net_device *dev = &dev_ne3210[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -414,7 +414,7 @@ int this_dev; for (this_dev = 0; this_dev < MAX_NE3210_CARDS; this_dev++) { - struct device *dev = &dev_ne3210[this_dev]; + struct net_device *dev = &dev_ne3210[this_dev]; if (dev->priv != NULL) { void *priv = dev->priv; free_irq(dev->irq, dev); diff -u --recursive --new-file v2.3.13/linux/drivers/net/net_init.c linux/drivers/net/net_init.c --- v2.3.13/linux/drivers/net/net_init.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/net_init.c Wed Aug 18 11:36:42 1999 @@ -62,7 +62,7 @@ /* The list of used and available "eth" slots (for "eth0", "eth1", etc.) */ #define MAX_ETH_CARDS 16 -static struct device *ethdev_index[MAX_ETH_CARDS]; +static struct net_device *ethdev_index[MAX_ETH_CARDS]; /* Fill in the fields of the device structure with ethernet-generic values. @@ -75,17 +75,17 @@ long. */ -struct device * -init_etherdev(struct device *dev, int sizeof_priv) +struct net_device * +init_etherdev(struct net_device *dev, int sizeof_priv) { int new_device = 0; int i; /* Use an existing correctly named device in Space.c:dev_base. */ if (dev == NULL) { - int alloc_size = sizeof(struct device) + sizeof("eth%d ") + int alloc_size = sizeof(struct net_device) + sizeof("eth%d ") + sizeof_priv + 3; - struct device *cur_dev; + struct net_device *cur_dev; char pname[8]; /* Putative name for the device. */ for (i = 0; i < MAX_ETH_CARDS; ++i) @@ -110,7 +110,7 @@ alloc_size &= ~3; /* Round to dword boundary. */ - dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL); + dev = (struct net_device *)kmalloc(alloc_size, GFP_KERNEL); if(dev==NULL) return NULL; memset(dev, 0, alloc_size); @@ -141,7 +141,7 @@ } -static int eth_mac_addr(struct device *dev, void *p) +static int eth_mac_addr(struct net_device *dev, void *p) { struct sockaddr *addr=p; if(dev->start) @@ -150,7 +150,7 @@ return 0; } -static int eth_change_mtu(struct device *dev, int new_mtu) +static int eth_change_mtu(struct net_device *dev, int new_mtu) { if ((new_mtu < 68) || (new_mtu > 1500)) return -EINVAL; @@ -160,7 +160,7 @@ #ifdef CONFIG_FDDI -static int fddi_change_mtu(struct device *dev, int new_mtu) +static int fddi_change_mtu(struct net_device *dev, int new_mtu) { if ((new_mtu < FDDI_K_SNAP_HLEN) || (new_mtu > FDDI_K_SNAP_DLEN)) return(-EINVAL); @@ -172,9 +172,9 @@ #ifdef CONFIG_HIPPI #define MAX_HIP_CARDS 4 -static struct device *hipdev_index[MAX_HIP_CARDS]; +static struct net_device *hipdev_index[MAX_HIP_CARDS]; -static int hippi_change_mtu(struct device *dev, int new_mtu) +static int hippi_change_mtu(struct net_device *dev, int new_mtu) { /* * HIPPI's got these nice large MTUs. @@ -190,7 +190,7 @@ * For HIPPI we will actually use the lower 4 bytes of the hardware * address as the I-FIELD rather than the actual hardware address. */ -static int hippi_mac_addr(struct device *dev, void *p) +static int hippi_mac_addr(struct net_device *dev, void *p) { struct sockaddr *addr = p; if(dev->start) @@ -200,16 +200,16 @@ } -struct device *init_hippi_dev(struct device *dev, int sizeof_priv) +struct net_device *init_hippi_dev(struct net_device *dev, int sizeof_priv) { int new_device = 0; int i; /* Use an existing correctly named device in Space.c:dev_base. */ if (dev == NULL) { - int alloc_size = sizeof(struct device) + sizeof("hip%d ") + int alloc_size = sizeof(struct net_device) + sizeof("hip%d ") + sizeof_priv + 3; - struct device *cur_dev; + struct net_device *cur_dev; char pname[8]; for (i = 0; i < MAX_HIP_CARDS; ++i) @@ -234,7 +234,7 @@ alloc_size &= ~3; /* Round to dword boundary. */ - dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL); + dev = (struct net_device *)kmalloc(alloc_size, GFP_KERNEL); if(dev==NULL) return NULL; memset(dev, 0, alloc_size); @@ -265,7 +265,7 @@ } -void unregister_hipdev(struct device *dev) +void unregister_hipdev(struct net_device *dev) { int i; rtnl_lock(); @@ -280,7 +280,7 @@ } -static int hippi_neigh_setup_dev(struct device *dev, struct neigh_parms *p) +static int hippi_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p) { /* Never send broadcast/multicast ARP messages */ p->mcast_probes = 0; @@ -296,7 +296,7 @@ #endif -void ether_setup(struct device *dev) +void ether_setup(struct net_device *dev) { int i; /* Fill in the fields of the device structure with ethernet-generic values. @@ -339,7 +339,7 @@ #ifdef CONFIG_FDDI -void fddi_setup(struct device *dev) +void fddi_setup(struct net_device *dev) { /* * Fill in the fields of the device structure with FDDI-generic values. @@ -369,7 +369,7 @@ #endif #ifdef CONFIG_HIPPI -void hippi_setup(struct device *dev) +void hippi_setup(struct net_device *dev) { int i; @@ -419,18 +419,18 @@ #if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) -static int ltalk_change_mtu(struct device *dev, int mtu) +static int ltalk_change_mtu(struct net_device *dev, int mtu) { return -EINVAL; } -static int ltalk_mac_addr(struct device *dev, void *addr) +static int ltalk_mac_addr(struct net_device *dev, void *addr) { return -EINVAL; } -void ltalk_setup(struct device *dev) +void ltalk_setup(struct net_device *dev) { /* Fill in the fields of the device structure with localtalk-generic values. */ @@ -456,7 +456,7 @@ #endif -int ether_config(struct device *dev, struct ifmap *map) +int ether_config(struct net_device *dev, struct ifmap *map) { if (map->mem_start != (u_long)(-1)) dev->mem_start = map->mem_start; @@ -473,7 +473,7 @@ return 0; } -static int etherdev_get_index(struct device *dev) +static int etherdev_get_index(struct net_device *dev) { int i=MAX_ETH_CARDS; @@ -488,7 +488,7 @@ return -1; } -static void etherdev_put_index(struct device *dev) +static void etherdev_put_index(struct net_device *dev) { int i; for (i = 0; i < MAX_ETH_CARDS; ++i) { @@ -499,7 +499,7 @@ } } -int register_netdev(struct device *dev) +int register_netdev(struct net_device *dev) { int i=-1; @@ -519,7 +519,7 @@ return 0; } -void unregister_netdev(struct device *dev) +void unregister_netdev(struct net_device *dev) { rtnl_lock(); unregister_netdevice(dev); @@ -531,18 +531,18 @@ #ifdef CONFIG_TR /* The list of used and available "tr" slots */ #define MAX_TR_CARDS 16 -static struct device *trdev_index[MAX_TR_CARDS]; +static struct net_device *trdev_index[MAX_TR_CARDS]; -struct device *init_trdev(struct device *dev, int sizeof_priv) +struct net_device *init_trdev(struct net_device *dev, int sizeof_priv) { int new_device = 0; int i; /* Use an existing correctly named device in Space.c:dev_base. */ if (dev == NULL) { - int alloc_size = sizeof(struct device) + sizeof("tr%d ") + int alloc_size = sizeof(struct net_device) + sizeof("tr%d ") + sizeof_priv + 3; - struct device *cur_dev; + struct net_device *cur_dev; char pname[8]; /* Putative name for the device. */ for (i = 0; i < MAX_TR_CARDS; ++i) @@ -566,7 +566,7 @@ } alloc_size &= ~3; /* Round to dword boundary. */ - dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL); + dev = (struct net_device *)kmalloc(alloc_size, GFP_KERNEL); if(dev==NULL) return NULL; memset(dev, 0, alloc_size); @@ -606,7 +606,7 @@ return dev; } -void tr_setup(struct device *dev) +void tr_setup(struct net_device *dev) { int i; @@ -624,7 +624,7 @@ } } -void tr_freedev(struct device *dev) +void tr_freedev(struct net_device *dev) { int i; for (i = 0; i < MAX_TR_CARDS; ++i) @@ -637,7 +637,7 @@ } } -int register_trdev(struct device *dev) +int register_trdev(struct net_device *dev) { dev_init_buffers(dev); @@ -648,7 +648,7 @@ return 0; } -void unregister_trdev(struct device *dev) +void unregister_trdev(struct net_device *dev) { rtnl_lock(); unregister_netdevice(dev); diff -u --recursive --new-file v2.3.13/linux/drivers/net/ni5010.c linux/drivers/net/ni5010.c --- v2.3.13/linux/drivers/net/ni5010.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/ni5010.c Wed Aug 18 11:36:42 1999 @@ -100,26 +100,26 @@ /* Index to functions, as function prototypes. */ -extern int ni5010_probe(struct device *dev); -static int ni5010_probe1(struct device *dev, int ioaddr); -static int ni5010_open(struct device *dev); -static int ni5010_send_packet(struct sk_buff *skb, struct device *dev); +extern int ni5010_probe(struct net_device *dev); +static int ni5010_probe1(struct net_device *dev, int ioaddr); +static int ni5010_open(struct net_device *dev); +static int ni5010_send_packet(struct sk_buff *skb, struct net_device *dev); static void ni5010_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void ni5010_rx(struct device *dev); -static int ni5010_close(struct device *dev); -static struct net_device_stats *ni5010_get_stats(struct device *dev); -static void ni5010_set_multicast_list(struct device *dev); -static void reset_receiver(struct device *dev); +static void ni5010_rx(struct net_device *dev); +static int ni5010_close(struct net_device *dev); +static struct net_device_stats *ni5010_get_stats(struct net_device *dev); +static void ni5010_set_multicast_list(struct net_device *dev); +static void reset_receiver(struct net_device *dev); -static int process_xmt_interrupt(struct device *dev); +static int process_xmt_interrupt(struct net_device *dev); #define tx_done(dev) 1 -extern void hardware_send_packet(struct device *dev, char *buf, int length); -extern void chipset_init(struct device *dev, int startp); +extern void hardware_send_packet(struct net_device *dev, char *buf, int length); +extern void chipset_init(struct net_device *dev, int startp); static void dump_packet(void *buf, int len); -static void show_registers(struct device *dev); +static void show_registers(struct net_device *dev); -int __init ni5010_probe(struct device *dev) +int __init ni5010_probe(struct net_device *dev) { int *port; @@ -182,7 +182,7 @@ * verifies that the correct device exists and functions. */ -static int __init ni5010_probe1(struct device *dev, int ioaddr) +static int __init ni5010_probe1(struct net_device *dev, int ioaddr) { static unsigned version_printed = 0; int i; @@ -355,7 +355,7 @@ * there is non-reboot way to recover if something goes wrong. */ -static int ni5010_open(struct device *dev) +static int ni5010_open(struct net_device *dev) { int ioaddr = dev->base_addr; int i; @@ -414,7 +414,7 @@ return 0; } -static void reset_receiver(struct device *dev) +static void reset_receiver(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -426,7 +426,7 @@ outb(0xff, EDLC_RMASK); /* Enable all rcv interrupts */ } -static int ni5010_send_packet(struct sk_buff *skb, struct device *dev) +static int ni5010_send_packet(struct sk_buff *skb, struct net_device *dev) { PRINTK2((KERN_DEBUG "%s: entering ni5010_send_packet\n", dev->name)); if (dev->tbusy) { @@ -472,7 +472,7 @@ static void ni5010_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct ni5010_local *lp; int ioaddr, status; int xmit_was_error = 0; @@ -531,7 +531,7 @@ /* We have a good packet, get it out of the buffer. */ static void -ni5010_rx(struct device *dev) +ni5010_rx(struct net_device *dev) { struct ni5010_local *lp = (struct ni5010_local *)dev->priv; int ioaddr = dev->base_addr; @@ -594,7 +594,7 @@ } -static int process_xmt_interrupt(struct device *dev) +static int process_xmt_interrupt(struct net_device *dev) { struct ni5010_local *lp = (struct ni5010_local *)dev->priv; int ioaddr = dev->base_addr; @@ -635,7 +635,7 @@ /* The inverse routine to ni5010_open(). */ static int -ni5010_close(struct device *dev) +ni5010_close(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -659,7 +659,7 @@ /* Get the current statistics. This may be called with the card open or closed. */ static struct net_device_stats * -ni5010_get_stats(struct device *dev) +ni5010_get_stats(struct net_device *dev) { struct ni5010_local *lp = (struct ni5010_local *)dev->priv; @@ -682,7 +682,7 @@ best-effort filtering. */ static void -ni5010_set_multicast_list(struct device *dev) +ni5010_set_multicast_list(struct net_device *dev) { short ioaddr = dev->base_addr; @@ -702,7 +702,7 @@ } } -extern void hardware_send_packet(struct device *dev, char *buf, int length) +extern void hardware_send_packet(struct net_device *dev, char *buf, int length) { struct ni5010_local *lp = (struct ni5010_local *)dev->priv; int ioaddr = dev->base_addr; @@ -751,13 +751,13 @@ if (NI5010_DEBUG) show_registers(dev); } -extern void chipset_init(struct device *dev, int startp) +extern void chipset_init(struct net_device *dev, int startp) { /* FIXME: Move some stuff here */ PRINTK3((KERN_DEBUG "%s: doing NOTHING in chipset_init\n", dev->name)); } -static void show_registers(struct device *dev) +static void show_registers(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -772,7 +772,7 @@ #ifdef MODULE static char devicename[9] = { 0, }; -static struct device dev_ni5010 = { +static struct net_device dev_ni5010 = { devicename, 0, 0, 0, 0, 0, 0, diff -u --recursive --new-file v2.3.13/linux/drivers/net/ni52.c linux/drivers/net/ni52.c --- v2.3.13/linux/drivers/net/ni52.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/ni52.c Wed Aug 18 11:36:42 1999 @@ -192,26 +192,26 @@ #define NI52_ADDR1 0x07 #define NI52_ADDR2 0x01 -static int ni52_probe1(struct device *dev,int ioaddr); +static int ni52_probe1(struct net_device *dev,int ioaddr); static void ni52_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr); -static int ni52_open(struct device *dev); -static int ni52_close(struct device *dev); -static int ni52_send_packet(struct sk_buff *,struct device *); -static struct net_device_stats *ni52_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static int ni52_open(struct net_device *dev); +static int ni52_close(struct net_device *dev); +static int ni52_send_packet(struct sk_buff *,struct net_device *); +static struct net_device_stats *ni52_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); #if 0 -static void ni52_dump(struct device *,void *); +static void ni52_dump(struct net_device *,void *); #endif /* helper-functions */ -static int init586(struct device *dev); -static int check586(struct device *dev,char *where,unsigned size); -static void alloc586(struct device *dev); -static void startrecv586(struct device *dev); -static void *alloc_rfa(struct device *dev,void *ptr); -static void ni52_rcv_int(struct device *dev); -static void ni52_xmt_int(struct device *dev); -static void ni52_rnr_int(struct device *dev); +static int init586(struct net_device *dev); +static int check586(struct net_device *dev,char *where,unsigned size); +static void alloc586(struct net_device *dev); +static void startrecv586(struct net_device *dev); +static void *alloc_rfa(struct net_device *dev,void *ptr); +static void ni52_rcv_int(struct net_device *dev); +static void ni52_xmt_int(struct net_device *dev); +static void ni52_rnr_int(struct net_device *dev); struct priv { @@ -238,7 +238,7 @@ /********************************************** * close device */ -static int ni52_close(struct device *dev) +static int ni52_close(struct net_device *dev) { free_irq(dev->irq, dev); @@ -255,7 +255,7 @@ /********************************************** * open device */ -static int ni52_open(struct device *dev) +static int ni52_open(struct net_device *dev) { ni_disint(); alloc586(dev); @@ -281,7 +281,7 @@ /********************************************** * Check to see if there's an 82586 out there. */ -static int check586(struct device *dev,char *where,unsigned size) +static int check586(struct net_device *dev,char *where,unsigned size) { struct priv pb; struct priv *p = /* (struct priv *) dev->priv*/ &pb; @@ -323,7 +323,7 @@ /****************************************************************** * set iscp at the right place, called by ni52_probe1 and open586. */ -void alloc586(struct device *dev) +void alloc586(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -358,7 +358,7 @@ /********************************************** * probe the ni5210-card */ -int __init ni52_probe(struct device *dev) +int __init ni52_probe(struct net_device *dev) { #ifndef MODULE int *port; @@ -409,7 +409,7 @@ return ENODEV; } -static int __init ni52_probe1(struct device *dev,int ioaddr) +static int __init ni52_probe1(struct net_device *dev,int ioaddr) { int i,size; @@ -534,7 +534,7 @@ * needs a correct 'allocated' memory */ -static int init586(struct device *dev) +static int init586(struct net_device *dev) { void *ptr; int i,result=0; @@ -769,7 +769,7 @@ * It sets up the Receive Frame Area (RFA). */ -static void *alloc_rfa(struct device *dev,void *ptr) +static void *alloc_rfa(struct net_device *dev,void *ptr) { volatile struct rfd_struct *rfd = (struct rfd_struct *)ptr; volatile struct rbd_struct *rbd; @@ -817,7 +817,7 @@ static void ni52_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; unsigned short stat; int cnt=0; struct priv *p; @@ -893,7 +893,7 @@ * receive-interrupt */ -static void ni52_rcv_int(struct device *dev) +static void ni52_rcv_int(struct net_device *dev) { int status,cnt=0; unsigned short totlen; @@ -1016,7 +1016,7 @@ * handle 'Receiver went not ready'. */ -static void ni52_rnr_int(struct device *dev) +static void ni52_rnr_int(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -1039,7 +1039,7 @@ * handle xmit - interrupt */ -static void ni52_xmt_int(struct device *dev) +static void ni52_xmt_int(struct net_device *dev) { int status; struct priv *p = (struct priv *) dev->priv; @@ -1092,7 +1092,7 @@ * (re)start the receiver */ -static void startrecv586(struct device *dev) +static void startrecv586(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -1108,7 +1108,7 @@ * send frame */ -static int ni52_send_packet(struct sk_buff *skb, struct device *dev) +static int ni52_send_packet(struct sk_buff *skb, struct net_device *dev) { int len,i; #ifndef NO_NOPCOMMANDS @@ -1258,7 +1258,7 @@ * Someone wanna have the statistics */ -static struct net_device_stats *ni52_get_stats(struct device *dev) +static struct net_device_stats *ni52_get_stats(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; unsigned short crc,aln,rsc,ovrn; @@ -1283,7 +1283,7 @@ /******************************************************** * Set MC list .. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { if(!dev->start) { @@ -1304,7 +1304,7 @@ #ifdef MODULE static char devicename[9] = { 0, }; -static struct device dev_ni52 = { +static struct net_device dev_ni52 = { devicename, /* "ni5210": device name inserted by net_init.c */ 0, 0, 0, 0, 0x300, 9, /* I/O address, IRQ */ @@ -1349,7 +1349,7 @@ /* * DUMP .. we expect a not running CMD unit and enough space */ -void ni52_dump(struct device *dev,void *ptr) +void ni52_dump(struct net_device *dev,void *ptr) { struct priv *p = (struct priv *) dev->priv; struct dump_cmd_struct *dump_cmd = (struct dump_cmd_struct *) ptr; diff -u --recursive --new-file v2.3.13/linux/drivers/net/ni65.c linux/drivers/net/ni65.c --- v2.3.13/linux/drivers/net/ni65.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/ni65.c Wed Aug 18 11:36:42 1999 @@ -220,19 +220,19 @@ int features; }; -static int ni65_probe1(struct device *dev,int); +static int ni65_probe1(struct net_device *dev,int); static void ni65_interrupt(int irq, void * dev_id, struct pt_regs *regs); -static void ni65_recv_intr(struct device *dev,int); -static void ni65_xmit_intr(struct device *dev,int); -static int ni65_open(struct device *dev); -static int ni65_lance_reinit(struct device *dev); +static void ni65_recv_intr(struct net_device *dev,int); +static void ni65_xmit_intr(struct net_device *dev,int); +static int ni65_open(struct net_device *dev); +static int ni65_lance_reinit(struct net_device *dev); static void ni65_init_lance(struct priv *p,unsigned char*,int,int); -static int ni65_send_packet(struct sk_buff *skb, struct device *dev); -static int ni65_close(struct device *dev); -static int ni65_alloc_buffer(struct device *dev); +static int ni65_send_packet(struct sk_buff *skb, struct net_device *dev); +static int ni65_close(struct net_device *dev); +static int ni65_alloc_buffer(struct net_device *dev); static void ni65_free_buffer(struct priv *p); -static struct net_device_stats *ni65_get_stats(struct device *); -static void set_multicast_list(struct device *dev); +static struct net_device_stats *ni65_get_stats(struct net_device *); +static void set_multicast_list(struct net_device *dev); static int irqtab[] __initdata = { 9,12,15,5 }; /* irq config-translate */ static int dmatab[] __initdata = { 0,3,5,6,7 }; /* dma config-translate and autodetect */ @@ -265,7 +265,7 @@ /* * open interface (up) */ -static int ni65_open(struct device *dev) +static int ni65_open(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; int irqval = request_irq(dev->irq, &ni65_interrupt,0, @@ -295,7 +295,7 @@ /* * close interface (down) */ -static int ni65_close(struct device *dev) +static int ni65_close(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -326,7 +326,7 @@ #ifdef MODULE static #endif -int __init ni65_probe(struct device *dev) +int __init ni65_probe(struct net_device *dev) { int *port; static int ports[] = {0x360,0x300,0x320,0x340, 0}; @@ -348,7 +348,7 @@ /* * this is the real card probe .. */ -static int __init ni65_probe1(struct device *dev,int ioaddr) +static int __init ni65_probe1(struct net_device *dev,int ioaddr) { int i,j; struct priv *p; @@ -531,7 +531,7 @@ /* * allocate memory area and check the 16MB border */ -static void *ni65_alloc_mem(struct device *dev,char *what,int size,int type) +static void *ni65_alloc_mem(struct net_device *dev,char *what,int size,int type) { struct sk_buff *skb=NULL; unsigned char *ptr; @@ -569,7 +569,7 @@ /* * allocate all memory structures .. send/recv buffers etc ... */ -static int ni65_alloc_buffer(struct device *dev) +static int ni65_alloc_buffer(struct net_device *dev) { unsigned char *ptr; struct priv *p; @@ -655,7 +655,7 @@ /* * stop and (re)start lance .. e.g after an error */ -static void ni65_stop_start(struct device *dev,struct priv *p) +static void ni65_stop_start(struct net_device *dev,struct priv *p) { int csr0 = CSR0_INEA; @@ -724,7 +724,7 @@ /* * init lance (write init-values .. init-buffers) (open-helper) */ -static int ni65_lance_reinit(struct device *dev) +static int ni65_lance_reinit(struct net_device *dev) { int i; struct priv *p = (struct priv *) dev->priv; @@ -809,7 +809,7 @@ static void ni65_interrupt(int irq, void * dev_id, struct pt_regs * regs) { int csr0; - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct priv *p; int bcnt = 32; @@ -925,7 +925,7 @@ * We have received an Xmit-Interrupt .. * send a new packet if necessary */ -static void ni65_xmit_intr(struct device *dev,int csr0) +static void ni65_xmit_intr(struct net_device *dev,int csr0) { struct priv *p = (struct priv *) dev->priv; @@ -990,7 +990,7 @@ /* * We have received a packet */ -static void ni65_recv_intr(struct device *dev,int csr0) +static void ni65_recv_intr(struct net_device *dev,int csr0) { struct rmd *rmdp; int rmdstat,len; @@ -1082,7 +1082,7 @@ /* * kick xmitter .. */ -static int ni65_send_packet(struct sk_buff *skb, struct device *dev) +static int ni65_send_packet(struct sk_buff *skb, struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -1162,7 +1162,7 @@ return 0; } -static struct net_device_stats *ni65_get_stats(struct device *dev) +static struct net_device_stats *ni65_get_stats(struct net_device *dev) { #if 0 @@ -1179,7 +1179,7 @@ return &((struct priv *) dev->priv)->stats; } -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { if(!ni65_lance_reinit(dev)) printk(KERN_ERR "%s: Can't switch card into MC mode!\n",dev->name); @@ -1189,7 +1189,7 @@ #ifdef MODULE static char devicename[9] = { 0, }; -static struct device dev_ni65 = { +static struct net_device dev_ni65 = { devicename, /* "ni6510": device name inserted by net_init.c */ 0, 0, 0, 0, 0x360, 9, /* I/O address, IRQ */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/olympic.c linux/drivers/net/olympic.c --- v2.3.13/linux/drivers/net/olympic.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/olympic.c Wed Aug 18 16:24:11 1999 @@ -22,6 +22,9 @@ * * 6/8/99 - Official Release 0.2.0 * Merged into the kernel code + * 8/18/99 - Updated driver for 2.3.13 kernel to use new pci + * resource. Driver also reports the card name returned by + * the pci resource. * * To Do: * @@ -83,7 +86,7 @@ */ static char *version = -"Olympic.c v0.2.0 6/8/99 - Peter De Schrijver & Mike Phillips" ; +"Olympic.c v0.3.0 8/18/99 - Peter De Schrijver & Mike Phillips" ; static char *open_maj_error[] = {"No error", "Lobe Media Test", "Physical Insertion", "Address Verification", "Neighbor Notification (Ring Poll)", @@ -128,26 +131,26 @@ MODULE_PARM(message_level, "1-" __MODULE_STRING(OLYMPIC_MAX_ADAPTERS) "i") ; -static int olympic_scan(struct device *dev); -static int olympic_init(struct device *dev); -static int olympic_open(struct device *dev); -static int olympic_xmit(struct sk_buff *skb, struct device *dev); -static int olympic_close(struct device *dev); -static void olympic_set_rx_mode(struct device *dev); +static int olympic_scan(struct net_device *dev); +static int olympic_init(struct net_device *dev); +static int olympic_open(struct net_device *dev); +static int olympic_xmit(struct sk_buff *skb, struct net_device *dev); +static int olympic_close(struct net_device *dev); +static void olympic_set_rx_mode(struct net_device *dev); static void olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static struct net_device_stats * olympic_get_stats(struct device *dev); -static int olympic_set_mac_address(struct device *dev, void *addr) ; -static void olympic_arb_cmd(struct device *dev); -static int olympic_change_mtu(struct device *dev, int mtu); -static void olympic_srb_bh(struct device *dev) ; -static void olympic_asb_bh(struct device *dev) ; +static struct net_device_stats * olympic_get_stats(struct net_device *dev); +static int olympic_set_mac_address(struct net_device *dev, void *addr) ; +static void olympic_arb_cmd(struct net_device *dev); +static int olympic_change_mtu(struct net_device *dev, int mtu); +static void olympic_srb_bh(struct net_device *dev) ; +static void olympic_asb_bh(struct net_device *dev) ; #if OLYMPIC_NETWORK_MONITOR #ifdef CONFIG_PROC_FS -static int sprintf_info(char *buffer, struct device *dev) ; +static int sprintf_info(char *buffer, struct net_device *dev) ; #endif #endif -__initfunc(int olympic_probe(struct device *dev)) +__initfunc(int olympic_probe(struct net_device *dev)) { int cards_found; @@ -155,7 +158,7 @@ return cards_found ? 0 : -ENODEV; } -__initfunc(static int olympic_scan(struct device *dev)) +__initfunc(static int olympic_scan(struct net_device *dev)) { struct pci_dev *pci_device = NULL ; struct olympic_private *olympic_priv; @@ -169,7 +172,7 @@ /* Check to see if io has been allocated, if so, we've already done this card, so continue on the card discovery loop */ - if (check_region(pci_device->base_address[0] & (~3), OLYMPIC_IO_SPACE)) { + if (check_region(pci_device->resource[0].start, OLYMPIC_IO_SPACE)) { card_no++ ; continue ; } @@ -184,12 +187,13 @@ dev->priv=(void *)olympic_priv; #if OLYMPIC_DEBUG printk("pci_device: %p, dev:%p, dev->priv: %p\n", pci_device, dev, dev->priv); -#endif +#endif dev->irq=pci_device->irq; - dev->base_addr=pci_device->base_address[0] & (~3); + dev->base_addr=pci_device->resource[0].start; dev->init=&olympic_init; - olympic_priv->olympic_mmio=ioremap(pci_device->base_address[1],256); - olympic_priv->olympic_lap=ioremap(pci_device->base_address[2],2048); + olympic_priv->olympic_card_name = (char *)pci_device->resource[0].name ; + olympic_priv->olympic_mmio=ioremap(pci_device->resource[1].start,256); + olympic_priv->olympic_lap=ioremap(pci_device->resource[2].start,2048); if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) ) olympic_priv->pkt_buf_sz = PKT_BUF_SZ ; @@ -222,7 +226,7 @@ } -__initfunc(static int olympic_init(struct device *dev)) +__initfunc(static int olympic_init(struct net_device *dev)) { struct olympic_private *olympic_priv; __u8 *olympic_mmio, *init_srb,*adapter_addr; @@ -233,7 +237,7 @@ olympic_mmio=olympic_priv->olympic_mmio; printk("%s \n", version); - printk("%s: IBM PCI tokenring card. I/O at %hx, MMIO at %p, LAP at %p, using irq %d\n",dev->name, (unsigned int) dev->base_addr,olympic_priv->olympic_mmio, olympic_priv->olympic_lap, dev->irq); + printk("%s: %s. I/O at %hx, MMIO at %p, LAP at %p, using irq %d\n",dev->name, olympic_priv->olympic_card_name, (unsigned int) dev->base_addr,olympic_priv->olympic_mmio, olympic_priv->olympic_lap, dev->irq); request_region(dev->base_addr, OLYMPIC_IO_SPACE, "olympic"); writel(readl(olympic_mmio+BCTL) | BCTL_SOFTRESET,olympic_mmio+BCTL); @@ -337,7 +341,7 @@ } -static int olympic_open(struct device *dev) +static int olympic_open(struct net_device *dev) { struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv; __u8 *olympic_mmio=olympic_priv->olympic_mmio,*init_srb; @@ -628,7 +632,7 @@ * of blindly processing the next frame. * */ -static void olympic_rx(struct device *dev) +static void olympic_rx(struct net_device *dev) { struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv; __u8 *olympic_mmio=olympic_priv->olympic_mmio; @@ -742,7 +746,7 @@ static void olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev= (struct device *)dev_id; + struct net_device *dev= (struct net_device *)dev_id; struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv; __u8 *olympic_mmio=olympic_priv->olympic_mmio; __u32 sisr; @@ -834,7 +838,7 @@ } -static int olympic_xmit(struct sk_buff *skb, struct device *dev) +static int olympic_xmit(struct sk_buff *skb, struct net_device *dev) { struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv; __u8 *olympic_mmio=olympic_priv->olympic_mmio; @@ -864,7 +868,7 @@ } -static int olympic_close(struct device *dev) +static int olympic_close(struct net_device *dev) { struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv; __u8 *olympic_mmio=olympic_priv->olympic_mmio,*srb; @@ -928,7 +932,7 @@ } -static void olympic_set_rx_mode(struct device *dev) +static void olympic_set_rx_mode(struct net_device *dev) { struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv ; __u8 *olympic_mmio = olympic_priv->olympic_mmio ; @@ -1028,7 +1032,7 @@ } -static void olympic_srb_bh(struct device *dev) +static void olympic_srb_bh(struct net_device *dev) { struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv ; __u8 *olympic_mmio = olympic_priv->olympic_mmio ; @@ -1175,14 +1179,14 @@ } -static struct net_device_stats * olympic_get_stats(struct device *dev) +static struct net_device_stats * olympic_get_stats(struct net_device *dev) { struct olympic_private *olympic_priv ; olympic_priv=(struct olympic_private *) dev->priv; return (struct net_device_stats *) &olympic_priv->olympic_stats; } -static int olympic_set_mac_address (struct device *dev, void *addr) +static int olympic_set_mac_address (struct net_device *dev, void *addr) { struct sockaddr *saddr = addr ; struct olympic_private *olympic_priv = (struct olympic_private *)dev->priv ; @@ -1204,7 +1208,7 @@ return 0 ; } -static void olympic_arb_cmd(struct device *dev) +static void olympic_arb_cmd(struct net_device *dev) { struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv; __u8 *olympic_mmio=olympic_priv->olympic_mmio; @@ -1394,7 +1398,7 @@ printk(KERN_WARNING "%s: Unknown arb command \n", dev->name); } -static void olympic_asb_bh(struct device *dev) +static void olympic_asb_bh(struct net_device *dev) { struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv ; __u8 *arb_block, *asb_block ; @@ -1434,7 +1438,7 @@ olympic_priv->asb_queued = 0 ; } -static int olympic_change_mtu(struct device *dev, int mtu) +static int olympic_change_mtu(struct net_device *dev, int mtu) { struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv; __u16 max_mtu ; @@ -1465,7 +1469,7 @@ off_t pos=0; int size; - struct device *dev; + struct net_device *dev; size = sprintf(buffer, @@ -1479,7 +1483,7 @@ for (dev = dev_base; dev != NULL; dev = dev->next) { - if (dev->base_addr == (pci_device->base_address[0] & (~3)) ) { /* Yep, an Olympic device */ + if (dev->base_addr == pci_device->resource[0].start ) { /* Yep, an Olympic device */ size = sprintf_info(buffer+len, dev); len+=size; pos=begin+len; @@ -1502,7 +1506,7 @@ return len; } -static int sprintf_info(char *buffer, struct device *dev) +static int sprintf_info(char *buffer, struct net_device *dev) { struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv; __u8 *oat = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ; @@ -1602,7 +1606,7 @@ #ifdef MODULE -static struct device* dev_olympic[OLYMPIC_MAX_ADAPTERS]; +static struct net_device* dev_olympic[OLYMPIC_MAX_ADAPTERS]; int init_module(void) { @@ -1625,7 +1629,7 @@ dev_olympic[i]->init = &olympic_probe; if (register_trdev(dev_olympic[i]) != 0) { - kfree_s(dev_olympic[i], sizeof(struct device)); + kfree_s(dev_olympic[i], sizeof(struct net_device)); dev_olympic[i] = NULL; if (i == 0) { printk("Olympic: No IBM PCI Token Ring cards found in system.\n"); @@ -1649,7 +1653,7 @@ unregister_trdev(dev_olympic[i]); release_region(dev_olympic[i]->base_addr, OLYMPIC_IO_SPACE); kfree_s(dev_olympic[i]->priv, sizeof(struct olympic_private)); - kfree_s(dev_olympic[i], sizeof(struct device)); + kfree_s(dev_olympic[i], sizeof(struct net_device)); dev_olympic[i] = NULL; } diff -u --recursive --new-file v2.3.13/linux/drivers/net/olympic.h linux/drivers/net/olympic.h --- v2.3.13/linux/drivers/net/olympic.h Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/olympic.h Wed Aug 18 16:24:11 1999 @@ -243,6 +243,7 @@ __u8 *olympic_mmio; __u8 *olympic_lap; + char *olympic_card_name ; volatile int srb_queued; /* True if an SRB is still posted */ wait_queue_head_t srb_wait; diff -u --recursive --new-file v2.3.13/linux/drivers/net/pcnet32.c linux/drivers/net/pcnet32.c --- v2.3.13/linux/drivers/net/pcnet32.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/pcnet32.c Wed Aug 18 11:36:42 1999 @@ -45,7 +45,7 @@ static int pcnet32_debug = 1; #ifdef MODULE -static struct device *pcnet32_dev = NULL; +static struct net_device *pcnet32_dev = NULL; #endif static const int max_interrupt_work = 20; @@ -264,22 +264,22 @@ full_duplex:1, /* full duplex possible */ mii:1; /* mii port available */ #ifdef MODULE - struct device *next; + struct net_device *next; #endif }; -int pcnet32_probe(struct device *); -static int pcnet32_probe1(struct device *, unsigned long, unsigned char, int, int); -static int pcnet32_open(struct device *); -static int pcnet32_init_ring(struct device *); -static int pcnet32_start_xmit(struct sk_buff *, struct device *); -static int pcnet32_rx(struct device *); +int pcnet32_probe(struct net_device *); +static int pcnet32_probe1(struct net_device *, unsigned long, unsigned char, int, int); +static int pcnet32_open(struct net_device *); +static int pcnet32_init_ring(struct net_device *); +static int pcnet32_start_xmit(struct sk_buff *, struct net_device *); +static int pcnet32_rx(struct net_device *); static void pcnet32_interrupt(int, void *, struct pt_regs *); -static int pcnet32_close(struct device *); -static struct net_device_stats *pcnet32_get_stats(struct device *); -static void pcnet32_set_multicast_list(struct device *); +static int pcnet32_close(struct net_device *); +static struct net_device_stats *pcnet32_get_stats(struct net_device *); +static void pcnet32_set_multicast_list(struct net_device *); #ifdef HAVE_PRIVATE_IOCTL -static int pcnet32_mii_ioctl(struct device *, struct ifreq *, int); +static int pcnet32_mii_ioctl(struct net_device *, struct ifreq *, int); #endif enum pci_flags_bit { @@ -291,7 +291,7 @@ const char *name; u16 vendor_id, device_id, svid, sdid, flags; int io_size; - int (*probe1) (struct device *, unsigned long, unsigned char, int, int); + int (*probe1) (struct net_device *, unsigned long, unsigned char, int, int); }; static struct pcnet32_pci_id_info pcnet32_tbl[] = { @@ -419,7 +419,7 @@ -int __init pcnet32_probe (struct device *dev) +int __init pcnet32_probe (struct net_device *dev) { unsigned long ioaddr = dev ? dev->base_addr: 0; unsigned int irq_line = dev ? dev->irq : 0; @@ -507,7 +507,7 @@ /* pcnet32_probe1 */ static int __init -pcnet32_probe1(struct device *dev, unsigned long ioaddr, unsigned char irq_line, int shared, int card_idx) +pcnet32_probe1(struct net_device *dev, unsigned long ioaddr, unsigned char irq_line, int shared, int card_idx) { struct pcnet32_private *lp; int i,media,fdx = 0, mii = 0; @@ -699,7 +699,7 @@ static int -pcnet32_open(struct device *dev) +pcnet32_open(struct net_device *dev) { struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; unsigned long ioaddr = dev->base_addr; @@ -807,7 +807,7 @@ */ static void -pcnet32_purge_tx_ring(struct device *dev) +pcnet32_purge_tx_ring(struct net_device *dev) { struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; int i; @@ -823,7 +823,7 @@ /* Initialize the PCNET32 Rx and Tx rings. */ static int -pcnet32_init_ring(struct device *dev) +pcnet32_init_ring(struct net_device *dev) { struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; int i; @@ -861,7 +861,7 @@ } static void -pcnet32_restart(struct device *dev, unsigned int csr0_bits) +pcnet32_restart(struct net_device *dev, unsigned int csr0_bits) { struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; unsigned long ioaddr = dev->base_addr; @@ -882,7 +882,7 @@ } static int -pcnet32_start_xmit(struct sk_buff *skb, struct device *dev) +pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; unsigned int ioaddr = dev->base_addr; @@ -972,7 +972,7 @@ static void pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct pcnet32_private *lp; unsigned long ioaddr; u16 csr0,rap; @@ -1104,7 +1104,7 @@ } static int -pcnet32_rx(struct device *dev) +pcnet32_rx(struct net_device *dev) { struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; int entry = lp->cur_rx & RX_RING_MOD_MASK; @@ -1195,7 +1195,7 @@ } static int -pcnet32_close(struct device *dev) +pcnet32_close(struct net_device *dev) { unsigned long ioaddr = dev->base_addr; struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; @@ -1241,7 +1241,7 @@ } static struct net_device_stats * -pcnet32_get_stats(struct device *dev) +pcnet32_get_stats(struct net_device *dev) { struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; unsigned long ioaddr = dev->base_addr; @@ -1259,7 +1259,7 @@ } /* taken from the sunlance driver, which it took from the depca driver */ -static void pcnet32_load_multicast (struct device *dev) +static void pcnet32_load_multicast (struct net_device *dev) { struct pcnet32_private *lp = (struct pcnet32_private *) dev->priv; volatile struct pcnet32_init_block *ib = &lp->init_block; @@ -1311,7 +1311,7 @@ /* * Set or clear the multicast filter for this adaptor. */ -static void pcnet32_set_multicast_list(struct device *dev) +static void pcnet32_set_multicast_list(struct net_device *dev) { unsigned long ioaddr = dev->base_addr; struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; @@ -1331,7 +1331,7 @@ } #ifdef HAVE_PRIVATE_IOCTL -static int pcnet32_mii_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int pcnet32_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { unsigned long ioaddr = dev->base_addr; struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv; @@ -1387,7 +1387,7 @@ void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ while (pcnet32_dev) { diff -u --recursive --new-file v2.3.13/linux/drivers/net/plip.c linux/drivers/net/plip.c --- v2.3.13/linux/drivers/net/plip.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/plip.c Wed Aug 18 11:36:42 1999 @@ -143,20 +143,20 @@ #define PAR_CONTROL(dev) ((dev)->base_addr+2) /* Bottom halfs */ -static void plip_kick_bh(struct device *dev); -static void plip_bh(struct device *dev); +static void plip_kick_bh(struct net_device *dev); +static void plip_bh(struct net_device *dev); /* Interrupt handler */ static void plip_interrupt(int irq, void *dev_id, struct pt_regs *regs); /* Functions for DEV methods */ static int plip_rebuild_header(struct sk_buff *skb); -static int plip_tx_packet(struct sk_buff *skb, struct device *dev); -static int plip_open(struct device *dev); -static int plip_close(struct device *dev); -static struct net_device_stats *plip_get_stats(struct device *dev); -static int plip_config(struct device *dev, struct ifmap *map); -static int plip_ioctl(struct device *dev, struct ifreq *ifr, int cmd); +static int plip_tx_packet(struct sk_buff *skb, struct net_device *dev); +static int plip_open(struct net_device *dev); +static int plip_close(struct net_device *dev); +static struct net_device_stats *plip_get_stats(struct net_device *dev); +static int plip_config(struct net_device *dev, struct ifmap *map); +static int plip_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); static int plip_preempt(void *handle); static void plip_wakeup(void *handle); @@ -229,12 +229,12 @@ PLIP is rather weird, because of the way it interacts with the parport system. It is _not_ initialised from Space.c. Instead, plip_init() - is called, and that function makes up a "struct device" for each port, and + is called, and that function makes up a "struct net_device" for each port, and then calls us here. */ int __init -plip_init_dev(struct device *dev, struct parport *pb) +plip_init_dev(struct net_device *dev, struct parport *pb) { struct net_local *nl; struct pardevice *pardev; @@ -311,7 +311,7 @@ This routine is kicked by do_timer(). Request `plip_bh' to be invoked. */ static void -plip_kick_bh(struct device *dev) +plip_kick_bh(struct net_device *dev) { struct net_local *nl = (struct net_local *)dev->priv; @@ -322,17 +322,17 @@ } /* Forward declarations of internal routines */ -static int plip_none(struct device *, struct net_local *, +static int plip_none(struct net_device *, struct net_local *, struct plip_local *, struct plip_local *); -static int plip_receive_packet(struct device *, struct net_local *, +static int plip_receive_packet(struct net_device *, struct net_local *, struct plip_local *, struct plip_local *); -static int plip_send_packet(struct device *, struct net_local *, +static int plip_send_packet(struct net_device *, struct net_local *, struct plip_local *, struct plip_local *); -static int plip_connection_close(struct device *, struct net_local *, +static int plip_connection_close(struct net_device *, struct net_local *, struct plip_local *, struct plip_local *); -static int plip_error(struct device *, struct net_local *, +static int plip_error(struct net_device *, struct net_local *, struct plip_local *, struct plip_local *); -static int plip_bh_timeout_error(struct device *dev, struct net_local *nl, +static int plip_bh_timeout_error(struct net_device *dev, struct net_local *nl, struct plip_local *snd, struct plip_local *rcv, int error); @@ -342,7 +342,7 @@ #define ERROR 2 #define HS_TIMEOUT 3 -typedef int (*plip_func)(struct device *dev, struct net_local *nl, +typedef int (*plip_func)(struct net_device *dev, struct net_local *nl, struct plip_local *snd, struct plip_local *rcv); static plip_func connection_state_table[] = @@ -356,7 +356,7 @@ /* Bottom half handler of PLIP. */ static void -plip_bh(struct device *dev) +plip_bh(struct net_device *dev) { struct net_local *nl = (struct net_local *)dev->priv; struct plip_local *snd = &nl->snd_data; @@ -374,7 +374,7 @@ } static int -plip_bh_timeout_error(struct device *dev, struct net_local *nl, +plip_bh_timeout_error(struct net_device *dev, struct net_local *nl, struct plip_local *snd, struct plip_local *rcv, int error) { @@ -450,7 +450,7 @@ } static int -plip_none(struct device *dev, struct net_local *nl, +plip_none(struct net_device *dev, struct net_local *nl, struct plip_local *snd, struct plip_local *rcv) { return OK; @@ -509,7 +509,7 @@ /* PLIP_RECEIVE_PACKET --- receive a packet */ static int -plip_receive_packet(struct device *dev, struct net_local *nl, +plip_receive_packet(struct net_device *dev, struct net_local *nl, struct plip_local *snd, struct plip_local *rcv) { unsigned short status_addr = PAR_STATUS(dev); @@ -675,7 +675,7 @@ /* PLIP_SEND_PACKET --- send a packet */ static int -plip_send_packet(struct device *dev, struct net_local *nl, +plip_send_packet(struct net_device *dev, struct net_local *nl, struct plip_local *snd, struct plip_local *rcv) { unsigned short data_addr = PAR_DATA(dev); @@ -791,7 +791,7 @@ } static int -plip_connection_close(struct device *dev, struct net_local *nl, +plip_connection_close(struct net_device *dev, struct net_local *nl, struct plip_local *snd, struct plip_local *rcv) { spin_lock_irq(&nl->lock); @@ -810,7 +810,7 @@ /* PLIP_ERROR --- wait till other end settled */ static int -plip_error(struct device *dev, struct net_local *nl, +plip_error(struct net_device *dev, struct net_local *nl, struct plip_local *snd, struct plip_local *rcv) { unsigned char status; @@ -838,7 +838,7 @@ static void plip_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *nl; struct plip_local *rcv; unsigned char c0; @@ -897,7 +897,7 @@ static int plip_rebuild_header(struct sk_buff *skb) { - struct device *dev = skb->dev; + struct net_device *dev = skb->dev; struct net_local *nl = (struct net_local *)dev->priv; struct ethhdr *eth = (struct ethhdr *)skb->data; @@ -910,7 +910,7 @@ } static int -plip_tx_packet(struct sk_buff *skb, struct device *dev) +plip_tx_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *nl = (struct net_local *)dev->priv; struct plip_local *snd = &nl->snd_data; @@ -962,7 +962,7 @@ its IRQ line. */ static int -plip_open(struct device *dev) +plip_open(struct net_device *dev) { struct net_local *nl = (struct net_local *)dev->priv; struct in_device *in_dev; @@ -1016,7 +1016,7 @@ /* The inverse routine to plip_open (). */ static int -plip_close(struct device *dev) +plip_close(struct net_device *dev) { struct net_local *nl = (struct net_local *)dev->priv; struct plip_local *snd = &nl->snd_data; @@ -1059,7 +1059,7 @@ static int plip_preempt(void *handle) { - struct device *dev = (struct device *)handle; + struct net_device *dev = (struct net_device *)handle; struct net_local *nl = (struct net_local *)dev->priv; /* Stand our ground if a datagram is on the wire */ @@ -1075,7 +1075,7 @@ static void plip_wakeup(void *handle) { - struct device *dev = (struct device *)handle; + struct net_device *dev = (struct net_device *)handle; struct net_local *nl = (struct net_local *)dev->priv; if (nl->port_owner) { @@ -1102,7 +1102,7 @@ } static struct net_device_stats * -plip_get_stats(struct device *dev) +plip_get_stats(struct net_device *dev) { struct net_local *nl = (struct net_local *)dev->priv; struct net_device_stats *r = &nl->enet_stats; @@ -1111,7 +1111,7 @@ } static int -plip_config(struct device *dev, struct ifmap *map) +plip_config(struct net_device *dev, struct ifmap *map) { struct net_local *nl = (struct net_local *) dev->priv; struct pardevice *pardev = nl->pardev; @@ -1132,7 +1132,7 @@ } static int -plip_ioctl(struct device *dev, struct ifreq *rq, int cmd) +plip_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct net_local *nl = (struct net_local *) dev->priv; struct plipconf *pc = (struct plipconf *) &rq->ifr_data; @@ -1158,7 +1158,7 @@ MODULE_PARM(parport, "1-" __MODULE_STRING(PLIP_MAX) "i"); MODULE_PARM(timid, "1i"); -static struct device *dev_plip[PLIP_MAX] = { NULL, }; +static struct net_device *dev_plip[PLIP_MAX] = { NULL, }; #ifdef MODULE void @@ -1245,13 +1245,13 @@ printk(KERN_ERR "plip: too many devices\n"); break; } - dev_plip[i] = kmalloc(sizeof(struct device), + dev_plip[i] = kmalloc(sizeof(struct net_device), GFP_KERNEL); if (!dev_plip[i]) { printk(KERN_ERR "plip: memory squeeze\n"); break; } - memset(dev_plip[i], 0, sizeof(struct device)); + memset(dev_plip[i], 0, sizeof(struct net_device)); dev_plip[i]->name = kmalloc(strlen("plipXXX"), GFP_KERNEL); if (!dev_plip[i]->name) { diff -u --recursive --new-file v2.3.13/linux/drivers/net/ppp.c linux/drivers/net/ppp.c --- v2.3.13/linux/drivers/net/ppp.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/ppp.c Wed Aug 18 11:36:42 1999 @@ -299,7 +299,7 @@ * Called at boot time if the PPP driver is compiled into the kernel. */ int -ppp_init(struct device *dev) +ppp_init(struct net_device *dev) { static int first_time = 1; int answer = 0; @@ -1450,12 +1450,12 @@ * Network device driver callback routines */ -static int ppp_init_dev(struct device *dev); -static int ppp_dev_open(struct device *); -static int ppp_dev_ioctl(struct device *dev, struct ifreq *ifr, int cmd); -static int ppp_dev_close(struct device *); -static int ppp_dev_xmit(struct sk_buff *, struct device *); -static struct net_device_stats *ppp_dev_stats (struct device *); +static int ppp_init_dev(struct net_device *dev); +static int ppp_dev_open(struct net_device *); +static int ppp_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static int ppp_dev_close(struct net_device *); +static int ppp_dev_xmit(struct sk_buff *, struct net_device *); +static struct net_device_stats *ppp_dev_stats (struct net_device *); /* * Information for the protocol decoder @@ -1493,7 +1493,7 @@ * Called when the PPP network interface device is actually created. */ static int -ppp_init_dev (struct device *dev) +ppp_init_dev (struct net_device *dev) { dev->hard_header_len = PPP_HDRLEN; @@ -1520,7 +1520,7 @@ */ static int -ppp_dev_open (struct device *dev) +ppp_dev_open (struct net_device *dev) { struct ppp *ppp = dev2ppp(dev); @@ -1539,7 +1539,7 @@ */ static int -ppp_dev_close (struct device *dev) +ppp_dev_close (struct net_device *dev) { struct ppp *ppp = dev2ppp (dev); @@ -1567,7 +1567,7 @@ * Callback from the network layer to process the sockioctl functions. */ static int -ppp_dev_ioctl (struct device *dev, struct ifreq *ifr, int cmd) +ppp_dev_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) { struct ppp *ppp = dev2ppp(dev); int nb; @@ -2611,7 +2611,7 @@ * Returns 1 iff the frame was not accepted. */ static int -ppp_dev_xmit(struct sk_buff *skb, struct device *dev) +ppp_dev_xmit(struct sk_buff *skb, struct net_device *dev) { struct ppp *ppp = dev2ppp(dev); struct tty_struct *tty = ppp2tty(ppp); @@ -2758,7 +2758,7 @@ * Generate the statistic information for the /proc/net/dev listing. */ static struct net_device_stats * -ppp_dev_stats (struct device *dev) +ppp_dev_stats (struct net_device *dev) { struct ppp *ppp = dev2ppp (dev); @@ -2799,7 +2799,7 @@ { int if_num; int status; - struct device *dev; + struct net_device *dev; struct ppp *ppp; /* try to find an free device */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/ppp_generic.c linux/drivers/net/ppp_generic.c --- v2.3.13/linux/drivers/net/ppp_generic.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/ppp_generic.c Wed Aug 18 11:36:42 1999 @@ -94,7 +94,7 @@ void *rc_state; /* its internal state */ unsigned long last_xmit; /* jiffies when last pkt sent */ unsigned long last_recv; /* jiffies when last pkt rcvd */ - struct device dev; /* network interface device */ + struct net_device dev; /* network interface device */ struct net_device_stats stats; /* statistics */ }; @@ -575,7 +575,7 @@ /* Called at boot time if ppp is compiled into the kernel, or at module load time (from init_module) if compiled as a module. */ int -ppp_init(struct device *dev) +ppp_init(struct net_device *dev) { int err; #ifndef MODULE @@ -605,7 +605,7 @@ * Network interface unit routines. */ static int -ppp_start_xmit(struct sk_buff *skb, struct device *dev) +ppp_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ppp *ppp = (struct ppp *) dev->priv; int npi, proto; @@ -678,7 +678,7 @@ } static struct net_device_stats * -ppp_net_stats(struct device *dev) +ppp_net_stats(struct net_device *dev) { struct ppp *ppp = (struct ppp *) dev->priv; @@ -686,7 +686,7 @@ } static int -ppp_net_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +ppp_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct ppp *ppp = dev->priv; int err = -EFAULT; @@ -729,7 +729,7 @@ } int -ppp_net_init(struct device *dev) +ppp_net_init(struct net_device *dev) { dev->hard_header_len = PPP_HDRLEN; dev->mtu = PPP_MTU; diff -u --recursive --new-file v2.3.13/linux/drivers/net/ptifddi.c linux/drivers/net/ptifddi.c --- v2.3.13/linux/drivers/net/ptifddi.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/ptifddi.c Wed Aug 18 11:36:42 1999 @@ -108,48 +108,48 @@ { } -static inline void pti_tx(struct ptifddi *pp, struct device *dev) +static inline void pti_tx(struct ptifddi *pp, struct net_device *dev) { } -static inline void myri_rx(struct ptifddi *pp, struct device *dev) +static inline void myri_rx(struct ptifddi *pp, struct net_device *dev) { } static void pti_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct ptifddi *pp = (struct ptifddi *) dev->priv; } -static int pti_open(struct device *dev) +static int pti_open(struct net_device *dev) { struct ptifddi *pp = (struct ptifddi *) dev->priv; return pti_init(pp, in_interrupt()); } -static int pti_close(struct device *dev) +static int pti_close(struct net_device *dev) { struct ptifddi *pp = (struct ptifddi *) dev->priv; return 0; } -static int pti_start_xmit(struct sk_buff *skb, struct device *dev) +static int pti_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ptifddi *pp = (struct ptifddi *) dev->priv; } -static struct enet_statistics *pti_get_stats(struct device *dev) +static struct enet_statistics *pti_get_stats(struct net_device *dev) { return &(((struct ptifddi *)dev->priv)->enet_stats); } -static void pti_set_multicast(struct device *dev) +static void pti_set_multicast(struct net_device *dev) { } -static inline int pti_fddi_init(struct device *dev, struct linux_sbus_device *sdev, int num) +static inline int pti_fddi_init(struct net_device *dev, struct linux_sbus_device *sdev, int num) { static unsigned version_printed = 0; struct ptifddi *pp; @@ -213,7 +213,7 @@ pti_load_main_firmware(pp); } -int __init ptifddi_sbus_probe(struct device *dev) +int __init ptifddi_sbus_probe(struct net_device *dev) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff -u --recursive --new-file v2.3.13/linux/drivers/net/ptifddi.h linux/drivers/net/ptifddi.h --- v2.3.13/linux/drivers/net/ptifddi.h Sat Nov 29 10:33:20 1997 +++ linux/drivers/net/ptifddi.h Wed Aug 18 11:36:45 1999 @@ -70,7 +70,7 @@ struct dfddi_ram *dpram; unsigned char *reset; unsigned char *unreset; - struct device *dev; + struct net_device *dev; struct ptifddi *next_module; }; diff -u --recursive --new-file v2.3.13/linux/drivers/net/rcpci45.c linux/drivers/net/rcpci45.c --- v2.3.13/linux/drivers/net/rcpci45.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/rcpci45.c Wed Aug 18 11:36:42 1999 @@ -127,7 +127,7 @@ * pointer to the device structure which is part * of the interface to the Linux kernel. */ - struct device *dev; + struct net_device *dev; char devname[8]; /* "ethN" string */ U8 id; /* the AdapterID */ @@ -136,7 +136,7 @@ U32 function; struct timer_list timer; /* timer */ struct enet_statistics stats; /* the statistics structure */ - struct device *next; /* points to the next RC adapter */ + struct net_device *next; /* points to the next RC adapter */ unsigned long numOutRcvBuffers;/* number of outstanding receive buffers*/ unsigned char shutdown; unsigned char reboot; @@ -157,31 +157,31 @@ }; -static int RCinit(struct device *dev); -static int RCscan(struct device *dev); -static int RCfound_device(struct device *, int, int, int, int, int, int); +static int RCinit(struct net_device *dev); +static int RCscan(struct net_device *dev); +static int RCfound_device(struct net_device *, int, int, int, int, int, int); -static int RCopen(struct device *); -static int RC_xmit_packet(struct sk_buff *, struct device *); +static int RCopen(struct net_device *); +static int RC_xmit_packet(struct sk_buff *, struct net_device *); static void RCinterrupt(int, void *, struct pt_regs *); -static int RCclose(struct device *dev); -static struct enet_statistics *RCget_stats(struct device *); -static int RCioctl(struct device *, struct ifreq *, int); -static int RCconfig(struct device *, struct ifmap *); +static int RCclose(struct net_device *dev); +static struct enet_statistics *RCget_stats(struct net_device *); +static int RCioctl(struct net_device *, struct ifreq *, int); +static int RCconfig(struct net_device *, struct ifmap *); static void RCxmit_callback(U32, U16, PU32, U16); static void RCrecv_callback(U32, U8, U32, PU32, U16); static void RCreset_callback(U32, U32, U32, U16); static void RCreboot_callback(U32, U32, U32, U16); -static int RC_allocate_and_post_buffers(struct device *, int); +static int RC_allocate_and_post_buffers(struct net_device *, int); /* A list of all installed RC devices, for removing the driver module. */ -static struct device *root_RCdev = NULL; +static struct net_device *root_RCdev = NULL; #ifdef MODULE int init_module(void) #else -int rcpci_probe(struct device *dev) +int rcpci_probe(struct net_device *dev) #endif { int cards_found; @@ -196,7 +196,7 @@ return cards_found ? 0 : -ENODEV; } -static int RCscan(struct device *dev) +static int RCscan(struct net_device *dev) { int cards_found = 0; static int pci_index = 0; @@ -251,7 +251,7 @@ return cards_found; } -static int RCinit(struct device *dev) +static int RCinit(struct net_device *dev) { dev->open = &RCopen; dev->hard_start_xmit = &RC_xmit_packet; @@ -263,7 +263,7 @@ } static int -RCfound_device(struct device *dev, int memaddr, int irq, +RCfound_device(struct net_device *dev, int memaddr, int irq, int bus, int function, int product_index, int card_idx) { int dev_size = 32768; @@ -273,15 +273,15 @@ /* * Allocate and fill new device structure. - * We need enough for struct device plus DPA plus the LAN API private + * We need enough for struct net_device plus DPA plus the LAN API private * area, which requires a minimum of 16KB. The top of the allocated - * area will be assigned to struct device; the next chunk will be + * area will be assigned to struct net_device; the next chunk will be * assigned to DPA; and finally, the rest will be assigned to the * the LAN API layer. */ #ifdef MODULE - dev = (struct device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC); + dev = (struct net_device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC); if (!dev) { printk("rc: unable to kmalloc dev\n"); @@ -291,10 +291,10 @@ /* * dev->priv will point to the start of DPA. */ - dev->priv = (void *)(((long)dev + sizeof(struct device) + 15) & ~15); + dev->priv = (void *)(((long)dev + sizeof(struct net_device) + 15) & ~15); #else dev->priv = 0; - dev->priv = (struct device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC); + dev->priv = (struct net_device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC); if (!dev->priv) { printk("rc: unable to kmalloc private area\n"); @@ -405,7 +405,7 @@ } static int -RCopen(struct device *dev) +RCopen(struct net_device *dev) { int post_buffers = MAX_NMBR_RCV_BUFFERS; PDPA pDpa = (PDPA) dev->priv; @@ -470,7 +470,7 @@ } static int -RC_xmit_packet(struct sk_buff *skb, struct device *dev) +RC_xmit_packet(struct sk_buff *skb, struct net_device *dev) { PDPA pDpa = (PDPA) dev->priv; @@ -551,7 +551,7 @@ { struct sk_buff *skb; PDPA pDpa; - struct device *dev; + struct net_device *dev; pDpa = PCIAdapters[AdapterID]; if (!pDpa) @@ -596,7 +596,7 @@ RCreset_callback(U32 Status, U32 p1, U32 p2, U16 AdapterID) { PDPA pDpa; - struct device *dev; + struct net_device *dev; pDpa = PCIAdapters[AdapterID]; dev = pDpa->dev; @@ -696,7 +696,7 @@ U32 len, count; PDPA pDpa; struct sk_buff *skb; - struct device *dev; + struct net_device *dev; singleTCB tcb; psingleTCB ptcb = &tcb; @@ -852,7 +852,7 @@ { PDPA pDpa; - struct device *dev = (struct device *)(dev_id); + struct net_device *dev = (struct net_device *)(dev_id); pDpa = (PDPA) (dev->priv); @@ -878,7 +878,7 @@ #define REBOOT_REINIT_RETRY_LIMIT 4 static void rc_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; PDPA pDpa = (PDPA) (dev->priv); int init_status; static int retry = 0; @@ -961,7 +961,7 @@ } static int -RCclose(struct device *dev) +RCclose(struct net_device *dev) { PDPA pDpa = (PDPA) dev->priv; @@ -1000,7 +1000,7 @@ } static struct enet_statistics * -RCget_stats(struct device *dev) +RCget_stats(struct net_device *dev) { RCLINKSTATS RCstats; @@ -1087,7 +1087,7 @@ return 0; } -static int RCioctl(struct device *dev, struct ifreq *rq, int cmd) +static int RCioctl(struct net_device *dev, struct ifreq *rq, int cmd) { RCuser_struct RCuser; PDPA pDpa = dev->priv; @@ -1244,7 +1244,7 @@ return 0; } -static int RCconfig(struct device *dev, struct ifmap *map) +static int RCconfig(struct net_device *dev, struct ifmap *map) { /* * To be completed ... @@ -1268,7 +1268,7 @@ cleanup_module(void) { PDPA pDpa; - struct device *next; + struct net_device *next; #ifdef RCDEBUG @@ -1297,7 +1297,7 @@ static int -RC_allocate_and_post_buffers(struct device *dev, int numBuffers) +RC_allocate_and_post_buffers(struct net_device *dev, int numBuffers) { int i; diff -u --recursive --new-file v2.3.13/linux/drivers/net/rrunner.c linux/drivers/net/rrunner.c --- v2.3.13/linux/drivers/net/rrunner.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/rrunner.c Wed Aug 18 11:36:42 1999 @@ -72,7 +72,7 @@ static int probed __initdata = 0; -int __init rr_hippi_probe (struct device *dev) +int __init rr_hippi_probe (struct net_device *dev) { int boards_found = 0; int version_disp; /* was version info already displayed? */ @@ -202,7 +202,7 @@ #endif } -static struct device *root_dev = NULL; +static struct net_device *root_dev = NULL; #ifdef MODULE #if LINUX_VERSION_CODE > 0x20118 @@ -224,7 +224,7 @@ void cleanup_module(void) { struct rr_private *rr; - struct device *next; + struct net_device *next; while (root_dev) { next = ((struct rr_private *)root_dev->priv)->next; @@ -286,7 +286,7 @@ * Reset the board in a sensible manner. The NIC is already halted * when we get here and a spin-lock is held. */ -static int rr_reset(struct device *dev) +static int rr_reset(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs *regs; @@ -502,7 +502,7 @@ } -static int __init rr_init(struct device *dev) +static int __init rr_init(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs *regs; @@ -552,7 +552,7 @@ } -static int rr_init1(struct device *dev) +static int rr_init1(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs *regs; @@ -703,7 +703,7 @@ * events) and are handled here, outside the main interrupt handler, * to reduce the size of the handler. */ -static u32 rr_handle_event(struct device *dev, u32 prodidx, u32 eidx) +static u32 rr_handle_event(struct net_device *dev, u32 prodidx, u32 eidx) { struct rr_private *rrpriv; struct rr_regs *regs; @@ -795,7 +795,7 @@ } -static void rx_int(struct device *dev, u32 rxlimit, u32 index) +static void rx_int(struct net_device *dev, u32 rxlimit, u32 index) { struct rr_private *rrpriv = (struct rr_private *)dev->priv; u32 pkt_len; @@ -866,7 +866,7 @@ { struct rr_private *rrpriv; struct rr_regs *regs; - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; u32 prodidx, rxindex, eidx, txcsmr, rxlimit, txcon; unsigned long flags; @@ -930,7 +930,7 @@ } -static int rr_open(struct device *dev) +static int rr_open(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs *regs; @@ -995,7 +995,7 @@ } -static void rr_dump(struct device *dev) +static void rr_dump(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs *regs; @@ -1059,7 +1059,7 @@ } -static int rr_close(struct device *dev) +static int rr_close(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs *regs; @@ -1131,7 +1131,7 @@ } -static int rr_start_xmit(struct sk_buff *skb, struct device *dev) +static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct rr_private *rrpriv = (struct rr_private *)dev->priv; struct rr_regs *regs = rrpriv->regs; @@ -1197,7 +1197,7 @@ } -static struct net_device_stats *rr_get_stats(struct device *dev) +static struct net_device_stats *rr_get_stats(struct net_device *dev) { struct rr_private *rrpriv; @@ -1214,7 +1214,7 @@ * This operation requires the NIC to be halted and is performed with * interrupts disabled and with the spinlock hold. */ -static int rr_load_firmware(struct device *dev) +static int rr_load_firmware(struct net_device *dev) { struct rr_private *rrpriv; struct rr_regs *regs; @@ -1319,7 +1319,7 @@ } -static int rr_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct rr_private *rrpriv; unsigned char *image, *oldimage; diff -u --recursive --new-file v2.3.13/linux/drivers/net/rrunner.h linux/drivers/net/rrunner.h --- v2.3.13/linux/drivers/net/rrunner.h Sat Apr 24 17:51:48 1999 +++ linux/drivers/net/rrunner.h Wed Aug 18 11:36:45 1999 @@ -805,7 +805,7 @@ struct rr_regs *regs; /* Register base */ struct ring_ctrl *rx_ctrl; /* Receive ring control */ struct rr_info *info; /* Shared info page */ - struct device *next; + struct net_device *next; spinlock_t lock; struct timer_list timer; u32 cur_rx, cur_cmd, cur_evt; @@ -821,20 +821,20 @@ /* * Prototypes */ -static int rr_init(struct device *dev); -static int rr_init1(struct device *dev); +static int rr_init(struct net_device *dev); +static int rr_init1(struct net_device *dev); static void rr_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int rr_open(struct device *dev); -static int rr_start_xmit(struct sk_buff *skb, struct device *dev); -static int rr_close(struct device *dev); -static struct net_device_stats *rr_get_stats(struct device *dev); -static int rr_ioctl(struct device *dev, struct ifreq *rq, int cmd); +static int rr_open(struct net_device *dev); +static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int rr_close(struct net_device *dev); +static struct net_device_stats *rr_get_stats(struct net_device *dev); +static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static unsigned int rr_read_eeprom(struct rr_private *rrpriv, unsigned long offset, unsigned char *buf, unsigned long length); static u32 rr_read_eeprom_word(struct rr_private *rrpriv, void * offset); -static int rr_load_firmware(struct device *dev); +static int rr_load_firmware(struct net_device *dev); #endif /* _RRUNNER_H_ */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/rtl8139.c linux/drivers/net/rtl8139.c --- v2.3.13/linux/drivers/net/rtl8139.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/rtl8139.c Wed Aug 18 11:36:42 1999 @@ -165,12 +165,12 @@ const char *name; u16 vendor_id, device_id, device_id_mask, flags; int io_size; - struct device *(*probe1)(int pci_bus, int pci_devfn, struct device *dev, + struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, long ioaddr, int irq, int chip_idx, int fnd_cnt); }; -static struct device * rtl8129_probe1(int pci_bus, int pci_devfn, - struct device *dev, long ioaddr, +static struct net_device * rtl8129_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, int irq, int chp_idx, int fnd_cnt); static struct pci_id_info pci_tbl[] = @@ -254,7 +254,7 @@ struct rtl8129_private { char devname[8]; /* Used only for kernel debugging. */ const char *product_name; - struct device *next_module; + struct net_device *next_module; int chip_id; int chip_revision; unsigned char pci_bus, pci_devfn; @@ -294,32 +294,32 @@ #endif #endif -static int rtl8129_open(struct device *dev); +static int rtl8129_open(struct net_device *dev); static int read_eeprom(long ioaddr, int location); -static int mdio_read(struct device *dev, int phy_id, int location); -static void mdio_write(struct device *dev, int phy_id, int location, int val); +static int mdio_read(struct net_device *dev, int phy_id, int location); +static void mdio_write(struct net_device *dev, int phy_id, int location, int val); static void rtl8129_timer(unsigned long data); -static void rtl8129_tx_timeout(struct device *dev); -static void rtl8129_init_ring(struct device *dev); -static int rtl8129_start_xmit(struct sk_buff *skb, struct device *dev); -static int rtl8129_rx(struct device *dev); +static void rtl8129_tx_timeout(struct net_device *dev); +static void rtl8129_init_ring(struct net_device *dev); +static int rtl8129_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int rtl8129_rx(struct net_device *dev); static void rtl8129_interrupt(int irq, void *dev_instance, struct pt_regs *regs); -static int rtl8129_close(struct device *dev); -static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd); -static struct enet_statistics *rtl8129_get_stats(struct device *dev); +static int rtl8129_close(struct net_device *dev); +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct enet_statistics *rtl8129_get_stats(struct net_device *dev); static inline u32 ether_crc(int length, unsigned char *data); -static void set_rx_mode(struct device *dev); +static void set_rx_mode(struct net_device *dev); /* A list of all installed RTL8129 devices, for removing the driver module. */ -static struct device *root_rtl8129_dev = NULL; +static struct net_device *root_rtl8129_dev = NULL; /* Ideally we would detect all network cards in slot order. That would be best done a central PCI probe dispatch, which wouldn't work well when dynamically adding drivers. So instead we detect just the Rtl81*9 cards in slot order. */ -int rtl8139_probe(struct device *dev) +int rtl8139_probe(struct net_device *dev) { int cards_found = 0; int pci_index = 0; @@ -405,8 +405,8 @@ return cards_found ? 0 : -ENODEV; } -static struct device *rtl8129_probe1(int pci_bus, int pci_devfn, - struct device *dev, long ioaddr, +static struct net_device *rtl8129_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, int irq, int chip_idx, int found_cnt) { static int did_version = 0; /* Already printed version info. */ @@ -596,7 +596,7 @@ } return; } -static int mdio_read(struct device *dev, int phy_id, int location) +static int mdio_read(struct net_device *dev, int phy_id, int location) { long mdio_addr = dev->base_addr + MII_SMI; int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location; @@ -629,7 +629,7 @@ return (retval>>1) & 0xffff; } -static void mdio_write(struct device *dev, int phy_id, int location, int value) +static void mdio_write(struct net_device *dev, int phy_id, int location, int value) { long mdio_addr = dev->base_addr + MII_SMI; int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value; @@ -662,7 +662,7 @@ static int -rtl8129_open(struct device *dev) +rtl8129_open(struct net_device *dev) { struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; long ioaddr = dev->base_addr; @@ -760,7 +760,7 @@ static void rtl8129_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; long ioaddr = dev->base_addr; int next_tick = 60*HZ; @@ -856,7 +856,7 @@ add_timer(&tp->timer); } -static void rtl8129_tx_timeout(struct device *dev) +static void rtl8129_tx_timeout(struct net_device *dev) { struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; long ioaddr = dev->base_addr; @@ -939,7 +939,7 @@ /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ static void -rtl8129_init_ring(struct device *dev) +rtl8129_init_ring(struct net_device *dev) { struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; int i; @@ -955,7 +955,7 @@ } static int -rtl8129_start_xmit(struct sk_buff *skb, struct device *dev) +rtl8129_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1000,7 +1000,7 @@ after the Tx thread. */ static void rtl8129_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_instance; + struct net_device *dev = (struct net_device *)dev_instance; struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; int boguscnt = max_interrupt_work; int status, link_changed = 0; @@ -1173,7 +1173,7 @@ /* The data sheet doesn't describe the Rx ring at all, so I'm guessing at the field alignments and semantics. */ -static int rtl8129_rx(struct device *dev) +static int rtl8129_rx(struct net_device *dev) { struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1283,7 +1283,7 @@ } static int -rtl8129_close(struct device *dev) +rtl8129_close(struct net_device *dev) { long ioaddr = dev->base_addr; struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; @@ -1328,7 +1328,7 @@ return 0; } -static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; u16 *data = (u16 *)&rq->ifr_data; @@ -1351,7 +1351,7 @@ } static struct enet_statistics * -rtl8129_get_stats(struct device *dev) +rtl8129_get_stats(struct net_device *dev) { struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1388,7 +1388,7 @@ AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01, }; -static void set_rx_mode(struct device *dev) +static void set_rx_mode(struct net_device *dev) { long ioaddr = dev->base_addr; u32 mc_filter[2]; /* Multicast hash filter */ @@ -1433,7 +1433,7 @@ void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ while (root_rtl8129_dev) { diff -u --recursive --new-file v2.3.13/linux/drivers/net/sdla.c linux/drivers/net/sdla.c --- v2.3.13/linux/drivers/net/sdla.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/sdla.c Wed Aug 18 11:36:42 1999 @@ -83,7 +83,7 @@ #define SDLA_WINDOW(dev,addr) outb((((addr) >> 13) & 0x1F), (dev)->base_addr + SDLA_REG_Z80_WINDOW) -static void sdla_read(struct device *dev, int addr, void *buf, short len) +static void sdla_read(struct net_device *dev, int addr, void *buf, short len) { unsigned long flags; char *temp, *base; @@ -108,7 +108,7 @@ } } -static void sdla_write(struct device *dev, int addr, void *buf, short len) +static void sdla_write(struct net_device *dev, int addr, void *buf, short len) { unsigned long flags; char *temp, *base; @@ -131,7 +131,7 @@ } } -static void sdla_clear(struct device *dev) +static void sdla_clear(struct net_device *dev) { unsigned long flags; char *base; @@ -155,7 +155,7 @@ restore_flags(flags); } -static char sdla_byte(struct device *dev, int addr) +static char sdla_byte(struct net_device *dev, int addr) { unsigned long flags; char byte, *temp; @@ -171,7 +171,7 @@ return(byte); } -void sdla_stop(struct device *dev) +void sdla_stop(struct net_device *dev) { struct frad_local *flp; @@ -198,7 +198,7 @@ } } -void sdla_start(struct device *dev) +void sdla_start(struct net_device *dev) { struct frad_local *flp; @@ -236,7 +236,7 @@ * ***************************************************/ -int sdla_z80_poll(struct device *dev, int z80_addr, int jiffs, char resp1, char resp2) +int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2) { unsigned long start, done, now; char resp, *temp; @@ -266,7 +266,7 @@ #define Z80_SCC_OK '3' /* SCC is on board */ #define Z80_SCC_BAD '4' /* SCC was not found */ -static int sdla_cpuspeed(struct device *dev, struct ifreq *ifr) +static int sdla_cpuspeed(struct net_device *dev, struct ifreq *ifr) { int jiffs; char data; @@ -328,7 +328,7 @@ struct _dlci_stat dlcis[SDLA_MAX_DLCI]; }; -static void sdla_errors(struct device *dev, int cmd, int dlci, int ret, int len, void *data) +static void sdla_errors(struct net_device *dev, int cmd, int dlci, int ret, int len, void *data) { struct _dlci_stat *pstatus; short *pdlci; @@ -411,7 +411,7 @@ } } -static int sdla_cmd(struct device *dev, int cmd, short dlci, short flags, +static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags, void *inbuf, short inlen, void *outbuf, short *outlen) { static struct _frad_stat status; @@ -492,9 +492,9 @@ * ***********************************************/ -static int sdla_reconfig(struct device *dev); +static int sdla_reconfig(struct net_device *dev); -int sdla_activate(struct device *slave, struct device *master) +int sdla_activate(struct net_device *slave, struct net_device *master) { struct frad_local *flp; int i; @@ -516,7 +516,7 @@ return(0); } -int sdla_deactivate(struct device *slave, struct device *master) +int sdla_deactivate(struct net_device *slave, struct net_device *master) { struct frad_local *flp; int i; @@ -538,7 +538,7 @@ return(0); } -int sdla_assoc(struct device *slave, struct device *master) +int sdla_assoc(struct net_device *slave, struct net_device *master) { struct frad_local *flp; int i; @@ -575,7 +575,7 @@ return(0); } -int sdla_deassoc(struct device *slave, struct device *master) +int sdla_deassoc(struct net_device *slave, struct net_device *master) { struct frad_local *flp; int i; @@ -604,7 +604,7 @@ return(0); } -int sdla_dlci_conf(struct device *slave, struct device *master, int get) +int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get) { struct frad_local *flp; struct dlci_local *dlp; @@ -643,7 +643,7 @@ **************************/ /* NOTE: the DLCI driver deals with freeing the SKB!! */ -static int sdla_transmit(struct sk_buff *skb, struct device *dev) +static int sdla_transmit(struct sk_buff *skb, struct net_device *dev) { struct frad_local *flp; int ret, addr, accept; @@ -742,9 +742,9 @@ return(ret); } -static void sdla_receive(struct device *dev) +static void sdla_receive(struct net_device *dev) { - struct device *master; + struct net_device *master; struct frad_local *flp; struct dlci_local *dlp; struct sk_buff *skb; @@ -872,7 +872,7 @@ static void sdla_isr(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev; + struct net_device *dev; struct frad_local *flp; char byte; @@ -930,10 +930,10 @@ static void sdla_poll(unsigned long device) { - struct device *dev; + struct net_device *dev; struct frad_local *flp; - dev = (struct device *) device; + dev = (struct net_device *) device; flp = dev->priv; if (sdla_byte(dev, SDLA_502_RCV_BUF)) @@ -943,7 +943,7 @@ add_timer(&flp->timer); } -static int sdla_close(struct device *dev) +static int sdla_close(struct net_device *dev) { struct frad_local *flp; struct intr_info intr; @@ -1005,7 +1005,7 @@ short dlci[CONFIG_DLCI_MAX]; }; -static int sdla_open(struct device *dev) +static int sdla_open(struct net_device *dev) { struct frad_local *flp; struct dlci_local *dlp; @@ -1105,7 +1105,7 @@ return(0); } -static int sdla_config(struct device *dev, struct frad_conf *conf, int get) +static int sdla_config(struct net_device *dev, struct frad_conf *conf, int get) { struct frad_local *flp; struct conf_data data; @@ -1203,7 +1203,7 @@ return(0); } -static int sdla_xfer(struct device *dev, struct sdla_mem *info, int read) +static int sdla_xfer(struct net_device *dev, struct sdla_mem *info, int read) { struct sdla_mem mem; char *temp; @@ -1234,7 +1234,7 @@ return(0); } -static int sdla_reconfig(struct device *dev) +static int sdla_reconfig(struct net_device *dev) { struct frad_local *flp; struct conf_data data; @@ -1258,7 +1258,7 @@ return(0); } -static int sdla_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int sdla_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct frad_local *flp; @@ -1325,7 +1325,7 @@ return(0); } -int sdla_change_mtu(struct device *dev, int new_mtu) +int sdla_change_mtu(struct net_device *dev, int new_mtu) { struct frad_local *flp; @@ -1338,7 +1338,7 @@ return(-EOPNOTSUPP); } -int sdla_set_config(struct device *dev, struct ifmap *map) +int sdla_set_config(struct net_device *dev, struct ifmap *map) { struct frad_local *flp; int i; @@ -1616,7 +1616,7 @@ return(0); } -static struct net_device_stats *sdla_stats(struct device *dev) +static struct net_device_stats *sdla_stats(struct net_device *dev) { struct frad_local *flp; flp = dev->priv; @@ -1624,7 +1624,7 @@ return(&flp->stats); } -int __init sdla_init(struct device *dev) +int __init sdla_init(struct net_device *dev) { struct frad_local *flp; @@ -1673,7 +1673,7 @@ } #ifdef MODULE -static struct device sdla0 = {"sdla0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, sdla_init}; +static struct net_device sdla0 = {"sdla0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, sdla_init}; int init_module(void) { diff -u --recursive --new-file v2.3.13/linux/drivers/net/sdla_fr.c linux/drivers/net/sdla_fr.c --- v2.3.13/linux/drivers/net/sdla_fr.c Mon Jan 4 11:37:29 1999 +++ linux/drivers/net/sdla_fr.c Wed Aug 18 11:36:42 1999 @@ -136,7 +136,7 @@ /****** Data Structures *****************************************************/ -/* This is an extention of the 'struct device' we create for each network +/* This is an extention of the 'struct net_device' we create for each network * interface to keep the rest of channel-specific data. */ typedef struct fr_channel { @@ -239,20 +239,20 @@ /* WAN link driver entry points. These are called by the WAN router module. */ static int update(wan_device_t * wandev); -static int new_if(wan_device_t * wandev, struct device *dev, +static int new_if(wan_device_t * wandev, struct net_device *dev, wanif_conf_t * conf); -static int del_if(wan_device_t * wandev, struct device *dev); +static int del_if(wan_device_t * wandev, struct net_device *dev); /* WANPIPE-specific entry points */ static int wpf_exec(struct sdla *card, void *u_cmd, void *u_data); /* Network device interface */ -static int if_init(struct device *dev); -static int if_open(struct device *dev); -static int if_close(struct device *dev); -static int if_header(struct sk_buff *skb, struct device *dev, +static int if_init(struct net_device *dev); +static int if_open(struct net_device *dev); +static int if_close(struct net_device *dev); +static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); static int if_rebuild_hdr(struct sk_buff *skb); -static int if_send(struct sk_buff *skb, struct device *dev); -static struct net_device_stats *if_stats(struct device *dev); +static int if_send(struct sk_buff *skb, struct net_device *dev); +static struct net_device_stats *if_stats(struct net_device *dev); /* Interrupt handlers */ static void fr502_isr(sdla_t * card); static void fr508_isr(sdla_t * card); @@ -281,9 +281,9 @@ static int fr_modem_failure(sdla_t * card, fr_mbox_t * mbox); static int fr_dlci_change(sdla_t * card, fr_mbox_t * mbox); /* Miscellaneous functions */ -static int update_chan_state(struct device *dev); -static void set_chan_state(struct device *dev, int state); -static struct device *find_channel(sdla_t * card, unsigned dlci); +static int update_chan_state(struct net_device *dev); +static void set_chan_state(struct net_device *dev, int state); +static struct net_device *find_channel(sdla_t * card, unsigned dlci); static int is_tx_ready(sdla_t * card, fr_channel_t * chan); static unsigned int dec_to_uint(unsigned char *str, int len); static int reply_udp(unsigned char *data, unsigned int mbox_len); @@ -292,8 +292,8 @@ static void init_global_statistics(sdla_t * card); static void read_DLCI_IB_mapping(sdla_t * card, fr_channel_t * chan); /* Udp management functions */ -static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct device *dev, int dlci, fr_channel_t * chan); -static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct device *dev, int dlci, fr_channel_t * chan); +static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, int dlci, fr_channel_t * chan); +static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, int dlci, fr_channel_t * chan); static int udp_pkt_type(struct sk_buff *skb, sdla_t * card); /* IPX functions */ static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming); @@ -499,7 +499,7 @@ * < 0 failure (channel will not be created) */ -static int new_if(wan_device_t * wandev, struct device *dev, wanif_conf_t * conf) +static int new_if(wan_device_t * wandev, struct net_device *dev, wanif_conf_t * conf) { sdla_t *card = wandev->private; fr_channel_t *chan; @@ -570,7 +570,7 @@ /*============================================================================ * Delete logical channel. */ -static int del_if(wan_device_t * wandev, struct device *dev) +static int del_if(wan_device_t * wandev, struct net_device *dev) { if (dev->priv) { @@ -627,7 +627,7 @@ * interface registration. Returning anything but zero will fail interface * registration. */ -static int if_init(struct device *dev) +static int if_init(struct net_device *dev) { fr_channel_t *chan = dev->priv; sdla_t *card = chan->card; @@ -668,11 +668,11 @@ * Return 0 if O.k. or errno. */ -static int if_open(struct device *dev) +static int if_open(struct net_device *dev) { fr_channel_t *chan = dev->priv; sdla_t *card = chan->card; - struct device *dev2; + struct net_device *dev2; int err = 0; fr508_flags_t *flags = card->flags; struct timeval tv; @@ -797,7 +797,7 @@ * o reset flags. */ -static int if_close(struct device *dev) +static int if_close(struct net_device *dev) { fr_channel_t *chan = dev->priv; sdla_t *card = chan->card; @@ -826,7 +826,7 @@ * Return: media header length. */ -static int if_header(struct sk_buff *skb, struct device *dev, +static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { int hdr_len = 0; @@ -852,7 +852,7 @@ static int if_rebuild_hdr(struct sk_buff *skb) { - struct device *dev=skb->dev; + struct net_device *dev=skb->dev; fr_channel_t *chan = dev->priv; sdla_t *card = chan->card; printk(KERN_INFO "%s: rebuild_header() called for interface %s!\n", @@ -879,13 +879,13 @@ * protocol stack and can be used for flow control with protocol layer. */ -static int if_send(struct sk_buff *skb, struct device *dev) +static int if_send(struct sk_buff *skb, struct net_device *dev) { fr_channel_t *chan = dev->priv; sdla_t *card = chan->card; int retry = 0, err; unsigned char *sendpacket; - struct device *dev2; + struct net_device *dev2; unsigned long check_braddr, check_mcaddr; fr508_flags_t *adptr_flags = card->flags; int udp_type, send_data; @@ -1230,7 +1230,7 @@ * Return a pointer to struct net_device_stats. */ -static struct net_device_stats *if_stats(struct device *dev) +static struct net_device_stats *if_stats(struct net_device *dev) { fr_channel_t *chan = dev->priv; if(chan==NULL) @@ -1270,8 +1270,8 @@ fr508_flags_t *flags = card->flags; fr_buf_ctl_t *bctl; char *ptr = &flags->iflag; - struct device *dev = card->wandev.dev; - struct device *dev2; + struct net_device *dev = card->wandev.dev; + struct net_device *dev2; int i; unsigned long host_cpu_flags; unsigned disable_tx_intr = 1; @@ -1429,7 +1429,7 @@ { fr_mbox_t *mbox = card->rxmb; struct sk_buff *skb; - struct device *dev; + struct net_device *dev; fr_channel_t *chan; unsigned dlci, len; void *buf; @@ -1517,7 +1517,7 @@ { fr_buf_ctl_t *frbuf = card->rxmb; struct sk_buff *skb; - struct device *dev; + struct net_device *dev; fr_channel_t *chan; unsigned dlci, len, offs; void *buf; @@ -1653,7 +1653,7 @@ */ static void tx_intr(sdla_t * card) { - struct device *dev = card->wandev.dev; + struct net_device *dev = card->wandev.dev; if (card->intr_mode == BUFFER_INTR_MODE) { for (; dev; dev = dev->slave) @@ -1801,7 +1801,7 @@ static void wpf_poll(sdla_t * card) { -/* struct device* dev = card->wandev.dev; */ +/* struct net_device* dev = card->wandev.dev; */ fr508_flags_t *flags = card->flags; unsigned long host_cpu_flags; ++card->statistics.poll_entry; @@ -2246,11 +2246,11 @@ int cnt = mbox->cmd.length / sizeof(dlci_status_t); fr_dlc_conf_t cfg; fr_channel_t *chan; - struct device *dev2; + struct net_device *dev2; for (; cnt; --cnt, ++status) { unsigned short dlci = status->dlci; - struct device *dev = find_channel(card, dlci); + struct net_device *dev = find_channel(card, dlci); if (dev == NULL) { printk(KERN_INFO @@ -2325,7 +2325,7 @@ /*============================================================================ * Update channel state. */ -static int update_chan_state(struct device *dev) +static int update_chan_state(struct net_device *dev) { fr_channel_t *chan = dev->priv; sdla_t *card = chan->card; @@ -2365,7 +2365,7 @@ /*============================================================================ * Set channel state. */ -static void set_chan_state(struct device *dev, int state) +static void set_chan_state(struct net_device *dev, int state) { fr_channel_t *chan = dev->priv; sdla_t *card = chan->card; @@ -2402,9 +2402,9 @@ /*============================================================================ * Find network device by its channel number. */ -static struct device *find_channel(sdla_t * card, unsigned dlci) +static struct net_device *find_channel(sdla_t * card, unsigned dlci) { - struct device *dev; + struct net_device *dev; for (dev = card->wandev.dev; dev; dev = dev->slave) if (((fr_channel_t *) dev->priv)->dlci == dlci) break; @@ -2454,7 +2454,7 @@ * Process UDP call of type FPIPE8ND */ -static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct device *dev, int dlci, fr_channel_t * chan) +static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, int dlci, fr_channel_t * chan) { int c_retry = MAX_CMD_RETRY; unsigned char *data; @@ -2818,7 +2818,7 @@ /*============================================================================ * Process UDP call of type DRVSTATS. */ -static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct device *dev, int dlci, fr_channel_t * chan) +static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, int dlci, fr_channel_t * chan) { int c_retry = MAX_CMD_RETRY; unsigned char *sendpacket; diff -u --recursive --new-file v2.3.13/linux/drivers/net/sdla_ppp.c linux/drivers/net/sdla_ppp.c --- v2.3.13/linux/drivers/net/sdla_ppp.c Mon Jan 4 11:37:29 1999 +++ linux/drivers/net/sdla_ppp.c Wed Aug 18 11:36:42 1999 @@ -147,20 +147,20 @@ /* WAN link driver entry points. These are called by the WAN router module. */ static int update(wan_device_t * wandev); -static int new_if(wan_device_t * wandev, struct device *dev, +static int new_if(wan_device_t * wandev, struct net_device *dev, wanif_conf_t * conf); -static int del_if(wan_device_t * wandev, struct device *dev); +static int del_if(wan_device_t * wandev, struct net_device *dev); /* WANPIPE-specific entry points */ static int wpp_exec(struct sdla *card, void *u_cmd, void *u_data); /* Network device interface */ -static int if_init(struct device *dev); -static int if_open(struct device *dev); -static int if_close(struct device *dev); -static int if_header(struct sk_buff *skb, struct device *dev, +static int if_init(struct net_device *dev); +static int if_open(struct net_device *dev); +static int if_close(struct net_device *dev); +static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); static int if_rebuild_hdr(struct sk_buff *skb); -static int if_send(struct sk_buff *skb, struct device *dev); -static struct enet_statistics *if_stats(struct device *dev); +static int if_send(struct sk_buff *skb, struct net_device *dev); +static struct enet_statistics *if_stats(struct net_device *dev); /* PPP firmware interface functions */ static int ppp_read_version(sdla_t * card, char *str); static int ppp_configure(sdla_t * card, void *data); @@ -185,8 +185,8 @@ static void show_disc_cause(sdla_t * card, unsigned cause); static unsigned char bps_to_speed_code(unsigned long bps); static int reply_udp(unsigned char *data, unsigned int mbox_len); -static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct device *dev, ppp_private_area_t * ppp_priv_area); -static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct device *dev, ppp_private_area_t * ppp_priv_area); +static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, ppp_private_area_t * ppp_priv_area); +static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, ppp_private_area_t * ppp_priv_area); static void init_ppp_tx_rx_buff(sdla_t * card); static int intr_test(sdla_t * card); static int udp_pkt_type(struct sk_buff *skb, sdla_t * card); @@ -310,7 +310,7 @@ * < 0 failure (channel will not be created) */ -static int new_if(wan_device_t * wandev, struct device *dev, wanif_conf_t * conf) +static int new_if(wan_device_t * wandev, struct net_device *dev, wanif_conf_t * conf) { sdla_t *card = wandev->private; ppp_private_area_t *ppp_priv_area; @@ -343,7 +343,7 @@ * Delete logical channel. */ -static int del_if(wan_device_t * wandev, struct device *dev) +static int del_if(wan_device_t * wandev, struct net_device *dev) { if (dev->priv) { kfree(dev->priv); @@ -391,7 +391,7 @@ * registration. */ -static int if_init(struct device *dev) +static int if_init(struct net_device *dev) { ppp_private_area_t *ppp_priv_area = dev->priv; sdla_t *card = ppp_priv_area->card; @@ -429,7 +429,7 @@ * Return 0 if O.k. or errno. */ -static int if_open(struct device *dev) +static int if_open(struct net_device *dev) { ppp_private_area_t *ppp_priv_area = dev->priv; sdla_t *card = ppp_priv_area->card; @@ -487,7 +487,7 @@ * o reset flags. */ -static int if_close(struct device *dev) +static int if_close(struct net_device *dev) { ppp_private_area_t *ppp_priv_area = dev->priv; sdla_t *card = ppp_priv_area->card; @@ -512,7 +512,7 @@ * Return: media header length. */ -static int if_header(struct sk_buff *skb, struct device *dev, +static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { switch (type) @@ -536,7 +536,7 @@ static int if_rebuild_hdr(struct sk_buff *skb) { - struct device *dev=skb->dev; + struct net_device *dev=skb->dev; ppp_private_area_t *ppp_priv_area = dev->priv; sdla_t *card = ppp_priv_area->card; printk(KERN_INFO "%s: rebuild_header() called for interface %s!\n", @@ -562,7 +562,7 @@ * protocol stack and can be used for flow control with protocol layer. */ -static int if_send(struct sk_buff *skb, struct device *dev) +static int if_send(struct sk_buff *skb, struct net_device *dev) { ppp_private_area_t *ppp_priv_area = dev->priv; sdla_t *card = ppp_priv_area->card; @@ -846,7 +846,7 @@ * Return a pointer to struct enet_statistics. */ -static struct enet_statistics *if_stats(struct device *dev) +static struct enet_statistics *if_stats(struct net_device *dev) { ppp_private_area_t *ppp_priv_area = dev->priv; sdla_t *card; @@ -1052,7 +1052,7 @@ ppp_flags_t *flags = card->flags; char *ptr = &flags->iflag; unsigned long host_cpu_flags; - struct device *dev = card->wandev.dev; + struct net_device *dev = card->wandev.dev; int i; card->in_isr = 1; ++card->statistics.isr_entry; @@ -1123,7 +1123,7 @@ static void rx_intr(sdla_t * card) { ppp_buf_ctl_t *rxbuf = card->rxmb; - struct device *dev = card->wandev.dev; + struct net_device *dev = card->wandev.dev; ppp_private_area_t *ppp_priv_area; struct sk_buff *skb; unsigned len; @@ -1227,7 +1227,7 @@ static void tx_intr(sdla_t * card) { - struct device *dev = card->wandev.dev; + struct net_device *dev = card->wandev.dev; if (!dev || !dev->start) { ++card->statistics.tx_intr_dev_not_started; return; @@ -1332,7 +1332,7 @@ static void wpp_poll(sdla_t * card) { - struct device *dev = card->wandev.dev; + struct net_device *dev = card->wandev.dev; ppp_flags_t *adptr_flags = card->flags; unsigned long host_cpu_flags; ++card->statistics.poll_entry; @@ -1430,7 +1430,7 @@ static void poll_disconnected(sdla_t * card) { - struct device *dev = card->wandev.dev; + struct net_device *dev = card->wandev.dev; if (dev && dev->start && ((jiffies - card->state_tick) > HOLD_DOWN_TIME)) { wanpipe_set_state(card, WAN_CONNECTING); @@ -1591,7 +1591,7 @@ * Process UDP call of type DRVSTATS. */ -static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct device *dev, ppp_private_area_t * ppp_priv_area) +static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, ppp_private_area_t * ppp_priv_area) { unsigned char *sendpacket; unsigned char buf2[5]; @@ -1776,7 +1776,7 @@ */ static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, - struct sk_buff *skb, struct device *dev, + struct sk_buff *skb, struct net_device *dev, ppp_private_area_t * ppp_priv_area) { unsigned char *sendpacket; diff -u --recursive --new-file v2.3.13/linux/drivers/net/sdla_x25.c linux/drivers/net/sdla_x25.c --- v2.3.13/linux/drivers/net/sdla_x25.c Mon Jan 4 11:37:29 1999 +++ linux/drivers/net/sdla_x25.c Wed Aug 18 11:36:42 1999 @@ -70,7 +70,7 @@ /****** Data Structures *****************************************************/ -/* This is an extention of the 'struct device' we create for each network +/* This is an extention of the 'struct net_device' we create for each network * interface to keep the rest of X.25 channel-specific data. */ typedef struct x25_channel @@ -114,22 +114,22 @@ /* WAN link driver entry points. These are called by the WAN router module. */ static int update (wan_device_t* wandev); -static int new_if (wan_device_t* wandev, struct device* dev, +static int new_if (wan_device_t* wandev, struct net_device* dev, wanif_conf_t* conf); -static int del_if (wan_device_t* wandev, struct device* dev); +static int del_if (wan_device_t* wandev, struct net_device* dev); /* WANPIPE-specific entry points */ static int wpx_exec (struct sdla* card, void* u_cmd, void* u_data); /* Network device interface */ -static int if_init (struct device* dev); -static int if_open (struct device* dev); -static int if_close (struct device* dev); -static int if_header (struct sk_buff* skb, struct device* dev, +static int if_init (struct net_device* dev); +static int if_open (struct net_device* dev); +static int if_close (struct net_device* dev); +static int if_header (struct sk_buff* skb, struct net_device* dev, unsigned short type, void* daddr, void* saddr, unsigned len); static int if_rebuild_hdr (struct sk_buff* skb); -static int if_send (struct sk_buff* skb, struct device* dev); -static struct net_device_stats * if_stats (struct device* dev); +static int if_send (struct sk_buff* skb, struct net_device* dev); +static struct net_device_stats * if_stats (struct net_device* dev); /* Interrupt handlers */ static void wpx_isr (sdla_t* card); @@ -173,11 +173,11 @@ /* Miscellaneous functions */ static int connect (sdla_t* card); static int disconnect (sdla_t* card); -static struct device* get_dev_by_lcn(wan_device_t* wandev, unsigned lcn); -static int chan_connect (struct device* dev); -static int chan_disc (struct device* dev); -static void set_chan_state (struct device* dev, int state); -static int chan_send (struct device* dev, struct sk_buff* skb); +static struct net_device* get_dev_by_lcn(wan_device_t* wandev, unsigned lcn); +static int chan_connect (struct net_device* dev); +static int chan_disc (struct net_device* dev); +static void set_chan_state (struct net_device* dev, int state); +static int chan_send (struct net_device* dev, struct sk_buff* skb); static unsigned char bps_to_speed_code (unsigned long bps); static unsigned int dec_to_uint (unsigned char* str, int len); static unsigned int hex_to_uint (unsigned char* str, int len); @@ -394,7 +394,7 @@ * Return: 0 o.k. * < 0 failure (channel will not be created) */ -static int new_if (wan_device_t* wandev, struct device* dev, wanif_conf_t* conf) +static int new_if (wan_device_t* wandev, struct net_device* dev, wanif_conf_t* conf) { sdla_t* card = wandev->private; x25_channel_t* chan; @@ -470,7 +470,7 @@ /*============================================================================ * Delete logical channel. */ -static int del_if (wan_device_t* wandev, struct device* dev) +static int del_if (wan_device_t* wandev, struct net_device* dev) { if (dev->priv) { @@ -531,7 +531,7 @@ * interface registration. Returning anything but zero will fail interface * registration. */ -static int if_init (struct device* dev) +static int if_init (struct net_device* dev) { x25_channel_t* chan = dev->priv; sdla_t* card = chan->card; @@ -577,7 +577,7 @@ * * Return 0 if O.k. or errno. */ -static int if_open (struct device* dev) +static int if_open (struct net_device* dev) { x25_channel_t* chan = dev->priv; sdla_t* card = chan->card; @@ -605,7 +605,7 @@ * o reset flags. * o if there's no more open channels then disconnect physical link. */ -static int if_close (struct device* dev) +static int if_close (struct net_device* dev) { x25_channel_t* chan = dev->priv; sdla_t* card = chan->card; @@ -637,7 +637,7 @@ * * Return: media header length. */ -static int if_header (struct sk_buff* skb, struct device* dev, +static int if_header (struct sk_buff* skb, struct net_device* dev, unsigned short type, void* daddr, void* saddr, unsigned len) { x25_channel_t* chan = dev->priv; @@ -665,7 +665,7 @@ static int if_rebuild_hdr (struct sk_buff* skb) { - struct device *dev=skb->dev; + struct net_device *dev=skb->dev; x25_channel_t* chan = dev->priv; sdla_t* card = chan->card; @@ -692,11 +692,11 @@ * protocol stack and can be used for flow control with protocol layer. */ -static int if_send (struct sk_buff* skb, struct device* dev) +static int if_send (struct sk_buff* skb, struct net_device* dev) { x25_channel_t* chan = dev->priv; sdla_t* card = chan->card; - struct device *dev2; + struct net_device *dev2; TX25Status* status = card->flags; unsigned long host_cpu_flags; @@ -823,7 +823,7 @@ * Return a pointer to struct net_device_stats */ -static struct net_device_stats* if_stats (struct device* dev) +static struct net_device_stats* if_stats (struct net_device* dev) { x25_channel_t* chan = dev->priv; if(chan==NULL) @@ -840,7 +840,7 @@ static void wpx_isr (sdla_t* card) { TX25Status* status = card->flags; - struct device *dev; + struct net_device *dev; unsigned long host_cpu_flags; card->in_isr = 1; @@ -933,7 +933,7 @@ unsigned len = rxmb->cmd.length; /* packet length */ unsigned qdm = rxmb->cmd.qdm; /* Q,D and M bits */ wan_device_t* wandev = &card->wandev; - struct device* dev = get_dev_by_lcn(wandev, lcn); + struct net_device* dev = get_dev_by_lcn(wandev, lcn); x25_channel_t* chan; struct sk_buff* skb; void* bufptr; @@ -1041,7 +1041,7 @@ static void tx_intr (sdla_t* card) { - struct device *dev; + struct net_device *dev; /* unbusy all devices and then dev_tint(); */ for(dev = card->wandev.dev; dev; dev = dev->slave) @@ -1165,7 +1165,7 @@ */ static void poll_active (sdla_t* card) { - struct device* dev; + struct net_device* dev; /* Fetch X.25 asynchronous events */ x25_fetch_events(card); @@ -1745,7 +1745,7 @@ { wan_device_t* wandev = &card->wandev; int new_lcn = mb->cmd.lcn; - struct device* dev = get_dev_by_lcn(wandev, new_lcn); + struct net_device* dev = get_dev_by_lcn(wandev, new_lcn); x25_channel_t* chan = NULL; int accept = 0; /* set to '1' if o.k. to accept call */ x25_call_info_t* info; @@ -1855,7 +1855,7 @@ static int call_accepted (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) { unsigned new_lcn = mb->cmd.lcn; - struct device* dev = get_dev_by_lcn(&card->wandev, new_lcn); + struct net_device* dev = get_dev_by_lcn(&card->wandev, new_lcn); x25_channel_t* chan; printk(KERN_INFO "%s: X.25 call accepted on LCN %d!\n", @@ -1887,7 +1887,7 @@ static int call_cleared (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) { unsigned new_lcn = mb->cmd.lcn; - struct device* dev = get_dev_by_lcn(&card->wandev, new_lcn); + struct net_device* dev = get_dev_by_lcn(&card->wandev, new_lcn); printk(KERN_INFO "%s: X.25 clear request on LCN %d! Cause:0x%02X " "Diagn:0x%02X\n", @@ -1905,7 +1905,7 @@ static int restart_event (sdla_t* card, int cmd, int lcn, TX25Mbox* mb) { wan_device_t* wandev = &card->wandev; - struct device* dev; + struct net_device* dev; printk(KERN_INFO "%s: X.25 restart request! Cause:0x%02X Diagn:0x%02X\n", @@ -1926,7 +1926,7 @@ if (mb->cmd.pktType == 0x05) /* call request time out */ { - struct device* dev = get_dev_by_lcn(&card->wandev, new_lcn); + struct net_device* dev = get_dev_by_lcn(&card->wandev, new_lcn); printk(KERN_INFO "%s: X.25 call timed timeout on LCN %d!\n", card->devname, new_lcn); @@ -1976,9 +1976,9 @@ /*============================================================================ * Find network device by its channel number. */ -static struct device* get_dev_by_lcn (wan_device_t* wandev, unsigned lcn) +static struct net_device* get_dev_by_lcn (wan_device_t* wandev, unsigned lcn) { - struct device* dev; + struct net_device* dev; for (dev = wandev->dev; dev; dev = dev->slave) if (((x25_channel_t*)dev->priv)->lcn == lcn) @@ -1995,7 +1995,7 @@ * >0 connection in progress * <0 failure */ -static int chan_connect (struct device* dev) +static int chan_connect (struct net_device* dev) { x25_channel_t* chan = dev->priv; sdla_t* card = chan->card; @@ -2024,7 +2024,7 @@ * Disconnect logical channel. * o if SVC then clear X.25 call */ -static int chan_disc (struct device* dev) +static int chan_disc (struct net_device* dev) { x25_channel_t* chan = dev->priv; @@ -2037,7 +2037,7 @@ /*============================================================================ * Set logical channel state. */ -static void set_chan_state (struct device* dev, int state) +static void set_chan_state (struct net_device* dev, int state) { x25_channel_t* chan = dev->priv; sdla_t* card = chan->card; @@ -2092,7 +2092,7 @@ * 2. When transmission is complete, an event notification should be issued * to the router. */ -static int chan_send (struct device* dev, struct sk_buff* skb) +static int chan_send (struct net_device* dev, struct sk_buff* skb) { x25_channel_t* chan = dev->priv; sdla_t* card = chan->card; diff -u --recursive --new-file v2.3.13/linux/drivers/net/sealevel.c linux/drivers/net/sealevel.c --- v2.3.13/linux/drivers/net/sealevel.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/sealevel.c Wed Aug 18 11:36:42 1999 @@ -73,7 +73,7 @@ * We've been placed in the UP state */ -static int sealevel_open(struct device *d) +static int sealevel_open(struct net_device *d) { struct slvl_device *slvl=d->priv; int err = -1; @@ -123,7 +123,7 @@ return 0; } -static int sealevel_close(struct device *d) +static int sealevel_close(struct net_device *d) { struct slvl_device *slvl=d->priv; int unit = slvl->channel; @@ -156,14 +156,14 @@ return 0; } -static int sealevel_ioctl(struct device *d, struct ifreq *ifr, int cmd) +static int sealevel_ioctl(struct net_device *d, struct ifreq *ifr, int cmd) { /* struct slvl_device *slvl=d->priv; z8530_ioctl(d,&slvl->sync.chanA,ifr,cmd) */ return sppp_do_ioctl(d, ifr,cmd); } -static struct enet_statistics *sealevel_get_stats(struct device *d) +static struct enet_statistics *sealevel_get_stats(struct net_device *d) { struct slvl_device *slvl=d->priv; if(slvl) @@ -176,7 +176,7 @@ * Passed PPP frames, fire them downwind. */ -static int sealevel_queue_xmit(struct sk_buff *skb, struct device *d) +static int sealevel_queue_xmit(struct sk_buff *skb, struct net_device *d) { struct slvl_device *slvl=d->priv; return z8530_queue_xmit(slvl->chan, skb); @@ -192,7 +192,7 @@ return 0; } -static int sealevel_neigh_setup_dev(struct device *dev, struct neigh_parms *p) +static int sealevel_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p) { if (p->tbl->family == AF_INET) { p->neigh_setup = sealevel_neigh_setup; @@ -204,7 +204,7 @@ #else -static int return_0(struct device *d) +static int return_0(struct net_device *d) { return 0; } @@ -342,7 +342,7 @@ sprintf(sv->name,"hdlc%d", i); if(dev_get(sv->name)==NULL) { - struct device *d=sv->chan->netdevice; + struct net_device *d=sv->chan->netdevice; /* * Initialise the PPP components diff -u --recursive --new-file v2.3.13/linux/drivers/net/seeq8005.c linux/drivers/net/seeq8005.c --- v2.3.13/linux/drivers/net/seeq8005.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/seeq8005.c Wed Aug 18 11:36:42 1999 @@ -78,22 +78,22 @@ /* Index to functions, as function prototypes. */ -extern int seeq8005_probe(struct device *dev); +extern int seeq8005_probe(struct net_device *dev); -static int seeq8005_probe1(struct device *dev, int ioaddr); -static int seeq8005_open(struct device *dev); -static int seeq8005_send_packet(struct sk_buff *skb, struct device *dev); +static int seeq8005_probe1(struct net_device *dev, int ioaddr); +static int seeq8005_open(struct net_device *dev); +static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev); static void seeq8005_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void seeq8005_rx(struct device *dev); -static int seeq8005_close(struct device *dev); -static struct net_device_stats *seeq8005_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static void seeq8005_rx(struct net_device *dev); +static int seeq8005_close(struct net_device *dev); +static struct net_device_stats *seeq8005_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); /* Example routines you must write ;->. */ #define tx_done(dev) (inw(SEEQ_STATUS) & SEEQSTAT_TX_ON) -static void hardware_send_packet(struct device *dev, char *buf, int length); -extern void seeq8005_init(struct device *dev, int startp); -static inline void wait_for_buffer(struct device *dev); +static void hardware_send_packet(struct net_device *dev, char *buf, int length); +extern void seeq8005_init(struct net_device *dev, int startp); +static inline void wait_for_buffer(struct net_device *dev); /* Check for a network adaptor of this type, and return '0' iff one exists. @@ -109,7 +109,7 @@ {"seeq8005", seeq8005_probe1, SEEQ8005_IO_EXTENT, seeq8005_portlist}; #else int __init -seeq8005_probe(struct device *dev) +seeq8005_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -135,7 +135,7 @@ probes on the ISA bus. A good device probes avoids doing writes, and verifies that the correct device exists and functions. */ -static int __init seeq8005_probe1(struct device *dev, int ioaddr) +static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) { static unsigned version_printed = 0; int i,j; @@ -344,7 +344,7 @@ there is non-reboot way to recover if something goes wrong. */ static int -seeq8005_open(struct device *dev) +seeq8005_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -369,7 +369,7 @@ } static int -seeq8005_send_packet(struct sk_buff *skb, struct device *dev) +seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev) { int ioaddr = dev->base_addr; struct net_local *lp = (struct net_local *)dev->priv; @@ -412,7 +412,7 @@ static void seeq8005_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *lp; int ioaddr, status, boguscount = 0; @@ -462,7 +462,7 @@ /* We have a good packet(s), get it/them out of the buffers. */ static void -seeq8005_rx(struct device *dev) +seeq8005_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int boguscount = 10; @@ -561,7 +561,7 @@ /* The inverse routine to net_open(). */ static int -seeq8005_close(struct device *dev) +seeq8005_close(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -584,7 +584,7 @@ /* Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *seeq8005_get_stats(struct device *dev) +static struct net_device_stats *seeq8005_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -598,7 +598,7 @@ best-effort filtering. */ static void -set_multicast_list(struct device *dev) +set_multicast_list(struct net_device *dev) { /* * I _could_ do up to 6 addresses here, but won't (yet?) @@ -620,7 +620,7 @@ #endif } -void seeq8005_init(struct device *dev, int startp) +void seeq8005_init(struct net_device *dev, int startp) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -677,7 +677,7 @@ } -static void hardware_send_packet(struct device * dev, char *buf, int length) +static void hardware_send_packet(struct net_device * dev, char *buf, int length) { int ioaddr = dev->base_addr; int status = inw(SEEQ_STATUS); @@ -722,7 +722,7 @@ * This routine waits for the SEEQ chip to assert that the FIFO is ready * by checking for a window interrupt, and then clearing it */ -inline void wait_for_buffer(struct device * dev) +inline void wait_for_buffer(struct net_device * dev) { int ioaddr = dev->base_addr; int tmp; @@ -740,7 +740,7 @@ static char devicename[9] = { 0, }; -static struct device dev_seeq = +static struct net_device dev_seeq = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, diff -u --recursive --new-file v2.3.13/linux/drivers/net/sgiseeq.c linux/drivers/net/sgiseeq.c --- v2.3.13/linux/drivers/net/sgiseeq.c Wed Jun 30 13:38:20 1999 +++ linux/drivers/net/sgiseeq.c Wed Aug 18 11:36:42 1999 @@ -134,7 +134,7 @@ hregs->rx_ctrl = HPC3_ERXCTRL_ACTIVE; } -static inline void seeq_load_eaddr(struct device *dev, +static inline void seeq_load_eaddr(struct net_device *dev, volatile struct sgiseeq_regs *sregs) { int i; @@ -148,7 +148,7 @@ #define RCNTCFG_INIT (HPCDMA_OWN | HPCDMA_EORP | HPCDMA_XIE) #define RCNTINFO_INIT (RCNTCFG_INIT | (PKT_BUF_SZ & HPCDMA_BCNT)) -static void seeq_init_ring(struct device *dev) +static void seeq_init_ring(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; volatile struct sgiseeq_init_block *ib = &sp->srings; @@ -196,7 +196,7 @@ #ifdef DEBUG static struct sgiseeq_private *gpriv; -static struct device *gdev; +static struct net_device *gdev; void sgiseeq_dump_rings(void) { @@ -241,7 +241,7 @@ #define TSTAT_INIT_EDLC ((TSTAT_INIT_SEEQ) | SEEQ_TCMD_RB2) #define RDMACFG_INIT (HPC3_ERXDCFG_FRXDC | HPC3_ERXDCFG_FEOP | HPC3_ERXDCFG_FIRQ) -static void init_seeq(struct device *dev, struct sgiseeq_private *sp, +static void init_seeq(struct net_device *dev, struct sgiseeq_private *sp, volatile struct sgiseeq_regs *sregs) { volatile struct hpc3_ethregs *hregs = sp->hregs; @@ -294,7 +294,7 @@ !((rd)->rdma.cntinfo & HPCDMA_OWN); \ (rd) = &(sp)->srings.rx_desc[(sp)->rx_new]) -static inline void sgiseeq_rx(struct device *dev, struct sgiseeq_private *sp, +static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp, volatile struct hpc3_ethregs *hregs, volatile struct sgiseeq_regs *sregs) { @@ -371,7 +371,7 @@ } } -static inline void sgiseeq_tx(struct device *dev, struct sgiseeq_private *sp, +static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp, volatile struct hpc3_ethregs *hregs, volatile struct sgiseeq_regs *sregs) { @@ -412,7 +412,7 @@ } static inline void tx_maybe_unbusy(struct sgiseeq_private *sp, - struct device *dev) + struct net_device *dev) { if((TX_BUFFS_AVAIL(sp) >= 0) && dev->tbusy) { dev->tbusy = 0; @@ -422,7 +422,7 @@ static void sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; volatile struct hpc3_ethregs *hregs = sp->hregs; volatile struct sgiseeq_regs *sregs = sp->sregs; @@ -442,7 +442,7 @@ dev->interrupt = 0; } -static int sgiseeq_open(struct device *dev) +static int sgiseeq_open(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *)dev->priv; volatile struct sgiseeq_regs *sregs = sp->sregs; @@ -464,7 +464,7 @@ return 0; } -static int sgiseeq_close(struct device *dev) +static int sgiseeq_close(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; volatile struct sgiseeq_regs *sregs = sp->sregs; @@ -480,7 +480,7 @@ return 0; } -static inline int sgiseeq_reset(struct device *dev) +static inline int sgiseeq_reset(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; volatile struct sgiseeq_regs *sregs = sp->sregs; @@ -502,7 +502,7 @@ } static inline int verify_tx(struct sgiseeq_private *sp, - struct device *dev, + struct net_device *dev, struct sk_buff *skb) { /* Are we bolixed? */ @@ -529,7 +529,7 @@ return 0; } -static int sgiseeq_start_xmit(struct sk_buff *skb, struct device *dev) +static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; volatile struct hpc3_ethregs *hregs = sp->hregs; @@ -585,14 +585,14 @@ return 0; } -static struct enet_statistics *sgiseeq_get_stats(struct device *dev) +static struct enet_statistics *sgiseeq_get_stats(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; return &sp->stats; } -static void sgiseeq_set_multicast(struct device *dev) +static void sgiseeq_set_multicast(struct net_device *dev) { } @@ -625,7 +625,7 @@ #define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf)) -int sgiseeq_init(struct device *dev, struct sgiseeq_regs *sregs, +int sgiseeq_init(struct net_device *dev, struct sgiseeq_regs *sregs, struct hpc3_ethregs *hregs, int irq) { static unsigned version_printed = 0; @@ -721,7 +721,7 @@ } } -int sgiseeq_probe(struct device *dev) +int sgiseeq_probe(struct net_device *dev) { static int initialized; char *ep; diff -u --recursive --new-file v2.3.13/linux/drivers/net/shaper.c linux/drivers/net/shaper.c --- v2.3.13/linux/drivers/net/shaper.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/shaper.c Wed Aug 18 11:36:42 1999 @@ -378,7 +378,7 @@ * bind. */ -static int shaper_open(struct device *dev) +static int shaper_open(struct net_device *dev) { struct shaper *shaper=dev->priv; @@ -400,7 +400,7 @@ * Closing a shaper flushes the queues. */ -static int shaper_close(struct device *dev) +static int shaper_close(struct net_device *dev) { struct shaper *shaper=dev->priv; shaper_flush(shaper); @@ -418,19 +418,19 @@ */ -static int shaper_start_xmit(struct sk_buff *skb, struct device *dev) +static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct shaper *sh=dev->priv; return shaper_qframe(sh, skb); } -static struct net_device_stats *shaper_get_stats(struct device *dev) +static struct net_device_stats *shaper_get_stats(struct net_device *dev) { struct shaper *sh=dev->priv; return &sh->stats; } -static int shaper_header(struct sk_buff *skb, struct device *dev, +static int shaper_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { struct shaper *sh=dev->priv; @@ -446,7 +446,7 @@ static int shaper_rebuild_header(struct sk_buff *skb) { struct shaper *sh=skb->dev->priv; - struct device *dev=skb->dev; + struct net_device *dev=skb->dev; int v; if(sh_debug) printk("Shaper rebuild header\n"); @@ -460,7 +460,7 @@ static int shaper_cache(struct neighbour *neigh, struct hh_cache *hh) { struct shaper *sh=neigh->dev->priv; - struct device *tmp; + struct net_device *tmp; int ret; if(sh_debug) printk("Shaper header cache bind\n"); @@ -471,7 +471,7 @@ return ret; } -static void shaper_cache_update(struct hh_cache *hh, struct device *dev, +static void shaper_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char *haddr) { struct shaper *sh=dev->priv; @@ -490,7 +490,7 @@ return 0; } -static int shaper_neigh_setup_dev(struct device *dev, struct neigh_parms *p) +static int shaper_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p) { if (p->tbl->family == AF_INET) { p->neigh_setup = shaper_neigh_setup; @@ -500,7 +500,7 @@ return 0; } -static int shaper_attach(struct device *shdev, struct shaper *sh, struct device *dev) +static int shaper_attach(struct net_device *shdev, struct shaper *sh, struct net_device *dev) { sh->dev = dev; sh->hard_start_xmit=dev->hard_start_xmit; @@ -553,7 +553,7 @@ return 0; } -static int shaper_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +static int shaper_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct shaperconf *ss= (struct shaperconf *)&ifr->ifr_data; struct shaper *sh=dev->priv; @@ -561,7 +561,7 @@ { case SHAPER_SET_DEV: { - struct device *them=dev_get(ss->ss_name); + struct net_device *them=dev_get(ss->ss_name); if(them==NULL) return -ENODEV; if(sh->dev) @@ -584,7 +584,7 @@ } } -static struct shaper *shaper_alloc(struct device *dev) +static struct shaper *shaper_alloc(struct net_device *dev) { struct shaper *sh=kmalloc(sizeof(struct shaper), GFP_KERNEL); if(sh==NULL) @@ -602,7 +602,7 @@ * Add a shaper device to the system */ -int __init shaper_probe(struct device *dev) +int __init shaper_probe(struct net_device *dev) { /* * Set up the shaper. @@ -655,7 +655,7 @@ static char devicename[9]; -static struct device dev_shape = +static struct net_device dev_shape = { devicename, 0, 0, 0, 0, @@ -696,7 +696,7 @@ #else -static struct device dev_sh0 = +static struct net_device dev_sh0 = { "shaper0", 0, 0, 0, 0, @@ -705,7 +705,7 @@ }; -static struct device dev_sh1 = +static struct net_device dev_sh1 = { "shaper1", 0, 0, 0, 0, @@ -714,7 +714,7 @@ }; -static struct device dev_sh2 = +static struct net_device dev_sh2 = { "shaper2", 0, 0, 0, 0, @@ -722,7 +722,7 @@ 0, 0, 0, NULL, shaper_probe }; -static struct device dev_sh3 = +static struct net_device dev_sh3 = { "shaper3", 0, 0, 0, 0, diff -u --recursive --new-file v2.3.13/linux/drivers/net/sk_g16.c linux/drivers/net/sk_g16.c --- v2.3.13/linux/drivers/net/sk_g16.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/sk_g16.c Wed Aug 18 11:36:42 1999 @@ -466,28 +466,28 @@ * See for short explanation of each function its definitions header. */ -int SK_init(struct device *dev); -static int SK_probe(struct device *dev, short ioaddr); +int SK_init(struct net_device *dev); +static int SK_probe(struct net_device *dev, short ioaddr); -static int SK_open(struct device *dev); -static int SK_send_packet(struct sk_buff *skb, struct device *dev); +static int SK_open(struct net_device *dev); +static int SK_send_packet(struct sk_buff *skb, struct net_device *dev); static void SK_interrupt(int irq, void *dev_id, struct pt_regs * regs); -static void SK_rxintr(struct device *dev); -static void SK_txintr(struct device *dev); -static int SK_close(struct device *dev); +static void SK_rxintr(struct net_device *dev); +static void SK_txintr(struct net_device *dev); +static int SK_close(struct net_device *dev); -static struct net_device_stats *SK_get_stats(struct device *dev); +static struct net_device_stats *SK_get_stats(struct net_device *dev); unsigned int SK_rom_addr(void); -static void set_multicast_list(struct device *dev); +static void set_multicast_list(struct net_device *dev); /* * LANCE Functions * --------------- */ -static int SK_lance_init(struct device *dev, unsigned short mode); +static int SK_lance_init(struct net_device *dev, unsigned short mode); void SK_reset_board(void); void SK_set_RAP(int reg_number); int SK_read_reg(int reg_number); @@ -499,9 +499,9 @@ * ------------------- */ -void SK_print_pos(struct device *dev, char *text); -void SK_print_dev(struct device *dev, char *text); -void SK_print_ram(struct device *dev); +void SK_print_pos(struct net_device *dev, char *text); +void SK_print_dev(struct net_device *dev, char *text); +void SK_print_ram(struct net_device *dev); /*- @@ -513,7 +513,7 @@ * This function gets called by dev_init which initializes * all Network devices. * - * Parameters : I : struct device *dev - structure preconfigured + * Parameters : I : struct net_device *dev - structure preconfigured * from Space.c * Return Value : 0 = Driver Found and initialized * Errors : ENODEV - no device found @@ -531,7 +531,7 @@ * (detachable devices only). */ -int __init SK_init(struct device *dev) +int __init SK_init(struct net_device *dev) { int ioaddr = 0; /* I/O port address used for POS regs */ int *port, ports[] = SK_IO_PORTS; /* SK_G16 supported ports */ @@ -603,7 +603,7 @@ * Description : This function is called by SK_init and * does the main part of initialization. * - * Parameters : I : struct device *dev - SK_G16 device structure + * Parameters : I : struct net_device *dev - SK_G16 device structure * I : short ioaddr - I/O Port address where POS is. * Return Value : 0 = Initialization done * Errors : ENODEV - No SK_G16 found @@ -614,7 +614,7 @@ * 94/06/30 pwe SK_ADDR now checked and at the correct place -*/ -int __init SK_probe(struct device *dev, short ioaddr) +int __init SK_probe(struct net_device *dev, short ioaddr) { int i,j; /* Counters */ int sk_addr_flag = 0; /* SK ADDR correct? 1 - no, 0 - yes */ @@ -832,7 +832,7 @@ * * (Called by dev_open() /net/inet/dev.c) * - * Parameters : I : struct device *dev - SK_G16 device structure + * Parameters : I : struct net_device *dev - SK_G16 device structure * Return Value : 0 - Device opened * Errors : -EAGAIN - Open failed * Side Effects : None @@ -840,7 +840,7 @@ * YY/MM/DD uid Description -*/ -static int SK_open(struct device *dev) +static int SK_open(struct net_device *dev) { int i = 0; int irqval = 0; @@ -994,7 +994,7 @@ * Description : Reset LANCE chip, fill RMD, TMD structures with * start values and Start LANCE. * - * Parameters : I : struct device *dev - SK_G16 device structure + * Parameters : I : struct net_device *dev - SK_G16 device structure * I : int mode - put LANCE into "mode" see data-sheet for * more info. * Return Value : 0 - Init done @@ -1003,7 +1003,7 @@ * YY/MM/DD uid Description -*/ -static int SK_lance_init(struct device *dev, unsigned short mode) +static int SK_lance_init(struct net_device *dev, unsigned short mode) { int i; unsigned long flags; @@ -1161,7 +1161,7 @@ * and starts transmission. * * Parameters : I : struct sk_buff *skb - packet to transfer - * I : struct device *dev - SK_G16 device structure + * I : struct net_device *dev - SK_G16 device structure * Return Value : 0 - OK * 1 - Could not transmit (dev_queue_xmit will queue it) * and try to sent it later @@ -1171,7 +1171,7 @@ * YY/MM/DD uid Description -*/ -static int SK_send_packet(struct sk_buff *skb, struct device *dev) +static int SK_send_packet(struct sk_buff *skb, struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; struct tmd *tmdp; @@ -1278,7 +1278,7 @@ static void SK_interrupt(int irq, void *dev_id, struct pt_regs * regs) { int csr0; - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct priv *p = (struct priv *) dev->priv; @@ -1342,7 +1342,7 @@ * statistics and relinquish ownership of transmit * descriptor ring. * - * Parameters : I : struct device *dev - SK_G16 device structure + * Parameters : I : struct net_device *dev - SK_G16 device structure * Return Value : None * Errors : None * Globals : None @@ -1350,7 +1350,7 @@ * YY/MM/DD uid Description -*/ -static void SK_txintr(struct device *dev) +static void SK_txintr(struct net_device *dev) { int tmdstat; struct tmd *tmdp; @@ -1470,7 +1470,7 @@ * YY/MM/DD uid Description -*/ -static void SK_rxintr(struct device *dev) +static void SK_rxintr(struct net_device *dev) { struct rmd *rmdp; @@ -1607,7 +1607,7 @@ * Description : close gets called from dev_close() and should * deinstall the card (free_irq, mem etc). * - * Parameters : I : struct device *dev - our device structure + * Parameters : I : struct net_device *dev - our device structure * Return Value : 0 - closed device driver * Errors : None * Globals : None @@ -1619,7 +1619,7 @@ * down' the system stops. So I don't shut set card to init state. */ -static int SK_close(struct device *dev) +static int SK_close(struct net_device *dev) { PRINTK(("## %s: SK_close(). CSR0: %#06x\n", @@ -1648,7 +1648,7 @@ * Description : Return current status structure to upper layers. * It is called by sprintf_stats (dev.c). * - * Parameters : I : struct device *dev - our device structure + * Parameters : I : struct net_device *dev - our device structure * Return Value : struct net_device_stats * - our current statistics * Errors : None * Side Effects : None @@ -1656,7 +1656,7 @@ * YY/MM/DD uid Description -*/ -static struct net_device_stats *SK_get_stats(struct device *dev) +static struct net_device_stats *SK_get_stats(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; @@ -1684,7 +1684,7 @@ * but it is also a security problem. You have to remember * that all information on the net is not encrypted. * - * Parameters : I : struct device *dev - SK_G16 device Structure + * Parameters : I : struct net_device *dev - SK_G16 device Structure * Return Value : None * Errors : None * Globals : None @@ -1697,7 +1697,7 @@ /* Set or clear the multicast filter for SK_G16. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { if (dev->flags&IFF_PROMISC) @@ -1949,7 +1949,7 @@ * Description : This function prints out the 4 POS (Programmable * Option Select) Registers. Used mainly to debug operation. * - * Parameters : I : struct device *dev - SK_G16 device structure + * Parameters : I : struct net_device *dev - SK_G16 device structure * I : char * - Text which will be printed as title * Return Value : None * Errors : None @@ -1957,7 +1957,7 @@ * YY/MM/DD uid Description -*/ -void SK_print_pos(struct device *dev, char *text) +void SK_print_pos(struct net_device *dev, char *text) { int ioaddr = dev->base_addr; @@ -1984,7 +1984,7 @@ * Description : This function simply prints out the important fields * of the device structure. * - * Parameters : I : struct device *dev - SK_G16 device structure + * Parameters : I : struct net_device *dev - SK_G16 device structure * I : char *text - Title for printing * Return Value : None * Errors : None @@ -1992,7 +1992,7 @@ * YY/MM/DD uid Description -*/ -void SK_print_dev(struct device *dev, char *text) +void SK_print_dev(struct net_device *dev, char *text) { if (dev == NULL) { @@ -2027,7 +2027,7 @@ * It contains a minor bug in printing, but has no effect to the values * only newlines are not correct. * - * Parameters : I : struct device *dev - SK_G16 device structure + * Parameters : I : struct net_device *dev - SK_G16 device structure * Return Value : None * Errors : None * Globals : None @@ -2035,7 +2035,7 @@ * YY/MM/DD uid Description -*/ -void SK_print_ram(struct device *dev) +void SK_print_ram(struct net_device *dev) { int i; diff -u --recursive --new-file v2.3.13/linux/drivers/net/sk_mca.c linux/drivers/net/sk_mca.c --- v2.3.13/linux/drivers/net/sk_mca.c Mon Jun 7 14:34:46 1999 +++ linux/drivers/net/sk_mca.c Wed Aug 18 11:36:42 1999 @@ -110,7 +110,7 @@ /* dump parts of shared memory - only needed during debugging */ #ifdef DEBUG -static void dumpmem(struct device *dev, u32 start, u32 len) +static void dumpmem(struct net_device *dev, u32 start, u32 len) { int z; @@ -199,7 +199,7 @@ /* reset the whole board */ -static void ResetBoard(struct device *dev) +static void ResetBoard(struct net_device *dev) { skmca_priv *priv = (skmca_priv*) dev->priv; @@ -210,7 +210,7 @@ /* set LANCE register - must be atomic */ -static void SetLANCE(struct device *dev, u16 addr, u16 value) +static void SetLANCE(struct net_device *dev, u16 addr, u16 value) { skmca_priv *priv = (skmca_priv*) dev->priv; unsigned long flags; @@ -247,7 +247,7 @@ /* get LANCE register */ -static u16 GetLANCE(struct device *dev, u16 addr) +static u16 GetLANCE(struct net_device *dev, u16 addr) { skmca_priv *priv = (skmca_priv*) dev->priv; unsigned long flags; @@ -287,7 +287,7 @@ /* build up descriptors in shared RAM */ -static void InitDscrs(struct device *dev) +static void InitDscrs(struct net_device *dev) { u32 bufaddr; @@ -381,7 +381,7 @@ /* feed ready-built initialization block into LANCE */ -static void InitLANCE(struct device *dev) +static void InitLANCE(struct net_device *dev) { skmca_priv *priv = (skmca_priv*) dev->priv; @@ -420,7 +420,7 @@ /* stop the LANCE so we can reinitialize it */ -static void StopLANCE(struct device *dev) +static void StopLANCE(struct net_device *dev) { /* can't take frames any more */ @@ -433,7 +433,7 @@ /* initialize card and LANCE for proper operation */ -static void InitBoard(struct device *dev) +static void InitBoard(struct net_device *dev) { LANCE_InitBlock block; @@ -458,7 +458,7 @@ /* deinitialize card and LANCE */ -static void DeinitBoard(struct device *dev) +static void DeinitBoard(struct net_device *dev) { /* stop LANCE */ @@ -475,7 +475,7 @@ /* LANCE has read initializazion block -> start it */ -static u16 irqstart_handler(struct device *dev, u16 oldcsr0) +static u16 irqstart_handler(struct net_device *dev, u16 oldcsr0) { /* now we're ready to transmit */ @@ -489,7 +489,7 @@ /* receive interrupt */ -static u16 irqrx_handler(struct device *dev, u16 oldcsr0) +static u16 irqrx_handler(struct net_device *dev, u16 oldcsr0) { skmca_priv *priv = (skmca_priv*) dev->priv; LANCE_RxDescr descr; @@ -575,7 +575,7 @@ /* transmit interrupt */ -static u16 irqtx_handler(struct device *dev, u16 oldcsr0) +static u16 irqtx_handler(struct net_device *dev, u16 oldcsr0) { skmca_priv *priv = (skmca_priv*) dev->priv; LANCE_TxDescr descr; @@ -653,7 +653,7 @@ static void irq_handler(int irq, void *device, struct pt_regs *regs) { - struct device *dev = (struct device*) device; + struct net_device *dev = (struct net_device*) device; u16 csr0val; /* read CSR0 to get interrupt cause */ @@ -692,7 +692,7 @@ static int skmca_getinfo(char *buf, int slot, void *d) { int len = 0, i; - struct device *dev = (struct device*) d; + struct net_device *dev = (struct net_device*) d; skmca_priv *priv; /* can't say anything about an uninitialized device... */ @@ -721,7 +721,7 @@ /* open driver. Means also initialization and start of LANCE */ -static int skmca_open(struct device *dev) +static int skmca_open(struct net_device *dev) { int result; skmca_priv *priv = (skmca_priv*) dev->priv; @@ -748,7 +748,7 @@ /* close driver. Shut down board and free allocated resources */ -static int skmca_close(struct device *dev) +static int skmca_close(struct net_device *dev) { /* turn off board */ DeinitBoard(dev); @@ -767,7 +767,7 @@ /* transmit a block. */ -static int skmca_tx(struct sk_buff *skb, struct device *dev) +static int skmca_tx(struct sk_buff *skb, struct net_device *dev) { skmca_priv *priv = (skmca_priv*) dev->priv; LANCE_TxDescr descr; @@ -864,7 +864,7 @@ /* return pointer to Ethernet statistics */ -static struct enet_statistics *skmca_stats(struct device *dev) +static struct enet_statistics *skmca_stats(struct net_device *dev) { skmca_priv *priv = (skmca_priv*) dev->priv; @@ -874,7 +874,7 @@ /* we don't support runtime reconfiguration, since am MCA card can be unambigously identified by its POS registers. */ -static int skmca_config(struct device *dev, struct ifmap *map) +static int skmca_config(struct net_device *dev, struct ifmap *map) { return 0; } @@ -882,7 +882,7 @@ /* switch receiver mode. We use the LANCE's multicast filter to prefilter multicast addresses. */ -static void skmca_set_multicast_list(struct device *dev) +static void skmca_set_multicast_list(struct net_device *dev) { LANCE_InitBlock block; @@ -929,7 +929,7 @@ #define startslot 0 /* otherwise a dummy, since there is only eth0 in-kern*/ #endif -int skmca_probe(struct device *dev) +int skmca_probe(struct net_device *dev) { int force_detect = 0; int junior, slot, i; @@ -1082,7 +1082,7 @@ #define DEVMAX 5 static char NameSpace[8 * DEVMAX]; -static struct device moddevs[DEVMAX] = +static struct net_device moddevs[DEVMAX] = {{NameSpace + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}, {NameSpace + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}, {NameSpace + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}, @@ -1110,7 +1110,7 @@ void cleanup_module(void) { - struct device *dev; + struct net_device *dev; skmca_priv *priv; int z; diff -u --recursive --new-file v2.3.13/linux/drivers/net/sk_mca.h linux/drivers/net/sk_mca.h --- v2.3.13/linux/drivers/net/sk_mca.h Mon Jun 7 14:34:46 1999 +++ linux/drivers/net/sk_mca.h Wed Aug 18 11:36:45 1999 @@ -168,7 +168,7 @@ #endif /* _SK_MCA_DRIVER_ */ -extern int skmca_probe(struct device *); +extern int skmca_probe(struct net_device *); #endif /* _SK_MCA_INCLUDE_ */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/skeleton.c linux/drivers/net/skeleton.c --- v2.3.13/linux/drivers/net/skeleton.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/skeleton.c Wed Aug 18 11:36:42 1999 @@ -96,21 +96,21 @@ /* Index to functions, as function prototypes. */ -extern int netcard_probe(struct device *dev); +extern int netcard_probe(struct net_device *dev); -static int netcard_probe1(struct device *dev, int ioaddr); -static int net_open(struct device *dev); -static int net_send_packet(struct sk_buff *skb, struct device *dev); +static int netcard_probe1(struct net_device *dev, int ioaddr); +static int net_open(struct net_device *dev); +static int net_send_packet(struct sk_buff *skb, struct net_device *dev); static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void net_rx(struct device *dev); -static int net_close(struct device *dev); -static struct net_device_stats *net_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static void net_rx(struct net_device *dev); +static int net_close(struct net_device *dev); +static struct net_device_stats *net_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); /* Example routines you must write ;->. */ #define tx_done(dev) 1 extern void hardware_send_packet(short ioaddr, char *buf, int length); -extern void chipset_init(struct device *dev, int startp); +extern void chipset_init(struct net_device *dev, int startp); /* * Check for a network adaptor of this type, and return '0' iff one exists. @@ -128,7 +128,7 @@ {cardname, netcard_probe1, NETCARD_IO_EXTENT, netcard_portlist}; #else int __init -netcard_probe(struct device *dev) +netcard_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -155,7 +155,7 @@ * probes on the ISA bus. A good device probes avoids doing writes, and * verifies that the correct device exists and functions. */ -static int __init netcard_probe1(struct device *dev, int ioaddr) +static int __init netcard_probe1(struct net_device *dev, int ioaddr) { static unsigned version_printed = 0; int i; @@ -306,7 +306,7 @@ * there is non-reboot way to recover if something goes wrong. */ static int -net_open(struct device *dev) +net_open(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -340,7 +340,7 @@ return 0; } -static int net_send_packet(struct sk_buff *skb, struct device *dev) +static int net_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -389,7 +389,7 @@ */ static void net_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *lp; int ioaddr, status, boguscount = 0; @@ -425,7 +425,7 @@ /* We have a good packet(s), get it/them out of the buffers. */ static void -net_rx(struct device *dev) +net_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -480,7 +480,7 @@ /* The inverse routine to net_open(). */ static int -net_close(struct device *dev) +net_close(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -512,7 +512,7 @@ * Get the current statistics. * This may be called with the card open or closed. */ -static struct net_device_stats *net_get_stats(struct device *dev) +static struct net_device_stats *net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; short ioaddr = dev->base_addr; @@ -533,7 +533,7 @@ * and do best-effort filtering. */ static void -set_multicast_list(struct device *dev) +set_multicast_list(struct net_device *dev) { short ioaddr = dev->base_addr; if (dev->flags&IFF_PROMISC) @@ -562,7 +562,7 @@ #ifdef MODULE static char devicename[9] = { 0, }; -static struct device this_device = { +static struct net_device this_device = { devicename, /* will be inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0, 0, /* I/O address, IRQ */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/sktr.c linux/drivers/net/sktr.c --- v2.3.13/linux/drivers/net/sktr.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/sktr.c Wed Aug 18 11:36:42 1999 @@ -116,63 +116,63 @@ */ /* "B" */ -static int sktr_bringup_diags(struct device *dev); +static int sktr_bringup_diags(struct net_device *dev); /* "C" */ static void sktr_cancel_tx_queue(struct net_local* tp); -static int sktr_chipset_init(struct device *dev); -static void sktr_chk_irq(struct device *dev); -static unsigned char sktr_chk_frame(struct device *dev, unsigned char *Addr); -static void sktr_chk_outstanding_cmds(struct device *dev); +static int sktr_chipset_init(struct net_device *dev); +static void sktr_chk_irq(struct net_device *dev); +static unsigned char sktr_chk_frame(struct net_device *dev, unsigned char *Addr); +static void sktr_chk_outstanding_cmds(struct net_device *dev); static void sktr_chk_src_addr(unsigned char *frame, unsigned char *hw_addr); static unsigned char sktr_chk_ssb(struct net_local *tp, unsigned short IrqType); -static int sktr_close(struct device *dev); -static void sktr_cmd_status_irq(struct device *dev); +static int sktr_close(struct net_device *dev); +static void sktr_cmd_status_irq(struct net_device *dev); /* "D" */ -static void sktr_disable_interrupts(struct device *dev); +static void sktr_disable_interrupts(struct net_device *dev); static void sktr_dump(unsigned char *Data, int length); /* "E" */ -static void sktr_enable_interrupts(struct device *dev); -static void sktr_exec_cmd(struct device *dev, unsigned short Command); -static void sktr_exec_sifcmd(struct device *dev, unsigned int WriteValue); +static void sktr_enable_interrupts(struct net_device *dev); +static void sktr_exec_cmd(struct net_device *dev, unsigned short Command); +static void sktr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue); /* "F" */ static unsigned char *sktr_fix_srouting(unsigned char *buf, short *FrameLen); /* "G" */ -static struct enet_statistics *sktr_get_stats(struct device *dev); +static struct enet_statistics *sktr_get_stats(struct net_device *dev); /* "H" */ -static void sktr_hardware_send_packet(struct device *dev, +static void sktr_hardware_send_packet(struct net_device *dev, struct net_local* tp); /* "I" */ -static int sktr_init_adapter(struct device *dev); -static int sktr_init_card(struct device *dev); +static int sktr_init_adapter(struct net_device *dev); +static int sktr_init_card(struct net_device *dev); static void sktr_init_ipb(struct net_local *tp); -static void sktr_init_net_local(struct device *dev); +static void sktr_init_net_local(struct net_device *dev); static void sktr_init_opb(struct net_local *tp); static void sktr_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static int sktr_isa_chk_card(struct device *dev, int ioaddr); +static int sktr_isa_chk_card(struct net_device *dev, int ioaddr); static int sktr_isa_chk_ioaddr(int ioaddr); /* "O" */ -static int sktr_open(struct device *dev); -static void sktr_open_adapter(struct device *dev); +static int sktr_open(struct net_device *dev); +static void sktr_open_adapter(struct net_device *dev); /* "P" */ -static int sktr_pci_chk_card(struct device *dev); -int sktr_probe(struct device *dev); -static int sktr_probe1(struct device *dev, int ioaddr); +static int sktr_pci_chk_card(struct net_device *dev); +int sktr_probe(struct net_device *dev); +static int sktr_probe1(struct net_device *dev, int ioaddr); /* "R" */ -static void sktr_rcv_status_irq(struct device *dev); -static void sktr_read_addr(struct device *dev, unsigned char *Address); -static void sktr_read_ptr(struct device *dev); -static void sktr_read_ram(struct device *dev, unsigned char *Data, +static void sktr_rcv_status_irq(struct net_device *dev); +static void sktr_read_addr(struct net_device *dev, unsigned char *Address); +static void sktr_read_ptr(struct net_device *dev); +static void sktr_read_ram(struct net_device *dev, unsigned char *Data, unsigned short Address, int Length); -static int sktr_reset_adapter(struct device *dev); -static void sktr_reset_interrupt(struct device *dev); -static void sktr_ring_status_irq(struct device *dev); +static int sktr_reset_adapter(struct net_device *dev); +static void sktr_reset_interrupt(struct net_device *dev); +static void sktr_ring_status_irq(struct net_device *dev); /* "S" */ -static int sktr_send_packet(struct sk_buff *skb, struct device *dev); -static void sktr_set_multicast_list(struct device *dev); +static int sktr_send_packet(struct sk_buff *skb, struct net_device *dev); +static void sktr_set_multicast_list(struct net_device *dev); /* "T" */ static void sktr_timer_chk(unsigned long data); static void sktr_timer_end_wait(unsigned long data); -static void sktr_tx_status_irq(struct device *dev); +static void sktr_tx_status_irq(struct net_device *dev); /* "U" */ static void sktr_update_rcv_stats(struct net_local *tp, unsigned char DataPtr[], unsigned int Length); @@ -186,7 +186,7 @@ * If dev->base_addr == 0, probe all likely locations. * If dev->base_addr == 1, always return failure. */ -int __init sktr_probe(struct device *dev) +int __init sktr_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -217,7 +217,7 @@ /* * Detect and setup the PCI SysKonnect TR cards in slot order. */ -static int __init sktr_pci_chk_card(struct device *dev) +static int __init sktr_pci_chk_card(struct net_device *dev) { static int pci_index = 0; unsigned char pci_bus, pci_device_fn; @@ -295,7 +295,7 @@ /* * Detect and setup the ISA SysKonnect TR cards. */ -static int __init sktr_isa_chk_card(struct device *dev, int ioaddr) +static int __init sktr_isa_chk_card(struct net_device *dev, int ioaddr) { int i, err; unsigned long flags; @@ -386,7 +386,7 @@ return (0); } -static int __init sktr_probe1(struct device *dev, int ioaddr) +static int __init sktr_probe1(struct net_device *dev, int ioaddr) { static unsigned version_printed = 0; struct net_local *tp; @@ -428,7 +428,7 @@ } /* Dummy function */ -static int __init sktr_init_card(struct device *dev) +static int __init sktr_init_card(struct net_device *dev) { if(sktr_debug > 3) printk("%s: sktr_init_card\n", dev->name); @@ -480,7 +480,7 @@ * 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 sktr_open(struct device *dev) +static int sktr_open(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; int err; @@ -549,7 +549,7 @@ */ static void sktr_timer_end_wait(unsigned long data) { - struct device *dev = (struct device*)data; + struct net_device *dev = (struct net_device*)data; struct net_local *tp = (struct net_local *)dev->priv; if(tp->Sleeping) @@ -564,7 +564,7 @@ /* * Initialize the chipset */ -static int sktr_chipset_init(struct device *dev) +static int sktr_chipset_init(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; unsigned char PosReg, Tmp; @@ -621,7 +621,7 @@ /* * Initializes the net_local structure. */ -static void sktr_init_net_local(struct device *dev) +static void sktr_init_net_local(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; int i; @@ -778,7 +778,7 @@ /* * Send OPEN command to adapter */ -static void sktr_open_adapter(struct device *dev) +static void sktr_open_adapter(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; @@ -795,7 +795,7 @@ * Clear the adapter's interrupt flag. Clear system interrupt enable * (SINTEN): disable adapter to system interrupts. */ -static void sktr_disable_interrupts(struct device *dev) +static void sktr_disable_interrupts(struct net_device *dev) { outb(0, dev->base_addr + SIFACL); @@ -806,7 +806,7 @@ * Set the adapter's interrupt flag. Set system interrupt enable * (SINTEN): enable adapter to system interrupts. */ -static void sktr_enable_interrupts(struct device *dev) +static void sktr_enable_interrupts(struct net_device *dev) { outb(ACL_SINTEN, dev->base_addr + SIFACL); @@ -816,7 +816,7 @@ /* * Put command in command queue, try to execute it. */ -static void sktr_exec_cmd(struct device *dev, unsigned short Command) +static void sktr_exec_cmd(struct net_device *dev, unsigned short Command) { struct net_local *tp = (struct net_local *)dev->priv; @@ -855,7 +855,7 @@ /* * Gets skb from system, queues it and checks if it can be sent */ -static int sktr_send_packet(struct sk_buff *skb, struct device *dev) +static int sktr_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; @@ -906,7 +906,7 @@ /* * Move frames from internal skb queue into adapter tx queue */ -static void sktr_hardware_send_packet(struct device *dev, struct net_local* tp) +static void sktr_hardware_send_packet(struct net_device *dev, struct net_local* tp) { TPL *tpl; short length; @@ -1014,7 +1014,7 @@ */ static void sktr_timer_chk(unsigned long data) { - struct device *dev = (struct device*)data; + struct net_device *dev = (struct net_device*)data; struct net_local *tp = (struct net_local*)dev->priv; if(tp->HaltInProgress) @@ -1045,7 +1045,7 @@ */ static void sktr_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; struct net_local *tp; int ioaddr; unsigned short irq_type; @@ -1139,7 +1139,7 @@ /* * Reset the INTERRUPT SYSTEM bit and issue SSB CLEAR command. */ -static void sktr_reset_interrupt(struct device *dev) +static void sktr_reset_interrupt(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; SSB *ssb = &tp->ssb; @@ -1225,7 +1225,7 @@ /* * Evaluates the command results status in the SSB status field. */ -static void sktr_cmd_status_irq(struct device *dev) +static void sktr_cmd_status_irq(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; unsigned short ssb_cmd, ssb_parm_0; @@ -1422,7 +1422,7 @@ /* * The inverse routine to sktr_open(). */ -static int sktr_close(struct device *dev) +static int sktr_close(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; @@ -1473,7 +1473,7 @@ * Get the current statistics. This may be called with the card open * or closed. */ -static struct enet_statistics *sktr_get_stats(struct device *dev) +static struct enet_statistics *sktr_get_stats(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; @@ -1483,7 +1483,7 @@ /* * Set or clear the multicast filter for this adapter. */ -static void sktr_set_multicast_list(struct device *dev) +static void sktr_set_multicast_list(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; unsigned int OpenOptions; @@ -1539,7 +1539,7 @@ /* * Write a command value to the SIFCMD register */ -static void sktr_exec_sifcmd(struct device *dev, unsigned int WriteValue) +static void sktr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue) { int ioaddr = dev->base_addr; unsigned short cmd; @@ -1561,7 +1561,7 @@ * Processes adapter hardware reset, halts adapter and downloads firmware, * clears the halt bit. */ -static int sktr_reset_adapter(struct device *dev) +static int sktr_reset_adapter(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; unsigned short *fw_ptr = (unsigned short *)&sktr_code; @@ -1630,7 +1630,7 @@ * Starts bring up diagnostics of token ring adapter and evaluates * diagnostic results. */ -static int sktr_bringup_diags(struct device *dev) +static int sktr_bringup_diags(struct net_device *dev) { int loop_cnt, retry_cnt; unsigned short Status; @@ -1685,7 +1685,7 @@ * Copy initialisation data to adapter memory, beginning at address * 1:0A00; Starting DMA test and evaluating result bits. */ -static int sktr_init_adapter(struct device *dev) +static int sktr_init_adapter(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; @@ -1787,7 +1787,7 @@ * Check for outstanding commands in command queue and tries to execute * command immediately. Corresponding command flag in command queue is cleared. */ -static void sktr_chk_outstanding_cmds(struct device *dev) +static void sktr_chk_outstanding_cmds(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; unsigned long Addr = 0; @@ -1967,7 +1967,7 @@ * error counter overflow (255); opened adapter is the only station in ring. * After some of the IRQs the adapter is closed! */ -static void sktr_ring_status_irq(struct device *dev) +static void sktr_ring_status_irq(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; @@ -2037,7 +2037,7 @@ * Issued if adapter has encountered an unrecoverable hardware * or software error. */ -static void sktr_chk_irq(struct device *dev) +static void sktr_chk_irq(struct net_device *dev) { int i; unsigned short AdapterCheckBlock[4]; @@ -2196,7 +2196,7 @@ * Internal adapter pointer to RAM data are copied from adapter into * host system. */ -static void sktr_read_ptr(struct device *dev) +static void sktr_read_ptr(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; unsigned short adapterram; @@ -2215,7 +2215,7 @@ /* * Reads a number of bytes from adapter to system memory. */ -static void sktr_read_ram(struct device *dev, unsigned char *Data, +static void sktr_read_ram(struct net_device *dev, unsigned char *Data, unsigned short Address, int Length) { int i; @@ -2256,7 +2256,7 @@ /* * Reads MAC address from adapter ROM. */ -static void sktr_read_addr(struct device *dev, unsigned char *Address) +static void sktr_read_addr(struct net_device *dev, unsigned char *Address) { int i, In; unsigned short ioaddr = dev->base_addr; @@ -2322,7 +2322,7 @@ * adapter. For a command complete interrupt, it is checked if we have to * issue a new transmit command or not. */ -static void sktr_tx_status_irq(struct device *dev) +static void sktr_tx_status_irq(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; unsigned char HighByte, HighAc, LowAc; @@ -2396,7 +2396,7 @@ * Called if a frame receive interrupt is generated by the adapter. * Check if the frame is valid and indicate it to system. */ -static void sktr_rcv_status_irq(struct device *dev) +static void sktr_rcv_status_irq(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; unsigned char *ReceiveDataPtr; @@ -2599,7 +2599,7 @@ * Check if it is a frame of myself. Compare source address with my current * address in reverse direction, and mask out the TR_RII. */ -static unsigned char sktr_chk_frame(struct device *dev, unsigned char *Addr) +static unsigned char sktr_chk_frame(struct net_device *dev, unsigned char *Addr) { int i; @@ -2635,7 +2635,7 @@ #ifdef MODULE -static struct device* dev_sktr[SKTR_MAX_ADAPTERS]; +static struct net_device* dev_sktr[SKTR_MAX_ADAPTERS]; static int io[SKTR_MAX_ADAPTERS] = { 0, 0 }; static int irq[SKTR_MAX_ADAPTERS] = { 0, 0 }; static int mem[SKTR_MAX_ADAPTERS] = { 0, 0 }; @@ -2664,7 +2664,7 @@ if(register_trdev(dev_sktr[i]) != 0) { - kfree_s(dev_sktr[i], sizeof(struct device)); + kfree_s(dev_sktr[i], sizeof(struct net_device)); dev_sktr[i] = NULL; if(i == 0) { @@ -2695,7 +2695,7 @@ free_dma(dev_sktr[i]->dma); if(dev_sktr[i]->priv) kfree_s(dev_sktr[i]->priv, sizeof(struct net_local)); - kfree_s(dev_sktr[i], sizeof(struct device)); + kfree_s(dev_sktr[i], sizeof(struct net_device)); dev_sktr[i] = NULL; } } diff -u --recursive --new-file v2.3.13/linux/drivers/net/slip.c linux/drivers/net/slip.c --- v2.3.13/linux/drivers/net/slip.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/slip.c Wed Aug 18 11:36:42 1999 @@ -91,7 +91,7 @@ typedef struct slip_ctrl { char if_name[8]; /* "sl0\0" .. "sl99999\0" */ struct slip ctrl; /* SLIP things */ - struct device dev; /* the device */ + struct net_device dev; /* the device */ } slip_ctrl_t; static slip_ctrl_t **slip_ctrls = NULL; @@ -109,7 +109,7 @@ #ifdef CONFIG_SLIP_SMART static void sl_keepalive(unsigned long sls); static void sl_outfill(unsigned long sls); -static int sl_ioctl(struct device *dev,struct ifreq *rq,int cmd); +static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd); #endif /******************************** @@ -233,7 +233,7 @@ static int sl_realloc_bufs(struct slip *sl, int mtu) { int err = 0; - struct device *dev = sl->dev; + struct net_device *dev = sl->dev; unsigned char *xbuff, *rbuff; #ifdef SL_INCLUDE_CSLIP unsigned char *cbuff; @@ -473,7 +473,7 @@ /* Encapsulate an IP datagram and kick it into a TTY queue. */ static int -sl_xmit(struct sk_buff *skb, struct device *dev) +sl_xmit(struct sk_buff *skb, struct net_device *dev) { struct slip *sl = (struct slip*)(dev->priv); @@ -536,7 +536,7 @@ /* Netdevice UP -> DOWN routine */ static int -sl_close(struct device *dev) +sl_close(struct net_device *dev) { struct slip *sl = (struct slip*)(dev->priv); @@ -557,7 +557,7 @@ /* Netdevice DOWN -> UP routine */ -static int sl_open(struct device *dev) +static int sl_open(struct net_device *dev) { struct slip *sl = (struct slip*)(dev->priv); @@ -573,7 +573,7 @@ /* Netdevice change MTU request */ -static int sl_change_mtu(struct device *dev, int new_mtu) +static int sl_change_mtu(struct net_device *dev, int new_mtu) { struct slip *sl = (struct slip*)(dev->priv); @@ -588,7 +588,7 @@ /* Netdevice get statistics request */ static struct net_device_stats * -sl_get_stats(struct device *dev) +sl_get_stats(struct net_device *dev) { static struct net_device_stats stats; struct slip *sl = (struct slip*)(dev->priv); @@ -624,7 +624,7 @@ /* Netdevice register callback */ -static int sl_init(struct device *dev) +static int sl_init(struct net_device *dev) { struct slip *sl = (struct slip*)(dev->priv); @@ -1243,7 +1243,7 @@ to allow get/set outfill/keepalive parameter by ifconfig */ -static int sl_ioctl(struct device *dev,struct ifreq *rq,int cmd) +static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) { struct slip *sl = (struct slip*)(dev->priv); @@ -1318,7 +1318,7 @@ #ifdef MODULE static int slip_init_ctrl_dev(void) #else /* !MODULE */ -int __init slip_init_ctrl_dev(struct device *dummy) +int __init slip_init_ctrl_dev(struct net_device *dummy) #endif /* !MODULE */ { int status; diff -u --recursive --new-file v2.3.13/linux/drivers/net/slip.h linux/drivers/net/slip.h --- v2.3.13/linux/drivers/net/slip.h Sun Mar 1 14:40:39 1998 +++ linux/drivers/net/slip.h Wed Aug 18 11:36:45 1999 @@ -52,7 +52,7 @@ /* Various fields. */ struct tty_struct *tty; /* ptr to TTY structure */ - struct device *dev; /* easy for intr handling */ + struct net_device *dev; /* easy for intr handling */ #ifdef SL_INCLUDE_CSLIP struct slcompress *slcomp; /* for header compression */ unsigned char *cbuff; /* compression buffer */ @@ -118,6 +118,6 @@ #define SLIP_MAGIC 0x5302 -extern int slip_init(struct device *dev); +extern int slip_init(struct net_device *dev); #endif /* _LINUX_SLIP.H */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/smc-mca.c linux/drivers/net/smc-mca.c --- v2.3.13/linux/drivers/net/smc-mca.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/smc-mca.c Wed Aug 18 11:36:42 1999 @@ -42,20 +42,20 @@ #include "smc-mca.h" #include -int ultramca_probe(struct device *dev); +int ultramca_probe(struct net_device *dev); -static int ultramca_open(struct device *dev); -static void ultramca_reset_8390(struct device *dev); -static void ultramca_get_8390_hdr(struct device *dev, +static int ultramca_open(struct net_device *dev); +static void ultramca_reset_8390(struct net_device *dev); +static void ultramca_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ultramca_block_input(struct device *dev, int count, +static void ultramca_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ultramca_block_output(struct device *dev, int count, +static void ultramca_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); -static int ultramca_close_card(struct device *dev); +static int ultramca_close_card(struct net_device *dev); #define START_PG 0x00 /* First page of TX buffer */ @@ -66,7 +66,7 @@ #define ULTRA_IO_EXTENT 32 #define EN0_ERWCNT 0x08 /* Early receive warning count. */ -int __init ultramca_probe(struct device *dev) +int __init ultramca_probe(struct net_device *dev) { unsigned short ioaddr; unsigned char reg4, num_pages; @@ -190,7 +190,7 @@ return 0; } -static int ultramca_open(struct device *dev) +static int ultramca_open(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ @@ -217,7 +217,7 @@ return 0; } -static void ultramca_reset_8390(struct device *dev) +static void ultramca_reset_8390(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ @@ -237,7 +237,7 @@ we don't need to be concerned with ring wrap as the header will be at the start of a page, so we optimize accordingly. */ -static void ultramca_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +static void ultramca_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = dev->mem_start + ((ring_page - START_PG)<<8); @@ -252,7 +252,7 @@ /* Block input and output are easy on shared memory ethercards, the only complication is when the ring buffer wraps. */ -static void ultramca_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +static void ultramca_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned long xfer_start = dev->mem_start + ring_offset - (START_PG<<8); @@ -272,7 +272,7 @@ } -static void ultramca_block_output(struct device *dev, int count, const unsigned char *buf, +static void ultramca_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { unsigned long shmem = dev->mem_start + ((start_page - START_PG)<<8); @@ -280,7 +280,7 @@ memcpy_toio(shmem, buf, count); } -static int ultramca_close_card(struct device *dev) +static int ultramca_close_card(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ @@ -310,7 +310,7 @@ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_ULTRAMCA_CARDS] = { 0, }; -static struct device dev_ultra[MAX_ULTRAMCA_CARDS] = +static struct net_device dev_ultra[MAX_ULTRAMCA_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ @@ -335,7 +335,7 @@ for (this_dev = 0; this_dev < MAX_ULTRAMCA_CARDS; this_dev++) { - struct device *dev = &dev_ultra[this_dev]; + struct net_device *dev = &dev_ultra[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -367,7 +367,7 @@ for (this_dev = 0; this_dev < MAX_ULTRAMCA_CARDS; this_dev++) { - struct device *dev = &dev_ultra[this_dev]; + struct net_device *dev = &dev_ultra[this_dev]; if (dev->priv != NULL) { void *priv = dev->priv; diff -u --recursive --new-file v2.3.13/linux/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c --- v2.3.13/linux/drivers/net/smc-ultra.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/smc-ultra.c Wed Aug 18 11:36:42 1999 @@ -66,24 +66,24 @@ static unsigned int ultra_portlist[] __initdata = {0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0}; -int ultra_probe(struct device *dev); -int ultra_probe1(struct device *dev, int ioaddr); +int ultra_probe(struct net_device *dev); +int ultra_probe1(struct net_device *dev, int ioaddr); -static int ultra_open(struct device *dev); -static void ultra_reset_8390(struct device *dev); -static void ultra_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static int ultra_open(struct net_device *dev); +static void ultra_reset_8390(struct net_device *dev); +static void ultra_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ultra_block_input(struct device *dev, int count, +static void ultra_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ultra_block_output(struct device *dev, int count, +static void ultra_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); -static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void ultra_pio_get_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ultra_pio_input(struct device *dev, int count, +static void ultra_pio_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ultra_pio_output(struct device *dev, int count, +static void ultra_pio_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); -static int ultra_close_card(struct device *dev); +static int ultra_close_card(struct net_device *dev); #define START_PG 0x00 /* First page of TX buffer */ @@ -106,7 +106,7 @@ {"ultra", ultra_probe1, NETCARD_IO_EXTENT, netcard_portlist}; #else -int __init ultra_probe(struct device *dev) +int __init ultra_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -128,7 +128,7 @@ } #endif -int __init ultra_probe1(struct device *dev, int ioaddr) +int __init ultra_probe1(struct net_device *dev, int ioaddr) { int i; int checksum = 0; @@ -250,7 +250,7 @@ } static int -ultra_open(struct device *dev) +ultra_open(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ unsigned char irq2reg[] = {0, 0, 0x04, 0x08, 0, 0x0C, 0, 0x40, @@ -281,7 +281,7 @@ } static void -ultra_reset_8390(struct device *dev) +ultra_reset_8390(struct net_device *dev) { int cmd_port = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC base addr */ @@ -305,7 +305,7 @@ the start of a page, so we optimize accordingly. */ static void -ultra_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +ultra_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = dev->mem_start + ((ring_page - START_PG)<<8); @@ -323,7 +323,7 @@ complication is when the ring buffer wraps. */ static void -ultra_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +ultra_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { unsigned long xfer_start = dev->mem_start + ring_offset - (START_PG<<8); @@ -345,7 +345,7 @@ } static void -ultra_block_output(struct device *dev, int count, const unsigned char *buf, +ultra_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { unsigned long shmem = dev->mem_start + ((start_page - START_PG)<<8); @@ -366,7 +366,7 @@ and must be always be rewritten between each read/write direction change. This is no problem for us, as the 8390 code ensures that we are single threaded. */ -static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static void ultra_pio_get_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ @@ -375,7 +375,7 @@ insw(ioaddr + IOPD, hdr, sizeof(struct e8390_pkt_hdr)>>1); } -static void ultra_pio_input(struct device *dev, int count, +static void ultra_pio_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ @@ -388,7 +388,7 @@ insw(ioaddr + IOPD, buf, (count+1)>>1); } -static void ultra_pio_output(struct device *dev, int count, +static void ultra_pio_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ @@ -399,7 +399,7 @@ } static int -ultra_close_card(struct device *dev) +ultra_close_card(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* CMDREG */ @@ -427,7 +427,7 @@ #define MAX_ULTRA_CARDS 4 /* Max number of Ultra cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_ULTRA_CARDS] = { 0, }; -static struct device dev_ultra[MAX_ULTRA_CARDS] = { +static struct net_device dev_ultra[MAX_ULTRA_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -452,7 +452,7 @@ int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) { - struct device *dev = &dev_ultra[this_dev]; + struct net_device *dev = &dev_ultra[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -478,7 +478,7 @@ int this_dev; for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) { - struct device *dev = &dev_ultra[this_dev]; + struct net_device *dev = &dev_ultra[this_dev]; if (dev->priv != NULL) { /* NB: ultra_close_card() does free_irq + irq2dev */ int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; diff -u --recursive --new-file v2.3.13/linux/drivers/net/smc-ultra32.c linux/drivers/net/smc-ultra32.c --- v2.3.13/linux/drivers/net/smc-ultra32.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/smc-ultra32.c Wed Aug 18 11:36:42 1999 @@ -60,18 +60,18 @@ #include #include "8390.h" -int ultra32_probe(struct device *dev); -int ultra32_probe1(struct device *dev, int ioaddr); -static int ultra32_open(struct device *dev); -static void ultra32_reset_8390(struct device *dev); -static void ultra32_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +int ultra32_probe(struct net_device *dev); +int ultra32_probe1(struct net_device *dev, int ioaddr); +static int ultra32_open(struct net_device *dev); +static void ultra32_reset_8390(struct net_device *dev); +static void ultra32_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void ultra32_block_input(struct device *dev, int count, +static void ultra32_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void ultra32_block_output(struct device *dev, int count, +static void ultra32_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); -static int ultra32_close(struct device *dev); +static int ultra32_close(struct net_device *dev); #define ULTRA32_CMDREG 0 /* Offset to ASIC command register. */ #define ULTRA32_RESET 0x80 /* Board reset, in ULTRA32_CMDREG. */ @@ -103,7 +103,7 @@ following. */ -int __init ultra32_probe(struct device *dev) +int __init ultra32_probe(struct net_device *dev) { const char *ifmap[] = {"UTP No Link", "", "UTP/AUI", "UTP/BNC"}; int ioaddr, edge, media; @@ -126,7 +126,7 @@ return ENODEV; } -int __init ultra32_probe1(struct device *dev, int ioaddr) +int __init ultra32_probe1(struct net_device *dev, int ioaddr) { int i; int checksum = 0; @@ -240,7 +240,7 @@ return 0; } -static int ultra32_open(struct device *dev) +static int ultra32_open(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* ASIC addr */ int irq_flags = (inb(ioaddr + ULTRA32_CFG5) & 0x08) ? 0 : SA_SHIRQ; @@ -261,7 +261,7 @@ return 0; } -static int ultra32_close(struct device *dev) +static int ultra32_close(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* CMDREG */ @@ -282,7 +282,7 @@ return 0; } -static void ultra32_reset_8390(struct device *dev) +static void ultra32_reset_8390(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* ASIC base addr */ @@ -302,7 +302,7 @@ we don't need to be concerned with ring wrap as the header will be at the start of a page, so we optimize accordingly. */ -static void ultra32_get_8390_hdr(struct device *dev, +static void ultra32_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { @@ -325,7 +325,7 @@ packet spans an 8KB boundary. Note that the current 8KB segment is already set by the get_8390_hdr routine. */ -static void ultra32_block_input(struct device *dev, +static void ultra32_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) @@ -353,7 +353,7 @@ } } -static void ultra32_block_output(struct device *dev, +static void ultra32_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) @@ -371,7 +371,7 @@ #define MAX_ULTRA32_CARDS 4 /* Max number of Ultra cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_ULTRA32_CARDS] = { 0, }; -static struct device dev_ultra[MAX_ULTRA32_CARDS] = { +static struct net_device dev_ultra[MAX_ULTRA32_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -385,7 +385,7 @@ int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_ULTRA32_CARDS; this_dev++) { - struct device *dev = &dev_ultra[this_dev]; + struct net_device *dev = &dev_ultra[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->init = ultra32_probe; if (register_netdev(dev) != 0) { @@ -407,7 +407,7 @@ int this_dev; for (this_dev = 0; this_dev < MAX_ULTRA32_CARDS; this_dev++) { - struct device *dev = &dev_ultra[this_dev]; + struct net_device *dev = &dev_ultra[this_dev]; if (dev->priv != NULL) { int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; void *priv = dev->priv; diff -u --recursive --new-file v2.3.13/linux/drivers/net/smc9194.c linux/drivers/net/smc9194.c --- v2.3.13/linux/drivers/net/smc9194.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/smc9194.c Wed Aug 18 11:36:42 1999 @@ -208,43 +208,43 @@ . . NB:This shouldn't be static since it is referred to externally. */ -int smc_init(struct device *dev); +int smc_init(struct net_device *dev); /* . The kernel calls this function when someone wants to use the device, . typically 'ifconfig ethX up'. */ -static int smc_open(struct device *dev); +static int smc_open(struct net_device *dev); /* . This is called by the kernel to send a packet out into the net. it's . responsible for doing a best-effort send, but if it's simply not possible . to send it, the packet gets dropped. */ -static int smc_send_packet(struct sk_buff *skb, struct device *dev); +static int smc_send_packet(struct sk_buff *skb, struct net_device *dev); /* . This is called by the kernel in response to 'ifconfig ethX down'. It . is responsible for cleaning up everything that the open routine . does, and maybe putting the card into a powerdown state. */ -static int smc_close(struct device *dev); +static int smc_close(struct net_device *dev); /* . This routine allows the proc file system to query the driver's . statistics. */ -static struct net_device_stats * smc_query_statistics( struct device *dev); +static struct net_device_stats * smc_query_statistics( struct net_device *dev); /* . Finally, a call to set promiscuous mode ( for TCPDUMP and related . programs ) and multicast modes. */ #ifdef SUPPORT_OLD_KERNEL -static void smc_set_multicast_list(struct device *dev, int num_addrs, +static void smc_set_multicast_list(struct net_device *dev, int num_addrs, void *addrs); #else -static void smc_set_multicast_list(struct device *dev); +static void smc_set_multicast_list(struct net_device *dev); #endif /*--------------------------------------------------------------- @@ -265,12 +265,12 @@ . This is a separate procedure to handle the receipt of a packet, to . leave the interrupt code looking slightly cleaner */ -inline static void smc_rcv( struct device *dev ); +inline static void smc_rcv( struct net_device *dev ); /* . This handles a TX interrupt, which is only called when an error . relating to a packet is sent. */ -inline static void smc_tx( struct device * dev ); +inline static void smc_tx( struct net_device * dev ); /* ------------------------------------------------------------ @@ -292,7 +292,7 @@ . of a device parameter. . It will give an error if it can't initialize the card. */ -static int smc_initcard( struct device *, int ioaddr ); +static int smc_initcard( struct net_device *, int ioaddr ); /* . A rather simple routine to print out a packet for debugging purposes. @@ -304,13 +304,13 @@ #define tx_done(dev) 1 /* this is called to actually send the packet to the chip */ -static void smc_hardware_send_packet( struct device * dev ); +static void smc_hardware_send_packet( struct net_device * dev ); /* Since I am not sure if I will have enough room in the chip's ram . to store the packet, I call this routine, which either sends it . now, or generates an interrupt when the card is ready for the . packet */ -static int smc_wait_to_send_packet( struct sk_buff * skb, struct device *dev ); +static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device *dev ); /* this does a soft reset on the device */ static void smc_reset( int ioaddr ); @@ -337,7 +337,7 @@ #endif #ifdef SUPPORT_OLD_KERNEL -extern struct device *init_etherdev(struct device *dev, int sizeof_private, +extern struct net_device *init_etherdev(struct net_device *dev, int sizeof_private, unsigned long *mem_startp ); #endif @@ -529,7 +529,7 @@ /* - . Function: smc_wait_to_send_packet( struct sk_buff * skb, struct device * ) + . Function: smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * ) . Purpose: . Attempt to allocate memory for a packet, if chip-memory is not . available, then tell the card to generate an interrupt when it @@ -544,7 +544,7 @@ . o (NO): Enable interrupts and let the interrupt handler deal with it. . o (YES):Send it now. */ -static int smc_wait_to_send_packet( struct sk_buff * skb, struct device * dev ) +static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * dev ) { struct smc_local *lp = (struct smc_local *)dev->priv; unsigned short ioaddr = dev->base_addr; @@ -621,7 +621,7 @@ } /* - . Function: smc_hardware_send_packet(struct device * ) + . Function: smc_hardware_send_packet(struct net_device * ) . Purpose: . This sends the actual packet to the SMC9xxx chip. . @@ -638,7 +638,7 @@ . Enable the transmit interrupt, so I know if it failed . Free the kernel data if I actually sent it. */ -static void smc_hardware_send_packet( struct device * dev ) +static void smc_hardware_send_packet( struct net_device * dev ) { struct smc_local *lp = (struct smc_local *)dev->priv; byte packet_no; @@ -737,7 +737,7 @@ /*------------------------------------------------------------------------- | - | smc_init( struct device * dev ) + | smc_init( struct net_device * dev ) | Input parameters: | dev->base_addr == 0, try to find all possible locations | dev->base_addr == 1, return failure code @@ -750,7 +750,7 @@ | --------------------------------------------------------------------------- */ -int __init smc_init(struct device *dev) +int __init smc_init(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -942,7 +942,7 @@ . o GRAB the region .----------------------------------------------------------------- */ -static int __init smc_initcard(struct device *dev, int ioaddr) +static int __init smc_initcard(struct net_device *dev, int ioaddr) { int i; @@ -1165,7 +1165,7 @@ * Set up everything, reset the card, etc .. * */ -static int smc_open(struct device *dev) +static int smc_open(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -1220,7 +1220,7 @@ . skeleton.c, from Becker. .-------------------------------------------------------- */ -static int smc_send_packet(struct sk_buff *skb, struct device *dev) +static int smc_send_packet(struct sk_buff *skb, struct net_device *dev) { if (dev->tbusy) { /* If we get here, some higher level has decided we are broken. @@ -1272,7 +1272,7 @@ static void smc_interrupt(int irq, struct pt_regs * regs) #endif { - struct device *dev = dev_id; + struct net_device *dev = dev_id; int ioaddr = dev->base_addr; struct smc_local *lp = (struct smc_local *)dev->priv; @@ -1414,7 +1414,7 @@ . o otherwise, read in the packet -------------------------------------------------------------- */ -static void smc_rcv(struct device *dev) +static void smc_rcv(struct net_device *dev) { struct smc_local *lp = (struct smc_local *)dev->priv; int ioaddr = dev->base_addr; @@ -1553,7 +1553,7 @@ . ( resend? Not really, since we don't want old packets around ) . Restore saved values ************************************************************************/ -static void smc_tx( struct device * dev ) +static void smc_tx( struct net_device * dev ) { int ioaddr = dev->base_addr; struct smc_local *lp = (struct smc_local *)dev->priv; @@ -1614,7 +1614,7 @@ . an 'ifconfig ethX down' . -----------------------------------------------------*/ -static int smc_close(struct device *dev) +static int smc_close(struct net_device *dev) { dev->tbusy = 1; dev->start = 0; @@ -1634,7 +1634,7 @@ . Get the current statistics. . This may be called with the card open or closed. .-------------------------------------------------------------*/ -static struct net_device_stats* smc_query_statistics(struct device *dev) { +static struct net_device_stats* smc_query_statistics(struct net_device *dev) { struct smc_local *lp = (struct smc_local *)dev->priv; return &lp->stats; @@ -1649,10 +1649,10 @@ . a select set of multicast packets */ #ifdef SUPPORT_OLD_KERNEL -static void smc_set_multicast_list( struct device * dev, +static void smc_set_multicast_list( struct net_device * dev, int num_addrs, void * addrs ) #else -static void smc_set_multicast_list(struct device *dev) +static void smc_set_multicast_list(struct net_device *dev) #endif { short ioaddr = dev->base_addr; @@ -1725,7 +1725,7 @@ #ifdef MODULE static char devicename[9] = { 0, }; -static struct device devSMC9194 = { +static struct net_device devSMC9194 = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0, 0, /* I/O address, IRQ */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/sonic.c linux/drivers/net/sonic.c --- v2.3.13/linux/drivers/net/sonic.c Wed Jun 30 13:38:20 1999 +++ linux/drivers/net/sonic.c Wed Aug 18 11:36:42 1999 @@ -26,7 +26,7 @@ * 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 sonic_open(struct device *dev) +static int sonic_open(struct net_device *dev) { if (sonic_debug > 2) printk("sonic_open: initializing sonic driver.\n"); @@ -67,7 +67,7 @@ * Close the SONIC device */ static int -sonic_close(struct device *dev) +sonic_close(struct net_device *dev) { unsigned int base_addr = dev->base_addr; @@ -93,7 +93,7 @@ /* * transmit packet */ -static int sonic_send_packet(struct sk_buff *skb, struct device *dev) +static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) { struct sonic_local *lp = (struct sonic_local *)dev->priv; unsigned int base_addr = dev->base_addr; @@ -183,7 +183,7 @@ static void sonic_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; unsigned int base_addr = dev->base_addr; struct sonic_local *lp; int status; @@ -301,7 +301,7 @@ * We have a good packet(s), get it/them out of the buffers. */ static void -sonic_rx(struct device *dev) +sonic_rx(struct net_device *dev) { unsigned int base_addr = dev->base_addr; struct sonic_local *lp = (struct sonic_local *)dev->priv; @@ -378,7 +378,7 @@ * This may be called with the device open or closed. */ static struct enet_statistics * -sonic_get_stats(struct device *dev) +sonic_get_stats(struct net_device *dev) { struct sonic_local *lp = (struct sonic_local *)dev->priv; unsigned int base_addr = dev->base_addr; @@ -399,7 +399,7 @@ * Set or clear the multicast filter for this adaptor. */ static void -sonic_multicast_list(struct device *dev) +sonic_multicast_list(struct net_device *dev) { struct sonic_local *lp = (struct sonic_local *)dev->priv; unsigned int base_addr = dev->base_addr; @@ -445,7 +445,7 @@ /* * Initialize the SONIC ethernet controller. */ -static int sonic_init(struct device *dev) +static int sonic_init(struct net_device *dev) { unsigned int base_addr = dev->base_addr; unsigned int cmd; diff -u --recursive --new-file v2.3.13/linux/drivers/net/sonic.h linux/drivers/net/sonic.h --- v2.3.13/linux/drivers/net/sonic.h Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/sonic.h Wed Aug 18 11:36:45 1999 @@ -17,6 +17,8 @@ #ifndef SONIC_H #define SONIC_H +#include + /* * SONIC register offsets */ @@ -463,14 +465,14 @@ /* Index to functions, as function prototypes. */ -static int sonic_open(struct device *dev); -static int sonic_send_packet(struct sk_buff *skb, struct device *dev); +static int sonic_open(struct net_device *dev); +static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev); static void sonic_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void sonic_rx(struct device *dev); -static int sonic_close(struct device *dev); -static struct enet_statistics *sonic_get_stats(struct device *dev); -static void sonic_multicast_list(struct device *dev); -static int sonic_init(struct device *dev); +static void sonic_rx(struct net_device *dev); +static int sonic_close(struct net_device *dev); +static struct enet_statistics *sonic_get_stats(struct net_device *dev); +static void sonic_multicast_list(struct net_device *dev); +static int sonic_init(struct net_device *dev); static const char *version = "sonic.c:v0.92 20.9.98 tsbogend@alpha.franken.de\n"; diff -u --recursive --new-file v2.3.13/linux/drivers/net/strip.c linux/drivers/net/strip.c --- v2.3.13/linux/drivers/net/strip.c Tue May 25 13:06:34 1999 +++ linux/drivers/net/strip.c Wed Aug 18 11:36:43 1999 @@ -311,7 +311,7 @@ struct tty_struct *tty; /* ptr to TTY structure */ char8 if_name; /* Dynamically generated name */ - struct device dev; /* Our device structure */ + struct net_device dev; /* Our device structure */ /* * Neighbour radio records @@ -505,7 +505,7 @@ restore_flags(x); } -static int arp_query(unsigned char *haddr, u32 paddr, struct device * dev) +static int arp_query(unsigned char *haddr, u32 paddr, struct net_device * dev) { struct neighbour *neighbor_entry; @@ -932,7 +932,7 @@ static int allocate_buffers(struct strip *strip_info) { - struct device *dev = &strip_info->dev; + struct net_device *dev = &strip_info->dev; int sx_size = MAX(STRIP_ENCAP_SIZE(MAX_RECV_MTU), 4096); int tx_size = STRIP_ENCAP_SIZE(dev->mtu) + MaxCommandStringLength; __u8 *r = kmalloc(MAX_RECV_MTU, GFP_ATOMIC); @@ -963,7 +963,7 @@ static void strip_changedmtu(struct strip *strip_info) { int old_mtu = strip_info->mtu; - struct device *dev = &strip_info->dev; + struct net_device *dev = &strip_info->dev; unsigned char *orbuff = strip_info->rx_buff; unsigned char *osbuff = strip_info->sx_buff; unsigned char *otbuff = strip_info->tx_buff; @@ -1636,7 +1636,7 @@ } /* Encapsulate a datagram and kick it into a TTY queue. */ -static int strip_xmit(struct sk_buff *skb, struct device *dev) +static int strip_xmit(struct sk_buff *skb, struct net_device *dev) { struct strip *strip_info = (struct strip *)(dev->priv); @@ -1693,7 +1693,7 @@ static void strip_IdleTask(unsigned long parameter) { - strip_xmit(NULL, (struct device *)parameter); + strip_xmit(NULL, (struct net_device *)parameter); } /* @@ -1707,7 +1707,7 @@ * rebuild_header later to fill in the address) */ -static int strip_header(struct sk_buff *skb, struct device *dev, +static int strip_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { struct strip *strip_info = (struct strip *)(dev->priv); @@ -2018,7 +2018,7 @@ if (ptr+16 > end) RecvErr("Bad Info Msg:", strip_info); } -static struct device *get_strip_dev(struct strip *strip_info) +static struct net_device *get_strip_dev(struct strip *strip_info) { /* If our hardware address is *manually set* to zero, and we know our */ /* real radio hardware address, try to find another strip device that has been */ @@ -2027,7 +2027,7 @@ !memcmp(strip_info->dev.dev_addr, zero_address.c, sizeof(zero_address)) && memcmp(&strip_info->true_dev_addr, zero_address.c, sizeof(zero_address))) { - struct device *dev; + struct net_device *dev; read_lock_bh(&dev_base_lock); dev = dev_base; while (dev) @@ -2414,7 +2414,7 @@ return 0; } -static int dev_set_mac_address(struct device *dev, void *addr) +static int dev_set_mac_address(struct net_device *dev, void *addr) { struct strip *strip_info = (struct strip *)(dev->priv); struct sockaddr *sa = addr; @@ -2423,7 +2423,7 @@ return 0; } -static struct enet_statistics *strip_get_stats(struct device *dev) +static struct enet_statistics *strip_get_stats(struct net_device *dev) { static struct enet_statistics stats; struct strip *strip_info = (struct strip *)(dev->priv); @@ -2468,7 +2468,7 @@ /* Open the low-level part of the STRIP channel. Easy! */ -static int strip_open_low(struct device *dev) +static int strip_open_low(struct net_device *dev) { struct strip *strip_info = (struct strip *)(dev->priv); struct in_device *in_dev = dev->ip_ptr; @@ -2509,7 +2509,7 @@ * Close the low-level part of the STRIP channel. Easy! */ -static int strip_close_low(struct device *dev) +static int strip_close_low(struct net_device *dev) { struct strip *strip_info = (struct strip *)(dev->priv); @@ -2546,7 +2546,7 @@ * (dynamically assigned) device is registered */ -static int strip_dev_init(struct device *dev) +static int strip_dev_init(struct net_device *dev) { /* * Finish setting up the DEVICE info. @@ -2821,7 +2821,7 @@ #ifdef MODULE static #endif -int strip_init_ctrl_dev(struct device *dummy) +int strip_init_ctrl_dev(struct net_device *dummy) { static struct tty_ldisc strip_ldisc; int status; diff -u --recursive --new-file v2.3.13/linux/drivers/net/sunbmac.c linux/drivers/net/sunbmac.c --- v2.3.13/linux/drivers/net/sunbmac.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/sunbmac.c Wed Aug 18 11:36:43 1999 @@ -199,7 +199,7 @@ static void bigmac_init_rings(struct bigmac *bp, int from_irq) { struct bmac_init_block *bb = bp->bmac_block; - struct device *dev = bp->dev; + struct net_device *dev = bp->dev; int i, gfp_flags = GFP_KERNEL; if(from_irq || in_interrupt()) @@ -1014,7 +1014,7 @@ } #endif -static int bigmac_open(struct device *dev) +static int bigmac_open(struct net_device *dev) { struct bigmac *bp = (struct bigmac *) dev->priv; int res; @@ -1041,7 +1041,7 @@ return res; } -static int bigmac_close(struct device *dev) +static int bigmac_close(struct net_device *dev) { struct bigmac *bp = (struct bigmac *) dev->priv; @@ -1057,7 +1057,7 @@ } /* Put a packet on the wire. */ -static int bigmac_start_xmit(struct sk_buff *skb, struct device *dev) +static int bigmac_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct bigmac *bp = (struct bigmac *) dev->priv; int len, entry; @@ -1123,7 +1123,7 @@ } #ifndef __sparc_v9__ -static int sun4c_bigmac_start_xmit(struct sk_buff *skb, struct device *dev) +static int sun4c_bigmac_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct bigmac *bp = (struct bigmac *) dev->priv; struct bigmac_buffers *bbufs = bp->sun4c_buffers; @@ -1182,7 +1182,7 @@ } #endif -static struct enet_statistics *bigmac_get_stats(struct device *dev) +static struct enet_statistics *bigmac_get_stats(struct net_device *dev) { struct bigmac *bp = (struct bigmac *) dev->priv; @@ -1193,7 +1193,7 @@ #define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */ #define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */ -static void bigmac_set_multicast(struct device *dev) +static void bigmac_set_multicast(struct net_device *dev) { struct bigmac *bp = (struct bigmac *) dev->priv; struct BIG_MAC_regs *bregs = bp->bregs; @@ -1253,7 +1253,7 @@ bregs->rx_cfg |= BIGMAC_RXCFG_ENABLE; } -static int __init bigmac_ether_init(struct device *dev, struct linux_sbus_device *qec_sdev) +static int __init bigmac_ether_init(struct net_device *dev, struct linux_sbus_device *qec_sdev) { static unsigned version_printed = 0; struct bigmac *bp = 0; @@ -1492,7 +1492,7 @@ return res; /* Return error code. */ } -int __init bigmac_probe(struct device *dev) +int __init bigmac_probe(struct net_device *dev) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff -u --recursive --new-file v2.3.13/linux/drivers/net/sunbmac.h linux/drivers/net/sunbmac.h --- v2.3.13/linux/drivers/net/sunbmac.h Mon Mar 15 16:11:30 1999 +++ linux/drivers/net/sunbmac.h Wed Aug 18 11:36:45 1999 @@ -356,7 +356,7 @@ struct enet_statistics enet_stats; struct linux_sbus_device *qec_sbus_dev; struct linux_sbus_device *bigmac_sbus_dev; - struct device *dev; + struct net_device *dev; struct bigmac *next_module; }; diff -u --recursive --new-file v2.3.13/linux/drivers/net/sunhme.c linux/drivers/net/sunhme.c --- v2.3.13/linux/drivers/net/sunhme.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/sunhme.c Wed Aug 18 11:36:43 1999 @@ -1046,7 +1046,7 @@ static void happy_meal_init_rings(struct happy_meal *hp, int from_irq) { struct hmeal_init_block *hb = hp->happy_block; - struct device *dev = hp->dev; + struct net_device *dev = hp->dev; int i, gfp_flags = GFP_KERNEL; if(from_irq || in_interrupt()) @@ -1841,7 +1841,7 @@ * ring when we cannot get a new skb and give them all back to the happy meal, * maybe things will be "happier" now. */ -static inline void happy_meal_rx(struct happy_meal *hp, struct device *dev, +static inline void happy_meal_rx(struct happy_meal *hp, struct net_device *dev, struct hmeal_gregs *gregs) { struct happy_meal_rxd *rxbase = &hp->happy_block->happy_meal_rxd[0]; @@ -1947,7 +1947,7 @@ } #ifdef CONFIG_PCI -static inline void pci_happy_meal_rx(struct happy_meal *hp, struct device *dev, +static inline void pci_happy_meal_rx(struct happy_meal *hp, struct net_device *dev, struct hmeal_gregs *gregs) { struct happy_meal_rxd *rxbase = &hp->happy_block->happy_meal_rxd[0]; @@ -2067,7 +2067,7 @@ #endif #ifndef __sparc_v9__ -static inline void sun4c_happy_meal_rx(struct happy_meal *hp, struct device *dev, +static inline void sun4c_happy_meal_rx(struct happy_meal *hp, struct net_device *dev, struct hmeal_gregs *gregs) { struct happy_meal_rxd *rxbase = &hp->happy_block->happy_meal_rxd[0]; @@ -2130,7 +2130,7 @@ RXD((">")); } -static inline void sun4d_happy_meal_rx(struct happy_meal *hp, struct device *dev, +static inline void sun4d_happy_meal_rx(struct happy_meal *hp, struct net_device *dev, struct hmeal_gregs *gregs) { struct happy_meal_rxd *rxbase = &hp->happy_block->happy_meal_rxd[0]; @@ -2242,7 +2242,7 @@ static void happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct happy_meal *hp = (struct happy_meal *) dev->priv; struct hmeal_gregs *gregs = hp->gregs; struct hmeal_tcvregs *tregs = hp->tcvregs; @@ -2287,7 +2287,7 @@ #ifdef CONFIG_PCI static void pci_happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct happy_meal *hp = (struct happy_meal *) dev->priv; struct hmeal_gregs *gregs = hp->gregs; struct hmeal_tcvregs *tregs = hp->tcvregs; @@ -2333,7 +2333,7 @@ #ifndef __sparc_v9__ static void sun4c_happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct happy_meal *hp = (struct happy_meal *) dev->priv; struct hmeal_gregs *gregs = hp->gregs; struct hmeal_tcvregs *tregs = hp->tcvregs; @@ -2377,7 +2377,7 @@ static void sun4d_happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; struct happy_meal *hp = (struct happy_meal *) dev->priv; struct hmeal_gregs *gregs = hp->gregs; struct hmeal_tcvregs *tregs = hp->tcvregs; @@ -2426,7 +2426,7 @@ int i; for(i = 0; i < 4; i++) { - struct device *hdev = qp->happy_meals[i]; + struct net_device *hdev = qp->happy_meals[i]; struct happy_meal *hp = (struct happy_meal *) hdev->priv; volatile u32 *sreg = qp->irq_status[i]; @@ -2439,7 +2439,7 @@ } } -static int happy_meal_open(struct device *dev) +static int happy_meal_open(struct net_device *dev) { struct happy_meal *hp = (struct happy_meal *) dev->priv; int res; @@ -2499,7 +2499,7 @@ return res; } -static int happy_meal_close(struct device *dev) +static int happy_meal_close(struct net_device *dev) { struct happy_meal *hp = (struct happy_meal *) dev->priv; @@ -2530,7 +2530,7 @@ #define SXD(x) #endif -static int happy_meal_start_xmit(struct sk_buff *skb, struct device *dev) +static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct happy_meal *hp = (struct happy_meal *) dev->priv; int len, entry; @@ -2593,7 +2593,7 @@ } #ifdef CONFIG_PCI -static int pci_happy_meal_start_xmit(struct sk_buff *skb, struct device *dev) +static int pci_happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct happy_meal *hp = (struct happy_meal *) dev->priv; int len, entry; @@ -2647,7 +2647,7 @@ #endif #ifndef __sparc_v9__ -static int sun4c_happy_meal_start_xmit(struct sk_buff *skb, struct device *dev) +static int sun4c_happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct happy_meal *hp = (struct happy_meal *) dev->priv; struct hmeal_buffers *hbufs = hp->sun4c_buffers; @@ -2703,7 +2703,7 @@ return 0; } -static int sun4d_happy_meal_start_xmit(struct sk_buff *skb, struct device *dev) +static int sun4d_happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct happy_meal *hp = (struct happy_meal *) dev->priv; int len, entry; @@ -2756,7 +2756,7 @@ } #endif -static struct net_device_stats *happy_meal_get_stats(struct device *dev) +static struct net_device_stats *happy_meal_get_stats(struct net_device *dev) { struct happy_meal *hp = (struct happy_meal *) dev->priv; @@ -2764,7 +2764,7 @@ return &hp->net_stats; } -static void happy_meal_set_multicast(struct device *dev) +static void happy_meal_set_multicast(struct net_device *dev) { struct happy_meal *hp = (struct happy_meal *) dev->priv; struct hmeal_bigmacregs *bregs = hp->bigmacregs; @@ -2822,7 +2822,7 @@ } /* Ethtool support... */ -static int happy_meal_ioctl(struct device *dev, +static int happy_meal_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct happy_meal *hp = (struct happy_meal *) dev->priv; @@ -3061,7 +3061,7 @@ static unsigned hme_version_printed = 0; -static int __init happy_meal_ether_init(struct device *dev, struct linux_sbus_device *sdev, int is_qfe) +static int __init happy_meal_ether_init(struct net_device *dev, struct linux_sbus_device *sdev, int is_qfe) { struct quattro *qp = NULL; struct happy_meal *hp; @@ -3250,7 +3250,7 @@ } #ifdef CONFIG_PCI -static int __init happy_meal_pci_init(struct device *dev, struct pci_dev *pdev) +static int __init happy_meal_pci_init(struct net_device *dev, struct pci_dev *pdev) { struct quattro *qp = NULL; struct pcidev_cookie *pcp; @@ -3423,7 +3423,7 @@ } #endif -int __init happy_meal_probe(struct device *dev) +int __init happy_meal_probe(struct net_device *dev) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff -u --recursive --new-file v2.3.13/linux/drivers/net/sunhme.h linux/drivers/net/sunhme.h --- v2.3.13/linux/drivers/net/sunhme.h Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/sunhme.h Wed Aug 18 11:36:45 1999 @@ -560,7 +560,7 @@ #ifdef CONFIG_PCI struct pci_dev *happy_pci_dev; #endif - struct device *dev; /* Backpointer */ + struct net_device *dev; /* Backpointer */ struct quattro *qfe_parent; /* For Quattro cards */ int qfe_ent; /* Which instance on quattro */ struct happy_meal *next_module; @@ -587,7 +587,7 @@ /* Support for QFE/Quattro cards. */ struct quattro { volatile u32 *irq_status[4]; - struct device *happy_meals[4]; + struct net_device *happy_meals[4]; void (*handler)(int, void *, struct pt_regs *); struct linux_sbus_device *quattro_sbus_dev; diff -u --recursive --new-file v2.3.13/linux/drivers/net/sunlance.c linux/drivers/net/sunlance.c --- v2.3.13/linux/drivers/net/sunlance.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/sunlance.c Wed Aug 18 11:36:43 1999 @@ -252,7 +252,7 @@ unsigned short busmaster_regval; unsigned short pio_buffer; - struct device *dev; /* Backpointer */ + struct net_device *dev; /* Backpointer */ struct lance_private *next_module; struct linux_sbus *sbus; struct timer_list multicast_timer; @@ -311,7 +311,7 @@ /* Setup the Lance Rx and Tx rings */ /* Sets dev->tbusy */ -static void lance_init_ring (struct device *dev) +static void lance_init_ring (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -444,7 +444,7 @@ return 0; } -static int lance_rx (struct device *dev) +static int lance_rx (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -518,7 +518,7 @@ return 0; } -static int lance_tx (struct device *dev) +static int lance_tx (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -599,7 +599,7 @@ static void lance_interrupt (int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; struct lance_private *lp = (struct lance_private *)dev->priv; volatile struct lance_regs *ll = lp->ll; int csr0; @@ -660,9 +660,9 @@ dev->interrupt = 0; } -struct device *last_dev = 0; +struct net_device *last_dev = 0; -static int lance_open (struct device *dev) +static int lance_open (struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -744,7 +744,7 @@ return status; } -static int lance_close (struct device *dev) +static int lance_close (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -762,7 +762,7 @@ return 0; } -static inline int lance_reset (struct device *dev) +static inline int lance_reset (struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -793,7 +793,7 @@ return status; } -static int lance_start_xmit (struct sk_buff *skb, struct device *dev) +static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) { struct lance_private *lp = (struct lance_private *)dev->priv; volatile struct lance_regs *ll = lp->ll; @@ -861,7 +861,7 @@ return 0; } -static struct net_device_stats *lance_get_stats (struct device *dev) +static struct net_device_stats *lance_get_stats (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; @@ -869,7 +869,7 @@ } /* taken from the depca driver */ -static void lance_load_multicast (struct device *dev) +static void lance_load_multicast (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -915,7 +915,7 @@ } } -static void lance_set_multicast (struct device *dev) +static void lance_set_multicast (struct net_device *dev) { struct lance_private *lp = (struct lance_private *) dev->priv; volatile struct lance_init_block *ib = lp->init_block; @@ -966,7 +966,7 @@ } static int __init -sparc_lance_init (struct device *dev, struct linux_sbus_device *sdev, +sparc_lance_init (struct net_device *dev, struct linux_sbus_device *sdev, struct Linux_SBus_DMA *ledma, struct linux_sbus_device *lebuffer) { @@ -1157,7 +1157,7 @@ #include /* Find all the lance cards on the system and initialize them */ -int __init sparc_lance_probe (struct device *dev) +int __init sparc_lance_probe (struct net_device *dev) { static struct linux_sbus_device sdev; static int called = 0; @@ -1179,7 +1179,7 @@ #else /* !CONFIG_SUN4 */ /* Find all the lance cards on the system and initialize them */ -int __init sparc_lance_probe (struct device *dev) +int __init sparc_lance_probe (struct net_device *dev) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff -u --recursive --new-file v2.3.13/linux/drivers/net/sunqe.c linux/drivers/net/sunqe.c --- v2.3.13/linux/drivers/net/sunqe.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/sunqe.c Wed Aug 18 11:36:43 1999 @@ -131,7 +131,7 @@ static void qe_init_rings(struct sunqe *qep, int from_irq) { struct qe_init_block *qb = qep->qe_block; - struct device *dev = qep->dev; + struct net_device *dev = qep->dev; int i, gfp_flags = GFP_KERNEL; if(from_irq || in_interrupt()) @@ -281,7 +281,7 @@ */ static int qe_is_bolixed(struct sunqe *qep, unsigned int qe_status) { - struct device *dev = qep->dev; + struct net_device *dev = qep->dev; int mace_hwbug_workaround = 0; if(qe_status & CREG_STAT_EDEFER) { @@ -631,7 +631,7 @@ while(channel < 4) { if(qec_status & 0xf) { struct sunqe *qep = qecp->qes[channel]; - struct device *dev = qep->dev; + struct net_device *dev = qep->dev; unsigned int qe_status; dev->interrupt = 1; @@ -671,7 +671,7 @@ while(channel < 4) { if(qec_status & 0xf) { struct sunqe *qep = qecp->qes[channel]; - struct device *dev = qep->dev; + struct net_device *dev = qep->dev; unsigned int qe_status; dev->interrupt = 1; @@ -700,7 +700,7 @@ } } -static int qe_open(struct device *dev) +static int qe_open(struct net_device *dev) { struct sunqe *qep = (struct sunqe *) dev->priv; int res; @@ -712,7 +712,7 @@ return res; } -static int qe_close(struct device *dev) +static int qe_close(struct net_device *dev) { struct sunqe *qep = (struct sunqe *) dev->priv; @@ -723,7 +723,7 @@ } /* Get a packet queued to go onto the wire. */ -static int qe_start_xmit(struct sk_buff *skb, struct device *dev) +static int qe_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct sunqe *qep = (struct sunqe *) dev->priv; int len, entry; @@ -774,7 +774,7 @@ return 0; } -static int sun4c_qe_start_xmit(struct sk_buff *skb, struct device *dev) +static int sun4c_qe_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct sunqe *qep = (struct sunqe *) dev->priv; struct sunqe_buffers *qbufs = qep->sun4c_buffers; @@ -823,7 +823,7 @@ return 0; } -static struct net_device_stats *qe_get_stats(struct device *dev) +static struct net_device_stats *qe_get_stats(struct net_device *dev) { struct sunqe *qep = (struct sunqe *) dev->priv; @@ -833,7 +833,7 @@ #define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */ #define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */ -static void qe_set_multicast(struct device *dev) +static void qe_set_multicast(struct net_device *dev) { struct sunqe *qep = (struct sunqe *) dev->priv; struct dev_mc_list *dmi = dev->mc_list; @@ -926,10 +926,10 @@ } /* Four QE's per QEC card. */ -static inline int qec_ether_init(struct device *dev, struct linux_sbus_device *sdev) +static inline int qec_ether_init(struct net_device *dev, struct linux_sbus_device *sdev) { static unsigned version_printed = 0; - struct device *qe_devs[4]; + struct net_device *qe_devs[4]; struct sunqe *qeps[4]; struct linux_sbus_device *qesdevs[4]; struct sunqec *qecp; @@ -1173,7 +1173,7 @@ return res; } -int __init qec_probe(struct device *dev) +int __init qec_probe(struct net_device *dev) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; diff -u --recursive --new-file v2.3.13/linux/drivers/net/sunqe.h linux/drivers/net/sunqe.h --- v2.3.13/linux/drivers/net/sunqe.h Fri May 8 00:20:48 1998 +++ linux/drivers/net/sunqe.h Wed Aug 18 11:36:45 1999 @@ -370,7 +370,7 @@ struct net_device_stats net_stats; /* Statistical counters */ struct linux_sbus_device *qe_sbusdev; /* QE's SBUS device struct */ - struct device *dev; /* QE's netdevice struct */ + struct net_device *dev; /* QE's netdevice struct */ int channel; /* Who am I? */ }; diff -u --recursive --new-file v2.3.13/linux/drivers/net/syncppp.c linux/drivers/net/syncppp.c --- v2.3.13/linux/drivers/net/syncppp.c Fri Apr 16 13:58:46 1999 +++ linux/drivers/net/syncppp.c Wed Aug 18 11:36:43 1999 @@ -148,7 +148,7 @@ * Interface down stub */ -static void if_down(struct device *dev) +static void if_down(struct net_device *dev) { ; } @@ -183,7 +183,7 @@ * Process the received packet. */ -void sppp_input (struct device *dev, struct sk_buff *skb) +void sppp_input (struct net_device *dev, struct sk_buff *skb) { struct ppp_header *h; struct sppp *sp = &((struct ppp_device *)dev)->sppp; @@ -312,7 +312,7 @@ * Handle transmit packets. */ -static int sppp_hard_header(struct sk_buff *skb, struct device *dev, __u16 type, +static int sppp_hard_header(struct sk_buff *skb, struct net_device *dev, __u16 type, void *daddr, void *saddr, unsigned int len) { struct sppp *sp = &((struct ppp_device *)dev)->sppp; @@ -363,7 +363,7 @@ for (sp=spppq; sp; sp=sp->pp_next) { - struct device *dev = sp->pp_if; + struct net_device *dev = sp->pp_if; /* Keepalive mode disabled or channel down? */ if (! (sp->pp_flags & PP_KEEPALIVE) || @@ -413,7 +413,7 @@ static void sppp_lcp_input (struct sppp *sp, struct sk_buff *skb) { struct lcp_header *h; - struct device *dev = sp->pp_if; + struct net_device *dev = sp->pp_if; int len = skb->len; u8 *p, opt[6]; u32 rmagic; @@ -648,7 +648,7 @@ static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb) { struct cisco_packet *h; - struct device *dev = sp->pp_if; + struct net_device *dev = sp->pp_if; if (skb->len != CISCO_PACKET_LEN && skb->len != CISCO_BIG_PACKET_LEN) { if (sp->pp_flags & PP_DEBUG) @@ -736,7 +736,7 @@ struct ppp_header *h; struct lcp_header *lh; struct sk_buff *skb; - struct device *dev = sp->pp_if; + struct net_device *dev = sp->pp_if; skb=alloc_skb(dev->hard_header_len+PPP_HEADER_LEN+LCP_HEADER_LEN+len, GFP_ATOMIC); @@ -785,7 +785,7 @@ struct ppp_header *h; struct cisco_packet *ch; struct sk_buff *skb; - struct device *dev = sp->pp_if; + struct net_device *dev = sp->pp_if; u32 t = jiffies * 1000/HZ; skb=alloc_skb(dev->hard_header_len+PPP_HEADER_LEN+CISCO_PACKET_LEN, @@ -819,7 +819,7 @@ } -int sppp_close (struct device *dev) +int sppp_close (struct net_device *dev) { struct sppp *sp = &((struct ppp_device *)dev)->sppp; dev->flags &= ~IFF_RUNNING; @@ -832,7 +832,7 @@ EXPORT_SYMBOL(sppp_close); -int sppp_open (struct device *dev) +int sppp_open (struct net_device *dev) { struct sppp *sp = &((struct ppp_device *)dev)->sppp; sppp_close(dev); @@ -844,7 +844,7 @@ EXPORT_SYMBOL(sppp_open); -int sppp_reopen (struct device *dev) +int sppp_reopen (struct net_device *dev) { struct sppp *sp = &((struct ppp_device *)dev)->sppp; sppp_close(dev); @@ -863,7 +863,7 @@ EXPORT_SYMBOL(sppp_reopen); -int sppp_change_mtu(struct device *dev, int new_mtu) +int sppp_change_mtu(struct net_device *dev, int new_mtu) { if(new_mtu<128||new_mtu>PPP_MTU||(dev->flags&IFF_UP)) return -EINVAL; @@ -873,7 +873,7 @@ EXPORT_SYMBOL(sppp_change_mtu); -int sppp_do_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +int sppp_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct sppp *sp = &((struct ppp_device *)dev)->sppp; @@ -908,7 +908,7 @@ void sppp_attach(struct ppp_device *pd) { - struct device *dev=&pd->dev; + struct net_device *dev=&pd->dev; struct sppp *sp = &pd->sppp; /* Initialize keepalive handler. */ @@ -963,7 +963,7 @@ EXPORT_SYMBOL(sppp_attach); -void sppp_detach (struct device *dev) +void sppp_detach (struct net_device *dev) { struct sppp **q, *p, *sp = &((struct ppp_device *)dev)->sppp; @@ -1039,7 +1039,7 @@ static void sppp_ipcp_input (struct sppp *sp, struct sk_buff *skb) { struct lcp_header *h; - struct device *dev = sp->pp_if; + struct net_device *dev = sp->pp_if; int len = skb->len; if (len < 4) @@ -1266,7 +1266,7 @@ * cards use. */ -int sppp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *p) +int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p) { sppp_input(dev,skb); return 0; diff -u --recursive --new-file v2.3.13/linux/drivers/net/syncppp.h linux/drivers/net/syncppp.h --- v2.3.13/linux/drivers/net/syncppp.h Sat Feb 6 12:46:21 1999 +++ linux/drivers/net/syncppp.h Wed Aug 18 11:36:45 1999 @@ -46,12 +46,12 @@ u32 ibytes,obytes; /* Bytes in/out */ u32 ipkts,opkts; /* Packets in/out */ struct timer_list pp_timer; - struct device *pp_if; + struct net_device *pp_if; }; struct ppp_device { - struct device dev; /* Network device */ + struct net_device dev; /* Network device */ struct sppp sppp; /* Synchronous PPP */ }; @@ -73,15 +73,15 @@ #define IPCP_STATE_OPENED 3 /* IPCP state: opened */ void sppp_attach (struct ppp_device *pd); -void sppp_detach (struct device *dev); -void sppp_input (struct device *dev, struct sk_buff *m); -int sppp_do_ioctl (struct device *dev, struct ifreq *ifr, int cmd); -struct sk_buff *sppp_dequeue (struct device *dev); -int sppp_isempty (struct device *dev); -void sppp_flush (struct device *dev); -int sppp_open (struct device *dev); -int sppp_reopen (struct device *dev); -int sppp_close (struct device *dev); +void sppp_detach (struct net_device *dev); +void sppp_input (struct net_device *dev, struct sk_buff *m); +int sppp_do_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd); +struct sk_buff *sppp_dequeue (struct net_device *dev); +int sppp_isempty (struct net_device *dev); +void sppp_flush (struct net_device *dev); +int sppp_open (struct net_device *dev); +int sppp_reopen (struct net_device *dev); +int sppp_close (struct net_device *dev); #endif #define SPPPIOCCISCO (SIOCDEVPRIVATE) diff -u --recursive --new-file v2.3.13/linux/drivers/net/tlan.c linux/drivers/net/tlan.c --- v2.3.13/linux/drivers/net/tlan.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/tlan.c Wed Aug 18 11:36:43 1999 @@ -46,12 +46,12 @@ -typedef u32 (TLanIntVectorFunc)( struct device *, u16 ); +typedef u32 (TLanIntVectorFunc)( struct net_device *, u16 ); #ifdef MODULE -static struct device *TLanDevices = NULL; +static struct net_device *TLanDevices = NULL; static int TLanDevicesInstalled = 0; static int aui = 0; @@ -159,57 +159,57 @@ static int TLan_PciProbe( u8 *, u8 *, u8 *, u32 *, u32 * ); -static int TLan_Init( struct device * ); -static int TLan_Open(struct device *dev); -static int TLan_StartTx(struct sk_buff *, struct device *); +static int TLan_Init( struct net_device * ); +static int TLan_Open(struct net_device *dev); +static int TLan_StartTx(struct sk_buff *, struct net_device *); static void TLan_HandleInterrupt(int, void *, struct pt_regs *); -static int TLan_Close(struct device *); -static struct net_device_stats *TLan_GetStats( struct device * ); -static void TLan_SetMulticastList( struct device * ); - -static u32 TLan_HandleInvalid( struct device *, u16 ); -static u32 TLan_HandleTxEOF( struct device *, u16 ); -static u32 TLan_HandleStatOverflow( struct device *, u16 ); -static u32 TLan_HandleRxEOF( struct device *, u16 ); -static u32 TLan_HandleDummy( struct device *, u16 ); -static u32 TLan_HandleTxEOC( struct device *, u16 ); -static u32 TLan_HandleStatusCheck( struct device *, u16 ); -static u32 TLan_HandleRxEOC( struct device *, u16 ); +static int TLan_Close(struct net_device *); +static struct net_device_stats *TLan_GetStats( struct net_device * ); +static void TLan_SetMulticastList( struct net_device * ); + +static u32 TLan_HandleInvalid( struct net_device *, u16 ); +static u32 TLan_HandleTxEOF( struct net_device *, u16 ); +static u32 TLan_HandleStatOverflow( struct net_device *, u16 ); +static u32 TLan_HandleRxEOF( struct net_device *, u16 ); +static u32 TLan_HandleDummy( struct net_device *, u16 ); +static u32 TLan_HandleTxEOC( struct net_device *, u16 ); +static u32 TLan_HandleStatusCheck( struct net_device *, u16 ); +static u32 TLan_HandleRxEOC( struct net_device *, u16 ); static void TLan_Timer( unsigned long ); -static void TLan_ResetLists( struct device * ); -static void TLan_FreeLists( struct device * ); +static void TLan_ResetLists( struct net_device * ); +static void TLan_FreeLists( struct net_device * ); static void TLan_PrintDio( u16 ); static void TLan_PrintList( TLanList *, char *, int ); -static void TLan_ReadAndClearStats( struct device *, int ); -static void TLan_ResetAdapter( struct device * ); -static void TLan_FinishReset( struct device * ); -static void TLan_SetMac( struct device *, int areg, char *mac ); - -static void TLan_PhyPrint( struct device * ); -static void TLan_PhyDetect( struct device * ); -static void TLan_PhyPowerDown( struct device * ); -static void TLan_PhyPowerUp( struct device * ); -static void TLan_PhyReset( struct device * ); -static void TLan_PhyStartLink( struct device * ); -static void TLan_PhyFinishAutoNeg( struct device * ); +static void TLan_ReadAndClearStats( struct net_device *, int ); +static void TLan_ResetAdapter( struct net_device * ); +static void TLan_FinishReset( struct net_device * ); +static void TLan_SetMac( struct net_device *, int areg, char *mac ); + +static void TLan_PhyPrint( struct net_device * ); +static void TLan_PhyDetect( struct net_device * ); +static void TLan_PhyPowerDown( struct net_device * ); +static void TLan_PhyPowerUp( struct net_device * ); +static void TLan_PhyReset( struct net_device * ); +static void TLan_PhyStartLink( struct net_device * ); +static void TLan_PhyFinishAutoNeg( struct net_device * ); /* -static int TLan_PhyNop( struct device * ); -static int TLan_PhyInternalCheck( struct device * ); -static int TLan_PhyInternalService( struct device * ); -static int TLan_PhyDp83840aCheck( struct device * ); +static int TLan_PhyNop( struct net_device * ); +static int TLan_PhyInternalCheck( struct net_device * ); +static int TLan_PhyInternalService( struct net_device * ); +static int TLan_PhyDp83840aCheck( struct net_device * ); */ -static int TLan_MiiReadReg( struct device *, u16, u16, u16 * ); +static int TLan_MiiReadReg( struct net_device *, u16, u16, u16 * ); static void TLan_MiiSendData( u16, u32, unsigned ); static void TLan_MiiSync( u16 ); -static void TLan_MiiWriteReg( struct device *, u16, u16, u16 ); +static void TLan_MiiWriteReg( struct net_device *, u16, u16, u16 ); static void TLan_EeSendStart( u16 ); static int TLan_EeSendByte( u16, u8, int ); static void TLan_EeReceiveByte( u16, u8 *, int ); -static int TLan_EeReadByte( struct device *, u8, u8 * ); +static int TLan_EeReadByte( struct net_device *, u8, u8 * ); static TLanIntVectorFunc *TLanIntVector[TLAN_INT_NUMBER_OF_INTS] = { @@ -224,7 +224,7 @@ }; static inline void -TLan_SetTimer( struct device *dev, u32 ticks, u32 type ) +TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; @@ -275,7 +275,7 @@ extern int init_module(void) { TLanPrivateInfo *priv; - struct device *dev; + struct net_device *dev; size_t dev_size; u8 dfn; u32 index; @@ -299,17 +299,17 @@ memset( TLanPadBuffer, 0, TLAN_MIN_FRAME_SIZE ); - dev_size = sizeof(struct device) + sizeof(TLanPrivateInfo); + dev_size = sizeof(struct net_device) + sizeof(TLanPrivateInfo); while ( ( found = TLan_PciProbe( &dfn, &irq, &rev, &io_base, &index ) ) ) { - dev = (struct device *) kmalloc( dev_size, GFP_KERNEL ); + dev = (struct net_device *) kmalloc( dev_size, GFP_KERNEL ); if ( dev == NULL ) { printk( "TLAN: Could not allocate memory for device.\n" ); continue; } memset( dev, 0, dev_size ); - dev->priv = priv = ( (void *) dev ) + sizeof(struct device); + dev->priv = priv = ( (void *) dev ) + sizeof(struct net_device); dev->name = priv->devName; strcpy( priv->devName, " " ); dev->base_addr = io_base; @@ -376,7 +376,7 @@ extern void cleanup_module(void) { - struct device *dev; + struct net_device *dev; TLanPrivateInfo *priv; while ( TLanDevicesInstalled ) { @@ -417,7 +417,7 @@ * **************************************************************/ -extern int tlan_probe( struct device *dev ) +extern int tlan_probe( struct net_device *dev ) { TLanPrivateInfo *priv; static int pad_allocated = 0; @@ -609,7 +609,7 @@ * **************************************************************/ -int TLan_Init( struct device *dev ) +int TLan_Init( struct net_device *dev ) { int dma_size; int err; @@ -697,7 +697,7 @@ * **************************************************************/ -int TLan_Open( struct device *dev ) +int TLan_Open( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; int err; @@ -757,7 +757,7 @@ * **************************************************************/ -int TLan_StartTx( struct sk_buff *skb, struct device *dev ) +int TLan_StartTx( struct sk_buff *skb, struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; TLanList *tail_list; @@ -859,12 +859,12 @@ void TLan_HandleInterrupt(int irq, void *dev_id, struct pt_regs *regs) { u32 ack; - struct device *dev; + struct net_device *dev; u32 host_cmd; u16 host_int; int type; - dev = (struct device *) dev_id; + dev = (struct net_device *) dev_id; cli(); if ( dev->interrupt ) { @@ -907,7 +907,7 @@ * **************************************************************/ -int TLan_Close(struct device *dev) +int TLan_Close(struct net_device *dev) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; @@ -946,7 +946,7 @@ * **************************************************************/ -struct net_device_stats *TLan_GetStats( struct device *dev ) +struct net_device_stats *TLan_GetStats( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; int i; @@ -994,7 +994,7 @@ * **************************************************************/ -void TLan_SetMulticastList( struct device *dev ) +void TLan_SetMulticastList( struct net_device *dev ) { struct dev_mc_list *dmi = dev->mc_list; u32 hash1 = 0; @@ -1068,7 +1068,7 @@ * **************************************************************/ -u32 TLan_HandleInvalid( struct device *dev, u16 host_int ) +u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int ) { host_int = 0; /* printk( "TLAN: Invalid interrupt on %s.\n", dev->name ); */ @@ -1101,7 +1101,7 @@ * **************************************************************/ -u32 TLan_HandleTxEOF( struct device *dev, u16 host_int ) +u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; int eoc = 0; @@ -1174,7 +1174,7 @@ * **************************************************************/ -u32 TLan_HandleStatOverflow( struct device *dev, u16 host_int ) +u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int ) { host_int = 0; TLan_ReadAndClearStats( dev, TLAN_RECORD ); @@ -1211,7 +1211,7 @@ * **************************************************************/ -u32 TLan_HandleRxEOF( struct device *dev, u16 host_int ) +u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u32 ack = 1; @@ -1335,7 +1335,7 @@ * **************************************************************/ -u32 TLan_HandleDummy( struct device *dev, u16 host_int ) +u32 TLan_HandleDummy( struct net_device *dev, u16 host_int ) { host_int = 0; printk( "TLAN: Test interrupt on %s.\n", dev->name ); @@ -1366,7 +1366,7 @@ * **************************************************************/ -u32 TLan_HandleTxEOC( struct device *dev, u16 host_int ) +u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; TLanList *head_list; @@ -1411,7 +1411,7 @@ * **************************************************************/ -u32 TLan_HandleStatusCheck( struct device *dev, u16 host_int ) +u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u32 ack; @@ -1485,7 +1485,7 @@ * **************************************************************/ -u32 TLan_HandleRxEOC( struct device *dev, u16 host_int ) +u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; TLanList *head_list; @@ -1548,7 +1548,7 @@ void TLan_Timer( unsigned long data ) { - struct device *dev = (struct device *) data; + struct net_device *dev = (struct net_device *) data; TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u32 elapsed; @@ -1620,7 +1620,7 @@ * **************************************************************/ -void TLan_ResetLists( struct device *dev ) +void TLan_ResetLists( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; int i; @@ -1675,7 +1675,7 @@ } /* TLan_ResetLists */ -void TLan_FreeLists( struct device *dev ) +void TLan_FreeLists( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; int i; @@ -1792,7 +1792,7 @@ * **************************************************************/ -void TLan_ReadAndClearStats( struct device *dev, int record ) +void TLan_ReadAndClearStats( struct net_device *dev, int record ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u32 tx_good, tx_under; @@ -1868,7 +1868,7 @@ **************************************************************/ void -TLan_ResetAdapter( struct device *dev ) +TLan_ResetAdapter( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; int i; @@ -1950,7 +1950,7 @@ void -TLan_FinishReset( struct device *dev ) +TLan_FinishReset( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u8 data; @@ -2036,7 +2036,7 @@ * **************************************************************/ -void TLan_SetMac( struct device *dev, int areg, char *mac ) +void TLan_SetMac( struct net_device *dev, int areg, char *mac ) { int i; @@ -2078,7 +2078,7 @@ * ********************************************************************/ -void TLan_PhyPrint( struct device *dev ) +void TLan_PhyPrint( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u16 i, data0, data1, data2, data3, phy; @@ -2127,7 +2127,7 @@ * ********************************************************************/ -void TLan_PhyDetect( struct device *dev ) +void TLan_PhyDetect( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u16 control; @@ -2174,7 +2174,7 @@ -void TLan_PhyPowerDown( struct device *dev ) +void TLan_PhyPowerDown( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u16 value; @@ -2199,7 +2199,7 @@ -void TLan_PhyPowerUp( struct device *dev ) +void TLan_PhyPowerUp( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u16 value; @@ -2220,7 +2220,7 @@ -void TLan_PhyReset( struct device *dev ) +void TLan_PhyReset( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u16 phy; @@ -2248,7 +2248,7 @@ -void TLan_PhyStartLink( struct device *dev ) +void TLan_PhyStartLink( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u16 ability; @@ -2329,7 +2329,7 @@ -void TLan_PhyFinishAutoNeg( struct device *dev ) +void TLan_PhyFinishAutoNeg( struct net_device *dev ) { TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; u16 an_adv; @@ -2424,7 +2424,7 @@ * **************************************************************/ -int TLan_MiiReadReg( struct device *dev, u16 phy, u16 reg, u16 *val ) +int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val ) { u8 nack; u16 sio, tmp; @@ -2595,7 +2595,7 @@ * **************************************************************/ -void TLan_MiiWriteReg( struct device *dev, u16 phy, u16 reg, u16 val ) +void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val ) { u16 sio; int minten; @@ -2824,7 +2824,7 @@ * **************************************************************/ -int TLan_EeReadByte( struct device *dev, u8 ee_addr, u8 *data ) +int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data ) { int err; diff -u --recursive --new-file v2.3.13/linux/drivers/net/tlan.h linux/drivers/net/tlan.h --- v2.3.13/linux/drivers/net/tlan.h Sun Aug 9 10:42:41 1998 +++ linux/drivers/net/tlan.h Wed Aug 18 11:36:45 1999 @@ -156,7 +156,7 @@ ****************************************************************/ typedef struct tlan_private_tag { - struct device *nextDevice; + struct net_device *nextDevice; void *dmaStorage; u8 *padBuffer; TLanList *rxList; diff -u --recursive --new-file v2.3.13/linux/drivers/net/tulip.c linux/drivers/net/tulip.c --- v2.3.13/linux/drivers/net/tulip.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/tulip.c Wed Aug 18 11:36:43 1999 @@ -367,7 +367,7 @@ struct tulip_private { char devname[8]; /* Used only for kernel debugging. */ const char *product_name; - struct device *next_module; + struct net_device *next_module; struct tulip_rx_desc rx_ring[RX_RING_SIZE]; struct tulip_tx_desc tx_ring[TX_RING_SIZE]; /* The saved address of a sent-in-place packet/buffer, for skfree(). */ @@ -409,36 +409,36 @@ int pad0, pad1; /* Used for 8-byte alignment */ }; -static struct device *tulip_probe1(int pci_bus, int pci_devfn, - struct device *dev, +static struct net_device *tulip_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, int chip_id, int options); -static void parse_eeprom(struct device *dev); +static void parse_eeprom(struct net_device *dev); static int read_eeprom(long ioaddr, int location); -static int mdio_read(struct device *dev, int phy_id, int location); -static void mdio_write(struct device *dev, int phy_id, int location, int value); -static void select_media(struct device *dev, int startup); -static int tulip_open(struct device *dev); +static int mdio_read(struct net_device *dev, int phy_id, int location); +static void mdio_write(struct net_device *dev, int phy_id, int location, int value); +static void select_media(struct net_device *dev, int startup); +static int tulip_open(struct net_device *dev); static void tulip_timer(unsigned long data); -static void tulip_tx_timeout(struct device *dev); -static void tulip_init_ring(struct device *dev); -static int tulip_start_xmit(struct sk_buff *skb, struct device *dev); -static int tulip_rx(struct device *dev); +static void tulip_tx_timeout(struct net_device *dev); +static void tulip_init_ring(struct net_device *dev); +static int tulip_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int tulip_rx(struct net_device *dev); static void tulip_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *regs); -static int tulip_close(struct device *dev); -static struct enet_statistics *tulip_get_stats(struct device *dev); +static int tulip_close(struct net_device *dev); +static struct enet_statistics *tulip_get_stats(struct net_device *dev); #ifdef HAVE_PRIVATE_IOCTL -static int private_ioctl(struct device *dev, struct ifreq *rq, int cmd); +static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); #endif #ifdef NEW_MULTICAST -static void set_rx_mode(struct device *dev); +static void set_rx_mode(struct net_device *dev); #else -static void set_rx_mode(struct device *dev, int num_addrs, void *addrs); +static void set_rx_mode(struct net_device *dev, int num_addrs, void *addrs); #endif /* A list of all installed Tulip devices, for removing the driver module. */ -static struct device *root_tulip_dev = NULL; +static struct net_device *root_tulip_dev = NULL; /* This 21040 probe no longer uses a large fixed contiguous Rx buffer region, but now receives directly into full-sized skbuffs that are allocated @@ -446,7 +446,7 @@ This allows the probe routine to use the old driver initialization interface. */ -int tulip_probe(struct device *dev) +int tulip_probe(struct net_device *dev) { int cards_found = 0; static int pci_index = 0; /* Static, for multiple probe calls. */ @@ -552,8 +552,8 @@ return cards_found ? 0 : -ENODEV; } -static struct device *tulip_probe1(int pci_bus, int pci_device_fn, - struct device *dev, +static struct net_device *tulip_probe1(int pci_bus, int pci_device_fn, + struct net_device *dev, int chip_id, int board_idx) { static int did_version = 0; /* Already printed version info. */ @@ -861,7 +861,7 @@ #define get_u16(ptr) (((u8*)(ptr))[0] + (((u8*)(ptr))[1]<<8)) #endif -static void parse_eeprom(struct device *dev) +static void parse_eeprom(struct net_device *dev) { /* The last media info list parsed, for multiport boards. */ static struct mediatable *last_mediatable = NULL; @@ -1102,7 +1102,7 @@ #define MDIO_ENB_IN 0x40000 #define MDIO_DATA_READ 0x80000 -static int mdio_read(struct device *dev, int phy_id, int location) +static int mdio_read(struct net_device *dev, int phy_id, int location) { struct tulip_private *tp = (struct tulip_private *)dev->priv; int i; @@ -1147,7 +1147,7 @@ return (retval>>1) & 0xffff; } -static void mdio_write(struct device *dev, int phy_id, int location, int value) +static void mdio_write(struct net_device *dev, int phy_id, int location, int value) { struct tulip_private *tp = (struct tulip_private *)dev->priv; int i; @@ -1192,7 +1192,7 @@ static int -tulip_open(struct device *dev) +tulip_open(struct net_device *dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1369,7 +1369,7 @@ } /* Set up the transceiver control registers for the selected media type. */ -static void select_media(struct device *dev, int startup) +static void select_media(struct net_device *dev, int startup) { long ioaddr = dev->base_addr; struct tulip_private *tp = (struct tulip_private *)dev->priv; @@ -1552,7 +1552,7 @@ static void tulip_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; u32 csr12 = inl(ioaddr + CSR12); @@ -1751,7 +1751,7 @@ of available transceivers. */ static void t21142_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; int csr12 = inl(ioaddr + CSR12); @@ -1814,7 +1814,7 @@ add_timer(&tp->timer); } -static void t21142_lnk_change( struct device *dev) +static void t21142_lnk_change( struct net_device *dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1866,7 +1866,7 @@ static void mxic_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; int next_tick = 60*HZ; @@ -1883,7 +1883,7 @@ static void pnic_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; int csr12 = inl(ioaddr + CSR12); @@ -1966,7 +1966,7 @@ add_timer(&tp->timer); } -static void tulip_tx_timeout(struct device *dev) +static void tulip_tx_timeout(struct net_device *dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; @@ -2057,7 +2057,7 @@ /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ static void -tulip_init_ring(struct device *dev) +tulip_init_ring(struct net_device *dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; int i; @@ -2102,7 +2102,7 @@ } static int -tulip_start_xmit(struct sk_buff *skb, struct device *dev) +tulip_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; int entry; @@ -2159,9 +2159,9 @@ static void tulip_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *regs) { #ifdef SA_SHIRQ /* Use the now-standard shared IRQ implementation. */ - struct device *dev = (struct device *)dev_instance; + struct net_device *dev = (struct net_device *)dev_instance; #else - struct device *dev = (struct device *)(irq2dev_map[irq]); + struct net_device *dev = (struct net_device *)(irq2dev_map[irq]); #endif struct tulip_private *tp; @@ -2339,7 +2339,7 @@ } static int -tulip_rx(struct device *dev) +tulip_rx(struct net_device *dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; int entry = tp->cur_rx % RX_RING_SIZE; @@ -2450,7 +2450,7 @@ } static int -tulip_close(struct device *dev) +tulip_close(struct net_device *dev) { long ioaddr = dev->base_addr; struct tulip_private *tp = (struct tulip_private *)dev->priv; @@ -2517,7 +2517,7 @@ } static struct enet_statistics * -tulip_get_stats(struct device *dev) +tulip_get_stats(struct net_device *dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; @@ -2530,7 +2530,7 @@ #ifdef HAVE_PRIVATE_IOCTL /* Provide ioctl() calls to examine the MII xcvr state. */ -static int private_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; @@ -2620,9 +2620,9 @@ } #ifdef NEW_MULTICAST -static void set_rx_mode(struct device *dev) +static void set_rx_mode(struct net_device *dev) #else -static void set_rx_mode(struct device *dev, int num_addrs, void *addrs) +static void set_rx_mode(struct net_device *dev, int num_addrs, void *addrs) #endif { long ioaddr = dev->base_addr; @@ -2737,7 +2737,7 @@ u16 dev_id; u32 io; u8 bus, devfn; - struct device *dev; + struct net_device *dev; if (loc->bus != LOC_PCI) return NULL; bus = loc->b.pci.bus; devfn = loc->b.pci.devfn; @@ -2759,7 +2759,7 @@ static void tulip_detach(dev_node_t *node) { - struct device **devp, **next; + struct net_device **devp, **next; printk(KERN_INFO "tulip_detach(%s)\n", node->dev_name); for (devp = &root_tulip_dev; *devp; devp = next) { next = &((struct tulip_private *)(*devp)->priv)->next_module; @@ -2813,7 +2813,7 @@ void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; #ifdef CARDBUS unregister_driver(&tulip_ops); diff -u --recursive --new-file v2.3.13/linux/drivers/net/via-rhine.c linux/drivers/net/via-rhine.c --- v2.3.13/linux/drivers/net/via-rhine.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/via-rhine.c Wed Aug 18 11:36:43 1999 @@ -250,12 +250,12 @@ const char *name; u16 vendor_id, device_id, device_id_mask, flags; int io_size; - struct device *(*probe1)(int pci_bus, int pci_devfn, struct device *dev, + struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, long ioaddr, int irq, int chip_idx, int fnd_cnt); }; -static struct device *via_probe1(int pci_bus, int pci_devfn, - struct device *dev, long ioaddr, int irq, +static struct net_device *via_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, int irq, int chp_idx, int fnd_cnt); static struct pci_id_info pci_tbl[] = { @@ -344,7 +344,7 @@ struct sk_buff* tx_skbuff[TX_RING_SIZE]; unsigned char *tx_buf[TX_RING_SIZE]; /* Tx bounce buffers */ unsigned char *tx_bufs; /* Tx bounce buffer region. */ - struct device *next_module; /* Link for devices of this type. */ + struct net_device *next_module; /* Link for devices of this type. */ struct net_device_stats stats; struct timer_list timer; /* Media monitoring timer. */ unsigned char pci_bus, pci_devfn; @@ -369,33 +369,33 @@ unsigned char phys[2]; /* MII device addresses. */ }; -static int mdio_read(struct device *dev, int phy_id, int location); -static void mdio_write(struct device *dev, int phy_id, int location, int value); -static int netdev_open(struct device *dev); -static void check_duplex(struct device *dev); +static int mdio_read(struct net_device *dev, int phy_id, int location); +static void mdio_write(struct net_device *dev, int phy_id, int location, int value); +static int netdev_open(struct net_device *dev); +static void check_duplex(struct net_device *dev); static void netdev_timer(unsigned long data); -static void tx_timeout(struct device *dev); -static void init_ring(struct device *dev); -static int start_tx(struct sk_buff *skb, struct device *dev); +static void tx_timeout(struct net_device *dev); +static void init_ring(struct net_device *dev); +static int start_tx(struct sk_buff *skb, struct net_device *dev); static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs); -static int netdev_rx(struct device *dev); -static void netdev_error(struct device *dev, int intr_status); -static void set_rx_mode(struct device *dev); -static struct net_device_stats *get_stats(struct device *dev); -static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd); -static int netdev_close(struct device *dev); +static int netdev_rx(struct net_device *dev); +static void netdev_error(struct net_device *dev, int intr_status); +static void set_rx_mode(struct net_device *dev); +static struct net_device_stats *get_stats(struct net_device *dev); +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static int netdev_close(struct net_device *dev); /* A list of our installed devices, for removing the driver module. */ -static struct device *root_net_dev = NULL; +static struct net_device *root_net_dev = NULL; /* Ideally we would detect all network cards in slot order. That would be best done a central PCI probe dispatch, which wouldn't work well when dynamically adding drivers. So instead we detect just the cards we know about in slot order. */ -static int pci_etherdev_probe(struct device *dev, struct pci_id_info pci_tbl[]) +static int pci_etherdev_probe(struct net_device *dev, struct pci_id_info pci_tbl[]) { int cards_found = 0; int pci_index = 0; @@ -503,15 +503,15 @@ } #ifndef MODULE -int via_rhine_probe(struct device *dev) +int via_rhine_probe(struct net_device *dev) { printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB); return pci_etherdev_probe(dev, pci_tbl); } #endif -static struct device *via_probe1(int pci_bus, int pci_devfn, - struct device *dev, long ioaddr, int irq, +static struct net_device *via_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, int irq, int chip_id, int card_idx) { struct netdev_private *np; @@ -599,7 +599,7 @@ /* Read and write over the MII Management Data I/O (MDIO) interface. */ -static int mdio_read(struct device *dev, int phy_id, int regnum) +static int mdio_read(struct net_device *dev, int phy_id, int regnum) { long ioaddr = dev->base_addr; int boguscnt = 1024; @@ -617,7 +617,7 @@ return readw(ioaddr + MIIData); } -static void mdio_write(struct device *dev, int phy_id, int regnum, int value) +static void mdio_write(struct net_device *dev, int phy_id, int regnum, int value) { long ioaddr = dev->base_addr; int boguscnt = 1024; @@ -634,7 +634,7 @@ } -static int netdev_open(struct device *dev) +static int netdev_open(struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; @@ -707,7 +707,7 @@ return 0; } -static void check_duplex(struct device *dev) +static void check_duplex(struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; @@ -733,7 +733,7 @@ static void netdev_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; int next_tick = 10*HZ; @@ -748,7 +748,7 @@ add_timer(&np->timer); } -static void tx_timeout(struct device *dev) +static void tx_timeout(struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; @@ -771,7 +771,7 @@ /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ -static void init_ring(struct device *dev) +static void init_ring(struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; int i; @@ -818,7 +818,7 @@ return; } -static int start_tx(struct sk_buff *skb, struct device *dev) +static int start_tx(struct sk_buff *skb, struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; unsigned entry; @@ -877,7 +877,7 @@ after the Tx thread. */ static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) { - struct device *dev = (struct device *)dev_instance; + struct net_device *dev = (struct net_device *)dev_instance; struct netdev_private *np; long ioaddr, boguscnt = max_interrupt_work; @@ -988,7 +988,7 @@ /* This routine is logically part of the interrupt handler, but isolated for clarity and better register allocation. */ -static int netdev_rx(struct device *dev) +static int netdev_rx(struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; int entry = np->cur_rx % RX_RING_SIZE; @@ -1082,7 +1082,7 @@ return 0; } -static void netdev_error(struct device *dev, int intr_status) +static void netdev_error(struct net_device *dev, int intr_status) { struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1123,7 +1123,7 @@ } } -static struct enet_statistics *get_stats(struct device *dev) +static struct enet_statistics *get_stats(struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1157,7 +1157,7 @@ return crc; } -static void set_rx_mode(struct device *dev) +static void set_rx_mode(struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1188,7 +1188,7 @@ writeb(np->rx_thresh | rx_mode, ioaddr + RxConfig); } -static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { u16 *data = (u16 *)&rq->ifr_data; @@ -1209,7 +1209,7 @@ } } -static int netdev_close(struct device *dev) +static int netdev_close(struct net_device *dev) { long ioaddr = dev->base_addr; struct netdev_private *np = (struct netdev_private *)dev->priv; diff -u --recursive --new-file v2.3.13/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c --- v2.3.13/linux/drivers/net/wavelan.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/wavelan.c Wed Aug 18 11:36:43 1999 @@ -1876,7 +1876,7 @@ * It is here that the wireless extensions are treated (iwconfig). */ static int -wavelan_ioctl(struct device * dev, /* device on which the ioctl is applied */ +wavelan_ioctl(struct net_device * dev, /* device on which the ioctl is applied */ struct ifreq * rq, /* data passed */ int cmd) /* ioctl number */ { @@ -4239,13 +4239,13 @@ device * dev; /* Create device and set basic arguments. */ - dev = kmalloc(sizeof(struct device), GFP_KERNEL); + dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); if(dev==NULL) { ret = -ENOMEM; break; } - memset(dev, 0x00, sizeof(struct device)); + memset(dev, 0x00, sizeof(struct net_device)); dev->name = name[i]; dev->base_addr = io[i]; dev->irq = irq[i]; @@ -4257,7 +4257,7 @@ { /* Deallocate everything. */ /* Note: if dev->priv is mallocated, there is no way to fail. */ - kfree_s(dev, sizeof(struct device)); + kfree_s(dev, sizeof(struct net_device)); } else { @@ -4310,7 +4310,7 @@ /* Free pieces. */ kfree_s(dev->priv, sizeof(struct net_local)); - kfree_s(dev, sizeof(struct device)); + kfree_s(dev, sizeof(struct net_device)); } #ifdef DEBUG_MODULE_TRACE diff -u --recursive --new-file v2.3.13/linux/drivers/net/wavelan.p.h linux/drivers/net/wavelan.p.h --- v2.3.13/linux/drivers/net/wavelan.p.h Thu Apr 29 11:53:41 1999 +++ linux/drivers/net/wavelan.p.h Wed Aug 18 11:36:45 1999 @@ -404,7 +404,7 @@ /****************************** TYPES ******************************/ /* Shortcuts */ -typedef struct device device; +typedef struct net_device device; typedef struct net_device_stats en_stats; typedef struct iw_statistics iw_stats; typedef struct iw_quality iw_qual; diff -u --recursive --new-file v2.3.13/linux/drivers/net/wd.c linux/drivers/net/wd.c --- v2.3.13/linux/drivers/net/wd.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/wd.c Wed Aug 18 11:36:43 1999 @@ -45,18 +45,18 @@ static unsigned int wd_portlist[] __initdata = {0x300, 0x280, 0x380, 0x240, 0}; -int wd_probe(struct device *dev); -int wd_probe1(struct device *dev, int ioaddr); +int wd_probe(struct net_device *dev); +int wd_probe1(struct net_device *dev, int ioaddr); -static int wd_open(struct device *dev); -static void wd_reset_8390(struct device *dev); -static void wd_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, +static int wd_open(struct net_device *dev); +static void wd_reset_8390(struct net_device *dev); +static void wd_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); -static void wd_block_input(struct device *dev, int count, +static void wd_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); -static void wd_block_output(struct device *dev, int count, +static void wd_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page); -static int wd_close(struct device *dev); +static int wd_close(struct net_device *dev); #define WD_START_PG 0x00 /* First page of TX buffer */ @@ -86,7 +86,7 @@ {"wd", wd_probe1, WD_IO_EXTENT, wd_portlist}; #else -int __init wd_probe(struct device *dev) +int __init wd_probe(struct net_device *dev) { int i; int base_addr = dev ? dev->base_addr : 0; @@ -108,7 +108,7 @@ } #endif -int __init wd_probe1(struct device *dev, int ioaddr) +int __init wd_probe1(struct net_device *dev, int ioaddr) { int i; int checksum = 0; @@ -313,7 +313,7 @@ } static int -wd_open(struct device *dev) +wd_open(struct net_device *dev) { int ioaddr = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ @@ -332,7 +332,7 @@ } static void -wd_reset_8390(struct device *dev) +wd_reset_8390(struct net_device *dev) { int wd_cmd_port = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ @@ -354,7 +354,7 @@ the start of a page, so we optimize accordingly. */ static void -wd_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) +wd_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ @@ -379,7 +379,7 @@ switch between 8- and 16-bit modes. */ static void -wd_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) +wd_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ unsigned long xfer_start = dev->mem_start + ring_offset - (WD_START_PG<<8); @@ -401,7 +401,7 @@ } static void -wd_block_output(struct device *dev, int count, const unsigned char *buf, +wd_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page) { int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ @@ -419,7 +419,7 @@ static int -wd_close(struct device *dev) +wd_close(struct net_device *dev) { int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ @@ -444,7 +444,7 @@ #define MAX_WD_CARDS 4 /* Max number of wd cards per module */ #define NAMELEN 8 /* # of chars for storing dev->name */ static char namelist[NAMELEN * MAX_WD_CARDS] = { 0, }; -static struct device dev_wd[MAX_WD_CARDS] = { +static struct net_device dev_wd[MAX_WD_CARDS] = { { NULL, /* assign a chunk of namelist[] below */ 0, 0, 0, 0, @@ -471,7 +471,7 @@ int this_dev, found = 0; for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) { - struct device *dev = &dev_wd[this_dev]; + struct net_device *dev = &dev_wd[this_dev]; dev->name = namelist+(NAMELEN*this_dev); dev->irq = irq[this_dev]; dev->base_addr = io[this_dev]; @@ -502,7 +502,7 @@ int this_dev; for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) { - struct device *dev = &dev_wd[this_dev]; + struct net_device *dev = &dev_wd[this_dev]; if (dev->priv != NULL) { void *priv = dev->priv; int ioaddr = dev->base_addr - WD_NIC_OFFSET; diff -u --recursive --new-file v2.3.13/linux/drivers/net/x25_asy.c linux/drivers/net/x25_asy.c --- v2.3.13/linux/drivers/net/x25_asy.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/x25_asy.c Wed Aug 18 11:36:43 1999 @@ -34,7 +34,7 @@ typedef struct x25_ctrl { char if_name[8]; /* "xasy0\0" .. "xasy99999\0" */ struct x25_asy ctrl; /* X.25 things */ - struct device dev; /* the device */ + struct net_device dev; /* the device */ } x25_asy_ctrl_t; static x25_asy_ctrl_t **x25_asy_ctrls = NULL; @@ -139,7 +139,7 @@ static void x25_asy_changed_mtu(struct x25_asy *sl) { - struct device *dev = sl->dev; + struct net_device *dev = sl->dev; unsigned char *xbuff, *rbuff, *oxbuff, *orbuff; int len; unsigned long flags; @@ -324,7 +324,7 @@ /* Encapsulate an IP datagram and kick it into a TTY queue. */ -static int x25_asy_xmit(struct sk_buff *skb, struct device *dev) +static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev) { struct x25_asy *sl = (struct x25_asy*)(dev->priv); int err; @@ -481,7 +481,7 @@ /* Open the low-level part of the X.25 channel. Easy! */ -static int x25_asy_open(struct device *dev) +static int x25_asy_open(struct net_device *dev) { struct lapb_register_struct x25_asy_callbacks; struct x25_asy *sl = (struct x25_asy*)(dev->priv); @@ -542,7 +542,7 @@ /* Close the low-level part of the X.25 channel. Easy! */ -static int x25_asy_close(struct device *dev) +static int x25_asy_close(struct net_device *dev) { struct x25_asy *sl = (struct x25_asy*)(dev->priv); int err; @@ -676,7 +676,7 @@ } -static struct net_device_stats *x25_asy_get_stats(struct device *dev) +static struct net_device_stats *x25_asy_get_stats(struct net_device *dev) { static struct net_device_stats stats; struct x25_asy *sl = (struct x25_asy*)(dev->priv); @@ -806,7 +806,7 @@ } } -static int x25_asy_open_dev(struct device *dev) +static int x25_asy_open_dev(struct net_device *dev) { struct x25_asy *sl = (struct x25_asy*)(dev->priv); if(sl->tty==NULL) @@ -818,7 +818,7 @@ #ifdef MODULE static int x25_asy_init_ctrl_dev(void) #else /* !MODULE */ -int __init x25_asy_init_ctrl_dev(struct device *dummy) +int __init x25_asy_init_ctrl_dev(struct net_device *dummy) #endif /* !MODULE */ { int status; @@ -869,7 +869,7 @@ /* Initialise the X.25 driver. Called by the device init code */ -int x25_asy_init(struct device *dev) +int x25_asy_init(struct net_device *dev) { struct x25_asy *sl = (struct x25_asy*)(dev->priv); diff -u --recursive --new-file v2.3.13/linux/drivers/net/x25_asy.h linux/drivers/net/x25_asy.h --- v2.3.13/linux/drivers/net/x25_asy.h Fri Apr 4 08:52:22 1997 +++ linux/drivers/net/x25_asy.h Wed Aug 18 11:36:45 1999 @@ -19,7 +19,7 @@ /* Various fields. */ struct tty_struct *tty; /* ptr to TTY structure */ - struct device *dev; /* easy for intr handling */ + struct net_device *dev; /* easy for intr handling */ /* These are pointers to the malloc()ed frame buffers. */ unsigned char *rbuff; /* receiver buffer */ @@ -53,6 +53,6 @@ #define X25_ASY_MAGIC 0x5303 -extern int x25_asy_init(struct device *dev); +extern int x25_asy_init(struct net_device *dev); #endif /* _LINUX_X25_ASY.H */ diff -u --recursive --new-file v2.3.13/linux/drivers/net/yellowfin.c linux/drivers/net/yellowfin.c --- v2.3.13/linux/drivers/net/yellowfin.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/yellowfin.c Wed Aug 18 11:36:43 1999 @@ -272,7 +272,7 @@ struct yellowfin_desc rx_ring[RX_RING_SIZE]; struct yellowfin_desc tx_ring[TX_RING_SIZE*2]; const char *product_name; - struct device *next_module; + struct net_device *next_module; /* The addresses of receive-in-place skbuffs. */ struct sk_buff* rx_skbuff[RX_RING_SIZE]; /* The saved address of a sent-in-place packet/buffer, for skfree(). */ @@ -316,32 +316,32 @@ #endif -static struct device *yellowfin_probe1(struct device *dev, long ioaddr, +static struct net_device *yellowfin_probe1(struct net_device *dev, long ioaddr, int irq, int chip_id, int options); static int read_eeprom(long ioaddr, int location); static int mdio_read(long ioaddr, int phy_id, int location); static void mdio_write(long ioaddr, int phy_id, int location, int value); #ifdef HAVE_PRIVATE_IOCTL -static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd); +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); #endif -static int yellowfin_open(struct device *dev); +static int yellowfin_open(struct net_device *dev); static void yellowfin_timer(unsigned long data); -static void yellowfin_tx_timeout(struct device *dev); -static void yellowfin_init_ring(struct device *dev); -static int yellowfin_start_xmit(struct sk_buff *skb, struct device *dev); +static void yellowfin_tx_timeout(struct net_device *dev); +static void yellowfin_init_ring(struct net_device *dev); +static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev); static void yellowfin_interrupt(int irq, void *dev_instance, struct pt_regs *regs); -static int yellowfin_rx(struct device *dev); -static void yellowfin_error(struct device *dev, int intr_status); -static int yellowfin_close(struct device *dev); -static struct enet_statistics *yellowfin_get_stats(struct device *dev); -static void set_rx_mode(struct device *dev); +static int yellowfin_rx(struct net_device *dev); +static void yellowfin_error(struct net_device *dev, int intr_status); +static int yellowfin_close(struct net_device *dev); +static struct enet_statistics *yellowfin_get_stats(struct net_device *dev); +static void set_rx_mode(struct net_device *dev); /* A list of all installed Yellowfin devices, for removing the driver module. */ -static struct device *root_yellowfin_dev = NULL; +static struct net_device *root_yellowfin_dev = NULL; -int yellowfin_probe(struct device *dev) +int yellowfin_probe(struct net_device *dev) { int cards_found = 0; int pci_index = 0; @@ -423,7 +423,7 @@ return cards_found ? 0 : -ENODEV; } -static struct device *yellowfin_probe1(struct device *dev, long ioaddr, +static struct net_device *yellowfin_probe1(struct net_device *dev, long ioaddr, int irq, int chip_id, int card_idx) { static int did_version = 0; /* Already printed version info. */ @@ -560,7 +560,7 @@ } -static int yellowfin_open(struct device *dev) +static int yellowfin_open(struct net_device *dev) { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; long ioaddr = dev->base_addr; @@ -645,7 +645,7 @@ static void yellowfin_timer(unsigned long data) { - struct device *dev = (struct device *)data; + struct net_device *dev = (struct net_device *)data; struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; long ioaddr = dev->base_addr; int next_tick = 0; @@ -683,7 +683,7 @@ } } -static void yellowfin_tx_timeout(struct device *dev) +static void yellowfin_tx_timeout(struct net_device *dev) { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; long ioaddr = dev->base_addr; @@ -717,7 +717,7 @@ /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ -static void yellowfin_init_ring(struct device *dev) +static void yellowfin_init_ring(struct net_device *dev) { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; int i; @@ -785,7 +785,7 @@ return; } -static int yellowfin_start_xmit(struct sk_buff *skb, struct device *dev) +static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; unsigned entry; @@ -859,7 +859,7 @@ after the Tx thread. */ static void yellowfin_interrupt(int irq, void *dev_instance, struct pt_regs *regs) { - struct device *dev = (struct device *)dev_instance; + struct net_device *dev = (struct net_device *)dev_instance; struct yellowfin_private *yp; long ioaddr, boguscnt = max_interrupt_work; @@ -1021,7 +1021,7 @@ /* This routine is logically part of the interrupt handler, but separated for clarity and better register allocation. */ -static int yellowfin_rx(struct device *dev) +static int yellowfin_rx(struct net_device *dev) { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; int entry = yp->cur_rx % RX_RING_SIZE; @@ -1155,7 +1155,7 @@ return 0; } -static void yellowfin_error(struct device *dev, int intr_status) +static void yellowfin_error(struct net_device *dev, int intr_status) { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; @@ -1168,7 +1168,7 @@ yp->stats.rx_errors++; } -static int yellowfin_close(struct device *dev) +static int yellowfin_close(struct net_device *dev) { long ioaddr = dev->base_addr; struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; @@ -1260,7 +1260,7 @@ return 0; } -static struct enet_statistics *yellowfin_get_stats(struct device *dev) +static struct enet_statistics *yellowfin_get_stats(struct net_device *dev) { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; return &yp->stats; @@ -1291,7 +1291,7 @@ } -static void set_rx_mode(struct device *dev) +static void set_rx_mode(struct net_device *dev) { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; long ioaddr = dev->base_addr; @@ -1338,7 +1338,7 @@ } #ifdef HAVE_PRIVATE_IOCTL -static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd) +static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { long ioaddr = dev->base_addr; u16 *data = (u16 *)&rq->ifr_data; @@ -1377,7 +1377,7 @@ void cleanup_module(void) { - struct device *next_dev; + struct net_device *next_dev; /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ while (root_yellowfin_dev) { diff -u --recursive --new-file v2.3.13/linux/drivers/net/z85230.c linux/drivers/net/z85230.c --- v2.3.13/linux/drivers/net/z85230.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/net/z85230.c Wed Aug 18 11:36:43 1999 @@ -609,7 +609,7 @@ }; -int z8530_sync_open(struct device *dev, struct z8530_channel *c) +int z8530_sync_open(struct net_device *dev, struct z8530_channel *c) { c->sync = 1; c->mtu = dev->mtu+64; @@ -631,7 +631,7 @@ EXPORT_SYMBOL(z8530_sync_open); -int z8530_sync_close(struct device *dev, struct z8530_channel *c) +int z8530_sync_close(struct net_device *dev, struct z8530_channel *c) { u8 chk; c->irqs = &z8530_nop; @@ -646,7 +646,7 @@ EXPORT_SYMBOL(z8530_sync_close); -int z8530_sync_dma_open(struct device *dev, struct z8530_channel *c) +int z8530_sync_dma_open(struct net_device *dev, struct z8530_channel *c) { unsigned long flags; @@ -766,7 +766,7 @@ EXPORT_SYMBOL(z8530_sync_dma_open); -int z8530_sync_dma_close(struct device *dev, struct z8530_channel *c) +int z8530_sync_dma_close(struct net_device *dev, struct z8530_channel *c) { u8 chk; unsigned long flags; @@ -832,7 +832,7 @@ EXPORT_SYMBOL(z8530_sync_dma_close); -int z8530_sync_txdma_open(struct device *dev, struct z8530_channel *c) +int z8530_sync_txdma_open(struct net_device *dev, struct z8530_channel *c) { unsigned long flags; @@ -925,7 +925,7 @@ EXPORT_SYMBOL(z8530_sync_txdma_open); -int z8530_sync_txdma_close(struct device *dev, struct z8530_channel *c) +int z8530_sync_txdma_close(struct net_device *dev, struct z8530_channel *c) { unsigned long flags; u8 chk; diff -u --recursive --new-file v2.3.13/linux/drivers/net/z85230.h linux/drivers/net/z85230.h --- v2.3.13/linux/drivers/net/z85230.h Sat May 15 15:05:36 1999 +++ linux/drivers/net/z85230.h Wed Aug 18 11:36:45 1999 @@ -320,7 +320,7 @@ */ void *private; /* For our owner */ - struct device *netdevice; /* Network layer device */ + struct net_device *netdevice; /* Network layer device */ struct net_device_stats stats; /* Network layer statistics */ /* @@ -397,12 +397,12 @@ extern void z8530_describe(struct z8530_dev *, char *mapping,int io); extern int z8530_init(struct z8530_dev *); extern int z8530_shutdown(struct z8530_dev *); -extern int z8530_sync_open(struct device *, struct z8530_channel *); -extern int z8530_sync_close(struct device *, struct z8530_channel *); -extern int z8530_sync_dma_open(struct device *, struct z8530_channel *); -extern int z8530_sync_dma_close(struct device *, struct z8530_channel *); -extern int z8530_sync_txdma_open(struct device *, struct z8530_channel *); -extern int z8530_sync_txdma_close(struct device *, struct z8530_channel *); +extern int z8530_sync_open(struct net_device *, struct z8530_channel *); +extern int z8530_sync_close(struct net_device *, struct z8530_channel *); +extern int z8530_sync_dma_open(struct net_device *, struct z8530_channel *); +extern int z8530_sync_dma_close(struct net_device *, struct z8530_channel *); +extern int z8530_sync_txdma_open(struct net_device *, struct z8530_channel *); +extern int z8530_sync_txdma_close(struct net_device *, struct z8530_channel *); extern int z8530_channel_load(struct z8530_channel *, u8 *); extern int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb); extern struct net_device_stats *z8530_get_stats(struct z8530_channel *c); diff -u --recursive --new-file v2.3.13/linux/drivers/net/znet.c linux/drivers/net/znet.c --- v2.3.13/linux/drivers/net/znet.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/net/znet.c Wed Aug 18 11:36:43 1999 @@ -180,15 +180,15 @@ char pad; }; -int znet_probe(struct device *dev); -static int znet_open(struct device *dev); -static int znet_send_packet(struct sk_buff *skb, struct device *dev); +int znet_probe(struct net_device *dev); +static int znet_open(struct net_device *dev); +static int znet_send_packet(struct sk_buff *skb, struct net_device *dev); static void znet_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void znet_rx(struct device *dev); -static int znet_close(struct device *dev); -static struct net_device_stats *net_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); -static void hardware_init(struct device *dev); +static void znet_rx(struct net_device *dev); +static int znet_close(struct net_device *dev); +static struct net_device_stats *net_get_stats(struct net_device *dev); +static void set_multicast_list(struct net_device *dev); +static void hardware_init(struct net_device *dev); static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset); #ifdef notdef @@ -200,7 +200,7 @@ BIOS area. We just scan for the signature, and pull the vital parameters out of the structure. */ -int __init znet_probe(struct device *dev) +int __init znet_probe(struct net_device *dev) { int i; struct netidblk *netinfo; @@ -283,7 +283,7 @@ } -static int znet_open(struct device *dev) +static int znet_open(struct net_device *dev) { int ioaddr = dev->base_addr; @@ -314,7 +314,7 @@ return 0; } -static int znet_send_packet(struct sk_buff *skb, struct device *dev) +static int znet_send_packet(struct sk_buff *skb, struct net_device *dev) { int ioaddr = dev->base_addr; struct net_local *lp = (struct net_local *)dev->priv; @@ -402,7 +402,7 @@ /* The ZNET interrupt handler. */ static void znet_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - struct device *dev = dev_id; + struct net_device *dev = dev_id; int ioaddr; int boguscnt = 20; @@ -465,7 +465,7 @@ return; } -static void znet_rx(struct device *dev) +static void znet_rx(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; @@ -589,7 +589,7 @@ } /* The inverse routine to znet_open(). */ -static int znet_close(struct device *dev) +static int znet_close(struct net_device *dev) { unsigned long flags; int ioaddr = dev->base_addr; @@ -617,7 +617,7 @@ /* Get the current statistics. This may be called with the card open or closed. */ -static struct net_device_stats *net_get_stats(struct device *dev) +static struct net_device_stats *net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; @@ -632,7 +632,7 @@ mode change persistent, but must be changed if this code is moved to a multiple adaptor environment. */ -static void set_multicast_list(struct device *dev) +static void set_multicast_list(struct net_device *dev) { short ioaddr = dev->base_addr; @@ -677,7 +677,7 @@ /* Initialize the hardware. We have to do this when the board is open()ed or when we come out of suspend mode. */ -static void hardware_init(struct device *dev) +static void hardware_init(struct net_device *dev) { unsigned long flags; short ioaddr = dev->base_addr; diff -u --recursive --new-file v2.3.13/linux/drivers/parport/ieee1284_ops.c linux/drivers/parport/ieee1284_ops.c --- v2.3.13/linux/drivers/parport/ieee1284_ops.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/parport/ieee1284_ops.c Thu Aug 12 11:53:18 1999 @@ -32,18 +32,12 @@ * One-way data transfer functions. * * ***/ -static inline -int polling (struct pardevice *dev) -{ - return dev->port->irq == PARPORT_IRQ_NONE; -} - /* Compatibility mode. */ size_t parport_ieee1284_write_compat (struct parport *port, const void *buffer, size_t len, int flags) { - int no_irq; + int no_irq = 1; ssize_t count = 0; const unsigned char *addr = buffer; unsigned char byte; @@ -51,11 +45,15 @@ unsigned char ctl = (PARPORT_CONTROL_SELECT | PARPORT_CONTROL_INIT); - if (port->irq != PARPORT_IRQ_NONE) + if (port->irq != PARPORT_IRQ_NONE) { parport_enable_irq (port); + no_irq = 0; + + /* Clear out previous irqs. */ + while (!down_trylock (&port->physport->ieee1284.irq)); + } port->physport->ieee1284.phase = IEEE1284_PH_FWD_DATA; - no_irq = polling (dev); while (count < len) { long expire = jiffies + dev->timeout; long wait = (HZ + 99) / 100; @@ -63,12 +61,6 @@ | PARPORT_STATUS_BUSY); unsigned char val = (PARPORT_STATUS_ERROR | PARPORT_STATUS_BUSY); - int i; - - /* Write the character to the data lines. */ - byte = *addr++; - parport_write_data (port, byte); - udelay (1); /* Wait until the peripheral's ready */ do { @@ -111,18 +103,23 @@ /* Is there a signal pending? */ if (signal_pending (current)) - goto stop; + break; /* Wait longer next time. */ wait *= 2; } while (time_before (jiffies, expire)); + if (signal_pending (current)) + break; + DPRINTK (KERN_DEBUG "%s: Timed out\n", port->name); break; ready: - /* Clear out previous irqs. */ - while (!down_trylock (&port->physport->ieee1284.irq)); + /* Write the character to the data lines. */ + byte = *addr++; + parport_write_data (port, byte); + udelay (1); /* Pulse strobe. */ parport_write_control (port, ctl | PARPORT_CONTROL_STROBE); @@ -131,30 +128,7 @@ parport_write_control (port, ctl); udelay (1); /* hold */ - if (no_irq) - /* Assume the peripheral received it. */ - goto done; - - /* Wait until it's received, up to 500us (this ought to be - * tuneable). */ - for (i = 500; i; i--) { - if (!down_trylock (&port->physport->ieee1284.irq) || - !(parport_read_status (port) & PARPORT_STATUS_ACK)) - goto done; - udelay (1); - } - - /* Two choices: - * 1. Assume that the peripheral got the data and just - * hasn't acknowledged it yet. - * 2. Assume that the peripheral never saw the strobe pulse. - * - * We can't know for sure, so let's be conservative. - */ - DPRINTK (KERN_DEBUG "%s: no ack", port->name); - break; - - done: + /* Assume the peripheral received it. */ count++; /* Let another process run if it needs to. */ @@ -547,7 +521,7 @@ goto out; /* Yield the port for a while. */ - if (count && polling (dev)) { + if (count && dev->port->irq != PARPORT_IRQ_NONE) { parport_release (dev); current->state = TASK_INTERRUPTIBLE; schedule_timeout ((HZ + 99) / 25); diff -u --recursive --new-file v2.3.13/linux/drivers/parport/parport_mfc3.c linux/drivers/parport/parport_mfc3.c --- v2.3.13/linux/drivers/parport/parport_mfc3.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/parport/parport_mfc3.c Sun Aug 15 11:48:32 1999 @@ -346,7 +346,7 @@ if (p->irq != PARPORT_IRQ_NONE) if (use_cnt++ == 0) - if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, 0, p->name, &pp_mfc3_ops)) + if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, SA_SHIRQ, p->name, &pp_mfc3_ops)) use_cnt--; if (parport_probe_hook) diff -u --recursive --new-file v2.3.13/linux/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c --- v2.3.13/linux/drivers/parport/parport_pc.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/parport/parport_pc.c Thu Aug 12 11:53:22 1999 @@ -76,7 +76,7 @@ outb ((inb (ECONTROL (pb)) & ~m) ^ v, ECONTROL (pb)); } -#if defined(CONFIG_PARPORT_1284) || defined(CONFIG_PARPORT_PC_FIFO) +#ifdef CONFIG_PARPORT_PC_FIFO /* Safely change the mode bits in the ECR */ static int change_mode(struct parport *p, int m) { @@ -134,6 +134,7 @@ return 0; } +#ifdef CONFIG_PARPORT_1284 /* Find FIFO lossage; FIFO is reset */ static int get_fifo_residue (struct parport *p) { @@ -180,8 +181,8 @@ return residue; } - -#endif /* IEEE 1284 support or FIFO support */ +#endif /* IEEE 1284 support */ +#endif /* FIFO support */ /* * Clear TIMEOUT BIT in EPP MODE @@ -1879,7 +1880,7 @@ if (p->irq != PARPORT_IRQ_NONE) free_irq(p->irq, p); release_region(p->base, 3); - if (p->size > 3); + if (p->size > 3) release_region(p->base + 3, p->size - 3); if (p->modes & PARPORT_MODE_ECP) release_region(p->base_hi, 3); diff -u --recursive --new-file v2.3.13/linux/drivers/parport/procfs.c linux/drivers/parport/procfs.c --- v2.3.13/linux/drivers/parport/procfs.c Wed Jul 28 14:47:42 1999 +++ linux/drivers/parport/procfs.c Thu Aug 12 10:19:59 1999 @@ -23,8 +23,12 @@ #include -#ifdef CONFIG_SYSCTL +#if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS) +#define PARPORT_MIN_TIMESLICE_VALUE 1ul +#define PARPORT_MAX_TIMESLICE_VALUE ((unsigned long) HZ) +#define PARPORT_MIN_SPINTIME_VALUE 1 +#define PARPORT_MAX_SPINTIME_VALUE 1000 static int do_active_device(ctl_table *table, int write, struct file *filp, void *result, size_t *lenp) @@ -167,6 +171,18 @@ #define PARPORT_DEVICES_ROOT_DIR { DEV_PARPORT_DEVICES, "devices", \ NULL, 0, 0555, NULL } +static const unsigned long parport_min_timeslice_value = +PARPORT_MIN_TIMESLICE_VALUE; + +static const unsigned long parport_max_timeslice_value = +PARPORT_MAX_TIMESLICE_VALUE; + +static const int parport_min_spintime_value = +PARPORT_MIN_SPINTIME_VALUE; + +static const int parport_max_spintime_value = +PARPORT_MAX_SPINTIME_VALUE; + struct parport_sysctl_table { struct ctl_table_header *sysctl_header; @@ -182,7 +198,9 @@ { { DEV_PARPORT_SPINTIME, "spintime", NULL, sizeof(int), 0644, NULL, - &proc_dointvec }, + &proc_dointvec_minmax, NULL, NULL, + (void*) &parport_min_spintime_value, + (void*) &parport_max_spintime_value }, { DEV_PARPORT_HARDWARE, "hardware", NULL, 0, 0444, NULL, &do_hardware }, @@ -230,7 +248,9 @@ { { DEV_PARPORT_DEVICE_TIMESLICE, "timeslice", NULL, sizeof(int), 0644, NULL, - &proc_dointvec }, + &proc_doulongvec_ms_jiffies_minmax, NULL, NULL, + (void*) &parport_min_timeslice_value, + (void*) &parport_max_timeslice_value }, }, { {0, NULL, NULL, 0, 0555, NULL}, {0}}, { PARPORT_DEVICES_ROOT_DIR, {0}}, @@ -258,11 +278,15 @@ { DEV_PARPORT_DEFAULT_TIMESLICE, "timeslice", &parport_default_timeslice, sizeof(parport_default_timeslice), 0644, NULL, - &proc_dointvec }, + &proc_doulongvec_ms_jiffies_minmax, NULL, NULL, + (void*) &parport_min_timeslice_value, + (void*) &parport_max_timeslice_value }, { DEV_PARPORT_DEFAULT_SPINTIME, "spintime", &parport_default_spintime, - sizeof(parport_default_timeslice), 0644, NULL, - &proc_dointvec }, + sizeof(parport_default_spintime), 0644, NULL, + &proc_dointvec_minmax, NULL, NULL, + (void*) &parport_min_spintime_value, + (void*) &parport_max_spintime_value }, {0} }, { { DEV_PARPORT_DEFAULT, "default", NULL, 0, 0555, @@ -395,7 +419,7 @@ return 0; } -#else /* no sysctl */ +#else /* no sysctl or no procfs*/ int parport_proc_register(struct parport *pp) { diff -u --recursive --new-file v2.3.13/linux/drivers/pci/Makefile linux/drivers/pci/Makefile --- v2.3.13/linux/drivers/pci/Makefile Mon Aug 9 14:59:22 1999 +++ linux/drivers/pci/Makefile Thu Aug 12 10:39:20 1999 @@ -18,7 +18,7 @@ O_OBJS = pci.o names.o L_OBJS := pci_syms.o else -L_OBJS := pci.o +L_OBJS := pci.o names.o endif ifdef CONFIG_PROC_FS diff -u --recursive --new-file v2.3.13/linux/drivers/pci/pci.c linux/drivers/pci/pci.c --- v2.3.13/linux/drivers/pci/pci.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/pci/pci.c Thu Aug 12 11:50:14 1999 @@ -27,6 +27,8 @@ #define DBG(x...) #endif +extern void pci_namedevice(struct pci_dev *); + struct pci_bus pci_root; struct pci_dev *pci_devices = NULL; int pci_reverse __initdata = 0; diff -u --recursive --new-file v2.3.13/linux/drivers/pnp/Config.in linux/drivers/pnp/Config.in --- v2.3.13/linux/drivers/pnp/Config.in Thu Jul 8 15:42:20 1999 +++ linux/drivers/pnp/Config.in Sun Aug 15 11:50:35 1999 @@ -1,3 +1,11 @@ # # Plug and Play configuration # +mainmenu_option next_comment +comment 'Plug and Play configuration' + +tristate 'Plug and Play support' CONFIG_PNP + +dep_tristate 'ISA Plug and Play support' CONFIG_ISAPNP $CONFIG_PNP + +endmenu diff -u --recursive --new-file v2.3.13/linux/drivers/pnp/Makefile linux/drivers/pnp/Makefile --- v2.3.13/linux/drivers/pnp/Makefile Thu Jul 8 15:42:20 1999 +++ linux/drivers/pnp/Makefile Sun Aug 15 11:50:35 1999 @@ -18,4 +18,12 @@ MI_OBJS := MIX_OBJS := +ifeq ($(CONFIG_ISAPNP),y) + LX_OBJS += isapnp.o +else + ifeq ($(CONFIG_ISAPNP),m) + MX_OBJS += isapnp.o + endif +endif + include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.3.13/linux/drivers/pnp/isapnp.c linux/drivers/pnp/isapnp.c --- v2.3.13/linux/drivers/pnp/isapnp.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/pnp/isapnp.c Wed Aug 18 09:59:26 1999 @@ -0,0 +1,2156 @@ +/* + * ISA Plug & Play support + * Copyright (c) by Jaroslav Kysela + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_PROC_FS +#include "isapnp_proc.c" +#endif + +#if 0 +#define ISAPNP_REGION_OK +#endif +#if 0 +#define ISAPNP_DEBUG +#endif + +struct resource *pidxr_res = NULL; +struct resource *pnpwrp_res = NULL; +struct resource *isapnp_rdp_res = NULL; + +int isapnp_disable = 0; /* Disable ISA PnP */ +int isapnp_rdp = 0; /* Read Data Port */ +int isapnp_reset = 0; /* reset all PnP cards (deactivate) */ +int isapnp_skip_pci_scan = 0; /* skip PCI resource scanning */ +int isapnp_verbose = 1; /* verbose mode */ +int isapnp_reserve_irq[16] = { [0 ... 15] = -1 }; /* reserve (don't use) some IRQ */ +int isapnp_reserve_dma[8] = { [0 ... 7] = -1 }; /* reserve (don't use) some DMA */ +int isapnp_reserve_io[16] = { [0 ... 15] = -1 }; /* reserve (don't use) some I/O region */ +int isapnp_reserve_mem[16] = { [0 ... 15] = -1 }; /* reserve (don't use) some memory region */ + +MODULE_AUTHOR("Jaroslav Kysela "); +MODULE_DESCRIPTION("Generic ISA Plug & Play support"); +MODULE_PARM(isapnp_disable, "i"); +MODULE_PARM_DESC(isapnp_disable, "ISA Plug & Play disable"); +MODULE_PARM(isapnp_rdp, "i"); +MODULE_PARM_DESC(isapnp_rdp, "ISA Plug & Play read data port"); +MODULE_PARM(isapnp_reset, "i"); +MODULE_PARM_DESC(isapnp_reset, "ISA Plug & Play reset all cards"); +MODULE_PARM(isapnp_skip_pci_scan, "i"); +MODULE_PARM_DESC(isapnp_skip_pci_scan, "ISA Plug & Play skip PCI resource scanning"); +MODULE_PARM(isapnp_verbose, "i"); +MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode"); +MODULE_PARM(isapnp_reserve_irq, "1-16i"); +MODULE_PARM_DESC(isapnp_reserve_irq, "ISA Plug & Play - reserve IRQ line(s)"); +MODULE_PARM(isapnp_reserve_dma, "1-8i"); +MODULE_PARM_DESC(isapnp_reserve_dma, "ISA Plug & Play - reserve DMA channel(s)"); +MODULE_PARM(isapnp_reserve_io, "1-16i"); +MODULE_PARM_DESC(isapnp_reserve_io, "ISA Plug & Play - reserve I/O region(s) - port,size"); +MODULE_PARM(isapnp_reserve_mem, "1-16i"); +MODULE_PARM_DESC(isapnp_reserve_mem, "ISA Plug & Play - reserve memory region(s) - address,size"); + +#define _PIDXR 0x279 +#define _PNPWRP 0xa79 + +/* short tags */ +#define _STAG_PNPVERNO 0x01 +#define _STAG_LOGDEVID 0x02 +#define _STAG_COMPATDEVID 0x03 +#define _STAG_IRQ 0x04 +#define _STAG_DMA 0x05 +#define _STAG_STARTDEP 0x06 +#define _STAG_ENDDEP 0x07 +#define _STAG_IOPORT 0x08 +#define _STAG_FIXEDIO 0x09 +#define _STAG_VENDOR 0x0e +#define _STAG_END 0x0f +/* long tags */ +#define _LTAG_MEMRANGE 0x81 +#define _LTAG_ANSISTR 0x82 +#define _LTAG_UNICODESTR 0x83 +#define _LTAG_VENDOR 0x84 +#define _LTAG_MEM32RANGE 0x85 +#define _LTAG_FIXEDMEM32RANGE 0x86 + +struct pci_bus *isapnp_cards = NULL; /* ISA PnP cards */ +struct pci_dev *isapnp_devices = NULL; /* ISA PnP devices */ +static struct pci_dev *isapnp_last_device = NULL; +static unsigned char isapnp_checksum_value; +static DECLARE_MUTEX(isapnp_cfg_mutex); +static int isapnp_detected = 0; + +/* some prototypes */ + +static int isapnp_config_prepare(struct pci_dev *dev); +static int isapnp_config_activate(struct pci_dev *dev); +static int isapnp_config_deactivate(struct pci_dev *dev); + +static inline void write_data(unsigned char x) +{ + outb(x, _PNPWRP); +} + +static inline void write_address(unsigned char x) +{ + outb(x, _PIDXR); + udelay(10); +} + +static inline unsigned char read_data(void) +{ + unsigned char val = inb(isapnp_rdp); + return val; +} + +unsigned char isapnp_read_byte(unsigned char idx) +{ + write_address(idx); + return read_data(); +} + +unsigned short isapnp_read_word(unsigned char idx) +{ + unsigned short val; + + val = isapnp_read_byte(idx); + val = (val << 8) + isapnp_read_byte(idx+1); + return val; +} + +unsigned int isapnp_read_dword(unsigned char idx) +{ + unsigned int val; + + val = isapnp_read_byte(idx); + val = (val << 8) + isapnp_read_byte(idx+1); + val = (val << 8) + isapnp_read_byte(idx+2); + val = (val << 8) + isapnp_read_byte(idx+3); + return val; +} + +void isapnp_write_byte(unsigned char idx, unsigned char val) +{ + write_address(idx); + write_data(val); +} + +void isapnp_write_word(unsigned char idx, unsigned short val) +{ + isapnp_write_byte(idx, val >> 8); + isapnp_write_byte(idx+1, val); +} + +void isapnp_write_dword(unsigned char idx, unsigned int val) +{ + isapnp_write_byte(idx, val >> 24); + isapnp_write_byte(idx+1, val >> 16); + isapnp_write_byte(idx+2, val >> 8); + isapnp_write_byte(idx+3, val); +} + +static void *isapnp_alloc(long size) +{ + void *result; + + result = kmalloc(size, GFP_KERNEL); + if (!result) + return NULL; + memset(result, 0, size); + return result; +} + +static void isapnp_key(void) +{ + unsigned char code = 0x6a, msb; + int i; + + mdelay(1); + write_address(0x00); + write_address(0x00); + + write_address(code); + + for (i = 1; i < 32; i++) { + msb = ((code & 0x01) ^ ((code & 0x02) >> 1)) << 7; + code = (code >> 1) | msb; + write_address(code); + } +} + +/* place all pnp cards in wait-for-key state */ +static void isapnp_wait(void) +{ + isapnp_write_byte(0x02, 0x02); +} + +void isapnp_wake(unsigned char csn) +{ + isapnp_write_byte(0x03, csn); +} + +void isapnp_device(unsigned char logdev) +{ + isapnp_write_byte(0x07, logdev); +} + +void isapnp_activate(unsigned char logdev) +{ + isapnp_device(logdev); + isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 1); + udelay(250); +} + +void isapnp_deactivate(unsigned char logdev) +{ + isapnp_device(logdev); + isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 0); +} + +static void __init isapnp_peek(unsigned char *data, int bytes) +{ + int i, j; + unsigned char d; + + for (i = 1; i <= bytes; i++) { + for (j = 0; j < 10; j++) { + d = isapnp_read_byte(0x05); + if (d & 1) + break; + udelay(10); + } + if (!(d & 1)) { + *data++ = 0xff; + continue; + } + d = isapnp_read_byte(0x04); /* PRESDI */ + isapnp_checksum_value += d; + if (data != NULL) + *data++ = d; + } +} + +#define RDP_STEP 32 /* minimum is 4 */ + +static int isapnp_next_rdp(void) +{ + int rdp = isapnp_rdp; + while (rdp <= 0x3ff) { + if (!check_region(rdp, 1)) { + isapnp_rdp = rdp; + return 0; + } + rdp += RDP_STEP; + } + return -1; +} + +/* Set read port address */ +static inline void isapnp_set_rdp(void) +{ + isapnp_write_byte(0x00, isapnp_rdp >> 2); + udelay(100); +} + + +static int __init isapnp_isolate_rdp_select(void) +{ + isapnp_wait(); + isapnp_key(); + + /* Control: reset CSN and conditionally everything else too */ + isapnp_write_byte(0x02, isapnp_reset ? 0x05 : 0x04); + mdelay(2); + + isapnp_wait(); + isapnp_key(); + isapnp_wake(0x00); + + if (isapnp_next_rdp() < 0) { + isapnp_wait(); + return -1; + } + + isapnp_set_rdp(); + udelay(1000); + write_address(0x01); + udelay(1000); + return 0; +} + +/* + * Isolate (assign uniqued CSN) to all ISA PnP devices. + */ + +static int __init isapnp_isolate(void) +{ + unsigned char checksum = 0x6a; + unsigned char chksum = 0x00; + unsigned char bit = 0x00; + int data; + int csn = 0; + int i; + int iteration = 1; + + isapnp_rdp = 0x213; + if (isapnp_isolate_rdp_select() < 0) + return -1; + + while (1) { + for (i = 1; i <= 64; i++) { + data = read_data() << 8; + udelay(250); + data = data | read_data(); + udelay(250); + if (data == 0x55aa) + bit = 0x01; + checksum = ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7) | (checksum >> 1); + bit = 0x00; + } + for (i = 65; i <= 72; i++) { + data = read_data() << 8; + udelay(250); + data = data | read_data(); + udelay(250); + if (data == 0x55aa) + chksum |= (1 << (i - 65)); + } + if (checksum != 0x00 && checksum == chksum) { + csn++; + + isapnp_write_byte(0x06, csn); + udelay(250); + iteration++; + isapnp_wake(0x00); + write_address(0x01); + goto __next; + } + if (iteration == 1) { + isapnp_rdp += RDP_STEP; + if (isapnp_isolate_rdp_select() < 0) + return -1; + } else if (iteration > 1) { + break; + } + __next: + checksum = 0x6a; + chksum = 0x00; + bit = 0x00; + } + isapnp_wait(); + return csn; +} + +/* + * Read one tag from stream. + */ + +static int __init isapnp_read_tag(unsigned char *type, unsigned short *size) +{ + unsigned char tag, tmp[2]; + + isapnp_peek(&tag, 1); + if (tag == 0) /* invalid tag */ + return -1; + if (tag & 0x80) { /* large item */ + *type = tag; + isapnp_peek(tmp, 2); + *size = (tmp[1] << 8) | tmp[0]; + } else { + *type = (tag >> 3) & 0x0f; + *size = tag & 0x07; + } +#if 0 + printk("tag = 0x%x, type = 0x%x, size = %i\n", tag, *type, *size); +#endif + if (type == 0) /* wrong type */ + return -1; + if (*type == 0xff && *size == 0xffff) /* probably invalid data */ + return -1; + return 0; +} + +/* + * Skip specified number of bytes from stream. + */ + +static void __init isapnp_skip_bytes(int count) +{ + isapnp_peek(NULL, count); +} + +/* + * Parse logical device tag. + */ + +static struct pci_dev * __init isapnp_parse_device(struct pci_bus *card, int size, int number) +{ + unsigned char tmp[6]; + struct pci_dev *dev; + + isapnp_peek(tmp, size); + dev = isapnp_alloc(sizeof(struct pci_dev)); + if (!dev) + return NULL; + dev->devfn = number; + dev->vendor = (tmp[1] << 8) | tmp[0]; + dev->device = (tmp[3] << 8) | tmp[2]; + dev->regs = tmp[4]; + dev->bus = card; + if (size > 5) + dev->regs |= tmp[5] << 8; + dev->prepare = isapnp_config_prepare; + dev->activate = isapnp_config_activate; + dev->deactivate = isapnp_config_deactivate; + return dev; +} + +/* + * Build new resources structure + */ + +static struct isapnp_resources * __init isapnp_build_resources(struct pci_dev *dev, int dependent) +{ + struct isapnp_resources *res, *ptr, *ptra; + + res = isapnp_alloc(sizeof(struct isapnp_resources)); + if (!res) + return NULL; + res->dev = dev; + ptr = (struct isapnp_resources *)dev->sysdata; + while (ptr && ptr->next) + ptr = ptr->next; + if (ptr && ptr->dependent && dependent) { /* add to another list */ + ptra = ptr->alt; + while (ptra && ptra->alt) + ptra = ptra->alt; + if (!ptra) + ptr->alt = res; + else + ptra->alt = res; + } else { + if (!ptr) + dev->sysdata = res; + else + ptr->next = res; + } + if (dependent) { + res->priority = dependent & 0xff; + if (res->priority > ISAPNP_RES_PRIORITY_FUNCTIONAL) + res->priority = ISAPNP_RES_PRIORITY_INVALID; + res->dependent = 1; + } else { + res->priority = ISAPNP_RES_PRIORITY_PREFERRED; + res->dependent = 0; + } + return res; +} + +/* + * Add IRQ resource to resources list. + */ + +static void __init isapnp_add_irq_resource(struct pci_dev *dev, + struct isapnp_resources **res, + int dependent, int size) +{ + unsigned char tmp[3]; + struct isapnp_irq *irq, *ptr; + + isapnp_peek(tmp, size); + irq = isapnp_alloc(sizeof(struct isapnp_irq)); + if (!irq) + return; + if (*res == NULL) { + *res = isapnp_build_resources(dev, dependent); + if (*res == NULL) { + kfree(irq); + return; + } + } + irq->map = (tmp[1] << 8) | tmp[0]; + if (size > 2) + irq->flags = tmp[2]; + else + irq->flags = DEVICE_IRQ_FLAG_HIGHEDGE; + irq->res = *res; + ptr = (*res)->irq; + while (ptr && ptr->next) + ptr = ptr->next; + if (ptr) + ptr->next = irq; + else + (*res)->irq = irq; +} + +/* + * Add DMA resource to resources list. + */ + +static void __init isapnp_add_dma_resource(struct pci_dev *dev, + struct isapnp_resources **res, + int dependent, int size) +{ + unsigned char tmp[2]; + struct isapnp_dma *dma, *ptr; + + isapnp_peek(tmp, size); + dma = isapnp_alloc(sizeof(struct isapnp_dma)); + if (!dma) + return; + if (*res == NULL) { + *res = isapnp_build_resources(dev, dependent); + if (*res == NULL) { + kfree(dma); + return; + } + } + dma->map = tmp[0]; + dma->type = tmp[1] & 3; + dma->flags = (tmp[1] >> 2) & 7; + dma->speed = (tmp[1] >> 6) & 3; + dma->res = *res; + ptr = (*res)->dma; + while (ptr && ptr->next) + ptr = ptr->next; + if (ptr) + ptr->next = dma; + else + (*res)->dma = dma; +} + +/* + * Add port resource to resources list. + */ + +static void __init isapnp_add_port_resource(struct pci_dev *dev, + struct isapnp_resources **res, + int dependent, int size) +{ + unsigned char tmp[7]; + struct isapnp_port *port, *ptr; + + isapnp_peek(tmp, size); + port = isapnp_alloc(sizeof(struct isapnp_port)); + if (!port) + return; + if (*res == NULL) { + *res = isapnp_build_resources(dev, dependent); + if (*res == NULL) { + kfree(port); + return; + } + } + port->min = (tmp[2] << 8) | tmp[1]; + port->max = (tmp[4] << 8) | tmp[3]; + port->align = tmp[5]; + port->size = tmp[6]; + port->flags = tmp[0] ? ISAPNP_PORT_FLAG_16BITADDR : 0; + port->res = *res; + ptr = (*res)->port; + while (ptr && ptr->next) + ptr = ptr->next; + if (ptr) + ptr->next = port; + else + (*res)->port = port; +} + +/* + * Add fixed port resource to resources list. + */ + +static void __init isapnp_add_fixed_port_resource(struct pci_dev *dev, + struct isapnp_resources **res, + int dependent, int size) +{ + unsigned char tmp[3]; + struct isapnp_port *port, *ptr; + + isapnp_peek(tmp, size); + port = isapnp_alloc(sizeof(struct isapnp_port)); + if (!port) + return; + if (*res == NULL) { + *res = isapnp_build_resources(dev, dependent); + if (*res == NULL) { + kfree(port); + return; + } + } + port->min = port->max = (tmp[1] << 8) | tmp[0]; + port->size = tmp[2]; + port->align = 0; + port->flags = ISAPNP_PORT_FLAG_FIXED; + port->res = *res; + ptr = (*res)->port; + while (ptr && ptr->next) + ptr = ptr->next; + if (ptr) + ptr->next = port; + else + (*res)->port = port; +} + +/* + * Add memory resource to resources list. + */ + +static void __init isapnp_add_mem_resource(struct pci_dev *dev, + struct isapnp_resources **res, + int dependent, int size) +{ + unsigned char tmp[9]; + struct isapnp_mem *mem, *ptr; + + isapnp_peek(tmp, size); + mem = isapnp_alloc(sizeof(struct isapnp_mem)); + if (!mem) + return; + if (*res == NULL) { + *res = isapnp_build_resources(dev, dependent); + if (*res == NULL) { + kfree(mem); + return; + } + } + mem->min = ((tmp[2] << 8) | tmp[1]) << 8; + mem->max = ((tmp[4] << 8) | tmp[3]) << 8; + mem->align = (tmp[6] << 8) | tmp[5]; + mem->size = ((tmp[8] << 8) | tmp[7]) << 8; + mem->flags = tmp[0] & 7; + mem->flags |= (tmp[0] >> 2) & 0x18; + mem->type = (tmp[0] >> 3) & 3; + mem->res = *res; + ptr = (*res)->mem; + while (ptr && ptr->next) + ptr = ptr->next; + if (ptr) + ptr->next = mem; + else + (*res)->mem = mem; +} + +/* + * Add 32-bit memory resource to resources list. + */ + +static void __init isapnp_add_mem32_resource(struct pci_dev *dev, + struct isapnp_resources **res, + int dependent, int size) +{ + unsigned char tmp[17]; + struct isapnp_mem32 *mem32, *ptr; + + isapnp_peek(tmp, size); + mem32 = isapnp_alloc(sizeof(struct isapnp_mem32)); + if (!mem32) + return; + if (*res == NULL) { + *res = isapnp_build_resources(dev, dependent); + if (*res == NULL) { + kfree(mem32); + return; + } + } + memcpy(mem32->data, tmp, 17); + mem32->res = *res; + ptr = (*res)->mem32; + while (ptr && ptr->next) + ptr = ptr->next; + if (ptr) + ptr->next = mem32; + else + (*res)->mem32 = mem32; +} + +/* + * Add 32-bit fixed memory resource to resources list. + */ + +static void __init isapnp_add_fixed_mem32_resource(struct pci_dev *dev, + struct isapnp_resources **res, + int dependent, int size) +{ + unsigned char tmp[17]; + struct isapnp_mem32 *mem32, *ptr; + + isapnp_peek(tmp, size); + mem32 = isapnp_alloc(sizeof(struct isapnp_mem32)); + if (!mem32) + return; + if (*res == NULL) { + *res = isapnp_build_resources(dev, dependent); + if (*res == NULL) { + kfree(mem32); + return; + } + } + memcpy(mem32->data, tmp, 17); + mem32->res = *res; + ptr = (*res)->mem32; + while (ptr && ptr->next) + ptr = ptr->next; + if (ptr) + ptr->next = mem32; + else + (*res)->mem32 = mem32; +} + +/* + * Parse resource map for logical device. + */ + +static int __init isapnp_create_device(struct pci_bus *card, + unsigned short size) +{ + int number = 0, skip = 0, dependent = 0, compat = 0; + unsigned char type, tmp[17]; + struct pci_dev *dev, *prev_dev; + struct isapnp_resources *res = NULL; + + if ((dev = isapnp_parse_device(card, size, number++)) == NULL) + return 1; + card->devices = dev; + if (isapnp_last_device) { + isapnp_last_device->next = dev; + isapnp_last_device = dev; + } else { + isapnp_devices = isapnp_last_device = dev; + } + while (1) { + if (isapnp_read_tag(&type, &size)<0) + return 1; + if (skip && type != _STAG_LOGDEVID && type != _STAG_END) + goto __skip; + switch (type) { + case _STAG_LOGDEVID: + if (size >= 5 && size <= 6) { + prev_dev = dev; + isapnp_config_prepare(dev); + if ((dev = isapnp_parse_device(card, size, number++)) == NULL) + return 1; + prev_dev->sibling = dev; + isapnp_last_device->next = dev; + isapnp_last_device = dev; + size = 0; + skip = 0; + } else { + skip = 1; + } + res = NULL; + dependent = 0; + compat = 0; + break; + case _STAG_COMPATDEVID: + if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) { + isapnp_peek(tmp, 4); + dev->vendor_compatible[compat] = (tmp[1] << 8) | tmp[0]; + dev->device_compatible[compat] = (tmp[3] << 8) | tmp[2]; + compat++; + size = 0; + } + break; + case _STAG_IRQ: + if (size < 2 || size > 3) + goto __skip; + isapnp_add_irq_resource(dev, &res, dependent, size); + size = 0; + break; + case _STAG_DMA: + if (size != 2) + goto __skip; + isapnp_add_dma_resource(dev, &res, dependent, size); + size = 0; + break; + case _STAG_STARTDEP: + if (size > 1) + goto __skip; + res = NULL; + dependent = 0x100 | ISAPNP_RES_PRIORITY_ACCEPTABLE; + if (size > 0) { + isapnp_peek(tmp, size); + dependent = 0x100 | tmp[0]; + size = 0; + } + break; + case _STAG_ENDDEP: + if (size != 0) + goto __skip; + res = NULL; + dependent = 0; + break; + case _STAG_IOPORT: + if (size != 7) + goto __skip; + isapnp_add_port_resource(dev, &res, dependent, size); + size = 0; + break; + case _STAG_FIXEDIO: + if (size != 3) + goto __skip; + isapnp_add_fixed_port_resource(dev, &res, dependent, size); + size = 0; + break; + case _STAG_VENDOR: + break; + case _LTAG_MEMRANGE: + if (size != 9) + goto __skip; + isapnp_add_mem_resource(dev, &res, dependent, size); + size = 0; + break; + case _LTAG_ANSISTR: + if (dev->name[0] == '\0') { + unsigned short size1 = size > 47 ? 47 : size; + isapnp_peek(dev->name, size1); + dev->name[size1] = '\0'; + size -= size1; + } + break; + case _LTAG_UNICODESTR: + /* silently ignore */ + /* who use unicode for hardware identification? */ + break; + case _LTAG_VENDOR: + break; + case _LTAG_MEM32RANGE: + if (size != 17) + goto __skip; + isapnp_add_mem32_resource(dev, &res, dependent, size); + size = 0; + break; + case _LTAG_FIXEDMEM32RANGE: + if (size != 17) + goto __skip; + isapnp_add_fixed_mem32_resource(dev, &res, dependent, size); + size = 0; + break; + case _STAG_END: + if (size > 0) + isapnp_skip_bytes(size); + return 1; + default: + printk("isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignored\n", type, dev->devfn, card->number); + } + __skip: + if (size > 0) + isapnp_skip_bytes(size); + } + isapnp_config_prepare(dev); + return 0; +} + +/* + * Parse resource map for ISA PnP card. + */ + +static void __init isapnp_parse_resource_map(struct pci_bus *card) +{ + unsigned char type, tmp[17]; + unsigned short size; + + while (1) { + if (isapnp_read_tag(&type, &size)<0) + return; + switch (type) { + case _STAG_PNPVERNO: + if (size != 2) + goto __skip; + isapnp_peek(tmp, 2); + card->pnpver = tmp[0]; + card->productver = tmp[1]; + size = 0; + break; + case _STAG_LOGDEVID: + if (size >= 5 && size <= 6) { + if (isapnp_create_device(card, size)==1) + return; + size = 0; + } + break; + case _STAG_VENDOR: + break; + case _LTAG_ANSISTR: + if (card->name[0] == '\0') { + unsigned short size1 = size > 47 ? 47 : size; + isapnp_peek(card->name, size1); + card->name[size1] = '\0'; + size -= size1; + } + break; + case _LTAG_UNICODESTR: + /* silently ignore */ + /* who use unicode for hardware identification? */ + break; + case _LTAG_VENDOR: + break; + case _STAG_END: + if (size > 0) + isapnp_skip_bytes(size); + return; + default: + printk("isapnp: unexpected or unknown tag type 0x%x for device %i, ignored\n", type, card->number); + } + __skip: + if (size > 0) + isapnp_skip_bytes(size); + } +} + +/* + * Compute ISA PnP checksum for first eight bytes. + */ + +static unsigned char __init isapnp_checksum(unsigned char *data) +{ + int i, j; + unsigned char checksum = 0x6a, bit, b; + + for (i = 0; i < 8; i++) { + b = data[i]; + for (j = 0; j < 8; j++) { + bit = 0; + if (b & (1 << j)) + bit = 1; + checksum = ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7) | (checksum >> 1); + } + } + return checksum; +} + +/* + * Build device list for all present ISA PnP devices. + */ + +static int __init isapnp_build_device_list(void) +{ + int csn; + unsigned char header[9], checksum; + struct pci_bus *card, *prev = NULL; + + isapnp_wait(); + isapnp_key(); + for (csn = 1; csn <= 10; csn++) { + isapnp_wake(csn); + isapnp_peek(header, 9); + checksum = isapnp_checksum(header); +#if 0 + printk("vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + header[0], header[1], header[2], header[3], + header[4], header[5], header[6], header[7], header[8]); + printk("checksum = 0x%x\n", checksum); +#endif + if (checksum == 0x00 || checksum != header[8]) /* not valid CSN */ + continue; + if ((card = isapnp_alloc(sizeof(struct pci_bus))) == NULL) + continue; + card->number = csn; + card->vendor = (header[1] << 8) | header[0]; + card->device = (header[3] << 8) | header[2]; + card->serial = (header[7] << 24) | (header[6] << 16) | (header[5] << 8) | header[4]; + isapnp_checksum_value = 0x00; + isapnp_parse_resource_map(card); + if (isapnp_checksum_value != 0x00) + printk("isapnp: checksum for device %i is not valid (0x%x)\n", csn, isapnp_checksum_value); + card->checksum = isapnp_checksum_value; + if (!isapnp_cards) + isapnp_cards = card; + else + prev->next = card; + prev = card; + } + return 0; +} + +/* + * Basic configuration routines. + */ + +int isapnp_present(void) +{ + if (isapnp_devices) + return 1; + return 0; +} + +int isapnp_cfg_begin(int csn, int logdev) +{ + if (csn < 1 || csn > 10 || logdev > 10) + return -EINVAL; + MOD_INC_USE_COUNT; + down(&isapnp_cfg_mutex); + isapnp_wait(); + isapnp_key(); + isapnp_wake(csn); +#if 1 /* to avoid malfunction when the isapnptools package is used */ + isapnp_set_rdp(); + udelay(1000); /* delay 1000us */ + write_address(0x01); + udelay(1000); /* delay 1000us */ +#endif + if (logdev >= 0) + isapnp_device(logdev); + return 0; +} + +int isapnp_cfg_end(void) +{ + isapnp_wait(); + up(&isapnp_cfg_mutex); + MOD_DEC_USE_COUNT; + return 0; +} + +/* + * Resource manager. + */ + +static struct isapnp_port *isapnp_find_port(struct pci_dev *dev, int index) +{ + struct isapnp_resources *res; + struct isapnp_port *port; + + if (!dev || index < 0 || index > 7) + return NULL; + for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) { + for (port = res->port; port; port = port->next) { + if (!index) + return port; + index--; + } + } + return NULL; +} + +struct isapnp_irq *isapnp_find_irq(struct pci_dev *dev, int index) +{ + struct isapnp_resources *res, *resa; + struct isapnp_irq *irq; + int index1, index2, index3; + + if (!dev || index < 0 || index > 7) + return NULL; + for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) { + index3 = 0; + for (resa = res; resa; resa = resa->alt) { + index1 = index; + index2 = 0; + for (irq = resa->irq; irq; irq = irq->next) { + if (!index1) + return irq; + index1--; + index2++; + } + if (index3 < index2) + index3 = index2; + } + index -= index3; + } + return NULL; +} + +struct isapnp_dma *isapnp_find_dma(struct pci_dev *dev, int index) +{ + struct isapnp_resources *res; + struct isapnp_dma *dma; + + if (!dev || index < 0 || index > 7) + return NULL; + for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) { + for (dma = res->dma; dma; dma = dma->next) { + if (!index) + return dma; + index--; + } + } + return NULL; +} + +struct isapnp_mem *isapnp_find_mem(struct pci_dev *dev, int index) +{ + struct isapnp_resources *res; + struct isapnp_mem *mem; + + if (!dev || index < 0 || index > 7) + return NULL; + for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) { + for (mem = res->mem; mem; mem = mem->next) { + if (!index) + return mem; + index--; + } + } + return NULL; +} + +struct isapnp_mem32 *isapnp_find_mem32(struct pci_dev *dev, int index) +{ + struct isapnp_resources *res; + struct isapnp_mem32 *mem32; + + if (!dev || index < 0 || index > 7) + return NULL; + for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) { + for (mem32 = res->mem32; mem32; mem32 = mem32->next) { + if (!index) + return mem32; + index--; + } + } + return NULL; +} + +/* + * Device manager. + */ + +struct pci_bus *isapnp_find_card(unsigned short vendor, + unsigned short device, + struct pci_bus *from) +{ + struct pci_bus *card; + + if (from == NULL) { + from = isapnp_cards; + } else { + from = from->next; + } + for (card = from; card; card = card->next) { + if (card->vendor == vendor && card->device == device) + return card; + } + return NULL; +} + +struct pci_dev *isapnp_find_dev(struct pci_bus *card, + unsigned short vendor, + unsigned short function, + struct pci_dev *from) +{ + struct pci_dev *dev; + int idx; + + if (card == NULL) { /* look for a logical device from all cards */ + if (from == NULL) { + from = isapnp_devices; + } else { + from = from->next; + } + for (dev = from; dev; dev = dev->next) { + if (dev->vendor == vendor && dev->device == function) + return dev; + for (idx = 0; idx < DEVICE_COUNT_COMPATIBLE; idx++) + if (dev->vendor_compatible[idx] == vendor && + dev->device_compatible[idx] == function) + return dev; + } + } else { + if (from == NULL) { + from = card->devices; + } else { + from = from->next; + } + if (from->bus != card) /* something is wrong */ + return NULL; + for (dev = from; dev; dev = dev->sibling) { + if (dev->vendor == vendor && dev->device == function) + return dev; + for (idx = 0; idx < DEVICE_COUNT_COMPATIBLE; idx++) + if (dev->vendor_compatible[idx] == vendor && + dev->device_compatible[idx] == function) + return dev; + } + } + return NULL; +} + +static int isapnp_config_prepare(struct pci_dev *dev) +{ + struct isapnp_resources *res, *resa; + struct isapnp_port *port; + struct isapnp_irq *irq; + struct isapnp_dma *dma; + struct isapnp_mem *mem; + int port_count, port_count1; + int irq_count, irq_count1; + int dma_count, dma_count1; + int mem_count, mem_count1; + int idx; + + if (dev == NULL) + return -EINVAL; + if (dev->active || dev->ro) + return -EBUSY; + dev->irq = dev->irq2 = DEVICE_IRQ_NOTSET; + dev->irq_flags = dev->irq2_flags = 0; + for (idx = 0; idx < DEVICE_COUNT_DMA; idx++) { + dev->dma[idx] = DEVICE_DMA_NOTSET; + dev->dma_type[idx] = DEVICE_DMA_TYPE_8AND16BIT; + dev->dma_flags[idx] = 0; + dev->dma_speed[idx] = DEVICE_DMA_SPEED_COMPATIBLE; + } + for (idx = 0; idx < DEVICE_COUNT_RESOURCE; idx++) { + dev->resource[idx].name = NULL; + dev->resource[idx].start = DEVICE_IO_NOTSET; + dev->resource[idx].end = 0; + dev->resource[idx].fixed = 0; + dev->resource[idx].bits = 12; + dev->resource[idx].hw_flags = 0; + dev->resource[idx].type = DEVICE_IO_TYPE_8AND16BIT; + } + port_count = irq_count = dma_count = mem_count = 0; + for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) { + port_count1 = irq_count1 = dma_count1 = mem_count1 = 0; + for (resa = res; resa; resa = resa->alt) { + for (port = resa->port, idx = 0; port; port = port->next, idx++) { + if (dev->resource[port_count + idx].start == DEVICE_IO_NOTSET) { + dev->resource[port_count + idx].start = DEVICE_IO_AUTO; + dev->resource[port_count + idx].end = port->size; + dev->resource[port_count + idx].bits = port->flags & ISAPNP_PORT_FLAG_16BITADDR ? 16 : 12; + dev->resource[port_count + idx].fixed = port->flags & ISAPNP_PORT_FLAG_FIXED ? 1 : 0; + } + } + if (port_count1 < idx) + port_count1 = idx; + for (irq = resa->irq, idx = 0; irq; irq = irq->next, idx++) { + if (irq_count + idx == 0) { + if (dev->irq == DEVICE_IRQ_NOTSET) { + dev->irq = DEVICE_IRQ_AUTO; + dev->irq_flags = irq->flags; + } + } else if (irq_count + idx == 1) { + if (dev->irq2 == DEVICE_IRQ_NOTSET) { + dev->irq2 = DEVICE_IRQ_AUTO; + dev->irq2_flags = irq->flags; + } + } + + } + if (irq_count1 < idx) + irq_count1 = idx; + for (dma = resa->dma, idx = 0; dma; dma = dma->next, idx++) + if (dev->dma[idx] == DEVICE_DMA_NOTSET) { + dev->dma[idx] = DEVICE_DMA_AUTO; + dev->dma_type[idx] = dma->type; + dev->dma_flags[idx] = dma->flags; + dev->dma_speed[idx] = dma->speed; + } + if (dma_count1 < idx) + dma_count1 = idx; + for (mem = resa->mem, idx = 0; mem; mem = mem->next, idx++) + if (dev->resource[mem_count + idx + 8].start == DEVICE_IO_AUTO) { + dev->resource[mem_count + idx].start = DEVICE_IO_AUTO; + dev->resource[mem_count + idx].end = mem->size; + dev->resource[mem_count + idx].bits = 24; + dev->resource[mem_count + idx].fixed = 0; + dev->resource[mem_count + idx].hw_flags = mem->flags; + dev->resource[mem_count + idx].type = mem->type; + } + if (mem_count1 < idx) + mem_count1 = idx; + } + port_count += port_count1; + irq_count += irq_count1; + dma_count += dma_count1; + mem_count += mem_count1; + } + return 0; +} + +struct isapnp_cfgtmp { + struct isapnp_port *port[8]; + struct isapnp_irq *irq[2]; + struct isapnp_dma *dma[2]; + struct isapnp_mem *mem[4]; + struct pci_dev *request; + struct pci_dev result; +}; + +static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg, + struct isapnp_resources *from, + struct isapnp_resources *to) +{ + int tmp, tmp1; + struct isapnp_port *port; + struct isapnp_irq *irq; + struct isapnp_dma *dma; + struct isapnp_mem *mem; + + if (!cfg) + return -EINVAL; + /* process port settings */ + for (tmp = 0; tmp < 8; tmp++) { + if (cfg->request->resource[tmp].start != DEVICE_IO_AUTO) + continue; /* don't touch */ + port = cfg->port[tmp]; + if (!port) { + cfg->port[tmp] = port = isapnp_find_port(cfg->request, tmp); + if (!port) + return -EINVAL; + } + if (from && port->res == from) { + while (port->res != to) { + if (!port->res->alt) + return -EINVAL; + port = port->res->alt->port; + for (tmp1 = tmp; tmp1 > 0 && port; tmp1--) + port = port->next; + cfg->port[tmp] = port; + cfg->result.resource[tmp].start = DEVICE_IO_AUTO; + if (!port) + return -ENOENT; + } + } + } + /* process irq settings */ + for (tmp = 0; tmp < 2; tmp++) { + if (tmp == 0) { + if (cfg->request->irq != DEVICE_IRQ_AUTO) + continue; /* don't touch */ + } else { + if (cfg->request->irq2 != DEVICE_IRQ_AUTO) + continue; /* don't touch */ + } + irq = cfg->irq[tmp]; + if (!irq) { + cfg->irq[tmp] = irq = isapnp_find_irq(cfg->request, tmp); + if (!irq) + return -EINVAL; + } + if (from && irq->res == from) { + while (irq->res != to) { + if (!irq->res->alt) + return -EINVAL; + irq = irq->res->alt->irq; + for (tmp1 = tmp; tmp1 > 0 && irq; tmp1--) + irq = irq->next; + cfg->irq[tmp] = irq; + if (tmp == 0) { + cfg->result.irq = DEVICE_IRQ_AUTO; + } else { + cfg->result.irq2 = DEVICE_IRQ_AUTO; + } + if (!irq) + return -ENOENT; + } + } + } + /* process dma settings */ + for (tmp = 0; tmp < 2; tmp++) { + if (cfg->request->dma[tmp] != DEVICE_DMA_AUTO) + continue; /* don't touch */ + dma = cfg->dma[tmp]; + if (!dma) { + cfg->dma[tmp] = dma = isapnp_find_dma(cfg->request, tmp); + if (!dma) + return -EINVAL; + } + if (from && dma->res == from) { + while (dma->res != to) { + if (!dma->res->alt) + return -EINVAL; + dma = dma->res->alt->dma; + for (tmp1 = tmp; tmp1 > 0 && dma; tmp1--) + dma = dma->next; + cfg->dma[tmp] = dma; + cfg->result.dma[tmp] = DEVICE_DMA_AUTO; + if (!dma) + return -ENOENT; + } + } + } + /* process memory settings */ + for (tmp = 0; tmp < 4; tmp++) { + if (cfg->request->resource[tmp + 8].start != DEVICE_IO_AUTO) + continue; /* don't touch */ + mem = cfg->mem[tmp]; + if (!mem) { + cfg->mem[tmp] = mem = isapnp_find_mem(cfg->request, tmp); + if (!mem) + return -EINVAL; + } + if (from && mem->res == from) { + while (mem->res != to) { + if (!mem->res->alt) + return -EINVAL; + mem = mem->res->alt->mem; + for (tmp1 = tmp; tmp1 > 0 && mem; tmp1--) + mem = mem->next; + cfg->mem[tmp] = mem; + cfg->result.resource[tmp + 8].start = DEVICE_IO_AUTO; + if (!mem) + return -ENOENT; + } + } + } + return 0; +} + +static int isapnp_check_port(struct isapnp_cfgtmp *cfg, int port, int size, int idx) +{ + int i, tmp, rport, rsize; + struct isapnp_port *xport; + struct pci_dev *dev; + + if (check_region(port, size)) + return 1; + for (i = 0; i < 8; i++) { + rport = isapnp_reserve_io[i << 1]; + rsize = isapnp_reserve_io[(i << 1) + 1]; + if (port >= rport && port < rport + rsize) + return 1; + if (port + size > rport && port + size < (rport + rsize) - 1) + return 1; + } + for (dev = isapnp_devices; dev; dev = dev->next) { + if (dev->active) { + for (tmp = 0; tmp < 8; tmp++) { + if (dev->resource[tmp].start != DEVICE_IO_NOTSET) { + rport = dev->resource[tmp].start; + rsize = (dev->resource[tmp].end - rport) + 1; + if (port >= rport && port < rport + rsize) + return 1; + if (port + size > rport && port + size < (rport + rsize) - 1) + return 1; + } + } + } + } + for (i = 0; i < 8; i++) { + if (i == idx) + continue; + tmp = cfg->request->resource[i].start; + if (tmp == DEVICE_IO_NOTSET) + continue; + if (tmp == DEVICE_IO_AUTO) { /* auto */ + xport = cfg->port[i]; + if (!xport) + return 1; + tmp = cfg->result.resource[i].start; + if (tmp == DEVICE_IO_AUTO) + continue; + if (tmp + xport->size >= port && tmp <= port + xport->size) + return 1; + continue; + } + if (port == tmp) + return 1; + xport = isapnp_find_port(cfg->request, i); + if (!xport) + return 1; + if (tmp + xport->size >= port && tmp <= port + xport->size) + return 1; + } + return 0; +} + +static int isapnp_valid_port(struct isapnp_cfgtmp *cfg, int idx) +{ + int err; + unsigned long *value; + struct isapnp_port *port; + + if (!cfg || idx < 0 || idx > 7) + return -EINVAL; + if (cfg->result.resource[idx].start != DEVICE_IO_AUTO) /* don't touch */ + return 0; + __again: + port = cfg->port[idx]; + if (!port) + return -EINVAL; + value = &cfg->result.resource[idx].start; + if (*value == DEVICE_IO_AUTO) { + if (!isapnp_check_port(cfg, *value = port->min, port->size, idx)) + return 0; + } + do { + *value += port->align; + if (*value > port->max || !port->align) { + if (port->res && port->res->alt) { + if ((err = isapnp_alternative_switch(cfg, port->res, port->res->alt))<0) + return err; + goto __again; + } + return -ENOENT; + } + } while (isapnp_check_port(cfg, *value, port->size, idx)); + return 0; +} + +static void isapnp_test_handler(int irq, void *dev_id, struct pt_regs *regs) +{ +} + +static int isapnp_check_interrupt(struct isapnp_cfgtmp *cfg, int irq, int idx) +{ + int i; + struct pci_dev *dev; + + if (irq < 0 || irq > 15) + return 1; + for (i = 0; i < 16; i++) { + if (isapnp_reserve_irq[i] == irq) + return 1; + } + for (dev = isapnp_devices; dev; dev = dev->next) { + if (dev->active) { + if (dev->irq == irq || dev->irq2 == irq) + return 1; + } + } + if (request_irq(irq, isapnp_test_handler, SA_INTERRUPT, "isapnp", NULL)) + return 1; + free_irq(irq, NULL); + if (idx != 0) { + if (cfg->result.irq != DEVICE_IRQ_AUTO && + cfg->result.irq != DEVICE_IRQ_NOTSET) + if (cfg->result.irq == irq) + return 1; + } + if (idx != 1) { + if (cfg->result.irq2 != DEVICE_IRQ_AUTO && + cfg->result.irq2 != DEVICE_IRQ_NOTSET) + if (cfg->result.irq2 == irq) + return 1; + } + return 0; +} + +static int isapnp_valid_irq(struct isapnp_cfgtmp *cfg, int idx) +{ + /* IRQ priority: table is good for i386 */ + static unsigned short xtab[16] = { + 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2 + }; + int err, i; + unsigned int *value; + struct isapnp_irq *irq; + + if (!cfg || idx < 0 || idx > 1) + return -EINVAL; + if (idx == 0) { + if (cfg->result.irq != DEVICE_IRQ_AUTO) /* don't touch */ + return 0; + } else { + if (cfg->result.irq2 != DEVICE_IRQ_AUTO) /* don't touch */ + return 0; + } + __again: + irq = cfg->irq[idx]; + if (!irq) + return -EINVAL; + if (idx == 0) { + value = &cfg->result.irq; + } else { + value = &cfg->result.irq2; + } + if (*value == DEVICE_IRQ_AUTO) { + for (i = 0; i < 16 && !(irq->map & (1<= 16) + return -ENOENT; + if (!isapnp_check_interrupt(cfg, *value = xtab[i], idx)) + return 0; + } + do { + for (i = 0; i < 16 && xtab[i] != *value; i++); + for (i++; i < 16 && !(irq->map & (1<= 16) { + if (irq->res && irq->res->alt) { + if ((err = isapnp_alternative_switch(cfg, irq->res, irq->res->alt))<0) + return err; + goto __again; + } + return -ENOENT; + } else { + *value = xtab[i]; + } + } while (isapnp_check_interrupt(cfg, *value, idx)); + return 0; +} + +static int isapnp_check_dma(struct isapnp_cfgtmp *cfg, int dma, int idx) +{ + int i; + struct pci_dev *dev; + + if (dma < 0 || dma == 4 || dma > 7) + return 1; + for (i = 0; i < 8; i++) { + if (isapnp_reserve_dma[i] == dma) + return 1; + } + for (dev = isapnp_devices; dev; dev = dev->next) { + if (dev->active) { + if (dev->dma[0] == dma || dev->dma[1] == dma) + return 1; + } + } + if (request_dma(dma, "isapnp")) + return 1; + free_dma(dma); + for (i = 0; i < 2; i++) { + if (i == idx) + continue; + if (cfg->result.dma[i] == DEVICE_DMA_NOTSET || + cfg->result.dma[i] == DEVICE_DMA_AUTO) + continue; + if (cfg->result.dma[i] == dma) + return 1; + } + return 0; +} + +static int isapnp_valid_dma(struct isapnp_cfgtmp *cfg, int idx) +{ + int err, i; + unsigned char *value; + struct isapnp_dma *dma; + + if (!cfg || idx < 0 || idx > 1) + return -EINVAL; + if (cfg->result.dma[idx] != DEVICE_DMA_AUTO) /* don't touch */ + return 0; + __again: + dma = cfg->dma[idx]; + if (!dma) + return -EINVAL; + value = &cfg->result.dma[idx]; + if (*value == DEVICE_DMA_AUTO) { + for (i = 0; i < 8 && !(dma->map & (1<= 8) + return -ENOENT; + if (!isapnp_check_dma(cfg, *value = i, idx)) + return 0; + } + do { + for (i = *value + 1; i < 8 && !(dma->map & (1<= 8) { + if (dma->res && dma->res->alt) { + if ((err = isapnp_alternative_switch(cfg, dma->res, dma->res->alt))<0) + return err; + goto __again; + } + return -ENOENT; + } else { + *value = i; + } + } while (isapnp_check_dma(cfg, *value, idx)); + return 0; +} + +static int isapnp_check_mem(struct isapnp_cfgtmp *cfg, unsigned int addr, unsigned int size, int idx) +{ + int i, tmp; + unsigned int raddr, rsize; + struct pci_dev *dev; + struct isapnp_mem *xmem; + + for (i = 0; i < 8; i++) { + raddr = (unsigned int)isapnp_reserve_mem[i << 1]; + rsize = (unsigned int)isapnp_reserve_mem[(i << 1) + 1]; + if (addr >= raddr && addr < raddr + rsize) + return 1; + if (addr + size > raddr && addr + size < (raddr + rsize) - 1) + return 1; + if (__check_region(&iomem_resource, addr, size)) + return 1; + } + for (dev = isapnp_devices; dev; dev = dev->next) { + if (dev->active) { + for (tmp = 0; tmp < 4; tmp++) { + if (dev->resource[tmp].start != DEVICE_IO_NOTSET) { + raddr = dev->resource[tmp + 8].start; + rsize = (dev->resource[tmp + 8].end - raddr) + 1; + if (addr >= raddr && addr < raddr + rsize) + return 1; + if (addr + size > raddr && addr + size < (raddr + rsize) - 1) + return 1; + } + } + } + } + for (i = 0; i < 4; i++) { + if (i == idx) + continue; + tmp = cfg->request->resource[i + 8].start; + if (tmp == DEVICE_IO_NOTSET) + continue; + if (tmp == DEVICE_IO_AUTO) { /* auto */ + xmem = cfg->mem[i]; + if (!xmem) + return 1; + tmp = cfg->result.resource[i + 8].start; + if (tmp == DEVICE_IO_AUTO) + continue; + if (tmp + xmem->size >= addr && tmp <= addr + xmem->size) + return 1; + continue; + } + if (addr == tmp) + return 1; + xmem = isapnp_find_mem(cfg->request, i); + if (!xmem) + return 1; + if (tmp + xmem->size >= addr && tmp <= addr + xmem->size) + return 1; + } + return 0; +} + +static int isapnp_valid_mem(struct isapnp_cfgtmp *cfg, int idx) +{ + int err; + unsigned long *value; + struct isapnp_mem *mem; + + if (!cfg || idx < 0 || idx > 3) + return -EINVAL; + if (cfg->result.resource[idx + 8].start != DEVICE_IO_AUTO) /* don't touch */ + return 0; + __again: + mem = cfg->mem[idx]; + if (!mem) + return -EINVAL; + value = &cfg->result.resource[idx].start; + if (*value == DEVICE_IO_AUTO) { + *value = mem->min; + if (!isapnp_check_mem(cfg, *value, mem->size, idx)) + return 0; + } + do { + *value += mem->align; + if (*value >= 8 || !mem->align) { + if (mem->res && mem->res->alt) { + if ((err = isapnp_alternative_switch(cfg, mem->res, mem->res->alt))<0) + return err; + goto __again; + } + return -ENOENT; + } + } while (isapnp_check_mem(cfg, *value, mem->size, idx)); + return 0; +} + +static int isapnp_check_valid(struct isapnp_cfgtmp *cfg) +{ + int tmp; + + for (tmp = 0; tmp < 8; tmp++) + if (cfg->result.resource[tmp].start == DEVICE_IO_AUTO) + return -EAGAIN; + if (cfg->result.irq == DEVICE_IRQ_AUTO) + return -EAGAIN; + if (cfg->result.irq2 == DEVICE_IRQ_AUTO) + return -EAGAIN; + for (tmp = 0; tmp < 2; tmp++) + if (cfg->result.dma[tmp] == DEVICE_DMA_AUTO) + return -EAGAIN; + for (tmp = 0; tmp < 4; tmp++) + if (cfg->result.resource[tmp + 1].start == DEVICE_IO_AUTO) + return -EAGAIN; + return 0; +} + +static int isapnp_config_activate(struct pci_dev *dev) +{ + struct isapnp_cfgtmp cfg; + int tmp, fauto, err; + + if (!dev) + return -EINVAL; + if (dev->active) + return -EBUSY; + memset(&cfg, 0, sizeof(cfg)); + cfg.request = dev; + memcpy(&cfg.result, dev, sizeof(struct pci_dev)); + /* check if all values are set, otherwise try auto-configuration */ + for (tmp = fauto = 0; !fauto && tmp < 8; tmp++) { + if (dev->resource[tmp].start == DEVICE_IO_AUTO) + fauto++; + } + if (dev->irq == DEVICE_IRQ_AUTO) + fauto++; + if (dev->irq2 == DEVICE_IRQ_AUTO) + fauto++; + for (tmp = 0; !fauto && tmp < 2; tmp++) { + if (dev->dma[tmp] == DEVICE_DMA_AUTO) + fauto++; + } + for (tmp = 0; !fauto && tmp < 4; tmp++) { + if (dev->resource[tmp + 8].start == DEVICE_IO_AUTO) + fauto++; + } + if (!fauto) + goto __skip_auto; + /* set variables to initial values */ + if ((err = isapnp_alternative_switch(&cfg, NULL, NULL))<0) + return err; + /* find first valid configuration */ + fauto = 0; + do { + for (tmp = 0; tmp < 8 && cfg.result.resource[tmp].start != DEVICE_IO_NOTSET; tmp++) + if ((err = isapnp_valid_port(&cfg, tmp))<0) + return err; + if (cfg.result.irq != DEVICE_IRQ_NOTSET) + if ((err = isapnp_valid_irq(&cfg, 0))<0) + return err; + if (cfg.result.irq2 != DEVICE_IRQ_NOTSET) + if ((err = isapnp_valid_irq(&cfg, 1))<0) + return err; + for (tmp = 0; tmp < 2 && tmp < cfg.result.dma[tmp] != DEVICE_DMA_NOTSET; tmp++) + if ((err = isapnp_valid_dma(&cfg, tmp))<0) + return err; + for (tmp = 0; tmp < 4 && tmp < cfg.result.resource[tmp + 8].start != DEVICE_IO_NOTSET; tmp++) + if ((err = isapnp_valid_mem(&cfg, tmp))<0) + return err; + } while (isapnp_check_valid(&cfg)<0 && fauto++ < 20); + if (fauto >= 20) + return -EAGAIN; + __skip_auto: + /* we have valid configuration, try configure hardware */ + isapnp_cfg_begin(dev->bus->number, dev->devfn); + dev->active = 1; + dev->irq = cfg.result.irq; + dev->irq2 = cfg.result.irq2; + dev->dma[0] = cfg.result.dma[0]; + dev->dma[1] = cfg.result.dma[1]; + for (tmp = 0; tmp < 12; tmp++) { + dev->resource[tmp].start = cfg.result.resource[tmp].start; + if (cfg.result.resource[tmp].start != DEVICE_IO_NOTSET && + cfg.result.resource[tmp].end != DEVICE_IO_AUTO) + dev->resource[tmp].end += cfg.result.resource[tmp].start; + } + for (tmp = 0; tmp < 8 && dev->resource[tmp].start != DEVICE_IO_NOTSET; tmp++) + isapnp_write_word(ISAPNP_CFG_PORT+(tmp<<1), dev->resource[tmp].start); + if (dev->irq != DEVICE_IRQ_NOTSET) { + if (dev->irq == 2) + dev->irq = 9; + isapnp_write_byte(ISAPNP_CFG_IRQ+(0<<1), dev->irq); + } + if (dev->irq2 != DEVICE_IRQ_NOTSET) { + if (dev->irq2 == 2) + dev->irq2 = 9; + isapnp_write_byte(ISAPNP_CFG_IRQ+(1<<1), dev->irq2); + } + for (tmp = 0; tmp < 2 && dev->dma[tmp] != DEVICE_DMA_NOTSET; tmp++) + isapnp_write_byte(ISAPNP_CFG_DMA+tmp, dev->dma[tmp]); + for (tmp = 0; tmp < 4 && dev->resource[tmp].start != DEVICE_IO_NOTSET; tmp++) + isapnp_write_word(ISAPNP_CFG_MEM+(tmp<<2), (dev->resource[tmp + 8].start >> 8) & 0xffff); + isapnp_activate(dev->devfn); + isapnp_cfg_end(); + return 0; +} + +static int isapnp_config_deactivate(struct pci_dev *dev) +{ + if (!dev || !dev->active) + return -EINVAL; + isapnp_cfg_begin(dev->bus->number, dev->devfn); + isapnp_deactivate(dev->devfn); + dev->activate = 0; + isapnp_cfg_end(); + return 0; +} + +/* + * Inititialization. + */ + +#ifdef MODULE + +static void isapnp_free_port(struct isapnp_port *port) +{ + struct isapnp_port *next; + + while (port) { + next = port->next; + kfree(port); + port = next; + } +} + +static void isapnp_free_irq(struct isapnp_irq *irq) +{ + struct isapnp_irq *next; + + while (irq) { + next = irq->next; + kfree(irq); + irq = next; + } +} + +static void isapnp_free_dma(struct isapnp_dma *dma) +{ + struct isapnp_dma *next; + + while (dma) { + next = dma->next; + kfree(dma); + dma = next; + } +} + +static void isapnp_free_mem(struct isapnp_mem *mem) +{ + struct isapnp_mem *next; + + while (mem) { + next = mem->next; + kfree(mem); + mem = next; + } +} + +static void isapnp_free_mem32(struct isapnp_mem32 *mem32) +{ + struct isapnp_mem32 *next; + + while (mem32) { + next = mem32->next; + kfree(mem32); + mem32 = next; + } +} + +static void isapnp_free_resources(struct isapnp_resources *resources, int alt) +{ + struct isapnp_resources *next; + + while (resources) { + next = alt ? resources->alt : resources->next; + isapnp_free_port(resources->port); + isapnp_free_irq(resources->irq); + isapnp_free_dma(resources->dma); + isapnp_free_mem(resources->mem); + isapnp_free_mem32(resources->mem32); + if (!alt && resources->alt) + isapnp_free_resources(resources->alt, 1); + kfree(resources); + resources = next; + } +} + +static void isapnp_free_device(struct pci_dev *dev) +{ + struct pci_dev *next; + + while (dev) { + next = dev->next; + isapnp_free_resources((struct isapnp_resources *)dev->sysdata, 0); + kfree(dev); + dev = next; + } +} + +#endif /* MODULE */ + +static void isapnp_free_all_resources(void) +{ +#ifdef MODULE + struct pci_bus *card, *cardnext; +#endif + +#ifdef ISAPNP_REGION_OK + release_resource(pidxr_res); +#endif + release_resource(pnpwrp_res); + if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff) + release_resource(isapnp_rdp_res); +#ifdef MODULE + for (card = isapnp_cards; card; card = cardnext) { + cardnext = card->next; + isapnp_free_device(card->devices); + kfree(card); + } +#ifdef CONFIG_PROC_FS + isapnp_proc_done(); +#endif +#endif +} + +static int __init isapnp_do_reserve_irq(int irq) +{ + int i; + + if (irq < 0 || irq > 15) + return -EINVAL; + for (i = 0; i < 16; i++) { + if (isapnp_reserve_irq[i] == irq) + return 0; + } + for (i = 0; i < 16; i++) { + if (isapnp_reserve_irq[i] < 0) { + isapnp_reserve_irq[i] = irq; +#ifdef ISAPNP_DEBUG + printk("IRQ %i is reserved now.\n", irq); +#endif + return 0; + } + } + return -ENOMEM; +} + +#ifdef CONFIG_PCI + +static void __init isapnp_pci_init(void) +{ + int devfn; + struct pci_dev *dev; + + for (devfn = 0; devfn < 255; devfn++) { + dev = pci_find_slot(0, devfn); + if (dev != NULL) + break; + } + if (dev == NULL) + return; + while (dev) { +#ifdef ISAPNP_DEBUG + printk("PCI: reserved IRQ: %i\n", dev->irq); +#endif + if (dev->irq > 0) + isapnp_do_reserve_irq(dev->irq); + dev = dev->next; + } +} + +#endif /* CONFIG_PCI */ + +EXPORT_SYMBOL(isapnp_present); +EXPORT_SYMBOL(isapnp_cfg_begin); +EXPORT_SYMBOL(isapnp_cfg_end); +EXPORT_SYMBOL(isapnp_read_byte); +EXPORT_SYMBOL(isapnp_read_word); +EXPORT_SYMBOL(isapnp_read_dword); +EXPORT_SYMBOL(isapnp_write_byte); +EXPORT_SYMBOL(isapnp_write_word); +EXPORT_SYMBOL(isapnp_write_dword); +EXPORT_SYMBOL(isapnp_wake); +EXPORT_SYMBOL(isapnp_device); +EXPORT_SYMBOL(isapnp_activate); +EXPORT_SYMBOL(isapnp_deactivate); +EXPORT_SYMBOL(isapnp_find_card); +EXPORT_SYMBOL(isapnp_find_dev); + +int __init isapnp_init(void) +{ + int cards; + struct pci_bus *card; + struct pci_dev *dev; + + if (isapnp_disable) { + isapnp_detected = 0; + printk("isapnp: ISA Plug & Play support disabled\n"); + return 0; + } +#ifdef ISAPNP_REGION_OK + pidxr_res=request_region(_PIDXR, 1, "isapnp index"); + if(!pidxr_res) { + printk("isapnp: Index Register 0x%x already used\n", _PIDXR); + return -EBUSY; + } +#endif + pnpwrp_res=request_region(_PNPWRP, 1, "isapnp write"); + if(!pnpwrp_res) { + printk("isapnp: Write Data Register 0x%x already used\n", _PNPWRP); + return -EBUSY; + } + if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff) { + isapnp_rdp |= 3; + isapnp_rdp_res=request_region(isapnp_rdp, 1, "isapnp read"); + if(!isapnp_rdp_res) { + printk("isapnp: Read Data Register 0x%x already used\n", isapnp_rdp); + return -EBUSY; + } + isapnp_set_rdp(); + } + isapnp_detected = 1; + if (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff) { + cards = isapnp_isolate(); + if (cards < 0 || + (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff)) { + isapnp_free_all_resources(); + isapnp_detected = 0; + printk("isapnp: No Plug & Play device found\n"); + return 0; + } + isapnp_rdp_res=request_region(isapnp_rdp, 1, "isapnp read"); + } + isapnp_build_device_list(); + cards = 0; + for (card = isapnp_cards; card; card = card->next) + cards++; + if (isapnp_verbose) { + for (card = isapnp_cards; card; card = card->next) { + printk( "isapnp: Card '%s'\n", card->name[0]?card->name:"Unknown"); + if (isapnp_verbose < 2) + continue; + for (dev = card->devices; dev; dev = dev->next) + printk("isapnp: Device '%s'\n", dev->name[0]?card->name:"Unknown"); + } + } + if (cards) { + printk("isapnp: %i Plug & Play card%s detected total\n", cards, cards>1?"s":""); + } else { + printk("isapnp: No Plug & Play card found\n"); + } +#ifdef CONFIG_PCI + if (!isapnp_skip_pci_scan) + isapnp_pci_init(); +#endif +#ifdef CONFIG_PROC_FS + isapnp_proc_init(); +#endif + return 0; +} + +#ifdef MODULE + +int init_module(void) +{ + return isapnp_init(); +} + +void cleanup_module(void) +{ + if (isapnp_detected) + isapnp_free_all_resources(); +} + +#endif diff -u --recursive --new-file v2.3.13/linux/drivers/pnp/isapnp_proc.c linux/drivers/pnp/isapnp_proc.c --- v2.3.13/linux/drivers/pnp/isapnp_proc.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/pnp/isapnp_proc.c Tue Aug 17 17:19:58 1999 @@ -0,0 +1,945 @@ +/* + * ISA Plug & Play support + * Copyright (c) by Jaroslav Kysela + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +static void *isapnp_alloc(long size); +struct pci_bus *isapnp_cards; +struct pci_dev *isapnp_devices; + +struct isapnp_info_buffer { + char *buffer; /* pointer to begin of buffer */ + char *curr; /* current position in buffer */ + unsigned long size; /* current size */ + unsigned long len; /* total length of buffer */ + int stop; /* stop flag */ + int error; /* error code */ +}; + +typedef struct isapnp_info_buffer isapnp_info_buffer_t; + +static struct proc_dir_entry *isapnp_proc_entry = NULL; + +static void isapnp_info_read(isapnp_info_buffer_t *buffer); +static void isapnp_info_write(isapnp_info_buffer_t *buffer); + +int isapnp_printf(isapnp_info_buffer_t * buffer, char *fmt,...) +{ + va_list args; + int res; + char sbuffer[512]; + + if (buffer->stop || buffer->error) + return 0; + va_start(args, fmt); + res = vsprintf(sbuffer, fmt, args); + va_end(args); + if (buffer->size + res >= buffer->len) { + buffer->stop = 1; + return 0; + } + strcpy(buffer->curr, sbuffer); + buffer->curr += res; + buffer->size += res; + return res; +} + +static loff_t isapnp_info_entry_lseek(struct file *file, loff_t offset, int orig) +{ + switch (orig) { + case 0: /* SEEK_SET */ + file->f_pos = offset; + return file->f_pos; + case 1: /* SEEK_CUR */ + file->f_pos += offset; + return file->f_pos; + case 2: /* SEEK_END */ + default: + return -EINVAL; + } + return -ENXIO; +} + +static ssize_t isapnp_info_entry_read(struct file *file, char *buffer, + size_t count, loff_t * offset) +{ + isapnp_info_buffer_t *buf; + long size = 0, size1; + int mode; + + mode = file->f_flags & O_ACCMODE; + if (mode != O_RDONLY) + return -EINVAL; + buf = (isapnp_info_buffer_t *) file->private_data; + if (!buf) + return -EIO; + if (file->f_pos >= buf->size) + return 0; + size = buf->size < count ? buf->size : count; + size1 = buf->size - file->f_pos; + if (size1 < size) + size = size1; + if (copy_to_user(buffer, buf->buffer + file->f_pos, size)) + return -EFAULT; + file->f_pos += size; + return size; +} + +static ssize_t isapnp_info_entry_write(struct file *file, const char *buffer, + size_t count, loff_t * offset) +{ + isapnp_info_buffer_t *buf; + long size = 0, size1; + int mode; + + mode = file->f_flags & O_ACCMODE; + if (mode != O_WRONLY) + return -EINVAL; + buf = (isapnp_info_buffer_t *) file->private_data; + if (!buf) + return -EIO; + if (file->f_pos < 0) + return -EINVAL; + if (file->f_pos >= buf->len) + return -ENOMEM; + size = buf->len < count ? buf->len : count; + size1 = buf->len - file->f_pos; + if (size1 < size) + size = size1; + if (copy_from_user(buf->buffer + file->f_pos, buffer, size)) + return -EFAULT; + if (buf->size < file->f_pos + size) + buf->size = file->f_pos + size; + file->f_pos += size; + return size; +} + +static int isapnp_info_entry_open(struct inode *inode, struct file *file) +{ + isapnp_info_buffer_t *buffer; + int mode; + + mode = file->f_flags & O_ACCMODE; + if (mode != O_RDONLY && mode != O_WRONLY) + return -EINVAL; + buffer = (isapnp_info_buffer_t *) + isapnp_alloc(sizeof(isapnp_info_buffer_t)); + if (!buffer) + return -ENOMEM; + buffer->len = 4 * PAGE_SIZE; + buffer->buffer = vmalloc(buffer->len); + if (!buffer->buffer) { + kfree(buffer); + return -ENOMEM; + } + buffer->curr = buffer->buffer; + file->private_data = buffer; + MOD_INC_USE_COUNT; + if (mode == O_RDONLY) + isapnp_info_read(buffer); + return 0; +} + +static int isapnp_info_entry_release(struct inode *inode, struct file *file) +{ + isapnp_info_buffer_t *buffer; + int mode; + + if ((buffer = (isapnp_info_buffer_t *) file->private_data) == NULL) + return -EINVAL; + mode = file->f_flags & O_ACCMODE; + if (mode == O_WRONLY) + isapnp_info_write(buffer); + vfree(buffer->buffer); + kfree(buffer); + MOD_DEC_USE_COUNT; + return 0; +} + +static unsigned int isapnp_info_entry_poll(struct file *file, poll_table * wait) +{ + if (!file->private_data) + return 0; + return POLLIN | POLLRDNORM; +} + +static int isapnp_info_entry_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + return -EINVAL; +} + +static int isapnp_info_entry_mmap(struct file *file, struct vm_area_struct *vma) +{ + return -ENXIO; +} + +static struct file_operations isapnp_info_entry_operations = +{ + isapnp_info_entry_lseek, /* lseek */ + isapnp_info_entry_read, /* read */ + isapnp_info_entry_write, /* write */ + NULL, /* readdir */ + isapnp_info_entry_poll, /* poll */ + isapnp_info_entry_ioctl, /* ioctl - default */ + isapnp_info_entry_mmap, /* mmap */ + isapnp_info_entry_open, /* open */ + NULL, /* flush */ + isapnp_info_entry_release, /* release */ + NULL, /* can't fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL, /* lock */ +}; + +static struct inode_operations isapnp_info_entry_inode_operations = +{ + &isapnp_info_entry_operations, /* default sound info directory file-ops */ + NULL, /* create */ + NULL, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + NULL, /* readlink */ + NULL, /* follow_link */ + NULL, /* readpage */ + NULL, /* writepage */ + NULL, /* bmap */ + NULL, /* truncate */ + NULL /* permission */ +}; + +__initfunc(static int isapnp_proc_init(void)) +{ + struct proc_dir_entry *p; + + isapnp_proc_entry = NULL; + p = create_proc_entry("isapnp", S_IFREG | S_IRUGO | S_IWUSR, &proc_root); + if (!p) + return -ENOMEM; + p->ops = &isapnp_info_entry_inode_operations; + isapnp_proc_entry = p; + return 0; +} + +#ifdef MODULE +static int isapnp_proc_done(void) +{ + if (isapnp_proc_entry) + proc_unregister(&proc_root, isapnp_proc_entry->low_ino); + return 0; +} +#endif /* MODULE */ + +/* + * + */ + +static void isapnp_print_devid(isapnp_info_buffer_t *buffer, unsigned short vendor, unsigned short device) +{ + char tmp[8]; + + sprintf(tmp, "%c%c%c%x%x%x%x", + 'A' + ((vendor >> 2) & 0x3f) - 1, + 'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1, + 'A' + ((vendor >> 8) & 0x1f) - 1, + (device >> 4) & 0x0f, + device & 0x0f, + (device >> 12) & 0x0f, + (device >> 8) & 0x0f); + isapnp_printf(buffer, tmp); +} + +static void isapnp_print_compatible(isapnp_info_buffer_t *buffer, struct pci_dev *dev) +{ + int idx; + + for (idx = 0; idx < DEVICE_COUNT_COMPATIBLE; idx++) { + if (dev->vendor_compatible[idx] == 0) + continue; + isapnp_printf(buffer, " Compatible device "); + isapnp_print_devid(buffer, + dev->vendor_compatible[idx], + dev->device_compatible[idx]); + isapnp_printf(buffer, "\n"); + } +} + +static void isapnp_print_port(isapnp_info_buffer_t *buffer, char *space, struct isapnp_port *port) +{ + isapnp_printf(buffer, "%sPort 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n", + space, port->min, port->max, port->align ? (port->align-1) : 0, port->size, + port->flags & ISAPNP_PORT_FLAG_16BITADDR ? 16 : 10); +} + +static void isapnp_print_irq(isapnp_info_buffer_t *buffer, char *space, struct isapnp_irq *irq) +{ + int first = 1, i; + + isapnp_printf(buffer, "%sIRQ ", space); + for (i = 0; i < 16; i++) + if (irq->map & (1<map) + isapnp_printf(buffer, ""); + if (irq->flags & DEVICE_IRQ_FLAG_HIGHEDGE) + isapnp_printf(buffer, " High-Edge"); + if (irq->flags & DEVICE_IRQ_FLAG_LOWEDGE) + isapnp_printf(buffer, " Low-Edge"); + if (irq->flags & DEVICE_IRQ_FLAG_HIGHLEVEL) + isapnp_printf(buffer, " High-Level"); + if (irq->flags & DEVICE_IRQ_FLAG_LOWLEVEL) + isapnp_printf(buffer, " Low-Level"); + isapnp_printf(buffer, "\n"); +} + +static void isapnp_print_dma(isapnp_info_buffer_t *buffer, char *space, struct isapnp_dma *dma) +{ + int first = 1, i; + char *s; + + isapnp_printf(buffer, "%sDMA ", space); + for (i = 0; i < 8; i++) + if (dma->map & (1<map) + isapnp_printf(buffer, ""); + switch (dma->type) { + case DEVICE_DMA_TYPE_8BIT: + s = "8-bit"; + break; + case DEVICE_DMA_TYPE_8AND16BIT: + s = "8-bit&16-bit"; + break; + default: + s = "16-bit"; + } + isapnp_printf(buffer, " %s", s); + if (dma->flags & DEVICE_DMA_FLAG_MASTER) + isapnp_printf(buffer, " master"); + if (dma->flags & DEVICE_DMA_FLAG_BYTE) + isapnp_printf(buffer, " byte-count"); + if (dma->flags & DEVICE_DMA_FLAG_WORD) + isapnp_printf(buffer, " word-count"); + switch (dma->speed) { + case DEVICE_DMA_SPEED_TYPEA: + s = "type-A"; + break; + case DEVICE_DMA_SPEED_TYPEB: + s = "type-B"; + break; + case DEVICE_DMA_SPEED_TYPEF: + s = "type-F"; + break; + default: + s = "compatible"; + break; + } + isapnp_printf(buffer, " %s\n", s); +} + +static void isapnp_print_mem(isapnp_info_buffer_t *buffer, char *space, struct isapnp_mem *mem) +{ + char *s; + + isapnp_printf(buffer, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x", + space, mem->min, mem->max, mem->align, mem->size); + if (mem->flags & DEVICE_IO_FLAG_WRITEABLE) + isapnp_printf(buffer, ", writeable"); + if (mem->flags & DEVICE_IO_FLAG_CACHEABLE) + isapnp_printf(buffer, ", cacheable"); + if (mem->flags & DEVICE_IO_FLAG_RANGELENGTH) + isapnp_printf(buffer, ", range-length"); + if (mem->flags & DEVICE_IO_FLAG_SHADOWABLE) + isapnp_printf(buffer, ", shadowable"); + if (mem->flags & DEVICE_IO_FLAG_EXPANSIONROM) + isapnp_printf(buffer, ", expansion ROM"); + switch (mem->type) { + case DEVICE_IO_TYPE_8BIT: + s = "8-bit"; + break; + case DEVICE_IO_TYPE_8AND16BIT: + s = "8-bit&16-bit"; + break; + default: + s = "16-bit"; + } + isapnp_printf(buffer, ", %s\n", s); +} + +static void isapnp_print_mem32(isapnp_info_buffer_t *buffer, char *space, struct isapnp_mem32 *mem32) +{ + int first = 1, i; + + isapnp_printf(buffer, "%s32-bit memory ", space); + for (i = 0; i < 17; i++) { + if (first) { + first = 0; + } else { + isapnp_printf(buffer, ":"); + } + isapnp_printf(buffer, "%02x", mem32->data[i]); + } +} + +static void isapnp_print_resources(isapnp_info_buffer_t *buffer, char *space, struct isapnp_resources *res) +{ + char *s; + struct isapnp_port *port; + struct isapnp_irq *irq; + struct isapnp_dma *dma; + struct isapnp_mem *mem; + struct isapnp_mem32 *mem32; + + switch (res->priority) { + case ISAPNP_RES_PRIORITY_PREFERRED: + s = "preferred"; + break; + case ISAPNP_RES_PRIORITY_ACCEPTABLE: + s = "acceptable"; + break; + case ISAPNP_RES_PRIORITY_FUNCTIONAL: + s = "functional"; + break; + default: + s = "invalid"; + } + isapnp_printf(buffer, "%sPriority %s\n", space, s); + for (port = res->port; port; port = port->next) + isapnp_print_port(buffer, space, port); + for (irq = res->irq; irq; irq = irq->next) + isapnp_print_irq(buffer, space, irq); + for (dma = res->dma; dma; dma = dma->next) + isapnp_print_dma(buffer, space, dma); + for (mem = res->mem; mem; mem = mem->next) + isapnp_print_mem(buffer, space, mem); + for (mem32 = res->mem32; mem32; mem32 = mem32->next) + isapnp_print_mem32(buffer, space, mem32); +} + +static void isapnp_print_configuration(isapnp_info_buffer_t *buffer, struct pci_dev *dev) +{ + int i, tmp, next; + char *space = " "; + + isapnp_cfg_begin(dev->bus->number, dev->devfn); + isapnp_printf(buffer, "%sDevice is %sactive\n", + space, isapnp_read_byte(ISAPNP_CFG_ACTIVATE)?"":"not "); + for (i = next = 0; i < 8; i++) { + tmp = isapnp_read_word(ISAPNP_CFG_PORT + (i << 1)); + if (!tmp) + continue; + if (!next) { + isapnp_printf(buffer, "%sActive port ", space); + next = 1; + } + isapnp_printf(buffer, "%s0x%x", i > 0 ? "," : "", tmp); + } + if (next) + isapnp_printf(buffer, "\n"); + for (i = next = 0; i < 2; i++) { + tmp = isapnp_read_word(ISAPNP_CFG_IRQ + (i << 1)); + if (!(tmp >> 8)) + continue; + if (!next) { + isapnp_printf(buffer, "%sActive IRQ ", space); + next = 1; + } + isapnp_printf(buffer, "%s%i", i > 0 ? "," : "", tmp >> 8); + if (tmp & 0xff) + isapnp_printf(buffer, " [0x%x]", tmp & 0xff); + } + if (next) + isapnp_printf(buffer, "\n"); + for (i = next = 0; i < 2; i++) { + tmp = isapnp_read_byte(ISAPNP_CFG_DMA + i); + if (tmp == 4) + continue; + if (!next) { + isapnp_printf(buffer, "%sActive DMA ", space); + next = 1; + } + isapnp_printf(buffer, "%s%i", i > 0 ? "," : "", tmp); + } + if (next) + isapnp_printf(buffer, "\n"); + for (i = next = 0; i < 4; i++) { + tmp = isapnp_read_dword(ISAPNP_CFG_MEM + (i << 3)); + if (!tmp) + continue; + if (!next) { + isapnp_printf(buffer, "%sActive memory ", space); + next = 1; + } + isapnp_printf(buffer, "%s0x%x", i > 0 ? "," : "", tmp); + } + if (next) + isapnp_printf(buffer, "\n"); + isapnp_cfg_end(); +} + +static void isapnp_print_device(isapnp_info_buffer_t *buffer, struct pci_dev *dev) +{ + int block, block1; + char *space = " "; + struct isapnp_resources *res, *resa; + + if (!dev) + return; + isapnp_printf(buffer, " Logical device %i '", dev->devfn); + isapnp_print_devid(buffer, dev->vendor, dev->device); + isapnp_printf(buffer, ":%s'", dev->name[0]?dev->name:"Unknown"); + isapnp_printf(buffer, "\n"); +#if 0 + isapnp_cfg_begin(dev->bus->number, dev->devfn); + for (block = 0; block < 128; block++) + if ((block % 16) == 15) + isapnp_printf(buffer, "%02x\n", isapnp_read_byte(block)); + else + isapnp_printf(buffer, "%02x:", isapnp_read_byte(block)); + isapnp_cfg_end(); +#endif + if (dev->regs) + isapnp_printf(buffer, "%sSupported registers 0x%x\n", space, dev->regs); + isapnp_print_compatible(buffer, dev); + isapnp_print_configuration(buffer, dev); + for (res = (struct isapnp_resources *)dev->sysdata, block = 0; res; res = res->next, block++) { + isapnp_printf(buffer, "%sResources %i\n", space, block); + isapnp_print_resources(buffer, " ", res); + for (resa = res->alt, block1 = 1; resa; resa = resa->alt, block1++) { + isapnp_printf(buffer, "%s Alternate resources %i:%i\n", space, block, block1); + isapnp_print_resources(buffer, " ", resa); + } + } +} + +/* + * Main read routine + */ + +static void isapnp_info_read(isapnp_info_buffer_t *buffer) +{ + struct pci_bus *card; + struct pci_dev *dev; + + for (card = isapnp_cards; card; card = card->next) { + isapnp_printf(buffer, "Card %i '", card->number); + isapnp_print_devid(buffer, card->vendor, card->device); + isapnp_printf(buffer, ":%s'", card->name[0]?card->name:"Unknown"); + if (card->pnpver) + isapnp_printf(buffer, " PnP version %x.%x", card->pnpver >> 4, card->pnpver & 0x0f); + if (card->productver) + isapnp_printf(buffer, " Product version %x.%x", card->productver >> 4, card->productver & 0x0f); + isapnp_printf(buffer,"\n"); + for (dev = card->devices; dev; dev = dev->sibling) + isapnp_print_device(buffer, dev); + } +} + +/* + * + */ + +static struct pci_bus *isapnp_info_card; +static struct pci_dev *isapnp_info_device; + +static char *isapnp_get_str(char *dest, char *src, int len) +{ + int c; + + while (*src == ' ' || *src == '\t') + src++; + if (*src == '"' || *src == '\'') { + c = *src++; + while (--len > 0 && *src && *src != c) { + *dest++ = *src++; + } + if (*src == c) + src++; + } else { + while (--len > 0 && *src && *src != ' ' && *src != '\t') { + *dest++ = *src++; + } + } + *dest = 0; + while (*src == ' ' || *src == '\t') + src++; + return src; +} + +static unsigned char isapnp_get_hex(unsigned char c) +{ + if (c >= '0' || c <= '9') + return c - '0'; + if (c >= 'a' || c <= 'f') + return (c - 'a') + 10; + if (c >= 'A' || c <= 'F') + return (c - 'A') + 10; + return 0; +} + +static unsigned int isapnp_parse_id(const char *id) +{ + if (strlen(id) != 7) { + printk("isapnp: wrong PnP ID\n"); + return 0; + } + return (ISAPNP_VENDOR(id[0], id[1], id[2])<<16) | + (isapnp_get_hex(id[3])<<4) | + (isapnp_get_hex(id[4])<<0) | + (isapnp_get_hex(id[5])<<12) | + (isapnp_get_hex(id[6])<<8); +} + +static int isapnp_set_card(char *line) +{ + int idx, idx1; + unsigned int id; + char index[16], value[32]; + + isapnp_info_card = NULL; + line = isapnp_get_str(index, line, sizeof(index)); + isapnp_get_str(value, line, sizeof(value)); + idx = idx1 = simple_strtoul(index, NULL, 0); + id = isapnp_parse_id(value); + isapnp_info_card = isapnp_find_card(id >> 16, id & 0xffff, NULL); + while (isapnp_info_card && idx1-- > 0) + isapnp_info_card = isapnp_find_card(id >> 16, id & 0xffff, isapnp_info_card); + if (isapnp_info_card == NULL) { + printk("isapnp: card '%s' order %i not found\n", value, idx); + return 1; + } + if (isapnp_cfg_begin(isapnp_info_card->number, -1)<0) { + printk("isapnp: configuration start sequence for device '%s' failed\n", value); + isapnp_info_card = NULL; + return 1; + } + return 0; +} + +static int isapnp_select_csn(char *line) +{ + int csn; + char index[16], value[32]; + + isapnp_info_device = NULL; + isapnp_get_str(index, line, sizeof(index)); + csn = simple_strtoul(index, NULL, 0); + for (isapnp_info_card = isapnp_cards; isapnp_info_card; isapnp_info_card = isapnp_info_card->next) + if (isapnp_info_card->number == csn) + break; + if (isapnp_info_card == NULL) { + printk("isapnp: cannot find CSN %i\n", csn); + return 1; + } + if (isapnp_cfg_begin(isapnp_info_card->number, -1)<0) { + printk("isapnp: configuration start sequence for device '%s' failed\n", value); + isapnp_info_card = NULL; + return 1; + } + return 0; +} + +static int isapnp_set_device(char *line) +{ + int idx, idx1; + unsigned int id; + char index[16], value[32]; + + line = isapnp_get_str(index, line, sizeof(index)); + isapnp_get_str(value, line, sizeof(value)); + idx = idx1 = simple_strtoul(index, NULL, 0); + id = isapnp_parse_id(value); + isapnp_info_device = isapnp_find_dev(isapnp_info_card, id >> 16, id & 0xffff, NULL); + while (isapnp_info_device && idx-- > 0) + isapnp_info_device = isapnp_find_dev(isapnp_info_card, id >> 16, id & 0xffff, isapnp_info_device); + if (isapnp_info_device == NULL) { + printk("isapnp: device '%s' order %i not found\n", value, idx); + return 1; + } + isapnp_device(isapnp_info_device->devfn); + return 0; +} + +static int isapnp_autoconfigure(void) +{ + if (isapnp_info_device == NULL) { + printk("isapnp: device is not set\n"); + return 0; + } + if (isapnp_info_device->active) + isapnp_info_device->deactivate(isapnp_info_device); + if (isapnp_info_device->prepare(isapnp_info_device) < 0) { + printk("isapnp: cannot prepare device for the activation"); + return 0; + } + if (isapnp_info_device->activate(isapnp_info_device) < 0) { + printk("isapnp: cannot activate device"); + return 0; + } + return 0; +} + +static int isapnp_set_port(char *line) +{ + int idx, port; + char index[16], value[32]; + + line = isapnp_get_str(index, line, sizeof(index)); + isapnp_get_str(value, line, sizeof(value)); + idx = simple_strtoul(index, NULL, 0); + port = simple_strtoul(value, NULL, 0); + if (idx < 0 || idx > 7) { + printk("isapnp: wrong port index %i\n", idx); + return 1; + } + if (port < 0 || port > 0xffff) { + printk("isapnp: wrong port value 0x%x\n", port); + return 1; + } + isapnp_write_word(ISAPNP_CFG_PORT + (idx << 1), port); + if (isapnp_info_device->resource[idx].start == DEVICE_IO_NOTSET) + return 0; + if (isapnp_info_device->resource[idx].start == DEVICE_IO_AUTO) { + isapnp_info_device->resource[idx].start = port; + isapnp_info_device->resource[idx].end += port - 1; + } else { + isapnp_info_device->resource[idx].end -= isapnp_info_device->resource[idx].start; + isapnp_info_device->resource[idx].start = port; + isapnp_info_device->resource[idx].end += port; + } + return 0; +} + +static int isapnp_set_irq(char *line) +{ + int idx, irq; + char index[16], value[32]; + + line = isapnp_get_str(index, line, sizeof(index)); + isapnp_get_str(value, line, sizeof(value)); + idx = simple_strtoul(index, NULL, 0); + irq = simple_strtoul(value, NULL, 0); + if (idx < 0 || idx > 1) { + printk("isapnp: wrong IRQ index %i\n", idx); + return 1; + } + if (irq == 2) + irq = 9; + if (irq < 0 || irq > 15) { + printk("isapnp: wrong IRQ value %i\n", irq); + return 1; + } + isapnp_write_byte(ISAPNP_CFG_IRQ + (idx << 1), irq); + if (idx == 0) { + if (isapnp_info_device->irq == DEVICE_IRQ_NOTSET) + return 0; + isapnp_info_device->irq = irq; + } else { + if (isapnp_info_device->irq2 == DEVICE_IRQ_NOTSET) + return 0; + isapnp_info_device->irq2 = irq; + } + return 0; +} + +static int isapnp_set_dma(char *line) +{ + int idx, dma; + char index[16], value[32]; + + line = isapnp_get_str(index, line, sizeof(index)); + isapnp_get_str(value, line, sizeof(value)); + idx = simple_strtoul(index, NULL, 0); + dma = simple_strtoul(value, NULL, 0); + if (idx < 0 || idx > 1) { + printk("isapnp: wrong DMA index %i\n", idx); + return 1; + } + if (dma < 0 || dma > 7) { + printk("isapnp: wrong DMA value %i\n", dma); + return 1; + } + isapnp_write_byte(ISAPNP_CFG_DMA + idx, dma); + if (isapnp_info_device->dma[idx] == DEVICE_DMA_NOTSET) + return 0; + isapnp_info_device->dma[idx] = dma; + return 0; +} + +static int isapnp_set_mem(char *line) +{ + int idx; + unsigned int mem; + char index[16], value[32]; + + line = isapnp_get_str(index, line, sizeof(index)); + isapnp_get_str(value, line, sizeof(value)); + idx = simple_strtoul(index, NULL, 0); + mem = simple_strtoul(value, NULL, 0); + if (idx < 0 || idx > 3) { + printk("isapnp: wrong memory index %i\n", idx); + return 1; + } + mem >>= 8; + isapnp_write_word(ISAPNP_CFG_MEM + (idx<<2), mem & 0xffff); + if (isapnp_info_device->resource[idx + 8].start == DEVICE_IO_NOTSET) + return 0; + if (isapnp_info_device->resource[idx + 8].start == DEVICE_IO_AUTO) { + isapnp_info_device->resource[idx + 8].start = mem & ~0x00ffff00; + isapnp_info_device->resource[idx + 8].end += (mem & ~0x00ffff00) - 1; + } else { + isapnp_info_device->resource[idx + 8].end -= isapnp_info_device->resource[idx + 8].start; + isapnp_info_device->resource[idx + 8].start = mem & ~0x00ffff00; + isapnp_info_device->resource[idx + 8].end += mem & ~0x00ffff00; + } + return 0; +} + +static int isapnp_poke(char *line, int what) +{ + int reg; + unsigned int val; + char index[16], value[32]; + + line = isapnp_get_str(index, line, sizeof(index)); + isapnp_get_str(value, line, sizeof(value)); + reg = simple_strtoul(index, NULL, 0); + val = simple_strtoul(value, NULL, 0); + if (reg < 0 || reg > 127) { + printk("isapnp: wrong register %i\n", reg); + return 1; + } + switch (what) { + case 1: + isapnp_write_word(reg, val); + break; + case 2: + isapnp_write_dword(reg, val); + break; + default: + isapnp_write_byte(reg, val); + break; + } + return 0; +} + +static int isapnp_decode_line(char *line) +{ + char cmd[32]; + + line = isapnp_get_str(cmd, line, sizeof(cmd)); + if (!strcmp(cmd, "card")) + return isapnp_set_card(line); + if (!strcmp(cmd, "csn")) + return isapnp_select_csn(line); + if (!isapnp_info_card) { + printk("isapnp: card is not selected\n"); + return 1; + } + if (!strncmp(cmd, "dev", 3)) + return isapnp_set_device(line); + if (!isapnp_info_device) { + printk("isapnp: device is not selected\n"); + return 1; + } + if (!strncmp(cmd, "auto", 4)) + return isapnp_autoconfigure(); + if (!strncmp(cmd, "act", 3)) { + isapnp_activate(isapnp_info_device->devfn); + isapnp_info_device->active = 1; + return 0; + } + if (!strncmp(cmd, "deact", 5)) { + isapnp_deactivate(isapnp_info_device->devfn); + isapnp_info_device->active = 0; + return 0; + } + if (!strcmp(cmd, "port")) + return isapnp_set_port(line); + if (!strcmp(cmd, "irq")) + return isapnp_set_irq(line); + if (!strcmp(cmd, "dma")) + return isapnp_set_dma(line); + if (!strncmp(cmd, "mem", 3)) + return isapnp_set_mem(line); + if (!strcmp(cmd, "poke")) + return isapnp_poke(line, 0); + if (!strcmp(cmd, "pokew")) + return isapnp_poke(line, 1); + if (!strcmp(cmd, "poked")) + return isapnp_poke(line, 2); + printk("isapnp: wrong command '%s'\n", cmd); + return 1; +} + +/* + * Main write routine + */ + +static void isapnp_info_write(isapnp_info_buffer_t *buffer) +{ + int c, idx, idx1 = 0; + char line[128]; + + if (buffer->size <= 0) + return; + isapnp_info_card = NULL; + isapnp_info_device = NULL; + for (idx = 0; idx < buffer->size; idx++) { + c = buffer->buffer[idx]; + if (c == '\n') { + line[idx1] = '\0'; + if (line[0] != '#') { + if (isapnp_decode_line(line)) + goto __end; + } + idx1 = 0; + continue; + } + if (idx1 >= sizeof(line)-1) { + printk("isapnp: line too long, aborting\n"); + return; + } + line[idx1++] = c; + } + __end: + if (isapnp_info_card) + isapnp_cfg_end(); +} diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/53c7xx.c linux/drivers/scsi/53c7xx.c --- v2.3.13/linux/drivers/scsi/53c7xx.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/scsi/53c7xx.c Sun Aug 15 11:48:32 1999 @@ -1074,7 +1074,7 @@ NCR53c7x0_driver_init (host); - if (request_irq(host->irq, NCR53c7x0_intr, 0, "53c7xx", host)) + if (request_irq(host->irq, NCR53c7x0_intr, SA_SHIRQ, "53c7xx", host)) { printk("scsi%d : IRQ%d not free, detaching\n", host->host_no, host->irq); diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/BusLogic.c linux/drivers/scsi/BusLogic.c --- v2.3.13/linux/drivers/scsi/BusLogic.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/scsi/BusLogic.c Thu Aug 12 10:31:05 1999 @@ -783,12 +783,10 @@ unsigned int IRQ_Channel = PCI_Device->irq; unsigned long BaseAddress0 = PCI_Device->resource[0].start; unsigned long BaseAddress1 = PCI_Device->resource[1].start; - BusLogic_IO_Address_T IO_Address = - BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK; - BusLogic_PCI_Address_T PCI_Address = - BaseAddress1 & PCI_BASE_ADDRESS_MEM_MASK; - if ((BaseAddress0 & PCI_BASE_ADDRESS_SPACE) - != PCI_BASE_ADDRESS_SPACE_IO) + BusLogic_IO_Address_T IO_Address = BaseAddress0; + BusLogic_PCI_Address_T PCI_Address = BaseAddress1; + + if (!(PCI_Device->resource[0].flags & PCI_BASE_ADDRESS_SPACE_IO)) { BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "MultiMaster Host Adapter\n", NULL, BaseAddress0); @@ -796,8 +794,7 @@ NULL, Bus, Device, IO_Address); continue; } - if ((BaseAddress1 & PCI_BASE_ADDRESS_SPACE) - != PCI_BASE_ADDRESS_SPACE_MEMORY) + if (PCI_Device->resource[1].flags & PCI_BASE_ADDRESS_SPACE_IO) { BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " "MultiMaster Host Adapter\n", NULL, BaseAddress1); @@ -986,8 +983,8 @@ unsigned char Bus = PCI_Device->bus->number; unsigned char Device = PCI_Device->devfn >> 3; unsigned int IRQ_Channel = PCI_Device->irq; - BusLogic_IO_Address_T IO_Address = - PCI_Device->resource[0].start & PCI_BASE_ADDRESS_IO_MASK; + BusLogic_IO_Address_T IO_Address = PCI_Device->resource[0].start; + if (IO_Address == 0 || IRQ_Channel == 0) continue; for (i = 0; i < BusLogic_ProbeInfoCount; i++) { @@ -1032,13 +1029,10 @@ unsigned int IRQ_Channel = PCI_Device->irq; unsigned long BaseAddress0 = PCI_Device->resource[0].start; unsigned long BaseAddress1 = PCI_Device->resource[1].start; - BusLogic_IO_Address_T IO_Address = - BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK; - BusLogic_PCI_Address_T PCI_Address = - BaseAddress1 & PCI_BASE_ADDRESS_MEM_MASK; + BusLogic_IO_Address_T IO_Address = BaseAddress0; + BusLogic_PCI_Address_T PCI_Address = BaseAddress1; #ifndef CONFIG_SCSI_OMIT_FLASHPOINT - if ((BaseAddress0 & PCI_BASE_ADDRESS_SPACE) - != PCI_BASE_ADDRESS_SPACE_IO) + if (!(PCI_Device->resource[0].flags & PCI_BASE_ADDRESS_SPACE_IO)) { BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, BaseAddress0); @@ -1046,8 +1040,7 @@ NULL, Bus, Device, IO_Address); continue; } - if ((BaseAddress1 & PCI_BASE_ADDRESS_SPACE) - != PCI_BASE_ADDRESS_SPACE_MEMORY) + if (PCI_Device->resource[1].flags & PCI_BASE_ADDRESS_SPACE_IO) { BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " "FlashPoint Host Adapter\n", NULL, BaseAddress1); diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile --- v2.3.13/linux/drivers/scsi/Makefile Thu Apr 29 11:53:41 1999 +++ linux/drivers/scsi/Makefile Wed Aug 18 10:00:52 1999 @@ -18,7 +18,7 @@ CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM .SUFFIXES: -.SUFFIXES: .c .o .h .a +.SUFFIXES: .c .o .h .a .S ifeq (${CFLAGS},) CFLAGS = -D__KERNEL__=1 \ @@ -241,6 +241,14 @@ endif endif +ifeq ($(CONFIG_OKTAGON_SCSI),y) +L_OBJS += NCR53C9x.o oktagon_esp.o oktagon_io.o +else + ifeq ($(CONFIG_OKTAGON_SCSI),m) + M_OBJS += NCR53C9x.o oktagon_esp.o oktagon_io.o + endif +endif + ifeq ($(CONFIG_ATARI_SCSI),y) L_OBJS += atari_scsi.o else @@ -249,6 +257,22 @@ endif endif +ifeq ($(CONFIG_MAC_SCSI_OLD),y) +L_OBJS += mac_scsi.o +else + ifeq ($(CONFIG_MAC_SCSI_OLD),m) + M_OBJS += mac_scsi.o + endif +endif + +ifeq ($(CONFIG_SCSI_MAC_ESP),y) +L_OBJS += mac_esp.o NCR53C9x.o +else + ifeq ($(CONFIG_SCSI_MAC_ESP),m) + M_OBJS += mac_esp.o NCR53C9x.o + endif +endif + ifeq ($(CONFIG_SCSI_PPA),y) L_OBJS += ppa.o else @@ -623,6 +647,10 @@ L_OBJS += NCR53C9x.o jazz_esp.o endif +ifeq ($(CONFIG_SUN3X_ESP),y) +L_OBJS += NCR53C9x.o sun3x_esp.o +endif + include $(TOPDIR)/Rules.make 53c8xx_d.h: 53c7,8xx.scr script_asm.pl @@ -643,8 +671,7 @@ 53c7xx_u.h: 53c7xx_d.h -53c7xx.o : 53c7xx_d.h 53c7xx.c - $(CC) $(CFLAGS) -c 53c7xx.c +53c7xx.o : 53c7xx_d.h initio.o: ini9100u.c i91uscsi.c $(CC) $(CFLAGS) -c ini9100u.c -o ini9100u.o diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/NCR53C9x.c linux/drivers/scsi/NCR53C9x.c --- v2.3.13/linux/drivers/scsi/NCR53C9x.c Thu Jul 8 15:42:20 1999 +++ linux/drivers/scsi/NCR53C9x.c Thu Aug 12 10:28:34 1999 @@ -2,12 +2,12 @@ * * Originally esp.c : EnhancedScsiProcessor Sun SCSI driver code. * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1995, 1998 David S. Miller (davem@caip.rutgers.edu) * * Most DMA dependencies put in driver specific files by * Jesper Skov (jskov@cygnus.co.uk) * - * Set up to use GETREG/SETREG (preprocessor macros in NCR53c9x.h) by + * Set up to use esp_read/esp_write (preprocessor macros in NCR53c9x.h) by * Tymm Twillman (tymm@coe.missouri.edu) */ @@ -21,6 +21,10 @@ * 4) Maybe change use of "esp" to something more "NCR"'ish. */ +#ifdef MODULE +#include +#endif + #include #include #include @@ -30,28 +34,12 @@ #include #include #include - #include #include "scsi.h" #include "hosts.h" #include "NCR53C9x.h" -#ifdef CONFIG_SCSI_SUNESP -#include "sparc_esp.h" -#include -#include -#include -#include -#include -#endif - -#if defined(CONFIG_BLZ1230_SCSI)||defined(CONFIG_BLZ2060_SCSI)||defined(CONFIG_CYBERSTORMII_SCSI) -#define SYMBIOS_HACK -#else -#undef SYMBIOS_HACK -#endif - #include #include #include @@ -95,6 +83,17 @@ in_tgterror = 0x84, /* Target did something stupid */ }; +enum { + /* Zero has special meaning, see skipahead[12]. */ +/*0*/ do_never, + +/*1*/ do_phase_determine, +/*2*/ do_reset_bus, +/*3*/ do_reset_complete, +/*4*/ do_work_bus, +/*5*/ do_intr_end +}; + struct proc_dir_entry proc_scsi_esp = { PROC_SCSI_ESP, 3, "esp", S_IFDIR | S_IRUGO | S_IXUGO, 2 @@ -227,7 +226,6 @@ "UNKNOWN")))))); } -#if defined(DEBUG_STATE_MACHINE) || defined(DEBUG_ESP) static char *phase_string(int phase) { switch(phase) { @@ -283,26 +281,31 @@ return "UNKNOWN"; }; } -#endif +#ifdef DEBUG_STATE_MACHINE static inline void esp_advance_phase(Scsi_Cmnd *s, int newphase) { -#ifdef DEBUG_STATE_MACHINE ESPLOG(("<%s>", phase_string(newphase))); -#endif s->SCp.sent_command = s->SCp.phase; s->SCp.phase = newphase; } +#else +#define esp_advance_phase(__s, __newphase) \ + (__s)->SCp.sent_command = (__s)->SCp.phase; \ + (__s)->SCp.phase = (__newphase); +#endif +#ifdef DEBUG_ESP_CMDS extern inline void esp_cmd(struct NCR_ESP *esp, struct ESP_regs *eregs, unchar cmd) { -#ifdef DEBUG_ESP_CMDS esp->espcmdlog[esp->espcmdent] = cmd; esp->espcmdent = (esp->espcmdent + 1) & 31; -#endif - SETREG(eregs->esp_cmnd, cmd); + esp_write(eregs->esp_cmnd, cmd); } +#else +#define esp_cmd(__esp, __eregs, __cmd) esp_write((__eregs)->esp_cmnd, (__cmd)) +#endif /* How we use the various Linux SCSI data structures for operation. * @@ -320,7 +323,6 @@ * the disconnect flag. */ - /* Manipulation of the ESP command queues. Thanks to the aha152x driver * and its author, Juergen E. Fischer, for the methods used here. * Note that these are per-ESP queues, not global queues like @@ -329,9 +331,7 @@ static inline void append_SC(Scsi_Cmnd **SC, Scsi_Cmnd *new_SC) { Scsi_Cmnd *end; - unsigned long flags; - save_flags(flags); cli(); new_SC->host_scribble = (unsigned char *) NULL; if(!*SC) *SC = new_SC; @@ -340,38 +340,28 @@ ; end->host_scribble = (unsigned char *) new_SC; } - restore_flags(flags); } static inline void prepend_SC(Scsi_Cmnd **SC, Scsi_Cmnd *new_SC) { - unsigned long flags; - - save_flags(flags); cli(); new_SC->host_scribble = (unsigned char *) *SC; *SC = new_SC; - restore_flags(flags); } static inline Scsi_Cmnd *remove_first_SC(Scsi_Cmnd **SC) { Scsi_Cmnd *ptr; - unsigned long flags; - save_flags(flags); cli(); ptr = *SC; if(ptr) *SC = (Scsi_Cmnd *) (*SC)->host_scribble; - restore_flags(flags); return ptr; } static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, int target, int lun) { Scsi_Cmnd *ptr, *prev; - unsigned long flags; - save_flags(flags); cli(); for(ptr = *SC, prev = NULL; ptr && ((ptr->target != target) || (ptr->lun != lun)); prev = ptr, ptr = (Scsi_Cmnd *) ptr->host_scribble) @@ -382,14 +372,13 @@ else *SC=(Scsi_Cmnd *)ptr->host_scribble; } - restore_flags(flags); return ptr; } /* Resetting various pieces of the ESP scsi driver chipset */ /* Reset the ESP chip, _not_ the SCSI bus. */ -static inline void esp_reset_esp(struct NCR_ESP *esp, struct ESP_regs *eregs) +static void esp_reset_esp(struct NCR_ESP *esp, struct ESP_regs *eregs) { int family_code, version, i; volatile int trash; @@ -397,6 +386,8 @@ /* Now reset the ESP chip */ esp_cmd(esp, eregs, ESP_CMD_RC); esp_cmd(esp, eregs, ESP_CMD_NULL | ESP_CMD_DMA); + if(esp->erev == fast) + esp_write(eregs->esp_cfg2, ESP_CONFIG2_FENAB); esp_cmd(esp, eregs, ESP_CMD_NULL | ESP_CMD_DMA); /* This is the only point at which it is reliable to read @@ -404,31 +395,45 @@ */ esp->max_period = ((35 * esp->ccycle) / 1000); if(esp->erev == fast) { - version = GETREG(eregs->esp_uid); + char *erev2string[] = { + "Emulex FAS236", + "Emulex FPESP100A", + "fast", + "QLogic FAS366", + "Emulex FAS216", + "Symbios Logic 53CF9x-2", + "unknown!" + }; + + version = esp_read(eregs->esp_uid); family_code = (version & 0xf8) >> 3; -#ifdef SYMBIOS_HACK - if (version == 0 && family_code == 0) - { - printk ("Detected SymBIOS chip with no family code.\n"); - version = 3; - family_code = 2; - } -#endif - if(family_code == 0x02) + if(family_code == 0x02) { if ((version & 7) == 2) esp->erev = fas216; else esp->erev = fas236; - else if(family_code == 0x0a) - esp->erev = fashme; /* Version is usually '5'. */ - else - esp->erev = fas100a; - printk("esp%d: FAST chip is %s (family=%d, version=%d)\n", - esp->esp_id, - (esp->erev == fas236) ? "fas236" : - ((esp->erev == fas216) ? "fas216" : - (((esp->erev == fas100a) ? "fas100a" : - "fasHME"))), family_code, (version & 7)); + } else if(family_code == 0x0a) + esp->erev = fas366; /* Version is usually '5'. */ + else if(family_code == 0x00) { + if ((version & 7) == 2) + esp->erev = fas100a; /* NCR53C9X */ + else + esp->erev = espunknown; + } else if(family_code == 0x14) { + if ((version & 7) == 2) + esp->erev = fsc; + else + esp->erev = espunknown; + } else if(family_code == 0x00) { + if ((version & 7) == 2) + esp->erev = fas100a; /* NCR53C9X */ + else + esp->erev = espunknown; + } else + esp->erev = espunknown; + ESPLOG(("esp%d: FAST chip is %s (family=%d, version=%d)\n", + esp->esp_id, erev2string[esp->erev - fas236], + family_code, (version & 7))); esp->min_period = ((4 * esp->ccycle) / 1000); } else { @@ -436,56 +441,63 @@ } /* Reload the configuration registers */ - SETREG(eregs->esp_cfact, esp->cfact); - SETREG(eregs->esp_stp, 0); - SETREG(eregs->esp_soff, 0); - SETREG(eregs->esp_timeo, esp->neg_defp); + esp_write(eregs->esp_cfact, esp->cfact); + esp->prev_stp = 0; + esp_write(eregs->esp_stp, 0); + esp->prev_soff = 0; + esp_write(eregs->esp_soff, 0); + esp_write(eregs->esp_timeo, esp->neg_defp); esp->max_period = (esp->max_period + 3)>>2; esp->min_period = (esp->min_period + 3)>>2; - SETREG(eregs->esp_cfg1, esp->config1); + esp_write(eregs->esp_cfg1, esp->config1); switch(esp->erev) { case esp100: /* nothing to do */ break; case esp100a: - SETREG(eregs->esp_cfg2, esp->config2); + esp_write(eregs->esp_cfg2, esp->config2); break; case esp236: /* Slow 236 */ - SETREG(eregs->esp_cfg2, esp->config2); - SETREG(eregs->esp_cfg3, esp->config3[0]); + esp_write(eregs->esp_cfg2, esp->config2); + esp->prev_cfg3 = esp->config3[0]; + esp_write(eregs->esp_cfg3, esp->prev_cfg3); + break; + case fas366: + panic("esp: FAS366 support not present, please notify " + "jongk@cs.utwente.nl"); break; - case fashme: - esp->config2 |= (ESP_CONFIG2_HME32 | ESP_CONFIG2_HMEFENAB); - /* fallthrough... */ - case fas216: + case fas216: case fas236: - /* Fast 236 or HME */ - SETREG(eregs->esp_cfg2, esp->config2); - for(i=0; i<8; i++) { - if(esp->erev == fashme) - esp->config3[i] |= - (ESP_CONFIG3_FCLOCK | ESP_CONFIG3_BIGID | ESP_CONFIG3_OBPUSH); - else - esp->config3[i] |= ESP_CONFIG3_FCLK; - } - SETREG(eregs->esp_cfg3, esp->config3[0]); - if(esp->erev == fashme) { - esp->radelay = 80; - } else { - if(esp->diff) - esp->radelay = 0; - else - esp->radelay = 96; - } + case fsc: + /* Fast ESP variants */ + esp_write(eregs->esp_cfg2, esp->config2); + for(i=0; i<8; i++) + esp->config3[i] |= ESP_CONFIG3_FCLK; + esp->prev_cfg3 = esp->config3[0]; + esp_write(eregs->esp_cfg3, esp->prev_cfg3); + if(esp->diff) + esp->radelay = 0; + else + esp->radelay = 16; + /* Different timeout constant for these chips */ + esp->neg_defp = + FSC_NEG_DEFP(esp->cfreq, + (esp->cfact == ESP_CCF_F0 ? + ESP_CCF_F7 + 1 : esp->cfact)); + esp_write(eregs->esp_timeo, esp->neg_defp); + /* Enable Active Negotiation if possible */ + if((esp->erev == fsc) && !esp->diff) + esp_write(eregs->esp_cfg4, ESP_CONFIG4_EAN); break; case fas100a: /* Fast 100a */ - SETREG(eregs->esp_cfg2, esp->config2); + esp_write(eregs->esp_cfg2, esp->config2); for(i=0; i<8; i++) esp->config3[i] |= ESP_CONFIG3_FCLOCK; - SETREG(eregs->esp_cfg3, esp->config3[0]); + esp->prev_cfg3 = esp->config3[0]; + esp_write(eregs->esp_cfg3, esp->prev_cfg3); esp->radelay = 32; break; default: @@ -494,12 +506,12 @@ }; /* Eat any bitrot in the chip */ - trash = GETREG(eregs->esp_intrpt); + trash = esp_read(eregs->esp_intrpt); udelay(100); } /* This places the ESP into a known state at boot time. */ -inline void esp_bootup_reset(struct NCR_ESP *esp, struct ESP_regs *eregs) +void esp_bootup_reset(struct NCR_ESP *esp, struct ESP_regs *eregs) { volatile unchar trash; @@ -511,13 +523,13 @@ esp_reset_esp(esp, eregs); /* Reset the SCSI bus, but tell ESP not to generate an irq */ - SETREG(eregs->esp_cfg1, GETREG(eregs->esp_cfg1) | ESP_CONFIG1_SRRDISAB); + esp_write(eregs->esp_cfg1, (esp_read(eregs->esp_cfg1) | ESP_CONFIG1_SRRDISAB)); esp_cmd(esp, eregs, ESP_CMD_RS); udelay(400); - SETREG(eregs->esp_cfg1, esp->config1); + esp_write(eregs->esp_cfg1, esp->config1); /* Eat any bitrot in the chip and we are done... */ - trash = GETREG(eregs->esp_intrpt); + trash = esp_read(eregs->esp_intrpt); } /* Allocate structure and insert basic data such as SCSI chip frequency @@ -538,6 +550,9 @@ esp->edev = esp_dev; esp->esp_id = nesps++; + /* Set bitshift value (only used on Amiga with multiple ESPs) */ + esp->shift = 2; + /* Put into the chain of esp chips detected */ if(espchain) { elink = espchain; @@ -551,6 +566,20 @@ return esp; } +void esp_deallocate(struct NCR_ESP *esp) +{ + struct NCR_ESP *elink; + + if(espchain == esp) { + espchain = 0; + } else { + for(elink = espchain; elink && (elink->next != esp); elink = elink->next); + if(elink) + elink->next = esp->next; + } + nesps--; +} + /* Complete initialization of ESP structure and device * Caller must have initialized appropriate parts of the ESP structure * between the call to esp_allocate and this function. @@ -639,9 +668,9 @@ esp->neg_defp = ESP_NEG_DEFP(fmhz, ccf); esp->sync_defp = SYNC_DEFP_SLOW; - printk("SCSI ID %d Clock %d MHz CCF=%d Time-Out %d ", + printk("SCSI ID %d Clk %dMHz CCF=%d TOut %d ", esp->scsi_id, (esp->cfreq / 1000000), - esp->ccf, (int) esp->neg_defp); + ccf, (int) esp->neg_defp); /* Fill in ehost data */ esp->ehost->base = (unsigned char *) eregs; @@ -654,61 +683,46 @@ /* Probe the revision of this esp */ esp->config1 = (ESP_CONFIG1_PENABLE | (esp->scsi_id & 7)); esp->config2 = (ESP_CONFIG2_SCSI2ENAB | ESP_CONFIG2_REGPARITY); - SETREG(eregs->esp_cfg2, esp->config2); -#ifndef SYMBIOS_HACK - if((GETREG(eregs->esp_cfg2) & ~(ESP_CONFIG2_MAGIC)) != + esp_write(eregs->esp_cfg2, esp->config2); + if((esp_read(eregs->esp_cfg2) & ~(ESP_CONFIG2_MAGIC)) != (ESP_CONFIG2_SCSI2ENAB | ESP_CONFIG2_REGPARITY)) { - printk("NCR53C90(esp100) detected\n"); + printk("NCR53C90(esp100)\n"); esp->erev = esp100; } else { -#endif esp->config2 = 0; - SETREG(eregs->esp_cfg2, esp->config2); - SETREG(eregs->esp_cfg3, 0); - esp->config3[0] = 5; - SETREG(eregs->esp_cfg3, esp->config3[0]); -#ifndef SYMBIOS_HACK - if(GETREG(eregs->esp_cfg3) != 5) { - printk("NCR53C90A(esp100a) detected\n"); + esp_write(eregs->esp_cfg2, 0); + esp_write(eregs->esp_cfg3, 5); + if(esp_read(eregs->esp_cfg3) != 5) { + printk("NCR53C90A(esp100a)\n"); esp->erev = esp100a; } else { -#else - { -#endif int target; - + for(target=0; target<8; target++) esp->config3[target] = 0; - SETREG(eregs->esp_cfg3, 0); -#ifndef SYMBIOS_HACK + esp->prev_cfg3 = 0; + esp_write(eregs->esp_cfg3, 0); if(ccf > ESP_CCF_F5) { -#endif - printk("NCR53C9XF(espfast) detected\n"); + printk("NCR53C9XF(espfast)\n"); esp->erev = fast; - esp->config2 = 0; - SETREG(eregs->esp_cfg2, esp->config2); esp->sync_defp = SYNC_DEFP_FAST; -#ifndef SYMBIOS_HACK } else { - printk("NCR53C9x(esp236) detected\n"); + printk("NCR53C9x(esp236)\n"); esp->erev = esp236; - esp->config2 = 0; - SETREG(eregs->esp_cfg2, esp->config2); } } -#endif } - + /* Initialize the command queues */ esp->current_SC = 0; esp->disconnected_SC = 0; esp->issue_SC = 0; - + /* Clear the state machines. */ esp->targets_present = 0; esp->resetting_bus = 0; esp->snip = 0; - esp->targets_present = 0; + esp->fas_premature_intr_workaround = 0; for(i = 0; i < 32; i++) esp->espcmdlog[i] = 0; esp->espcmdent = 0; @@ -719,9 +733,15 @@ esp->prevmsgout = esp->prevmsgin = 0; esp->msgout_len = esp->msgin_len = 0; + /* Clear the one behind caches to hold unmatchable values. */ + esp->prev_soff = esp->prev_stp = esp->prev_cfg3 = 0xff; + /* Reset the thing before we try anything... */ esp_bootup_reset(esp, eregs); - + +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif esps_in_use++; } @@ -740,15 +760,17 @@ case esp100a: return "ESP100A (NCR53C90A)"; case esp236: - return "ESP236"; + return "ESP236 (NCR53C9x)"; case fas216: - return "ESP216-FAST"; + return "Emulex FAS216"; case fas236: - return "ESP236-FAST"; - case fashme: - return "ESP366-HME"; + return "Emulex FAS236"; + case fas366: + return "QLogic FAS366"; case fas100a: - return "ESP100A-FAST"; + return "FPESP100A"; + case fsc: + return "Symbios Logic 53CF9x-2"; default: panic("Bogon ESP revision"); }; @@ -807,69 +829,41 @@ info.offset = offset; info.pos = 0; - copy_info(&info, "Sparc ESP Host Adapter:\n"); - copy_info(&info, "\tPROM node\t\t%08lx\n", (unsigned long) esp->prom_node); - copy_info(&info, "\tPROM name\t\t%s\n", esp->prom_name); + copy_info(&info, "ESP Host Adapter:\n"); copy_info(&info, "\tESP Model\t\t"); switch(esp->erev) { case esp100: - copy_info(&info, "ESP100\n"); + copy_info(&info, "ESP100 (NCR53C90)\n"); break; case esp100a: - copy_info(&info, "ESP100A\n"); + copy_info(&info, "ESP100A (NCR53C90A)\n"); break; case esp236: - copy_info(&info, "ESP236\n"); + copy_info(&info, "ESP236 (NCR53C9x)\n"); break; case fas216: - copy_info(&info, "FAS216\n"); + copy_info(&info, "Emulex FAS216\n"); break; case fas236: - copy_info(&info, "FAS236\n"); + copy_info(&info, "Emulex FAS236\n"); break; case fas100a: - copy_info(&info, "FAS100A\n"); + copy_info(&info, "FPESP100A\n"); break; case fast: - copy_info(&info, "FAST\n"); - break; - case fashme: - copy_info(&info, "Happy Meal FAS\n"); - break; - case espunknown: - default: - copy_info(&info, "Unknown!\n"); - break; - }; -#ifdef CONFIG_SCSI_SUNESP - copy_info(&info, "\tDMA Revision\t\t"); - switch(((struct Linux_SBus_DMA*) (esp->dma))->revision) { - case dvmarev0: - copy_info(&info, "Rev 0\n"); - break; - case dvmaesc1: - copy_info(&info, "ESC Rev 1\n"); - break; - case dvmarev1: - copy_info(&info, "Rev 1\n"); - break; - case dvmarev2: - copy_info(&info, "Rev 2\n"); + copy_info(&info, "Generic FAST\n"); break; - case dvmarev3: - copy_info(&info, "Rev 3\n"); + case fas366: + copy_info(&info, "QLogic FAS366\n"); break; - case dvmarevplus: - copy_info(&info, "Rev 1+\n"); - break; - case dvmahme: - copy_info(&info, "Rev HME/FAS\n"); + case fsc: + copy_info(&info, "Symbios Logic 53C9x-2\n"); break; + case espunknown: default: copy_info(&info, "Unknown!\n"); break; }; -#endif copy_info(&info, "\tLive Targets\t\t[ "); for(i = 0; i < 15; i++) { if(esp->targets_present & (1 << i)) @@ -878,7 +872,7 @@ copy_info(&info, "]\n\n"); /* Now describe the state of each existing target. */ - copy_info(&info, "Target #\tconfig3\t\tSync Capabilities\tDisconnect\tWide\n"); + copy_info(&info, "Target #\tconfig3\t\tSync Capabilities\tDisconnect\n"); for(i = 0; i < 15; i++) { if(esp->targets_present & (1 << i)) { Scsi_Device *SDptr = esp->ehost->host_queue; @@ -892,9 +886,7 @@ copy_info(&info, "%08lx\t", esp->config3[i]); copy_info(&info, "[%02lx,%02lx]\t\t\t", SDptr->sync_max_offset, SDptr->sync_min_period); - copy_info(&info, "%s\t\t", SDptr->disconnect ? "yes" : "no"); - copy_info(&info, "%s\n", - (esp->config3[i] & ESP_CONFIG3_EWIDE) ? "yes" : "no"); + copy_info(&info, "%s\n", SDptr->disconnect ? "yes" : "no"); } } @@ -923,6 +915,60 @@ return esp_host_info(esp, buffer, offset, length); } +static void esp_get_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp) +{ + if(sp->use_sg == 0) { + sp->SCp.this_residual = sp->request_bufflen; + sp->SCp.buffer = (struct scatterlist *) sp->request_buffer; + sp->SCp.buffers_residual = 0; + if (esp->dma_mmu_get_scsi_one) + esp->dma_mmu_get_scsi_one(esp, sp); + else + sp->SCp.have_data_in = (int) sp->SCp.ptr = + (char *) virt_to_phys(sp->request_buffer); + } else { + sp->SCp.buffer = (struct scatterlist *) sp->buffer; + sp->SCp.buffers_residual = sp->use_sg - 1; + sp->SCp.this_residual = sp->SCp.buffer->length; + if (esp->dma_mmu_get_scsi_sgl) + esp->dma_mmu_get_scsi_sgl(esp, sp); + else + sp->SCp.ptr = + (char *) virt_to_phys(sp->SCp.buffer->address); + } +} + +static void esp_release_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp) +{ + if(sp->use_sg == 0) { + if (esp->dma_mmu_release_scsi_one) + esp->dma_mmu_release_scsi_one(esp, sp); + } else { + if (esp->dma_mmu_release_scsi_sgl) + esp->dma_mmu_release_scsi_sgl(esp, sp); + } +} + +static void esp_restore_pointers(struct NCR_ESP *esp, Scsi_Cmnd *sp) +{ + struct esp_pointers *ep = &esp->data_pointers[sp->target]; + + sp->SCp.ptr = ep->saved_ptr; + sp->SCp.buffer = ep->saved_buffer; + sp->SCp.this_residual = ep->saved_this_residual; + sp->SCp.buffers_residual = ep->saved_buffers_residual; +} + +static void esp_save_pointers(struct NCR_ESP *esp, Scsi_Cmnd *sp) +{ + struct esp_pointers *ep = &esp->data_pointers[sp->target]; + + ep->saved_ptr = sp->SCp.ptr; + ep->saved_buffer = sp->SCp.buffer; + ep->saved_this_residual = sp->SCp.this_residual; + ep->saved_buffers_residual = sp->SCp.buffers_residual; +} + /* Some rules: * * 1) Never ever panic while something is live on the bus. @@ -970,29 +1016,7 @@ esp->msgout_len = 5; } -/* SIZE is in bits, currently HME only supports 16 bit wide transfers. */ -static inline void build_wide_nego_msg(struct NCR_ESP *esp, int size) -{ - esp->cur_msgout[0] = EXTENDED_MESSAGE; - esp->cur_msgout[1] = 2; - esp->cur_msgout[2] = EXTENDED_WDTR; - switch(size) { - case 32: - esp->cur_msgout[3] = 2; - break; - case 16: - esp->cur_msgout[3] = 1; - break; - case 8: - default: - esp->cur_msgout[3] = 0; - break; - }; - - esp->msgout_len = 4; -} - -static inline void esp_exec_cmd(struct NCR_ESP *esp) +static void esp_exec_cmd(struct NCR_ESP *esp) { struct ESP_regs *eregs = esp->eregs; Scsi_Cmnd *SCptr; @@ -1002,15 +1026,18 @@ int lun, target; int i; - /* Hold off if we've been reselected or an IRQ is showing... */ - if(esp->disconnected_SC || esp->dma_irq_p(esp)) + /* Hold off if we have disconnected commands and + * an IRQ is showing... + */ + if(esp->disconnected_SC && esp->dma_irq_p(esp)) return; /* Grab first member of the issue queue. */ SCptr = esp->current_SC = remove_first_SC(&esp->issue_SC); /* Safe to panic here because current_SC is null. */ - if(!SCptr) panic("esp: esp_exec_cmd and issue queue is NULL"); + if(!SCptr) + panic("esp: esp_exec_cmd and issue queue is NULL"); SDptr = SCptr->device; lun = SCptr->lun; @@ -1053,7 +1080,7 @@ if(SDptr->sync) { /* this targets sync is known */ -#ifdef CONFIG_SCSI_SUNESP +#ifdef CONFIG_SCSI_MAC_ESP do_sync_known: #endif if(SDptr->disconnect) @@ -1090,51 +1117,28 @@ } else { int toshiba_cdrom_hwbug_wkaround = 0; -#ifdef CONFIG_SCSI_SUNESP - /* Never allow disconnects or synchronous transfers on - * SparcStation1 and SparcStation1+. Allowing those - * to be enabled seems to lockup the machine completely. - */ - if((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) || - (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) { - /* But we are nice and allow tapes to disconnect. */ - if(SDptr->type == TYPE_TAPE) - SDptr->disconnect = 1; - else - SDptr->disconnect = 0; - SDptr->sync_max_offset = 0; - SDptr->sync_min_period = 0; - SDptr->sync = 1; - esp->snip = 0; - goto do_sync_known; - } +#ifdef CONFIG_SCSI_MAC_ESP + /* Never allow synchronous transfers (disconnect OK) on + * Macintosh. Well, maybe later when we figured out how to + * do DMA on the machines that support it ... + */ + SDptr->disconnect = 1; + SDptr->sync_max_offset = 0; + SDptr->sync_min_period = 0; + SDptr->sync = 1; + esp->snip = 0; + goto do_sync_known; #endif /* We've talked to this guy before, - * but never negotiated. Let's try, - * need to attempt WIDE first, before - * sync nego, as per SCSI 2 standard. - */ - if(esp->erev == fashme && !SDptr->wide) { - if(!SDptr->borken && - (SDptr->type != TYPE_ROM || - strncmp(SDptr->vendor, "TOSHIBA", 7))) { - build_wide_nego_msg(esp, 16); - esp->config3[SCptr->target] |= ESP_CONFIG3_EWIDE; - SDptr->wide = 1; - esp->wnip = 1; - goto after_nego_msg_built; - } else { - SDptr->wide = 1; - /* Fall through and try sync. */ - } - } - + * but never negotiated. Let's try + * sync negotiation. + */ if(!SDptr->borken) { if((SDptr->type == TYPE_ROM) && (!strncmp(SDptr->vendor, "TOSHIBA", 7))) { /* Nice try sucker... */ - printk(KERN_INFO "esp%d: Disabling sync for buggy " - "Toshiba CDROM.\n", esp->esp_id); + ESPMISC(("esp%d: Disabling sync for buggy " + "Toshiba CDROM.\n", esp->esp_id)); toshiba_cdrom_hwbug_wkaround = 1; build_sync_nego_msg(esp, 0, 0); } else { @@ -1146,7 +1150,6 @@ SDptr->sync = 1; esp->snip = 1; -after_nego_msg_built: /* A fix for broken SCSI1 targets, when they disconnect * they lock up the bus and confuse ESP. So disallow * disconnects for SCSI1 targets for now until we @@ -1171,13 +1174,9 @@ * thank you very much. ;-) */ if(((SDptr->scsi_level < 3) && (SDptr->type != TYPE_TAPE)) || -#if 1 /* Until I find out why HME barfs with disconnects enabled... */ - toshiba_cdrom_hwbug_wkaround || SDptr->borken || esp->erev == fashme) { -#else toshiba_cdrom_hwbug_wkaround || SDptr->borken) { -#endif - printk(KERN_INFO "esp%d: Disabling DISCONNECT for target %d " - "lun %d\n", esp->esp_id, SCptr->target, SCptr->lun); + ESPMISC((KERN_INFO "esp%d: Disabling DISCONNECT for target %d " + "lun %d\n", esp->esp_id, SCptr->target, SCptr->lun)); SDptr->disconnect = 0; *cmdp++ = IDENTIFY(0, lun); } else { @@ -1199,49 +1198,48 @@ for(i = 0; i < SCptr->cmd_len; i++) *cmdp++ = SCptr->cmnd[i]; - /* HME sucks... */ - if(esp->erev == fashme) - SETREG(eregs->esp_busid, (target & 0xf) | - (ESP_BUSID_RESELID | ESP_BUSID_CTR32BIT)); - else - SETREG(eregs->esp_busid, (target & 7)); - SETREG(eregs->esp_soff, SDptr->sync_max_offset); - SETREG(eregs->esp_stp, SDptr->sync_min_period); - if(esp->erev > esp100a) - SETREG(eregs->esp_cfg3, esp->config3[target]); - + esp_write(eregs->esp_busid, (target & 7)); + if (esp->prev_soff != SDptr->sync_max_offset || + esp->prev_stp != SDptr->sync_min_period || + (esp->erev > esp100a && + esp->prev_cfg3 != esp->config3[target])) { + esp->prev_soff = SDptr->sync_max_offset; + esp_write(eregs->esp_soff, esp->prev_soff); + esp->prev_stp = SDptr->sync_min_period; + esp_write(eregs->esp_stp, esp->prev_stp); + if(esp->erev > esp100a) { + esp->prev_cfg3 = esp->config3[target]; + esp_write(eregs->esp_cfg3, esp->prev_cfg3); + } + } i = (cmdp - esp->esp_command); /* Set up the DMA and ESP counters */ if(esp->do_pio_cmds){ int j = 0; + /* + * XXX MSch: + * + * It seems this is required, at least to clean up + * after failed commands when using PIO mode ... + */ + esp_cmd(esp, eregs, ESP_CMD_FLUSH); + for(;jesp_fdata, esp->esp_command[j]); + esp_write(eregs->esp_fdata, esp->esp_command[j]); the_esp_command &= ~ESP_CMD_DMA; /* Tell ESP to "go". */ esp_cmd(esp, eregs, the_esp_command); } else { - if(esp->erev == fashme) { - esp_cmd(esp, eregs, ESP_CMD_FLUSH); /* Grrr! */ - - /* Set up the HME counters */ - SETREG(eregs->esp_tclow, i); - SETREG(eregs->esp_tcmed, 0); - SETREG(eregs->fas_rlo, 0); - SETREG(eregs->fas_rhi, 0); - esp_cmd(esp, eregs, the_esp_command); - esp->dma_init_write(esp, esp->esp_command_dvma, 16); - } else { - /* Set up the ESP counters */ - SETREG(eregs->esp_tclow, i); - SETREG(eregs->esp_tcmed, 0); - esp->dma_init_write(esp, esp->esp_command_dvma, i); + /* Set up the ESP counters */ + esp_write(eregs->esp_tclow, i); + esp_write(eregs->esp_tcmed, 0); + esp->dma_init_write(esp, esp->esp_command_dvma, i); - /* Tell ESP to "go". */ - esp_cmd(esp, eregs, the_esp_command); - } + /* Tell ESP to "go". */ + esp_cmd(esp, eregs, the_esp_command); } } @@ -1249,7 +1247,6 @@ int esp_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { struct NCR_ESP *esp; - unsigned long flags; /* Set up func ptr and initial driver cmd-phase. */ SCpnt->scsi_done = done; @@ -1263,32 +1260,10 @@ /* We use the scratch area. */ ESPQUEUE(("esp_queue: target=%d lun=%d ", SCpnt->target, SCpnt->lun)); ESPDISC(("N<%02x,%02x>", SCpnt->target, SCpnt->lun)); - if(!SCpnt->use_sg) { - ESPQUEUE(("!use_sg\n")); - SCpnt->SCp.this_residual = SCpnt->request_bufflen; - SCpnt->SCp.buffer = - (struct scatterlist *) SCpnt->request_buffer; - SCpnt->SCp.buffers_residual = 0; - if (esp->dma_mmu_get_scsi_one) - esp->dma_mmu_get_scsi_one (esp, SCpnt); - else - SCpnt->SCp.have_data_in = (int) SCpnt->SCp.ptr = - (char *) virt_to_phys(SCpnt->request_buffer); - } else { - ESPQUEUE(("use_sg ")); -#ifdef DEBUG_ESP_SG - printk("esp%d: sglist at %p with %d buffers\n", - esp->esp_id, SCpnt->buffer, SCpnt->use_sg); -#endif - SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer; - SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1; - SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length; - if (esp->dma_mmu_get_scsi_sgl) - esp->dma_mmu_get_scsi_sgl (esp, SCpnt); - else - SCpnt->SCp.ptr = - (char *) virt_to_phys(SCpnt->SCp.buffer->address); - } + + esp_get_dmabufs(esp, SCpnt); + esp_save_pointers(esp, SCpnt); /* FIXME for tag queueing */ + SCpnt->SCp.Status = CHECK_CONDITION; SCpnt->SCp.Message = 0xff; SCpnt->SCp.sent_command = 0; @@ -1302,13 +1277,10 @@ append_SC(&esp->issue_SC, SCpnt); } - save_and_cli(flags); - /* Run it now if we can. */ if(!esp->current_SC && !esp->resetting_bus) esp_exec_cmd(esp); - restore_flags(flags); return 0; } @@ -1324,7 +1296,7 @@ } /* Dump driver state. */ -static inline void esp_dump_cmd(Scsi_Cmnd *SCptr) +static void esp_dump_cmd(Scsi_Cmnd *SCptr) { ESPLOG(("[tgt<%02x> lun<%02x> " "pphase<%s> cphase<%s>]", @@ -1333,8 +1305,8 @@ phase_string(SCptr->SCp.phase))); } -static inline void esp_dump_state(struct NCR_ESP *esp, - struct ESP_regs *eregs) +static void esp_dump_state(struct NCR_ESP *esp, + struct ESP_regs *eregs) { Scsi_Cmnd *SCptr = esp->current_SC; #ifdef DEBUG_ESP_CMDS @@ -1349,8 +1321,8 @@ ESPLOG(("esp%d: SW [sreg<%02x> sstep<%02x> ireg<%02x>]\n", esp->esp_id, esp->sreg, esp->seqreg, esp->ireg)); ESPLOG(("esp%d: HW reread [sreg<%02x> sstep<%02x> ireg<%02x>]\n", - esp->esp_id, GETREG(eregs->esp_status), - GETREG(eregs->esp_sstep), GETREG(eregs->esp_intrpt))); + esp->esp_id, esp_read(eregs->esp_status), esp_read(eregs->esp_sstep), + esp_read(eregs->esp_intrpt))); #ifdef DEBUG_ESP_CMDS printk("esp%d: last ESP cmds [", esp->esp_id); i = (esp->espcmdent - 1) & 31; @@ -1392,7 +1364,6 @@ struct NCR_ESP *esp = (struct NCR_ESP *) SCptr->host->hostdata; struct ESP_regs *eregs = esp->eregs; int don; - unsigned long flags; ESPLOG(("esp%d: Aborting command\n", esp->esp_id)); esp_dump_state(esp, eregs); @@ -1403,16 +1374,13 @@ * in the driver and timeout because the eventual phase change * will cause the ESP to (eventually) give an interrupt. */ - save_and_cli(flags); if(esp->current_SC == SCptr) { esp->cur_msgout[0] = ABORT; esp->msgout_len = 1; esp->msgout_ctr = 0; esp_cmd(esp, eregs, ESP_CMD_SATN); - restore_flags(flags); return SCSI_ABORT_PENDING; } - restore_flags(flags); /* If it is still in the issue queue then we can safely * call the completion routine and report abort success. @@ -1431,6 +1399,7 @@ if(this == SCptr) { *prev = (Scsi_Cmnd *) this->host_scribble; this->host_scribble = NULL; + esp_release_dmabufs(esp, this); this->result = DID_ABORT << 16; this->done(this); if(don) @@ -1445,8 +1414,11 @@ * on the bus at this time. So, we let the SCSI code wait * a little bit and try again later. */ - if(esp->current_SC) + if(esp->current_SC) { + if(don) + esp->dma_ints_on(esp); return SCSI_ABORT_BUSY; + } /* It's disconnected, we have to reconnect to re-establish * the nexus and tell the device to abort. However, we really @@ -1455,20 +1427,68 @@ * happens, we are really hung so reset the bus. */ + if(don) + esp->dma_ints_on(esp); return SCSI_ABORT_SNOOZE; } +/* We've sent ESP_CMD_RS to the ESP, the interrupt had just + * arrived indicating the end of the SCSI bus reset. Our job + * is to clean out the command queues and begin re-execution + * of SCSI commands once more. + */ +static int esp_finish_reset(struct NCR_ESP *esp, + struct ESP_regs *eregs) +{ + Scsi_Cmnd *sp = esp->current_SC; + + /* Clean up currently executing command, if any. */ + if (sp != NULL) { + esp_release_dmabufs(esp, sp); + sp->result = (DID_RESET << 16); + sp->scsi_done(sp); + esp->current_SC = NULL; + } + + /* Clean up disconnected queue, they have been invalidated + * by the bus reset. + */ + if (esp->disconnected_SC) { + while((sp = remove_first_SC(&esp->disconnected_SC)) != NULL) { + esp_release_dmabufs(esp, sp); + sp->result = (DID_RESET << 16); + sp->scsi_done(sp); + } + } + + /* SCSI bus reset is complete. */ + esp->resetting_bus = 0; + + /* Ok, now it is safe to get commands going once more. */ + if(esp->issue_SC) + esp_exec_cmd(esp); + + return do_intr_end; +} + +static int esp_do_resetbus(struct NCR_ESP *esp, + struct ESP_regs *eregs) +{ + ESPLOG(("esp%d: Resetting scsi bus\n", esp->esp_id)); + esp->resetting_bus = 1; + esp_cmd(esp, eregs, ESP_CMD_RS); + + return do_intr_end; +} + /* Reset ESP chip, reset hanging bus, then kill active and * disconnected commands for targets without soft reset. */ int esp_reset(Scsi_Cmnd *SCptr, unsigned int how) { struct NCR_ESP *esp = (struct NCR_ESP *) SCptr->host->hostdata; - struct ESP_regs *eregs = esp->eregs; - ESPLOG(("esp%d: Resetting scsi bus\n", esp->esp_id)); - esp->resetting_bus = 1; - esp_cmd(esp, eregs, ESP_CMD_RS); + (void) esp_do_resetbus(esp, esp->eregs); return SCSI_RESET_PENDING; } @@ -1478,36 +1498,15 @@ Scsi_Cmnd *done_SC; if(esp->current_SC) { - unsigned long flags; - done_SC = esp->current_SC; esp->current_SC = NULL; - - /* Free dvma entry. */ - if(!done_SC->use_sg) { - if (esp->dma_mmu_release_scsi_one) - esp->dma_mmu_release_scsi_one (esp, done_SC); - } else { -#ifdef DEBUG_ESP_SG - printk("esp%d: unmapping sg ", esp->esp_id); -#endif - if (esp->dma_mmu_release_scsi_sgl) - esp->dma_mmu_release_scsi_sgl (esp, done_SC); -#ifdef DEBUG_ESP_SG - printk("done.\n"); -#endif - } - + esp_release_dmabufs(esp, done_SC); done_SC->result = error; done_SC->scsi_done(done_SC); - save_and_cli(flags); - /* Bus is free, issue any commands in the queue. */ if(esp->issue_SC && !esp->current_SC) esp_exec_cmd(esp); - - restore_flags(flags); } else { /* Panic is safe as current_SC is null so we may still * be able to accept more commands to sync disk buffers. @@ -1519,11 +1518,6 @@ /* Wheee, ESP interrupt engine. */ -enum { - do_phase_determine, do_reset_bus, do_reset_complete, - do_work_bus, do_intr_end, -}; - /* Forward declarations. */ static int esp_do_phase_determine(struct NCR_ESP *esp, struct ESP_regs *eregs); @@ -1535,67 +1529,8 @@ static int esp_do_msgout(struct NCR_ESP *esp, struct ESP_regs *eregs); static int esp_do_cmdbegin(struct NCR_ESP *esp, struct ESP_regs *eregs); -static inline int sreg_datainp(unchar sreg) -{ - return (sreg & ESP_STAT_PMASK) == ESP_DIP; -} - -static inline int sreg_dataoutp(unchar sreg) -{ - return (sreg & ESP_STAT_PMASK) == ESP_DOP; -} - -/* Did they drop these fabs on the floor or what?!?!! */ -static inline void hme_fifo_hwbug_workaround(struct NCR_ESP *esp, - struct ESP_regs *eregs) -{ - unchar status = esp->sreg; - - /* Cannot safely frob the fifo for these following cases. */ - if(sreg_datainp(status) || sreg_dataoutp(status) || - (esp->current_SC && esp->current_SC->SCp.phase == in_data_done)) { - ESPHME(("")); - return; - } else { - unsigned long count = 0; - unsigned long fcnt = GETREG(eregs->esp_fflags) & ESP_FF_FBYTES; - - /* The HME stores bytes in multiples of 2 in the fifo. */ - ESPHME(("hme_fifo[fcnt=%d", (int)fcnt)); - while(fcnt) { - esp->hme_fifo_workaround_buffer[count++] = - GETREG(eregs->esp_fdata); - esp->hme_fifo_workaround_buffer[count++] = - GETREG(eregs->esp_fdata); - ESPHME(("<%02x,%02x>", esp->hme_fifo_workaround_buffer[count-2], esp->hme_fifo_workaround_buffer[count-1])); - fcnt--; - } - if(GETREG(eregs->esp_status2) & ESP_STAT2_F1BYTE) { - ESPHME(("")); - SETREG(eregs->esp_fdata, 0); - esp->hme_fifo_workaround_buffer[count++] = - GETREG(eregs->esp_fdata); - ESPHME(("<%02x,0x00>", esp->hme_fifo_workaround_buffer[count-1])); - ESPHME(("CMD_FLUSH")); - esp_cmd(esp, eregs, ESP_CMD_FLUSH); - } else { - ESPHME(("no_xtra_byte")); - } - esp->hme_fifo_workaround_count = count; - ESPHME(("wkarnd_cnt=%d]", (int)count)); - } -} - -static inline void hme_fifo_push(struct NCR_ESP *esp, struct ESP_regs *eregs, - unchar *bytes, unchar count) -{ - esp_cmd(esp, eregs, ESP_CMD_FLUSH); - while(count) { - SETREG(eregs->esp_fdata, *bytes++); - SETREG(eregs->esp_fdata, 0); - count--; - } -} +#define sreg_datainp(__sreg) (((__sreg) & ESP_STAT_PMASK) == ESP_DIP) +#define sreg_dataoutp(__sreg) (((__sreg) & ESP_STAT_PMASK) == ESP_DOP) /* We try to avoid some interrupts by jumping ahead and see if the ESP * has gotten far enough yet. Hence the following. @@ -1608,20 +1543,8 @@ if(esp->dma_irq_p(esp)) { /* Yes, we are able to save an interrupt. */ - esp->sreg = GETREG(eregs->esp_status); - if(esp->erev == fashme) { - /* This chip is really losing. */ - ESPHME(("HME[")); - /* Must latch fifo before reading the interrupt - * register else garbage ends up in the FIFO - * which confuses the driver utterly. - * Happy Meal indeed.... - */ - ESPHME(("fifo_workaround]")); - hme_fifo_hwbug_workaround(esp, eregs); - } - esp->ireg = GETREG(eregs->esp_intrpt); - esp->sreg &= ~(ESP_STAT_INTR); + esp->sreg = (esp_read(eregs->esp_status) & ~(ESP_STAT_INTR)); + esp->ireg = esp_read(eregs->esp_intrpt); if(!(esp->ireg & ESP_INTR_SR)) return 0; else @@ -1642,21 +1565,8 @@ return 0; if(esp->dma_irq_p(esp)) { /* Yes, we are able to save an interrupt. */ - esp->sreg = GETREG(eregs->esp_status); - if(esp->erev == fashme) { - /* This chip is really losing. */ - ESPHME(("HME[")); - - /* Must latch fifo before reading the interrupt - * register else garbage ends up in the FIFO - * which confuses the driver utterly. - * Happy Meal indeed.... - */ - ESPHME(("fifo_workaround]")); - hme_fifo_hwbug_workaround(esp, eregs); - } - esp->ireg = GETREG(eregs->esp_intrpt); - esp->sreg &= ~(ESP_STAT_INTR); + esp->sreg = (esp_read(eregs->esp_status) & ~(ESP_STAT_INTR)); + esp->ireg = esp_read(eregs->esp_intrpt); if(!(esp->ireg & ESP_INTR_SR)) return 0; else @@ -1667,56 +1577,31 @@ return do_intr_end; } -/* Misc. esp helper routines. */ -static inline void esp_setcount(struct ESP_regs *eregs, int cnt, int hme) -{ - SETREG(eregs->esp_tclow, (cnt & 0xff)); - SETREG(eregs->esp_tcmed, ((cnt >> 8) & 0xff)); - if(hme) { - SETREG(eregs->fas_rlo, 0); - SETREG(eregs->fas_rhi, 0); - } -} - -static inline int esp_getcount(struct ESP_regs *eregs) -{ - return (((GETREG(eregs->esp_tclow))&0xff) | - (((GETREG(eregs->esp_tcmed))&0xff) << 8)); -} +/* Misc. esp helper macros. */ +#define esp_setcount(__eregs, __cnt) \ + esp_write((__eregs)->esp_tclow, ((__cnt) & 0xff)); \ + esp_write((__eregs)->esp_tcmed, (((__cnt) >> 8) & 0xff)) + +#define esp_getcount(__eregs) \ + ((esp_read((__eregs)->esp_tclow)&0xff) | \ + ((esp_read((__eregs)->esp_tcmed)&0xff) << 8)) -static inline int fcount(struct NCR_ESP *esp, struct ESP_regs *eregs) -{ - if(esp->erev == fashme) - return esp->hme_fifo_workaround_count; - else - return GETREG(eregs->esp_fflags) & ESP_FF_FBYTES; -} +#define fcount(__esp, __eregs) \ + (esp_read((__eregs)->esp_fflags) & ESP_FF_FBYTES) -static inline int fnzero(struct NCR_ESP *esp, struct ESP_regs *eregs) -{ - if(esp->erev == fashme) - return 0; - else - return GETREG(eregs->esp_fflags) & ESP_FF_ONOTZERO; -} +#define fnzero(__esp, __eregs) \ + (esp_read((__eregs)->esp_fflags) & ESP_FF_ONOTZERO) /* XXX speculative nops unnecessary when continuing amidst a data phase * XXX even on esp100!!! another case of flooding the bus with I/O reg * XXX writes... */ -static inline void esp_maybe_nop(struct NCR_ESP *esp, struct ESP_regs *eregs) -{ - if(esp->erev == esp100) - esp_cmd(esp, eregs, ESP_CMD_NULL); -} +#define esp_maybe_nop(__esp, __eregs) \ + if((__esp)->erev == esp100) \ + esp_cmd((__esp), (__eregs), ESP_CMD_NULL) -static inline int sreg_to_dataphase(unchar sreg) -{ - if((sreg & ESP_STAT_PMASK) == ESP_DOP) - return in_dataout; - else - return in_datain; -} +#define sreg_to_dataphase(__sreg) \ + ((((__sreg) & ESP_STAT_PMASK) == ESP_DOP) ? in_dataout : in_datain) /* The ESP100 when in synchronous data phase, can mistake a long final * REQ pulse from the target as an extra byte, it places whatever is on @@ -1731,8 +1616,8 @@ { /* Do not touch this piece of code. */ if((!(esp->erev == esp100)) || - (!(sreg_datainp((esp->sreg = GETREG(eregs->esp_status))) && !fifocnt) - && !(sreg_dataoutp(esp->sreg) && !fnzero(esp, eregs)))) { + (!(sreg_datainp((esp->sreg = esp_read(eregs->esp_status))) && !fifocnt) && + !(sreg_dataoutp(esp->sreg) && !fnzero(esp, eregs)))) { if(sp->SCp.phase == in_dataout) esp_cmd(esp, eregs, ESP_CMD_FLUSH); return 0; @@ -1759,7 +1644,7 @@ if(esp->erev != esp100) return 0; - junk = GETREG(eregs->esp_intrpt); + junk = esp_read(eregs->esp_intrpt); if(junk & ESP_INTR_SR) return 1; @@ -1775,24 +1660,14 @@ if(2 != fcount(esp, eregs)) return -1; - if(esp->erev == fashme) { - /* HME does not latch it's own BUS ID bits during - * a reselection. Also the target number is given - * as an unsigned char, not as a sole bit number - * like the other ESP's do. - * Happy Meal indeed.... - */ - targ = esp->hme_fifo_workaround_buffer[0]; - } else { - it = GETREG(eregs->esp_fdata); - if(!(it & me)) - return -1; - it &= ~me; - if(it & (it - 1)) - return -1; - while(!(it & 1)) - targ++, it >>= 1; - } + it = esp_read(eregs->esp_fdata); + if(!(it & me)) + return -1; + it &= ~me; + if(it & (it - 1)) + return -1; + while(!(it & 1)) + targ++, it >>= 1; return targ; } @@ -1805,14 +1680,20 @@ if((esp->sreg & ESP_STAT_PMASK) != ESP_MIP) return -1; - if(esp->erev == fashme) - lun = esp->hme_fifo_workaround_buffer[1]; - else - lun = GETREG(eregs->esp_fdata); + lun = esp_read(eregs->esp_fdata); + + /* Yes, you read this correctly. We report lun of zero + * if we see parity error. ESP reports parity error for + * the lun byte, and this is the only way to hope to recover + * because the target is connected. + */ if(esp->sreg & ESP_STAT_PERR) return 0; + + /* Check for illegal bits being set in the lun. */ if((lun & 0x40) || !(lun & 0x80)) return -1; + return lun & 7; } @@ -1823,13 +1704,20 @@ Scsi_Cmnd *sp) { Scsi_Device *dp = sp->device; - SETREG(eregs->esp_soff, dp->sync_max_offset); - SETREG(eregs->esp_stp, dp->sync_min_period); - if(esp->erev > esp100a) - SETREG(eregs->esp_cfg3, esp->config3[sp->target]); - if(esp->erev == fashme) - SETREG(eregs->esp_busid, (sp->target & 0xf) | - (ESP_BUSID_RESELID | ESP_BUSID_CTR32BIT)); + + if(esp->prev_soff != dp->sync_max_offset || + esp->prev_stp != dp->sync_min_period || + (esp->erev > esp100a && + esp->prev_cfg3 != esp->config3[sp->target])) { + esp->prev_soff = dp->sync_max_offset; + esp_write(eregs->esp_soff, esp->prev_soff); + esp->prev_stp = dp->sync_min_period; + esp_write(eregs->esp_stp, esp->prev_stp); + if(esp->erev > esp100a) { + esp->prev_cfg3 = esp->config3[sp->target]; + esp_write(eregs->esp_cfg3, esp->prev_cfg3); + } + } esp->current_SC = sp; } @@ -1839,8 +1727,8 @@ static inline void esp_reconnect(struct NCR_ESP *esp, Scsi_Cmnd *sp) { if(!esp->disconnected_SC) - printk("esp%d: Weird, being reselected but disconnected " - "command queue is empty.\n", esp->esp_id); + ESPLOG(("esp%d: Weird, being reselected but disconnected " + "command queue is empty.\n", esp->esp_id)); esp->snip = 0; esp->current_SC = 0; sp->SCp.phase = not_issued; @@ -1848,12 +1736,9 @@ } /* Begin message in phase. */ -static inline int esp_do_msgin(struct NCR_ESP *esp, struct ESP_regs *eregs) +static int esp_do_msgin(struct NCR_ESP *esp, struct ESP_regs *eregs) { - /* Must be very careful with the fifo on the HME */ - if((esp->erev != fashme) || !(GETREG(eregs->esp_status2) & - ESP_STAT2_FEMPTY)) - esp_cmd(esp, eregs, ESP_CMD_FLUSH); + esp_cmd(esp, eregs, ESP_CMD_FLUSH); esp_maybe_nop(esp, eregs); esp_cmd(esp, eregs, ESP_CMD_TI); esp->msgin_len = 1; @@ -1867,10 +1752,10 @@ ++sp->SCp.buffer; --sp->SCp.buffers_residual; sp->SCp.this_residual = sp->SCp.buffer->length; - if (esp->dma_advance_sg) - esp->dma_advance_sg (sp); - else - sp->SCp.ptr = (char *)virt_to_phys(sp->SCp.buffer->address); + if (esp->dma_advance_sg) + esp->dma_advance_sg (sp); + else + sp->SCp.ptr = (char *)virt_to_phys(sp->SCp.buffer->address); } /* Please note that the way I've coded these routines is that I _always_ @@ -1891,8 +1776,7 @@ * within a buffer or sub-buffer should not upset us at all no matter * how bad the target and/or ESP fucks things up. */ - -static inline int esp_do_data(struct NCR_ESP *esp, struct ESP_regs *eregs) +static int esp_do_data(struct NCR_ESP *esp, struct ESP_regs *eregs) { Scsi_Cmnd *SCptr = esp->current_SC; int thisphase, hmuch; @@ -1903,31 +1787,204 @@ esp_advance_phase(SCptr, thisphase); ESPDATA(("newphase<%s> ", (thisphase == in_datain) ? "DATAIN" : "DATAOUT")); hmuch = esp->dma_can_transfer(esp, SCptr); - ESPDATA(("hmuch<%d> ", hmuch)); - esp->current_transfer_size = hmuch; - if(esp->erev == fashme) { - /* Touchy chip, this stupid HME scsi adapter... */ - esp_setcount(eregs, hmuch, 1); - esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI); - if(thisphase == in_datain) - esp->dma_init_read(esp, (__u32)((unsigned long)SCptr->SCp.ptr), hmuch); - else - esp->dma_init_write(esp, (__u32)((unsigned long)SCptr->SCp.ptr), hmuch); - } else { - esp_setcount(eregs, hmuch, 0); - esp->dma_setup(esp, - (__u32)((unsigned long)SCptr->SCp.ptr), + /* + * XXX MSch: cater for PIO transfer here; PIO used if hmuch == 0 + */ + if (hmuch) { /* DMA */ + /* + * DMA + */ + ESPDATA(("hmuch<%d> ", hmuch)); + esp->current_transfer_size = hmuch; + esp_setcount(eregs, (esp->fas_premature_intr_workaround ? + (hmuch + 0x40) : hmuch)); + esp->dma_setup(esp, (__u32)((unsigned long)SCptr->SCp.ptr), hmuch, (thisphase == in_datain)); ESPDATA(("DMA|TI --> do_intr_end\n")); esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI); - } + return do_intr_end; + /* + * end DMA + */ + } else { + /* + * PIO + */ + int oldphase, i = 0; /* or where we left off last time ?? esp->current_data ?? */ + int fifocnt = 0; + + oldphase = esp_read(eregs->esp_status) & ESP_STAT_PMASK; + + /* + * polled transfer; ugly, can we make this happen in a DRQ + * interrupt handler ?? + * requires keeping track of state information in host or + * command struct! + * Problem: I've never seen a DRQ happen on Mac, not even + * with ESP_CMD_DMA ... + */ + + /* figure out how much needs to be transfered */ + hmuch = SCptr->SCp.this_residual; + ESPDATA(("hmuch<%d> pio ", hmuch)); + esp->current_transfer_size = hmuch; + + /* tell the ESP ... */ + esp_setcount(eregs, hmuch); + + /* loop */ + while (hmuch) { + int j, fifo_stuck = 0, newphase; + unsigned long flags, timeout; +#if 0 + if ( i % 10 ) + ESPDATA(("\r")); + else + ESPDATA(( /*"\n"*/ "\r")); +#endif + save_flags(flags); +#if 0 + cli(); +#endif + if(thisphase == in_datain) { + /* 'go' ... */ + esp_cmd(esp, eregs, ESP_CMD_TI); + + /* wait for data */ + timeout = 1000000; + while (!((esp->sreg=esp_read(eregs->esp_status)) & ESP_STAT_INTR) && --timeout) + udelay(2); + if (timeout == 0) + printk("DRQ datain timeout! \n"); + + newphase = esp->sreg & ESP_STAT_PMASK; + + /* see how much we got ... */ + fifocnt = (esp_read(eregs->esp_fflags) & ESP_FF_FBYTES); + + if (!fifocnt) + fifo_stuck++; + else + fifo_stuck = 0; + + ESPDATA(("\rgot %d st %x ph %x", fifocnt, esp->sreg, newphase)); + + /* read fifo */ + for(j=0;jSCp.ptr[i++] = esp_read(eregs->esp_fdata); + + ESPDATA(("(%d) ", i)); + + /* how many to go ?? */ + hmuch -= fifocnt; + + /* break if status phase !! */ + if(newphase == ESP_STATP) { + /* clear int. */ + esp->ireg = esp_read(eregs->esp_intrpt); + break; + } + } else { +#define MAX_FIFO 8 + /* how much will fit ? */ + int this_count = MAX_FIFO - fifocnt; + if (this_count > hmuch) + this_count = hmuch; + + /* fill fifo */ + for(j=0;jesp_fdata, SCptr->SCp.ptr[i++]); + + /* how many left if this goes out ?? */ + hmuch -= this_count; + + /* 'go' ... */ + esp_cmd(esp, eregs, ESP_CMD_TI); + + /* wait for 'got it' */ + timeout = 1000000; + while (!((esp->sreg=esp_read(eregs->esp_status)) & ESP_STAT_INTR) && --timeout) + udelay(2); + if (timeout == 0) + printk("DRQ dataout timeout! \n"); + + newphase = esp->sreg & ESP_STAT_PMASK; + + /* need to check how much was sent ?? */ + fifocnt = (esp_read(eregs->esp_fflags) & ESP_FF_FBYTES); + + ESPDATA(("\rsent %d st %x ph %x", this_count - fifocnt, esp->sreg, newphase)); + + ESPDATA(("(%d) ", i)); + + /* break if status phase !! */ + if(newphase == ESP_STATP) { + /* clear int. */ + esp->ireg = esp_read(eregs->esp_intrpt); + break; + } + + } + + /* clear int. */ + esp->ireg = esp_read(eregs->esp_intrpt); + + ESPDATA(("ir %x ... ", esp->ireg)); + + if (hmuch == 0) + ESPDATA(("done! \n")); + + restore_flags(flags); + + /* check new bus phase */ + if (newphase != oldphase && i < esp->current_transfer_size) { + /* something happened; disconnect ?? */ + ESPDATA(("phase change, dropped out with %d done ... ", i)); + break; + } + + /* check int. status */ + if (esp->ireg & ESP_INTR_DC) { + /* disconnect */ + ESPDATA(("disconnect; %d transfered ... ", i)); + break; + } else if (esp->ireg & ESP_INTR_FDONE) { + /* function done */ + ESPDATA(("function done; %d transfered ... ", i)); + break; + } + + /* XXX fixme: bail out on stall */ + if (fifo_stuck > 10) { + /* we're stuck */ + ESPDATA(("fifo stall; %d transfered ... ", i)); + break; + } + } + + ESPDATA(("\n")); + /* check successful completion ?? */ + + if (thisphase == in_dataout) + hmuch += fifocnt; /* stuck?? adjust data pointer ...*/ + + /* tell do_data_finale how much was transfered */ + esp->current_transfer_size -= hmuch; + + /* still not completely sure on this one ... */ + return /*do_intr_end*/ do_work_bus /*do_phase_determine*/ ; + + /* + * end PIO + */ + } return do_intr_end; } /* See how successful the data transfer was. */ -static inline int esp_do_data_finale(struct NCR_ESP *esp, - struct ESP_regs *eregs) +static int esp_do_data_finale(struct NCR_ESP *esp, + struct ESP_regs *eregs) { Scsi_Cmnd *SCptr = esp->current_SC; int bogus_data = 0, bytes_sent = 0, fifocnt, ecount = 0; @@ -1963,77 +2020,83 @@ return esp_do_phase_determine(esp, eregs); } - /* Check for partial transfers and other horrible events. - * Note, here we read the real fifo flags register even - * on HME broken adapters because we skip the HME fifo - * workaround code in esp_handle() if we are doing data - * phase things. We don't want to fuck directly with - * the fifo like that, especially if doing syncronous - * transfers! Also, will need to double the count on - * HME if we are doing wide transfers, as the HME fifo - * will move and count 16-bit quantities during wide data. - * SMCC _and_ Qlogic can both bite me. - */ - fifocnt = GETREG(eregs->esp_fflags) & ESP_FF_FBYTES; - if(esp->erev != fashme) - ecount = esp_getcount(eregs); + /* Check for partial transfers and other horrible events. */ + fifocnt = (esp_read(eregs->esp_fflags) & ESP_FF_FBYTES); + ecount = esp_getcount(eregs); + if(esp->fas_premature_intr_workaround) + ecount -= 0x40; bytes_sent = esp->current_transfer_size; - /* Uhhh, might not want both of these conditionals to run - * at once on HME due to the fifo problems it has. Consider - * changing it to: - * - * if(!(esp->sreg & ESP_STAT_TCNT)) { - * bytes_sent -= ecount; - * } else if(SCptr->SCp.phase == in_dataout) { - * bytes_sent -= fifocnt; - * } - * - * But only for the HME case, leave the current code alone - * for all other ESP revisions as we know the existing code - * works just fine for them. - */ ESPDATA(("trans_sz=%d, ", bytes_sent)); - if(esp->erev == fashme) { - if(!(esp->sreg & ESP_STAT_TCNT)) { - bytes_sent -= esp_getcount(eregs); - } else if(SCptr->SCp.phase == in_dataout) { - bytes_sent -= fifocnt; - } - } else { - if(!(esp->sreg & ESP_STAT_TCNT)) - bytes_sent -= ecount; - if(SCptr->SCp.phase == in_dataout) - bytes_sent -= fifocnt; - } + if(!(esp->sreg & ESP_STAT_TCNT)) + bytes_sent -= ecount; + if(SCptr->SCp.phase == in_dataout) + bytes_sent -= fifocnt; - ESPDATA(("bytes_sent=%d, ", bytes_sent)); + ESPDATA(("bytes_sent=%d (ecount=%d, fifocnt=%d), ", bytes_sent, + ecount, fifocnt)); /* If we were in synchronous mode, check for peculiarities. */ - if(esp->erev == fashme) { - if(SCptr->device->sync_max_offset) { - if(SCptr->SCp.phase == in_dataout) - esp_cmd(esp, eregs, ESP_CMD_FLUSH); - } else { - esp_cmd(esp, eregs, ESP_CMD_FLUSH); - } - } else { - if(SCptr->device->sync_max_offset) - bogus_data = esp100_sync_hwbug(esp, eregs, SCptr, fifocnt); - else - esp_cmd(esp, eregs, ESP_CMD_FLUSH); - } + if(SCptr->device->sync_max_offset) + bogus_data = esp100_sync_hwbug(esp, eregs, SCptr, fifocnt); + else + esp_cmd(esp, eregs, ESP_CMD_FLUSH); /* Until we are sure of what has happened, we are certainly * in the dark. */ esp_advance_phase(SCptr, in_the_dark); + /* Check for premature interrupt condition. Can happen on FAS2x6 + * chips. QLogic recommends a workaround by overprogramming the + * transfer counters, but this makes doing scatter-gather impossible. + * Until there is a way to disable scatter-gather for a single target, + * and not only for the entire host adapter as it is now, the workaround + * is way to expensive performance wise. + * Instead, it turns out that when this happens the target has disconnected + * allready but it doesn't show in the interrupt register. Compensate for + * that here to try and avoid a SCSI bus reset. + */ + if(!esp->fas_premature_intr_workaround && (fifocnt == 1) && + sreg_dataoutp(esp->sreg)) { + ESPLOG(("esp%d: Premature interrupt, enabling workaround\n", + esp->esp_id)); +#if 0 + /* Disable scatter-gather operations, they are not possible + * when using this workaround. + */ + esp->ehost->sg_tablesize = 0; + esp->ehost->use_clustering = ENABLE_CLUSTERING; + esp->fas_premature_intr_workaround = 1; + bytes_sent = 0; + if(SCptr->use_sg) { + ESPLOG(("esp%d: Aborting scatter-gather operation\n", + esp->esp_id)); + esp->cur_msgout[0] = ABORT; + esp->msgout_len = 1; + esp->msgout_ctr = 0; + esp_cmd(esp, eregs, ESP_CMD_SATN); + esp_setcount(eregs, 0xffff); + esp_cmd(esp, eregs, ESP_CMD_NULL); + esp_cmd(esp, eregs, ESP_CMD_TPAD | ESP_CMD_DMA); + return do_intr_end; + } +#else + /* Just set the disconnected bit. That's what appears to + * happen anyway. The state machine will pick it up when + * we return. + */ + esp->ireg |= ESP_INTR_DC; +#endif + } + if(bytes_sent < 0) { /* I've seen this happen due to lost state in this * driver. No idea why it happened, but allowing * this value to be negative caused things to * lock up. This allows greater chance of recovery. + * In fact every time I've seen this, it has been + * a driver bug without question. */ ESPLOG(("esp%d: yieee, bytes_sent < 0!\n", esp->esp_id)); ESPLOG(("esp%d: csz=%d fifocount=%d ecount=%d\n", @@ -2042,6 +2105,10 @@ ESPLOG(("esp%d: use_sg=%d ptr=%p this_residual=%d\n", esp->esp_id, SCptr->use_sg, SCptr->SCp.ptr, SCptr->SCp.this_residual)); + ESPLOG(("esp%d: Forcing async for target %d\n", esp->esp_id, + SCptr->target)); + SCptr->device->borken = 1; + SCptr->device->sync = 0; bytes_sent = 0; } @@ -2050,7 +2117,7 @@ SCptr->SCp.this_residual -= bytes_sent; if(SCptr->SCp.this_residual < 0) { /* shit */ - printk("esp%d: Data transfer overrun.\n", esp->esp_id); + ESPLOG(("esp%d: Data transfer overrun.\n", esp->esp_id)); SCptr->SCp.this_residual = 0; } @@ -2066,13 +2133,15 @@ * imagine the hell I went through trying to * figure this out. */ - if(SCptr->use_sg && !SCptr->SCp.this_residual) + if(!SCptr->SCp.this_residual && SCptr->SCp.buffers_residual) advance_sg(esp, SCptr); +#ifdef DEBUG_ESP_DATA if(sreg_datainp(esp->sreg) || sreg_dataoutp(esp->sreg)) { ESPDATA(("to more data\n")); - return esp_do_data(esp, eregs); + } else { + ESPDATA(("to new phase\n")); } - ESPDATA(("to new phase\n")); +#endif return esp_do_phase_determine(esp, eregs); } /* Bogus data, just wait for next interrupt. */ @@ -2081,10 +2150,48 @@ return do_intr_end; } +/* We received a non-good status return at the end of + * running a SCSI command. This is used to decide if + * we should clear our synchronous transfer state for + * such a device when that happens. + * + * The idea is that when spinning up a disk or rewinding + * a tape, we don't want to go into a loop re-negotiating + * synchronous capabilities over and over. + */ +static int esp_should_clear_sync(Scsi_Cmnd *sp) +{ + unchar cmd1 = sp->cmnd[0]; + unchar cmd2 = sp->data_cmnd[0]; + + /* These cases are for spinning up a disk and + * waiting for that spinup to complete. + */ + if(cmd1 == START_STOP || + cmd2 == START_STOP) + return 0; + + if(cmd1 == TEST_UNIT_READY || + cmd2 == TEST_UNIT_READY) + return 0; + + /* One more special case for SCSI tape drives, + * this is what is used to probe the device for + * completion of a rewind or tape load operation. + */ + if(sp->device->type == TYPE_TAPE) { + if(cmd1 == MODE_SENSE || + cmd2 == MODE_SENSE) + return 0; + } + + return 1; +} + /* Either a command is completing or a target is dropping off the bus * to continue the command in the background so we can do other work. */ -static inline int esp_do_freebus(struct NCR_ESP *esp, struct ESP_regs *eregs) +static int esp_do_freebus(struct NCR_ESP *esp, struct ESP_regs *eregs) { Scsi_Cmnd *SCptr = esp->current_SC; int rval; @@ -2101,12 +2208,14 @@ esp->prevmsgout = NOP; if(esp->prevmsgin == COMMAND_COMPLETE) { /* Normal end of nexus. */ - if(esp->disconnected_SC || (esp->erev == fashme)) + if(esp->disconnected_SC) esp_cmd(esp, eregs, ESP_CMD_ESEL); - if(SCptr->SCp.Status != GOOD && SCptr->SCp.Status != CONDITION_GOOD && + if(SCptr->SCp.Status != GOOD && + SCptr->SCp.Status != CONDITION_GOOD && ((1<target) & esp->targets_present) && - SCptr->device->sync && SCptr->device->sync_max_offset) { + SCptr->device->sync && + SCptr->device->sync_max_offset) { /* SCSI standard says that the synchronous capabilities * should be renegotiated at this point. Most likely * we are about to request sense from this target @@ -2123,15 +2232,7 @@ * can report not ready many times right after * loading up a tape. */ - if(SCptr->cmnd[0] != START_STOP && - SCptr->data_cmnd[0] != START_STOP && - SCptr->cmnd[0] != TEST_UNIT_READY && - SCptr->data_cmnd[0] != TEST_UNIT_READY && - !(SCptr->device->type == TYPE_TAPE && - (SCptr->cmnd[0] == TEST_UNIT_READY || - SCptr->data_cmnd[0] == TEST_UNIT_READY || - SCptr->cmnd[0] == MODE_SENSE || - SCptr->data_cmnd[0] == MODE_SENSE))) + if(esp_should_clear_sync(SCptr) != 0) SCptr->device->sync = 0; } ESPDISC(("F<%02x,%02x>", SCptr->target, SCptr->lun)); @@ -2158,9 +2259,43 @@ return do_intr_end; } +/* When a reselect occurs, and we cannot find the command to + * reconnect to in our queues, we do this. + */ +static int esp_bad_reconnect(struct NCR_ESP *esp) +{ + Scsi_Cmnd *sp; + + ESPLOG(("esp%d: Eieeee, reconnecting unknown command!\n", + esp->esp_id)); + ESPLOG(("QUEUE DUMP\n")); + sp = esp->issue_SC; + ESPLOG(("esp%d: issue_SC[", esp->esp_id)); + while(sp) { + ESPLOG(("<%02x,%02x>", sp->target, sp->lun)); + sp = (Scsi_Cmnd *) sp->host_scribble; + } + ESPLOG(("]\n")); + sp = esp->current_SC; + ESPLOG(("esp%d: current_SC[", esp->esp_id)); + while(sp) { + ESPLOG(("<%02x,%02x>", sp->target, sp->lun)); + sp = (Scsi_Cmnd *) sp->host_scribble; + } + ESPLOG(("]\n")); + sp = esp->disconnected_SC; + ESPLOG(("esp%d: disconnected_SC[", esp->esp_id)); + while(sp) { + ESPLOG(("<%02x,%02x>", sp->target, sp->lun)); + sp = (Scsi_Cmnd *) sp->host_scribble; + } + ESPLOG(("]\n")); + return do_reset_bus; +} + /* Do the needy when a target tries to reconnect to us. */ -static inline int esp_do_reconnect(struct NCR_ESP *esp, - struct ESP_regs *eregs) +static int esp_do_reconnect(struct NCR_ESP *esp, + struct ESP_regs *eregs) { int lun, target; Scsi_Cmnd *SCptr; @@ -2180,53 +2315,21 @@ /* Things look ok... */ ESPDISC(("R<%02x,%02x>", target, lun)); - /* Must flush both FIFO and the DVMA on HME. */ - if(esp->erev == fashme) { - /* XXX this still doesn't fix the problem... */ - esp_cmd(esp, eregs, ESP_CMD_FLUSH); - if(esp->dma_invalidate) - esp->dma_invalidate(esp); - } else { - esp_cmd(esp, eregs, ESP_CMD_FLUSH); - if(esp100_reconnect_hwbug(esp, eregs)) - return do_reset_bus; - esp_cmd(esp, eregs, ESP_CMD_NULL); - } + esp_cmd(esp, eregs, ESP_CMD_FLUSH); + if(esp100_reconnect_hwbug(esp, eregs)) + return do_reset_bus; + esp_cmd(esp, eregs, ESP_CMD_NULL); SCptr = remove_SC(&esp->disconnected_SC, (unchar) target, (unchar) lun); - if(!SCptr) { - Scsi_Cmnd *sp; + if(!SCptr) + return esp_bad_reconnect(esp); - ESPLOG(("esp%d: Eieeee, reconnecting unknown command!\n", - esp->esp_id)); - ESPLOG(("QUEUE DUMP\n")); - sp = esp->issue_SC; - ESPLOG(("esp%d: issue_SC[", esp->esp_id)); - while(sp) { - ESPLOG(("<%02x,%02x>", sp->target, sp->lun)); - sp = (Scsi_Cmnd *) sp->host_scribble; - } - ESPLOG(("]\n")); - sp = esp->current_SC; - ESPLOG(("esp%d: current_SC[", esp->esp_id)); - while(sp) { - ESPLOG(("<%02x,%02x>", sp->target, sp->lun)); - sp = (Scsi_Cmnd *) sp->host_scribble; - } - ESPLOG(("]\n")); - sp = esp->disconnected_SC; - ESPLOG(("esp%d: disconnected_SC[", esp->esp_id)); - while(sp) { - ESPLOG(("<%02x,%02x>", sp->target, sp->lun)); - sp = (Scsi_Cmnd *) sp->host_scribble; - } - ESPLOG(("]\n")); - return do_reset_bus; - } esp_connect(esp, eregs, SCptr); esp_cmd(esp, eregs, ESP_CMD_MOK); - /* No need for explicit restore pointers operation. */ + /* Reconnect implies a restore pointers operation. */ + esp_restore_pointers(esp, SCptr); + esp->snip = 0; esp_advance_phase(SCptr, in_the_dark); return do_intr_end; @@ -2348,121 +2451,132 @@ } } -/* The target has control of the bus and we have to see where it has - * taken us. - */ -static int esp_do_phase_determine(struct NCR_ESP *esp, - struct ESP_regs *eregs) +static int esp_enter_status(struct NCR_ESP *esp, + struct ESP_regs *eregs) { - Scsi_Cmnd *SCptr = esp->current_SC; + unchar thecmd = ESP_CMD_ICCSEQ; - ESPPHASE(("esp_do_phase_determine: ")); - if(!(esp->ireg & ESP_INTR_DC)) { - switch(esp->sreg & ESP_STAT_PMASK) { - case ESP_DOP: - case ESP_DIP: - ESPPHASE(("to data phase\n")); - return esp_do_data(esp, eregs); + esp_cmd(esp, eregs, ESP_CMD_FLUSH); - case ESP_STATP: - /* Whee, status phase, finish up the command. */ - ESPPHASE(("to status phase\n")); + if(esp->do_pio_cmds) { + esp_advance_phase(esp->current_SC, in_status); + esp_cmd(esp, eregs, thecmd); + while(!(esp_read(esp->eregs->esp_status) & ESP_STAT_INTR)); + esp->esp_command[0] = esp_read(eregs->esp_fdata); + while(!(esp_read(esp->eregs->esp_status) & ESP_STAT_INTR)); + esp->esp_command[1] = esp_read(eregs->esp_fdata); + } else { + esp->esp_command[0] = esp->esp_command[1] = 0xff; + esp_write(eregs->esp_tclow, 2); + esp_write(eregs->esp_tcmed, 0); + esp->dma_init_read(esp, esp->esp_command_dvma, 2); + thecmd |= ESP_CMD_DMA; + esp_cmd(esp, eregs, thecmd); + esp_advance_phase(esp->current_SC, in_status); + } - esp_cmd(esp, eregs, ESP_CMD_FLUSH); + return esp_do_status(esp, eregs); +} - if(esp->do_pio_cmds){ - esp_advance_phase(SCptr, in_status); - esp_cmd(esp, eregs, ESP_CMD_ICCSEQ); - while(!(GETREG(esp->eregs->esp_status) - & ESP_STAT_INTR)); - esp->esp_command[0] = GETREG(eregs->esp_fdata); - while(!(GETREG(esp->eregs->esp_status) - & ESP_STAT_INTR)); - esp->esp_command[1] = GETREG(eregs->esp_fdata); - } else { - if(esp->erev != fashme) { - esp->esp_command[0] = 0xff; - esp->esp_command[1] = 0xff; - SETREG(eregs->esp_tclow, 2); - SETREG(eregs->esp_tcmed, 0); - esp->dma_init_read(esp, esp->esp_command_dvma, 2); - esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_ICCSEQ); - } else { - /* Using DVMA for status/message bytes is - * unreliable on HME, nice job QLogic. - * Happy Meal indeed.... - */ - esp_cmd(esp, eregs, ESP_CMD_ICCSEQ); - } - esp_advance_phase(SCptr, in_status); - } - return esp_do_status(esp, eregs); +static int esp_disconnect_amidst_phases(struct NCR_ESP *esp, + struct ESP_regs *eregs) +{ + Scsi_Cmnd *sp = esp->current_SC; + Scsi_Device *dp = sp->device; - case ESP_MOP: - ESPPHASE(("to msgout phase\n")); - esp_advance_phase(SCptr, in_msgout); - return esp_do_msgout(esp, eregs); - - case ESP_MIP: - ESPPHASE(("to msgin phase\n")); - esp_advance_phase(SCptr, in_msgin); - return esp_do_msgin(esp, eregs); - - case ESP_CMDP: - /* Ugh, we're running a non-standard command the - * ESP doesn't understand, one byte at a time. - */ - ESPPHASE(("to cmd phase\n")); - esp_advance_phase(SCptr, in_cmdbegin); - return esp_do_cmdbegin(esp, eregs); - }; - } else { - Scsi_Device *dp = SCptr->device; + /* This means real problems if we see this + * here. Unless we were actually trying + * to force the device to abort/reset. + */ + ESPLOG(("esp%d: Disconnect amidst phases, ", esp->esp_id)); + ESPLOG(("pphase<%s> cphase<%s>, ", + phase_string(sp->SCp.phase), + phase_string(sp->SCp.sent_command))); - /* This means real problems if we see this - * here. Unless we were actually trying - * to force the device to abort/reset. - */ - ESPLOG(("esp%d Disconnect amidst phases, ", esp->esp_id)); - ESPLOG(("pphase<%s> cphase<%s>, ", - phase_string(SCptr->SCp.phase), - phase_string(SCptr->SCp.sent_command))); - if(esp->disconnected_SC || (esp->erev == fashme)) - esp_cmd(esp, eregs, ESP_CMD_ESEL); + if(esp->disconnected_SC) + esp_cmd(esp, eregs, ESP_CMD_ESEL); - switch(esp->cur_msgout[0]) { - default: - /* We didn't expect this to happen at all. */ - ESPLOG(("device is bolixed\n")); - esp_advance_phase(SCptr, in_tgterror); - esp_done(esp, (DID_ERROR << 16)); - break; + switch(esp->cur_msgout[0]) { + default: + /* We didn't expect this to happen at all. */ + ESPLOG(("device is bolixed\n")); + esp_advance_phase(sp, in_tgterror); + esp_done(esp, (DID_ERROR << 16)); + break; + + case BUS_DEVICE_RESET: + ESPLOG(("device reset successful\n")); + dp->sync_max_offset = 0; + dp->sync_min_period = 0; + dp->sync = 0; + esp_advance_phase(sp, in_resetdev); + esp_done(esp, (DID_RESET << 16)); + break; + + case ABORT: + ESPLOG(("device abort successful\n")); + esp_advance_phase(sp, in_abortone); + esp_done(esp, (DID_ABORT << 16)); + break; - case BUS_DEVICE_RESET: - ESPLOG(("device reset successful\n")); - dp->sync_max_offset = 0; - dp->sync_min_period = 0; - dp->sync = 0; - esp_advance_phase(SCptr, in_resetdev); - esp_done(esp, (DID_RESET << 16)); - break; + }; + return do_intr_end; +} - case ABORT: - ESPLOG(("device abort successful\n")); - esp_advance_phase(SCptr, in_abortone); - esp_done(esp, (DID_ABORT << 16)); - break; +static int esp_enter_msgout(struct NCR_ESP *esp, + struct ESP_regs *eregs) +{ + esp_advance_phase(esp->current_SC, in_msgout); + return esp_do_msgout(esp, eregs); +} - }; - return do_intr_end; - } +static int esp_enter_msgin(struct NCR_ESP *esp, + struct ESP_regs *eregs) +{ + esp_advance_phase(esp->current_SC, in_msgin); + return esp_do_msgin(esp, eregs); +} + +static int esp_enter_cmd(struct NCR_ESP *esp, + struct ESP_regs *eregs) +{ + esp_advance_phase(esp->current_SC, in_cmdbegin); + return esp_do_cmdbegin(esp, eregs); +} - ESPLOG(("esp%d: to unknown phase\n", esp->esp_id)); - printk("esp%d: Bizarre bus phase %2x.\n", esp->esp_id, - esp->sreg & ESP_STAT_PMASK); +static int esp_enter_badphase(struct NCR_ESP *esp, + struct ESP_regs *eregs) +{ + ESPLOG(("esp%d: Bizarre bus phase %2x.\n", esp->esp_id, + esp->sreg & ESP_STAT_PMASK)); return do_reset_bus; } +typedef int (*espfunc_t)(struct NCR_ESP *, + struct ESP_regs *); + +static espfunc_t phase_vector[] = { + esp_do_data, /* ESP_DOP */ + esp_do_data, /* ESP_DIP */ + esp_enter_cmd, /* ESP_CMDP */ + esp_enter_status, /* ESP_STATP */ + esp_enter_badphase, /* ESP_STAT_PMSG */ + esp_enter_badphase, /* ESP_STAT_PMSG | ESP_STAT_PIO */ + esp_enter_msgout, /* ESP_MOP */ + esp_enter_msgin, /* ESP_MIP */ +}; + +/* The target has control of the bus and we have to see where it has + * taken us. + */ +static int esp_do_phase_determine(struct NCR_ESP *esp, + struct ESP_regs *eregs) +{ + if ((esp->ireg & ESP_INTR_DC) != 0) + return esp_disconnect_amidst_phases(esp, eregs); + return phase_vector[esp->sreg & ESP_STAT_PMASK](esp, eregs); +} + /* First interrupt after exec'ing a cmd comes here. */ static int esp_select_complete(struct NCR_ESP *esp, struct ESP_regs *eregs) { @@ -2470,12 +2584,7 @@ Scsi_Device *SDptr = SCptr->device; int cmd_bytes_sent, fcnt; - if(esp->erev != fashme) - esp->seqreg = (GETREG(eregs->esp_sstep) & ESP_STEP_VBITS); - if(esp->erev == fashme) - fcnt = esp->hme_fifo_workaround_count; - else - fcnt = (GETREG(eregs->esp_fflags) & ESP_FF_FBYTES); + fcnt = (esp_read(eregs->esp_fflags) & ESP_FF_FBYTES); cmd_bytes_sent = esp->dma_bytes_sent(esp, fcnt); if(esp->dma_invalidate) esp->dma_invalidate(esp); @@ -2583,14 +2692,12 @@ if(SCptr->SCp.phase == in_slct_norm) cmd_bytes_sent -= 1; }; - if(esp->erev != fashme) - esp_cmd(esp, eregs, ESP_CMD_NULL); + esp_cmd(esp, eregs, ESP_CMD_NULL); /* Be careful, we could really get fucked during synchronous * data transfers if we try to flush the fifo now. */ - if((esp->erev != fashme) && /* not a Happy Meal and... */ - !fcnt && /* Fifo is empty and... */ + if(!fcnt && /* Fifo is empty and... */ /* either we are not doing synchronous transfers or... */ (!SDptr->sync_max_offset || /* We are not going into data in phase. */ @@ -2651,9 +2758,8 @@ SCptr->SCp.phase == in_slct_stop)) { /* shit */ esp->snip = 0; - printk("esp%d: Failed synchronous negotiation for target %d " - "lun %d\n", - esp->esp_id, SCptr->target, SCptr->lun); + ESPLOG(("esp%d: Failed synchronous negotiation for target %d " + "lun %d\n", esp->esp_id, SCptr->target, SCptr->lun)); SDptr->sync_max_offset = 0; SDptr->sync_min_period = 0; SDptr->sync = 1; /* so we don't negotiate again */ @@ -2680,8 +2786,8 @@ * But first make sure that is really what is happening. */ if(((1<target) & esp->targets_present)) { - printk("esp%d: Warning, live target %d not responding to " - "selection.\n", esp->esp_id, SCptr->target); + ESPLOG(("esp%d: Warning, live target %d not responding to " + "selection.\n", esp->esp_id, SCptr->target)); /* This _CAN_ happen. The SCSI standard states that * the target is to _not_ respond to selection if @@ -2710,9 +2816,9 @@ esp_print_seqreg(esp->seqreg); printk("\n"); printk("esp%d: New -- ", esp->esp_id); - esp->sreg = GETREG(eregs->esp_status); - esp->seqreg = GETREG(eregs->esp_sstep); - esp->ireg = GETREG(eregs->esp_intrpt); + esp->sreg = esp_read(eregs->esp_status); + esp->seqreg = esp_read(eregs->esp_sstep); + esp->ireg = esp_read(eregs->esp_intrpt); esp_print_ireg(esp->ireg); printk(" "); esp_print_statreg(esp->sreg); @@ -2743,14 +2849,14 @@ * have miscoded something..... so, try to * recover as best we can. */ - printk("esp%d: message in mis-carriage.\n", esp->esp_id); + ESPLOG(("esp%d: message in mis-carriage.\n", esp->esp_id)); } esp_advance_phase(esp->current_SC, in_the_dark); return do_phase_determine; } -static inline int check_singlebyte_msg(struct NCR_ESP *esp, - struct ESP_regs *eregs) +static int check_singlebyte_msg(struct NCR_ESP *esp, + struct ESP_regs *eregs) { esp->prevmsgin = esp->cur_msgin[0]; if(esp->cur_msgin[0] & 0x80) { @@ -2779,8 +2885,20 @@ return 0; case RESTORE_POINTERS: + /* In this case we might also have to backup the + * "slow command" pointer. It is rare to get such + * a save/restore pointer sequence so early in the + * bus transition sequences, but cover it. + */ + if(esp->esp_slowcmd) { + esp->esp_scmdleft = esp->current_SC->cmd_len; + esp->esp_scmdp = &esp->current_SC->cmnd[0]; + } + esp_restore_pointers(esp, esp->current_SC); + return 0; + case SAVE_POINTERS: - /* We handle this all automatically. */ + esp_save_pointers(esp, esp->current_SC); return 0; case COMMAND_COMPLETE: @@ -2815,9 +2933,9 @@ * the SCSI2 standard specifically recommends against targets doing * this because so many initiators cannot cope with this occuring. */ -static inline int target_with_ants_in_pants(struct NCR_ESP *esp, - Scsi_Cmnd *SCptr, - Scsi_Device *SDptr) +static int target_with_ants_in_pants(struct NCR_ESP *esp, + Scsi_Cmnd *SCptr, + Scsi_Device *SDptr) { if(SDptr->sync || SDptr->borken) { /* sorry, no can do */ @@ -2834,7 +2952,7 @@ return 0; } -static inline void sync_report(struct NCR_ESP *esp) +static void sync_report(struct NCR_ESP *esp) { int msg3, msg4; char *type; @@ -2845,30 +2963,31 @@ int hz = 1000000000 / (msg3 * 4); int integer = hz / 1000000; int fraction = (hz - (integer * 1000000)) / 10000; - if((esp->erev == fashme) && - (esp->config3[esp->current_SC->target] & ESP_CONFIG3_EWIDE)) { - type = "FAST-WIDE"; - integer <<= 1; - fraction <<= 1; - } else if((msg3 * 4) < 200) { + if((msg3 * 4) < 200) { type = "FAST"; } else { type = "synchronous"; } - printk(KERN_INFO "esp%d: target %d [period %dns offset %d %d.%02dMHz %s SCSI%s]\n", - esp->esp_id, esp->current_SC->target, - (int) msg3 * 4, - (int) msg4, - integer, fraction, type, - (((msg3 * 4) < 200) ? "-II" : "")); + + /* Do not transform this back into one big printk + * again, it triggers a bug in our sparc64-gcc272 + * sibling call optimization. -DaveM + */ + ESPLOG((KERN_INFO "esp%d: target %d ", + esp->esp_id, esp->current_SC->target)); + ESPLOG(("[period %dns offset %d %d.%02dMHz ", + (int) msg3 * 4, (int) msg4, + integer, fraction)); + ESPLOG(("%s SCSI%s]\n", type, + (((msg3 * 4) < 200) ? "-II" : ""))); } else { - printk(KERN_INFO "esp%d: target %d asynchronous\n", - esp->esp_id, esp->current_SC->target); + ESPLOG((KERN_INFO "esp%d: target %d asynchronous\n", + esp->esp_id, esp->current_SC->target)); } } -static inline int check_multibyte_msg(struct NCR_ESP *esp, - struct ESP_regs *eregs) +static int check_multibyte_msg(struct NCR_ESP *esp, + struct ESP_regs *eregs) { Scsi_Cmnd *SCptr = esp->current_SC; Scsi_Device *SDptr = SCptr->device; @@ -2923,10 +3042,7 @@ ESPSDTR(("period is ok, ")); tmp = esp->ccycle / 1000; regval = (((period << 2) + tmp - 1) / tmp); - if(regval && ((esp->erev == fas100a || - esp->erev == fas216 || - esp->erev == fas236 || - esp->erev == fashme))) { + if(regval && (esp->erev > esp236)) { if(period >= 50) regval--; } @@ -2937,8 +3053,8 @@ SDptr->sync_min_period = (regval & 0x1f); SDptr->sync_max_offset = (offset | esp->radelay); - if((esp->erev == fas100a || esp->erev == fas216 || esp->erev == fas236 || esp->erev == fashme)) { - if((esp->erev == fas100a) || (esp->erev == fashme)) + if(esp->erev > esp236) { + if(esp->erev == fas100a) bit = ESP_CONFIG3_FAST; else bit = ESP_CONFIG3_FSCSI; @@ -2946,11 +3062,13 @@ esp->config3[SCptr->target] |= bit; else esp->config3[SCptr->target] &= ~bit; - SETREG(eregs->esp_cfg3, - esp->config3[SCptr->target]); + esp->prev_cfg3 = esp->config3[SCptr->target]; + esp_write(eregs->esp_cfg3, esp->prev_cfg3); } - SETREG(eregs->esp_soff, SDptr->sync_min_period); - SETREG(eregs->esp_stp, SDptr->sync_max_offset); + esp->prev_soff = SDptr->sync_min_period; + esp_write(eregs->esp_soff, esp->prev_soff); + esp->prev_stp = SDptr->sync_max_offset; + esp_write(eregs->esp_stp, esp->prev_stp); ESPSDTR(("soff=%2x stp=%2x cfg3=%2x\n", SDptr->sync_max_offset, @@ -2965,16 +3083,18 @@ ESPSDTR(("unaccaptable sync nego, forcing async\n")); SDptr->sync_max_offset = 0; SDptr->sync_min_period = 0; - SETREG(eregs->esp_soff, 0); - SETREG(eregs->esp_stp, 0); - if((esp->erev == fas100a || esp->erev == fas216 || esp->erev == fas236 || esp->erev == fashme)) { - if((esp->erev == fas100a) || (esp->erev == fashme)) + esp->prev_soff = 0; + esp_write(eregs->esp_soff, 0); + esp->prev_stp = 0; + esp_write(eregs->esp_stp, 0); + if(esp->erev > esp236) { + if(esp->erev == fas100a) bit = ESP_CONFIG3_FAST; else bit = ESP_CONFIG3_FSCSI; esp->config3[SCptr->target] &= ~bit; - SETREG(eregs->esp_cfg3, - esp->config3[SCptr->target]); + esp->prev_cfg3 = esp->config3[SCptr->target]; + esp_write(eregs->esp_cfg3, esp->prev_cfg3); } } @@ -2995,48 +3115,12 @@ esp_advance_phase(SCptr, in_the_dark); /* ...or else! */ return 0; } else if(esp->cur_msgin[2] == EXTENDED_WDTR) { - int size = 8 << esp->cur_msgin[3]; - - esp->wnip = 0; - if(esp->erev != fashme) { - printk("esp%d: AIEEE wide msg received and not HME.\n", - esp->esp_id); - message_out = MESSAGE_REJECT; - } else if(size > 16) { - printk("esp%d: AIEEE wide transfer for %d size not supported.\n", - esp->esp_id, size); - message_out = MESSAGE_REJECT; - } else { - /* Things look good; let's see what we got. */ - if(size == 16) { - /* Set config 3 register for this target. */ - printk("esp%d: 16 byte WIDE transfers enabled for target %d.\n", - esp->esp_id, SCptr->target); - esp->config3[SCptr->target] |= ESP_CONFIG3_EWIDE; - } else { - /* Just make sure it was one byte sized. */ - if(size != 8) { - printk("esp%d: Aieee, wide nego of %d size.\n", - esp->esp_id, size); - message_out = MESSAGE_REJECT; - goto finish; - } - /* Pure paranoia. */ - esp->config3[SCptr->target] &= ~(ESP_CONFIG3_EWIDE); - } - SETREG(eregs->esp_cfg3, esp->config3[SCptr->target]); - - /* Regardless, next try for sync transfers. */ - build_sync_nego_msg(esp, esp->sync_defp, 15); - SDptr->sync = 1; - esp->snip = 1; - message_out = EXTENDED_MESSAGE; - } + ESPLOG(("esp%d: AIEEE wide msg received\n", esp->esp_id)); + message_out = MESSAGE_REJECT; } else if(esp->cur_msgin[2] == EXTENDED_MODIFY_DATA_POINTER) { ESPLOG(("esp%d: rejecting modify data ptr msg\n", esp->esp_id)); message_out = MESSAGE_REJECT; } -finish: esp_advance_phase(SCptr, in_the_dark); return message_out; } @@ -3054,26 +3138,17 @@ if(esp->msgin_len && (esp->sreg & ESP_STAT_PERR)) { message_out = MSG_PARITY_ERROR; esp_cmd(esp, eregs, ESP_CMD_FLUSH); - } else if(esp->erev != fashme && - (it = (GETREG(eregs->esp_fflags) - & ESP_FF_FBYTES))!=1) { + } else if((it = (esp_read(eregs->esp_fflags) & ESP_FF_FBYTES))!=1) { /* We certainly dropped the ball somewhere. */ message_out = INITIATOR_ERROR; esp_cmd(esp, eregs, ESP_CMD_FLUSH); } else if(!esp->msgin_len) { - if(esp->erev == fashme) - it = esp->hme_fifo_workaround_buffer[0]; - else - it = GETREG(eregs->esp_fdata); + it = esp_read(eregs->esp_fdata); esp_advance_phase(SCptr, in_msgincont); } else { /* it is ok and we want it */ - if(esp->erev == fashme) - it = esp->cur_msgin[esp->msgin_ctr] = - esp->hme_fifo_workaround_buffer[0]; - else - it = esp->cur_msgin[esp->msgin_ctr] = - GETREG(eregs->esp_fdata); + it = esp->cur_msgin[esp->msgin_ctr] = + esp_read(eregs->esp_fdata); esp->msgin_ctr++; } } else { @@ -3114,7 +3189,7 @@ esp_advance_phase(SCptr, in_the_dark); esp->msgin_len = 0; } - esp->sreg = GETREG(eregs->esp_status); + esp->sreg = esp_read(eregs->esp_status); esp->sreg &= ~(ESP_STAT_INTR); if((esp->sreg & (ESP_STAT_PMSG|ESP_STAT_PCD)) == (ESP_STAT_PMSG|ESP_STAT_PCD)) esp_cmd(esp, eregs, ESP_CMD_MOK); @@ -3126,35 +3201,21 @@ static int esp_do_cmdbegin(struct NCR_ESP *esp, struct ESP_regs *eregs) { + unsigned char tmp; Scsi_Cmnd *SCptr = esp->current_SC; esp_advance_phase(SCptr, in_cmdend); - if(esp->erev == fashme) { - int i; - - for(i = 0; i < esp->esp_scmdleft; i++) - esp->esp_command[i] = *esp->esp_scmdp++; - esp->esp_scmdleft = 0; - esp_cmd(esp, eregs, ESP_CMD_FLUSH); - esp_setcount(eregs, i, 1); - esp_cmd(esp, eregs, (ESP_CMD_DMA | ESP_CMD_TI)); - esp->dma_init_write(esp, esp->esp_command_dvma, i); - } else { - esp_cmd(esp, eregs, ESP_CMD_FLUSH); - SETREG(eregs->esp_fdata, *esp->esp_scmdp++); - esp->esp_scmdleft--; - esp_cmd(esp, eregs, ESP_CMD_TI); - } + esp_cmd(esp, eregs, ESP_CMD_FLUSH); + tmp = *esp->esp_scmdp++; + esp->esp_scmdleft--; + esp_write(eregs->esp_fdata, tmp); + esp_cmd(esp, eregs, ESP_CMD_TI); return do_intr_end; } -static inline int esp_do_cmddone(struct NCR_ESP *esp, struct ESP_regs *eregs) +static int esp_do_cmddone(struct NCR_ESP *esp, struct ESP_regs *eregs) { - if(esp->erev == fashme){ - if(esp->dma_invalidate) - esp->dma_invalidate(esp); - } else - esp_cmd(esp, eregs, ESP_CMD_NULL); + esp_cmd(esp, eregs, ESP_CMD_NULL); if(esp->ireg & ESP_INTR_BSERV) { esp_advance_phase(esp->current_SC, in_the_dark); return esp_do_phase_determine(esp, eregs); @@ -3169,79 +3230,61 @@ esp_cmd(esp, eregs, ESP_CMD_FLUSH); switch(esp->msgout_len) { case 1: - if(esp->erev == fashme) - hme_fifo_push(esp, eregs, &esp->cur_msgout[0], 1); - else - SETREG(eregs->esp_fdata, esp->cur_msgout[0]); + esp_write(eregs->esp_fdata, esp->cur_msgout[0]); esp_cmd(esp, eregs, ESP_CMD_TI); break; case 2: if(esp->do_pio_cmds){ - SETREG(eregs->esp_fdata, esp->cur_msgout[0]); - SETREG(eregs->esp_fdata, esp->cur_msgout[1]); + esp_write(eregs->esp_fdata, esp->cur_msgout[0]); + esp_write(eregs->esp_fdata, esp->cur_msgout[1]); esp_cmd(esp, eregs, ESP_CMD_TI); } else { esp->esp_command[0] = esp->cur_msgout[0]; esp->esp_command[1] = esp->cur_msgout[1]; - if(esp->erev == fashme) { - hme_fifo_push(esp, eregs, &esp->cur_msgout[0], 2); - esp_cmd(esp, eregs, ESP_CMD_TI); - } else { - esp->dma_setup(esp, esp->esp_command_dvma, 2, 0); - esp_setcount(eregs, 2, 0); - esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI); - } + esp->dma_setup(esp, esp->esp_command_dvma, 2, 0); + esp_setcount(eregs, 2); + esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI); } break; case 4: esp->snip = 1; if(esp->do_pio_cmds){ - SETREG(eregs->esp_fdata, esp->cur_msgout[0]); - SETREG(eregs->esp_fdata, esp->cur_msgout[1]); - SETREG(eregs->esp_fdata, esp->cur_msgout[2]); - SETREG(eregs->esp_fdata, esp->cur_msgout[3]); + esp_write(eregs->esp_fdata, esp->cur_msgout[0]); + esp_write(eregs->esp_fdata, esp->cur_msgout[1]); + esp_write(eregs->esp_fdata, esp->cur_msgout[2]); + esp_write(eregs->esp_fdata, esp->cur_msgout[3]); esp_cmd(esp, eregs, ESP_CMD_TI); } else { esp->esp_command[0] = esp->cur_msgout[0]; esp->esp_command[1] = esp->cur_msgout[1]; esp->esp_command[2] = esp->cur_msgout[2]; esp->esp_command[3] = esp->cur_msgout[3]; - if(esp->erev == fashme) { - hme_fifo_push(esp, eregs, &esp->cur_msgout[0], 4); - esp_cmd(esp, eregs, ESP_CMD_TI); - } else { - esp->dma_setup(esp, esp->esp_command_dvma, 4, 0); - esp_setcount(eregs, 4, 0); - esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI); - } + esp->dma_setup(esp, esp->esp_command_dvma, 4, 0); + esp_setcount(eregs, 4); + esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI); } break; case 5: esp->snip = 1; if(esp->do_pio_cmds){ - SETREG(eregs->esp_fdata, esp->cur_msgout[0]); - SETREG(eregs->esp_fdata, esp->cur_msgout[1]); - SETREG(eregs->esp_fdata, esp->cur_msgout[2]); - SETREG(eregs->esp_fdata, esp->cur_msgout[3]); - SETREG(eregs->esp_fdata, esp->cur_msgout[4]); + esp_write(eregs->esp_fdata, esp->cur_msgout[0]); + esp_write(eregs->esp_fdata, esp->cur_msgout[1]); + esp_write(eregs->esp_fdata, esp->cur_msgout[2]); + esp_write(eregs->esp_fdata, esp->cur_msgout[3]); + esp_write(eregs->esp_fdata, esp->cur_msgout[4]); esp_cmd(esp, eregs, ESP_CMD_TI); } else { - SETREG(esp->esp_command[0], esp->cur_msgout[0]); - SETREG(esp->esp_command[1], esp->cur_msgout[1]); - SETREG(esp->esp_command[2], esp->cur_msgout[2]); - SETREG(esp->esp_command[3], esp->cur_msgout[3]); - SETREG(esp->esp_command[4], esp->cur_msgout[4]); - if(esp->erev == fashme) { - hme_fifo_push(esp, eregs, &esp->cur_msgout[0], 5); - esp_cmd(esp, eregs, ESP_CMD_TI); - } else { - esp->dma_setup(esp, esp->esp_command_dvma, 5, 0); - esp_setcount(eregs, 5, 0); - esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI); - } + esp->esp_command[0] = esp->cur_msgout[0]; + esp->esp_command[1] = esp->cur_msgout[1]; + esp->esp_command[2] = esp->cur_msgout[2]; + esp->esp_command[3] = esp->cur_msgout[3]; + esp->esp_command[4] = esp->cur_msgout[4]; + esp->dma_setup(esp, esp->esp_command_dvma, 5, 0); + esp_setcount(eregs, 5); + esp_cmd(esp, eregs, ESP_CMD_DMA | ESP_CMD_TI); } break; @@ -3249,11 +3292,7 @@ /* whoops */ ESPMISC(("bogus msgout sending NOP\n")); esp->cur_msgout[0] = NOP; - if(esp->erev == fashme) { - hme_fifo_push(esp, eregs, &esp->cur_msgout[0], 1); - } else { - SETREG(eregs->esp_fdata, esp->cur_msgout[0]); - } + esp_write(eregs->esp_fdata, esp->cur_msgout[0]); esp->msgout_len = 1; esp_cmd(esp, eregs, ESP_CMD_TI); break; @@ -3262,15 +3301,14 @@ return do_intr_end; } -static inline int esp_do_msgoutdone(struct NCR_ESP *esp, - struct ESP_regs *eregs) +static int esp_do_msgoutdone(struct NCR_ESP *esp, + struct ESP_regs *eregs) { if((esp->msgout_len > 1) && esp->dma_barrier) esp->dma_barrier(esp); if(!(esp->ireg & ESP_INTR_DC)) { - if(esp->erev != fashme) - esp_cmd(esp, eregs, ESP_CMD_NULL); + esp_cmd(esp, eregs, ESP_CMD_NULL); switch(esp->sreg & ESP_STAT_PMASK) { case ESP_MOP: /* whoops, parity error */ @@ -3285,17 +3323,12 @@ break; default: - /* Happy Meal fifo is touchy... */ - if((esp->erev != fashme) && - !fcount(esp, eregs) && + if(!fcount(esp, eregs) && !(esp->current_SC->device->sync_max_offset)) esp_cmd(esp, eregs, ESP_CMD_FLUSH); break; }; - } else { - ESPLOG(("esp%d: disconnect, resetting bus\n", esp->esp_id)); - return do_reset_bus; } /* If we sent out a synchronous negotiation message, update @@ -3312,89 +3345,66 @@ return esp_do_phase_determine(esp, eregs); } +static int esp_bus_unexpected(struct NCR_ESP *esp, struct ESP_regs *eregs) +{ + ESPLOG(("esp%d: command in weird state %2x\n", + esp->esp_id, esp->current_SC->SCp.phase)); + return do_reset_bus; +} + +static espfunc_t bus_vector[] = { + esp_do_data_finale, + esp_do_data_finale, + esp_bus_unexpected, + esp_do_msgin, + esp_do_msgincont, + esp_do_msgindone, + esp_do_msgout, + esp_do_msgoutdone, + esp_do_cmdbegin, + esp_do_cmddone, + esp_do_status, + esp_do_freebus, + esp_do_phase_determine, + esp_bus_unexpected, + esp_bus_unexpected, + esp_bus_unexpected, +}; + /* This is the second tier in our dual-level SCSI state machine. */ -static inline int esp_work_bus(struct NCR_ESP *esp, struct ESP_regs *eregs) +static int esp_work_bus(struct NCR_ESP *esp, struct ESP_regs *eregs) { Scsi_Cmnd *SCptr = esp->current_SC; + unsigned int phase; ESPBUS(("esp_work_bus: ")); if(!SCptr) { ESPBUS(("reconnect\n")); return esp_do_reconnect(esp, eregs); } - - switch(SCptr->SCp.phase) { - case in_the_dark: - ESPBUS(("in the dark\n")); - return esp_do_phase_determine(esp, eregs); - - case in_slct_norm: - case in_slct_stop: - case in_slct_msg: - case in_slct_tag: - case in_slct_sneg: - ESPBUS(("finish selection\n")); + phase = SCptr->SCp.phase; + if ((phase & 0xf0) == in_phases_mask) + return bus_vector[(phase & 0x0f)](esp, eregs); + else if((phase & 0xf0) == in_slct_mask) return esp_select_complete(esp, eregs); - - case in_datain: - case in_dataout: - ESPBUS(("finish data\n")); - return esp_do_data_finale(esp, eregs); - - case in_msgout: - ESPBUS(("message out ")); - return esp_do_msgout(esp, eregs); - - case in_msgoutdone: - ESPBUS(("finish message out ")); - return esp_do_msgoutdone(esp, eregs); - - case in_msgin: - ESPBUS(("message in ")); - return esp_do_msgin(esp, eregs); - - case in_msgincont: - ESPBUS(("continue message in ")); - return esp_do_msgincont(esp, eregs); - - case in_msgindone: - ESPBUS(("finish message in ")); - return esp_do_msgindone(esp, eregs); - - case in_status: - ESPBUS(("status phase ")); - return esp_do_status(esp, eregs); - - case in_freeing: - ESPBUS(("freeing the bus ")); - return esp_do_freebus(esp, eregs); - - case in_cmdbegin: - ESPBUS(("begin slow cmd ")); - return esp_do_cmdbegin(esp, eregs); - - case in_cmdend: - ESPBUS(("end slow cmd ")); - return esp_do_cmddone(esp, eregs); - - default: - printk("esp%d: command in weird state %2x\n", - esp->esp_id, esp->current_SC->SCp.phase); - return do_reset_bus; - }; + else + return esp_bus_unexpected(esp, eregs); } +static espfunc_t isvc_vector[] = { + 0, + esp_do_phase_determine, + esp_do_resetbus, + esp_finish_reset, + esp_work_bus +}; + /* Main interrupt handler for an esp adapter. */ -inline void esp_handle(struct NCR_ESP *esp) +void esp_handle(struct NCR_ESP *esp) { struct ESP_regs *eregs; Scsi_Cmnd *SCptr; int what_next = do_intr_end; - unsigned long flags; -#ifdef CONFIG_SCSI_SUNESP - struct sparc_dma_registers *dregs = - (struct sparc_dma_registers*) esp->dregs; -#endif eregs = esp->eregs; SCptr = esp->current_SC; @@ -3402,12 +3412,12 @@ esp->dma_irq_entry(esp); /* Check for errors. */ - esp->sreg = GETREG(eregs->esp_status); + esp->sreg = esp_read(eregs->esp_status); esp->sreg &= (~ESP_STAT_INTR); - if(esp->erev == fashme) { - esp->sreg2 = GETREG(eregs->esp_status2); - esp->seqreg = (GETREG(eregs->esp_sstep) & ESP_STEP_VBITS); - } + esp->seqreg = (esp_read(eregs->esp_sstep) & ESP_STEP_VBITS); + esp->ireg = esp_read(eregs->esp_intrpt); /* Unlatch intr and stat regs */ + ESPIRQ(("handle_irq: [sreg<%02x> sstep<%02x> ireg<%02x>]\n", + esp->sreg, esp->seqreg, esp->ireg)); if(esp->sreg & (ESP_STAT_SPAM)) { /* Gross error, could be due to one of: * @@ -3435,56 +3445,10 @@ ESPLOG(("esp%d: No current cmd during gross error, " "resetting bus\n", esp->esp_id)); what_next = do_reset_bus; - goto again; + goto state_machine; } } -#ifdef CONFIG_SCSI_SUNESP - if(dregs->cond_reg & DMA_HNDL_ERROR) { - /* A DMA gate array error. Here we must - * be seeing one of two things. Either the - * virtual to physical address translation - * on the SBUS could not occur, else the - * translation it did get pointed to a bogus - * page. Ho hum... - */ - ESPLOG(("esp%d: DMA error %08x\n", esp->esp_id, - dregs->cond_reg)); - - /* DMA gate array itself must be reset to clear the - * error condition. - */ - if(esp->dma_reset) - esp->dma_reset(esp); - - what_next = do_reset_bus; - goto again; - } -#endif /* CONFIG_SCSI_SUNESP */ - - if(esp->erev == fashme) { - /* This chip is really losing. */ - ESPHME(("HME[")); - - ESPHME(("sreg2=%02x,", esp->sreg2)); - /* Must latch fifo before reading the interrupt - * register else garbage ends up in the FIFO - * which confuses the driver utterly. - */ - if(!(esp->sreg2 & ESP_STAT2_FEMPTY) || - (esp->sreg2 & ESP_STAT2_F1BYTE)) { - ESPHME(("fifo_workaround]")); - hme_fifo_hwbug_workaround(esp, eregs); - } else { - ESPHME(("no_fifo_workaround]")); - } - } - - esp->ireg = GETREG(eregs->esp_intrpt); /* Unlatch intr and stat regs */ - - /* This cannot be done until this very moment. -DaveM */ - synchronize_irq(); - /* No current cmd is only valid at this point when there are * commands off the bus or we are trying a reset. */ @@ -3497,7 +3461,7 @@ if(esp->ireg & (ESP_INTR_IC)) { /* Illegal command fed to ESP. Outside of obvious * software bugs that could cause this, there is - * a condition with esp100 where we can confuse the + * a condition with ESP100 where we can confuse the * ESP into an erroneous illegal command interrupt * because it does not scrape the FIFO properly * for reselection. See esp100_reconnect_hwbug() @@ -3523,10 +3487,7 @@ } what_next = do_reset_bus; - goto again; - } - - if(!(esp->ireg & ~(ESP_INTR_FDONE | ESP_INTR_BSERV | ESP_INTR_DC))) { + } else if(!(esp->ireg & ~(ESP_INTR_FDONE | ESP_INTR_BSERV | ESP_INTR_DC))) { int phase; if(SCptr) { @@ -3538,13 +3499,12 @@ } else { ESPLOG(("esp%d: interrupt for no good reason...\n", esp->esp_id)); - goto esp_handle_done; + what_next = do_intr_end; } } else { ESPLOG(("esp%d: BSERV or FDONE or DC while SCptr==NULL\n", esp->esp_id)); what_next = do_reset_bus; - goto again; } } else if(esp->ireg & ESP_INTR_SR) { ESPLOG(("esp%d: SCSI bus reset interrupt\n", esp->esp_id)); @@ -3553,7 +3513,6 @@ ESPLOG(("esp%d: AIEEE we have been selected by another initiator!\n", esp->esp_id)); what_next = do_reset_bus; - goto again; } else if(esp->ireg & ESP_INTR_RSEL) { if(!SCptr) { /* This is ok. */ @@ -3568,114 +3527,40 @@ ESPLOG(("esp%d: Reselected while bus is busy\n", esp->esp_id)); what_next = do_reset_bus; - goto again; } } - /* We're trying to fight stack problems, and inline as much as - * possible without making this driver a mess. hate hate hate - * This is tier-one in our dual level SCSI state machine. - */ -again: - switch(what_next) { - case do_intr_end: - goto esp_handle_done; - - case do_work_bus: - what_next = esp_work_bus(esp, eregs); - break; - - case do_phase_determine: - what_next = esp_do_phase_determine(esp, eregs); - break; - - case do_reset_bus: - ESPLOG(("esp%d: resetting bus...\n", esp->esp_id)); - esp->resetting_bus = 1; - esp_cmd(esp, eregs, ESP_CMD_RS); - goto esp_handle_done; - - case do_reset_complete: - /* Tricky, we don't want to cause any more commands to - * go out until we clear all the live cmds by hand. - */ - if(esp->current_SC) { - Scsi_Cmnd *SCptr = esp->current_SC; - - if(!SCptr->use_sg) { - if (esp->dma_mmu_release_scsi_one) - esp->dma_mmu_release_scsi_one (esp, SCptr); - } else { - if (esp->dma_mmu_release_scsi_sgl) - esp->dma_mmu_release_scsi_sgl (esp, SCptr); - } - SCptr->result = (DID_RESET << 16); - - spin_lock_irqsave(&io_request_lock,flags); - SCptr->scsi_done(SCptr); - spin_unlock_irqrestore(&io_request_lock, flags); - } - esp->current_SC = NULL; - if(esp->disconnected_SC) { - Scsi_Cmnd *SCptr; - while((SCptr = remove_first_SC(&esp->disconnected_SC))) { - if(!SCptr->use_sg) { - if (esp->dma_mmu_release_scsi_one) - esp->dma_mmu_release_scsi_one (esp, SCptr); - } else { - if (esp->dma_mmu_release_scsi_sgl) - esp->dma_mmu_release_scsi_sgl (esp, SCptr); - } - SCptr->result = (DID_RESET << 16); - - spin_lock_irqsave(&io_request_lock,flags); - SCptr->scsi_done(SCptr); - spin_unlock_irqrestore(&io_request_lock, flags); - } - } - esp->resetting_bus = 0; - - if(esp->current_SC) { - printk("esp%d: weird weird weird, current_SC not NULL after " - "SCSI bus reset.\n", esp->esp_id); - goto esp_handle_done; + /* This is tier-one in our dual level SCSI state machine. */ +state_machine: + while(what_next != do_intr_end) { + if (what_next >= do_phase_determine && + what_next < do_intr_end) + what_next = isvc_vector[what_next](esp, eregs); + else { + /* state is completely lost ;-( */ + ESPLOG(("esp%d: interrupt engine loses state, resetting bus\n", + esp->esp_id)); + what_next = do_reset_bus; } - - /* Now it is safe to execute more things. */ - if(esp->issue_SC) - esp_exec_cmd(esp); - goto esp_handle_done; - - default: - /* state is completely lost ;-( */ - ESPLOG(("esp%d: interrupt engine loses state, resetting bus\n", - esp->esp_id)); - what_next = do_reset_bus; - break; - - }; - goto again; - -esp_handle_done: + } if(esp->dma_irq_exit) esp->dma_irq_exit(esp); - return; } -#ifndef __sparc_v9__ - #ifndef __SMP__ void esp_intr(int irq, void *dev_id, struct pt_regs *pregs) { struct NCR_ESP *esp; + unsigned long flags; int again; /* Handle all ESP interrupts showing at this IRQ level. */ + spin_lock_irqsave(&io_request_lock, flags); repeat: again = 0; for_each_esp(esp) { #ifndef __mips__ - if(((esp)->irq & 0xf) == irq) { + if(((esp)->irq & 0xff) == irq) { #endif if(esp->dma_irq_p(esp)) { again = 1; @@ -3694,14 +3579,17 @@ } if(again) goto repeat; + spin_unlock_irqrestore(&io_request_lock, flags); } #else /* For SMP we only service one ESP on the list list at our IRQ level! */ -void esp_intr(int irq, void *dev_id, struct pt_regs *pregs) +static void esp_intr(int irq, void *dev_id, struct pt_regs *pregs) { struct NCR_ESP *esp; + unsigned long flags; /* Handle all ESP interrupts showing at this IRQ level. */ + spin_lock_irqsave(&io_request_lock, flags); for_each_esp(esp) { if(((esp)->irq & 0xf) == irq) { if(esp->dma_irq_p(esp)) { @@ -3713,28 +3601,22 @@ ESPIRQ((")")); esp->dma_ints_on(esp); - return; + goto out; } } } +out: + spin_unlock_irqrestore(&io_request_lock, flags); } #endif -#else /* __sparc_v9__ */ - -static void esp_intr(int irq, void *dev_id, struct pt_regs *pregs) +#ifdef MODULE +int init_module(void) { return 0; } +void cleanup_module(void) {} +void esp_release(void) { - struct NCR_ESP *esp = dev_id; - - if(esp->dma_irq_p(esp)) { - esp->dma_ints_off(dregs); - - ESPIRQ(("I[%d:%d](", smp_processor_id(), esp->esp_id)); - esp_handle(esp); - ESPIRQ((")")); - - esp->dma_ints_on(esp); - } + MOD_DEC_USE_COUNT; + esps_in_use--; + esps_running = esps_in_use; } - #endif diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/NCR53C9x.h linux/drivers/scsi/NCR53C9x.h --- v2.3.13/linux/drivers/scsi/NCR53C9x.h Tue Jun 22 14:42:32 1999 +++ linux/drivers/scsi/NCR53C9x.h Thu Aug 12 10:28:34 1999 @@ -1,4 +1,4 @@ -/* NCR53C9x.h: Defines and structures for the NCR53C9x generic driver. +/* NCR53C9x.c: Defines and structures for the NCR53C9x generic driver. * * Originaly esp.h: Defines and structures for the Sparc ESP * (Enhanced SCSI Processor) driver under Linux. @@ -15,10 +15,32 @@ #include +/* djweis for mac driver */ +#if defined(CONFIG_MAC) +#define PAD_SIZE 15 +#else +#define PAD_SIZE 3 +#endif + +/* Handle multiple hostadapters on Amiga + * generally PAD_SIZE = 3 + * but there is one exception: Oktagon (PAD_SIZE = 1) */ +#if defined(CONFIG_OKTAGON_SCSI) || defined(CONFIG_OKTAGON_SCSI_MODULE) +#undef PAD_SIZE +#if defined(CONFIG_BLZ1230_SCSI) || defined(CONFIG_BLZ1230_SCSI_MODULE) || \ + defined(CONFIG_BLZ2060_SCSI) || defined(CONFIG_BLZ2060_SCSI_MODULE) || \ + defined(CONFIG_CYBERSTORM_SCSI) || defined(CONFIG_CYBERSTORM_SCSI_MODULE) || \ + defined(CONFIG_CYBERSTORMII_SCSI) || defined(CONFIG_CYBERSTORMII_SCSI_MODULE) || \ + defined(CONFIG_FASTLANE_SCSI) || defined(CONFIG_FASTLANE_SCSI_MODULE) +#define MULTIPLE_PAD_SIZES +#else +#define PAD_SIZE 1 +#endif +#endif + /* Macros for debugging messages */ -/* #define DEBUG_ESP */ -/* #define DEBUG_ESP_HME */ +#define DEBUG_ESP /* #define DEBUG_ESP_DATA */ /* #define DEBUG_ESP_QUEUE */ /* #define DEBUG_ESP_DISCONNECT */ @@ -43,12 +65,6 @@ #define ESPLOG(foo) #endif /* (DEBUG_ESP) */ -#if defined(DEBUG_ESP_HME) -#define ESPHME(foo) printk foo -#else -#define ESPHME(foo) -#endif - #if defined(DEBUG_ESP_DATA) #define ESPDATA(foo) printk foo #else @@ -103,21 +119,15 @@ #define ESPMISC(foo) #endif -#define INTERNAL_ESP_ERROR \ - (panic ("Internal ESP driver error in file %s, line %d\n", \ - __FILE__, __LINE__)) - -#define INTERNAL_ESP_ERROR_NOPANIC \ - (printk ("Internal ESP driver error in file %s, line %d\n", \ - __FILE__, __LINE__)) - /* * padding for register structure */ #ifdef CONFIG_JAZZ_ESP #define EREGS_PAD(n) #else -#define EREGS_PAD(n) unchar n[3]; +#ifndef MULTIPLE_PAD_SIZES +#define EREGS_PAD(n) unchar n[PAD_SIZE]; +#endif #endif /* The ESP SCSI controllers have their register sets in three @@ -130,18 +140,12 @@ * Yet, they all live within the same IO space. */ -/* All the ESP registers are one byte each and are accessed longwords - * apart with a big-endian ordering to the bytes. - */ - -/* - * On intel, we must use inb() and outb() for register access, and the registers - * are consecutive; no padding. - */ - #ifndef __i386__ -#define SETREG(reg, val) (reg = val) -#define GETREG(reg) (reg) + +#ifndef MULTIPLE_PAD_SIZES + +#define esp_write(__reg, __val) ((__reg) = (__val)) +#define esp_read(__reg) (__reg) struct ESP_regs { /* Access Description Offset */ @@ -151,7 +155,7 @@ EREGS_PAD(fdpad); volatile unchar esp_fdata; /* rw FIFO data bits 0x08 */ EREGS_PAD(cbpad); - volatile unchar esp_cmnd; /* rw SCSI command bits 0x0c */ + volatile unchar esp_cmnd; /* rw SCSI command bits 0x0c */ EREGS_PAD(stpad); volatile unchar esp_status; /* ro ESP status register 0x10 */ #define esp_busid esp_status /* wo Bus ID for select/reselect 0x10 */ @@ -168,7 +172,6 @@ volatile unchar esp_cfg1; /* rw First configuration register 0x20 */ EREGS_PAD(cfpad); volatile unchar esp_cfact; /* wo Clock conversion factor 0x24 */ -#define esp_status2 esp_cfact /* ro HME status2 register 0x24 */ EREGS_PAD(ctpad); volatile unchar esp_ctest; /* wo Chip test register 0x28 */ EREGS_PAD(cf2pd); @@ -177,63 +180,89 @@ /* The following is only found on the 53C9X series SCSI chips */ volatile unchar esp_cfg3; /* rw Third configuration register 0x30 */ - EREGS_PAD(holep); - volatile unchar esp_hole; /* hole in register map 0x34 */ - EREGS_PAD(thpd); + EREGS_PAD(cf4pd); + volatile unchar esp_cfg4; /* rw Fourth configuration register 0x34 */ + EREGS_PAD(thpd); /* The following is found on all chips except the NCR53C90 (ESP100) */ volatile unchar esp_tchi; /* rw High bits of transfer count 0x38 */ #define esp_uid esp_tchi /* ro Unique ID code 0x38 */ -#define fas_rlo esp_tchi /* rw HME extended counter 0x38 */ EREGS_PAD(fgpad); volatile unchar esp_fgrnd; /* rw Data base for fifo 0x3c */ -#define fas_rhi esp_fgrnd /* rw HME extended counter 0x3c */ }; -#else -#define SETREG(reg, val) outb(val, reg) -#define GETREG(reg) inb(reg) +#else /* MULTIPLE_PAD_SIZES */ + +#define esp_write(__reg, __val) (*(__reg) = (__val)) +#define esp_read(__reg) (*(__reg)) struct ESP_regs { -#ifdef CONFIG_MCA - unsigned int slot; + unsigned char io_addr[64]; /* dummy */ + /* Access Description Offset */ +#define esp_tclow io_addr /* rw Low bits of the transfer count 0x00 */ +#define esp_tcmed io_addr + (1<<(esp->shift)) /* rw Mid bits of the transfer count 0x04 */ +#define esp_fdata io_addr + (2<<(esp->shift)) /* rw FIFO data bits 0x08 */ +#define esp_cmnd io_addr + (3<<(esp->shift)) /* rw SCSI command bits 0x0c */ +#define esp_status io_addr + (4<<(esp->shift)) /* ro ESP status register 0x10 */ +#define esp_busid esp_status /* wo Bus ID for select/reselect 0x10 */ +#define esp_intrpt io_addr + (5<<(esp->shift)) /* ro Kind of interrupt 0x14 */ +#define esp_timeo esp_intrpt /* wo Timeout value for select/resel 0x14 */ +#define esp_sstep io_addr + (6<<(esp->shift)) /* ro Sequence step register 0x18 */ +#define esp_stp esp_sstep /* wo Transfer period per sync 0x18 */ +#define esp_fflags io_addr + (7<<(esp->shift)) /* ro Bits of current FIFO info 0x1c */ +#define esp_soff esp_fflags /* wo Sync offset 0x1c */ +#define esp_cfg1 io_addr + (8<<(esp->shift)) /* rw First configuration register 0x20 */ +#define esp_cfact io_addr + (9<<(esp->shift)) /* wo Clock conversion factor 0x24 */ +#define esp_ctest io_addr + (10<<(esp->shift)) /* wo Chip test register 0x28 */ +#define esp_cfg2 io_addr + (11<<(esp->shift)) /* rw Second configuration register 0x2c */ + + /* The following is only found on the 53C9X series SCSI chips */ +#define esp_cfg3 io_addr + (12<<(esp->shift)) /* rw Third configuration register 0x30 */ +#define esp_cfg4 io_addr + (13<<(esp->shift)) /* rw Fourth configuration register 0x34 */ + + /* The following is found on all chips except the NCR53C90 (ESP100) */ +#define esp_tchi io_addr + (14<<(esp->shift)) /* rw High bits of transfer count 0x38 */ +#define esp_uid esp_tchi /* ro Unique ID code 0x38 */ +#define esp_fgrnd io_addr + (15<<(esp->shift)) /* rw Data base for fifo 0x3c */ +}; + #endif + +#else /* !defined __i386__ */ + +#define esp_write(__reg, __val) outb((__val), (__reg)) +#define esp_read(__reg) inb((__reg)) + +struct ESP_regs { unsigned int io_addr; - /* Access Description Offset */ + /* Access Description Offset */ #define esp_tclow io_addr /* rw Low bits of the transfer count 0x00 */ #define esp_tcmed io_addr + 1 /* rw Mid bits of the transfer count 0x04 */ #define esp_fdata io_addr + 2 /* rw FIFO data bits 0x08 */ -#define esp_cmnd io_addr + 3 /* rw SCSI command bits 0x0c */ +#define esp_cmnd io_addr + 3 /* rw SCSI command bits 0x0c */ #define esp_status io_addr + 4 /* ro ESP status register 0x10 */ -#define esp_busid esp_status /* wo Bus ID for select/reselect 0x10 */ +#define esp_busid esp_status /* wo Bus ID for select/reselect 0x10 */ #define esp_intrpt io_addr + 5 /* ro Kind of interrupt 0x14 */ -#define esp_timeo esp_intrpt /* wo Timeout value for select/resel 0x14 */ +#define esp_timeo esp_intrpt /* wo Timeout value for select/resel 0x14 */ #define esp_sstep io_addr + 6 /* ro Sequence step register 0x18 */ -#define esp_stp esp_sstep /* wo Transfer period per sync 0x18 */ +#define esp_stp esp_sstep /* wo Transfer period per sync 0x18 */ #define esp_fflags io_addr + 7 /* ro Bits of current FIFO info 0x1c */ -#define esp_soff esp_fflags /* wo Sync offset 0x1c */ +#define esp_soff esp_fflags /* wo Sync offset 0x1c */ #define esp_cfg1 io_addr + 8 /* rw First configuration register 0x20 */ #define esp_cfact io_addr + 9 /* wo Clock conversion factor 0x24 */ -#define esp_status2 esp_cfact /* ro HME status2 register 0x24 */ #define esp_ctest io_addr + 10 /* wo Chip test register 0x28 */ #define esp_cfg2 io_addr + 11 /* rw Second configuration register 0x2c */ /* The following is only found on the 53C9X series SCSI chips */ #define esp_cfg3 io_addr + 12 /* rw Third configuration register 0x30 */ -#define esp_hole io_addr + 13 /* hole in register map 0x34 */ +#define esp_cfg4 io_addr + 13 /* rw Fourth configuration register 0x34 */ /* The following is found on all chips except the NCR53C90 (ESP100) */ #define esp_tchi io_addr + 14 /* rw High bits of transfer count 0x38 */ -#define esp_uid esp_tchi /* ro Unique ID code 0x38 */ -#define fas_rlo esp_tchi /* rw HME extended counter 0x38 */ +#define esp_uid esp_tchi /* ro Unique ID code 0x38 */ #define esp_fgrnd io_addr + 15 /* rw Data base for fifo 0x3c */ -#define fas_rhi esp_fgrnd /* rw HME extended counter 0x3c */ }; -#ifndef save_and_cli -#define save_and_cli(flags) save_flags(flags); cli(); -#endif - -#endif +#endif /* !defined(__i386__) */ /* Various revisions of the ESP board. */ enum esp_rev { @@ -243,26 +272,21 @@ fas236 = 0x03, fas100a = 0x04, fast = 0x05, - fashme = 0x06, - fas216 = 0x07, - espunknown = 0x08 + fas366 = 0x06, + fas216 = 0x07, + fsc = 0x08, /* SYM53C94-2 */ + espunknown = 0x09 }; /* We get one of these for each ESP probed. */ struct NCR_ESP { struct NCR_ESP *next; /* Next ESP on probed or NULL */ struct ESP_regs *eregs; /* All esp registers */ -#ifndef __i386__ - struct Linux_DMA *dma; /* Who I do transfers with. */ -#else - int dma; -#endif + int dma; /* Who I do transfers with. */ void *dregs; /* And his registers. */ struct Scsi_Host *ehost; /* Backpointer to SCSI Host */ void *edev; /* Pointer to controller base/SBus */ - char prom_name[64]; /* Name of ESP device from prom */ - int prom_node; /* Prom node where ESP found */ int esp_id; /* Unique per-ESP ID number */ /* ESP Configuration Registers */ @@ -292,11 +316,29 @@ unchar ireg; /* Copy of ESP interrupt register */ unchar sreg; /* Same for ESP status register */ unchar seqreg; /* The ESP sequence register */ - unchar sreg2; /* Copy of HME status2 register */ - /* The HME is the biggest piece of shit I have ever seen. */ - unchar hme_fifo_workaround_buffer[16 * 2]; /* 16-bit/entry fifo for wide scsi */ - unchar hme_fifo_workaround_count; + /* The following is set when a premature interrupt condition is detected + * in some FAS revisions. + */ + unchar fas_premature_intr_workaround; + + /* To save register writes to the ESP, which can be expensive, we + * keep track of the previous value that various registers had for + * the last target we connected to. If they are the same for the + * current target, we skip the register writes as they are not needed. + */ + unchar prev_soff, prev_stp, prev_cfg3; + + /* For each target we keep track of save/restore data + * pointer information. This needs to be updated majorly + * when we add support for tagged queueing. -DaveM + */ + struct esp_pointers { + char *saved_ptr; + struct scatterlist *saved_buffer; + int saved_this_residual; + int saved_buffers_residual; + } data_pointers[16] /*XXX [MAX_TAGS_PER_TARGET]*/; /* Clock periods, frequencies, synchronization, etc. */ unsigned int cfreq; /* Clock frequency in HZ */ @@ -308,7 +350,6 @@ unsigned int sync_defp; /* Default sync transfer period */ unsigned int max_period; /* longest our period can be */ unsigned int min_period; /* shortest period we can withstand */ - unsigned char ccf; /* Clock conversion factor */ /* For slow to medium speed input clock rates we shoot for 5mb/s, * but for high input clock rates we try to do 10mb/s although I * don't think a transfer can even run that fast with an ESP even @@ -328,15 +369,11 @@ /* Misc. info about this ESP */ enum esp_rev erev; /* ESP revision */ - int irq; /* SBus IRQ for this ESP */ + int irq; /* IRQ for this ESP */ int scsi_id; /* Who am I as initiator? */ int scsi_id_mask; /* Bitmask of 'me'. */ int diff; /* Differential SCSI bus? */ - int bursts; /* Burst sizes our DVMA supports */ - -#ifdef CONFIG_MCA - int slot; /* MCA slot the adapter occupies */ -#endif + int slot; /* Slot the adapter occupies */ /* Our command queues, only one cmd lives in the current_SC queue. */ Scsi_Cmnd *issue_SC; /* Commands to be issued */ @@ -357,6 +394,9 @@ unchar do_pio_cmds; /* Do command transfer with pio */ + /* How much bits do we have to shift the registers */ + unsigned char shift; + /* Functions handling DMA */ /* Required functions */ @@ -400,38 +440,38 @@ #define ESP_CONFIG1_SRRDISAB 0x40 /* Disable SCSI reset reports */ #define ESP_CONFIG1_SLCABLE 0x80 /* Enable slow cable mode */ -/* ESP config reg 2, read-write, found only on esp100a+esp200+esp236 chips */ -#define ESP_CONFIG2_DMAPARITY 0x01 /* enable DMA Parity (200,236) */ -#define ESP_CONFIG2_REGPARITY 0x02 /* enable reg Parity (200,236) */ +/* ESP config reg 2, read-write, found only on esp100a+esp200+esp236+fsc chips */ +#define ESP_CONFIG2_DMAPARITY 0x01 /* enable DMA Parity (200,236,fsc) */ +#define ESP_CONFIG2_REGPARITY 0x02 /* enable reg Parity (200,236,fsc) */ #define ESP_CONFIG2_BADPARITY 0x04 /* Bad parity target abort */ #define ESP_CONFIG2_SCSI2ENAB 0x08 /* Enable SCSI-2 features (tmode only) */ #define ESP_CONFIG2_HI 0x10 /* High Impedance DREQ ??? */ #define ESP_CONFIG2_HMEFENAB 0x10 /* HME features enable */ -#define ESP_CONFIG2_BCM 0x20 /* Enable byte-ctrl (236) */ -#define ESP_CONFIG2_DISPINT 0x20 /* Disable pause irq (hme) */ -#define ESP_CONFIG2_FENAB 0x40 /* Enable features (fas100,esp216) */ +#define ESP_CONFIG2_BCM 0x20 /* Enable byte-ctrl (236,fsc) */ +#define ESP_CONFIG2_FENAB 0x40 /* Enable features (fas100,esp216,fsc) */ #define ESP_CONFIG2_SPL 0x40 /* Enable status-phase latch (esp236) */ -#define ESP_CONFIG2_MKDONE 0x40 /* HME magic feature */ -#define ESP_CONFIG2_HME32 0x80 /* HME 32 extended */ +#define ESP_CONFIG2_RFB 0x80 /* Reserve FIFO byte (fsc) */ #define ESP_CONFIG2_MAGIC 0xe0 /* Invalid bits... */ -/* ESP config register 3 read-write, found only esp236+fas236+fas100a+hme chips */ -#define ESP_CONFIG3_FCLOCK 0x01 /* FAST SCSI clock rate (esp100a/hme) */ -#define ESP_CONFIG3_TEM 0x01 /* Enable thresh-8 mode (esp/fas236) */ -#define ESP_CONFIG3_FAST 0x02 /* Enable FAST SCSI (esp100a/hme) */ -#define ESP_CONFIG3_ADMA 0x02 /* Enable alternate-dma (esp/fas236) */ -#define ESP_CONFIG3_TENB 0x04 /* group2 SCSI2 support (esp100a/hme) */ -#define ESP_CONFIG3_SRB 0x04 /* Save residual byte (esp/fas236) */ -#define ESP_CONFIG3_TMS 0x08 /* Three-byte msg's ok (esp100a/hme) */ -#define ESP_CONFIG3_FCLK 0x08 /* Fast SCSI clock rate (esp/fas236) */ -#define ESP_CONFIG3_IDMSG 0x10 /* ID message checking (esp100a/hme) */ -#define ESP_CONFIG3_FSCSI 0x10 /* Enable FAST SCSI (esp/fas236) */ -#define ESP_CONFIG3_GTM 0x20 /* group2 SCSI2 support (esp/fas236) */ -#define ESP_CONFIG3_BIGID 0x20 /* SCSI-ID's are 4bits (hme) */ -#define ESP_CONFIG3_TBMS 0x40 /* Three-byte msg's ok (esp/fas236) */ -#define ESP_CONFIG3_EWIDE 0x40 /* Enable Wide-SCSI (hme) */ -#define ESP_CONFIG3_IMS 0x80 /* ID msg chk'ng (esp/fas236) */ -#define ESP_CONFIG3_OBPUSH 0x80 /* Push odd-byte to dma (hme) */ +/* ESP config register 3 read-write, found only esp236+fas236+fas100a+fsc chips */ +#define ESP_CONFIG3_FCLOCK 0x01 /* FAST SCSI clock rate (esp100a/fas366) */ +#define ESP_CONFIG3_TEM 0x01 /* Enable thresh-8 mode (esp/fas236/fsc) */ +#define ESP_CONFIG3_FAST 0x02 /* Enable FAST SCSI (esp100a) */ +#define ESP_CONFIG3_ADMA 0x02 /* Enable alternate-dma (esp/fas236/fsc) */ +#define ESP_CONFIG3_TENB 0x04 /* group2 SCSI2 support (esp100a) */ +#define ESP_CONFIG3_SRB 0x04 /* Save residual byte (esp/fas236/fsc) */ +#define ESP_CONFIG3_TMS 0x08 /* Three-byte msg's ok (esp100a) */ +#define ESP_CONFIG3_FCLK 0x08 /* Fast SCSI clock rate (esp/fas236/fsc) */ +#define ESP_CONFIG3_IDMSG 0x10 /* ID message checking (esp100a) */ +#define ESP_CONFIG3_FSCSI 0x10 /* Enable FAST SCSI (esp/fas236/fsc) */ +#define ESP_CONFIG3_GTM 0x20 /* group2 SCSI2 support (esp/fas236/fsc) */ +#define ESP_CONFIG3_TBMS 0x40 /* Three-byte msg's ok (esp/fas236/fsc) */ +#define ESP_CONFIG3_IMS 0x80 /* ID msg chk'ng (esp/fas236/fsc) */ + +/* ESP config register 4 read-write, found only on fsc chips */ +#define ESP_CONFIG4_BBTE 0x01 /* Back-to-Back transfer enable */ +#define ESP_CONFIG4_TEST 0x02 /* Transfer counter test mode */ +#define ESP_CONFIG4_EAN 0x04 /* Enable Active Negotiation */ /* ESP command register read-write */ /* Group 1 commands: These may be sent at any point in time to the ESP @@ -482,10 +522,9 @@ #define ESP_CMD_SA3 0x46 /* Select w/ATN3 */ #define ESP_CMD_RSEL3 0x47 /* Reselect3 */ -/* This bit enables the ESP's DMA on the SBus */ +/* This bit enables the ESP's DMA */ #define ESP_CMD_DMA 0x80 /* Do DMA? */ - /* ESP status register read-only */ #define ESP_STAT_PIO 0x01 /* IO phase bit */ #define ESP_STAT_PCD 0x02 /* CD phase bit */ @@ -495,21 +534,11 @@ #define ESP_STAT_TCNT 0x10 /* Transfer Counter Is Zero */ #define ESP_STAT_PERR 0x20 /* Parity error */ #define ESP_STAT_SPAM 0x40 /* Real bad error */ -/* This indicates the 'interrupt pending' condition on esp236, it is a reserved - * bit on other revs of the ESP. +/* This indicates the 'interrupt pending' condition, it is a reserved + * bit on old revs of the ESP (ESP100, ESP100A, FAS100A). */ #define ESP_STAT_INTR 0x80 /* Interrupt */ -/* HME only: status 2 register */ -#define ESP_STAT2_SCHBIT 0x01 /* Upper bits 3-7 of sstep enabled */ -#define ESP_STAT2_FFLAGS 0x02 /* The fifo flags are now latched */ -#define ESP_STAT2_XCNT 0x04 /* The transfer counter is latched */ -#define ESP_STAT2_CREGA 0x08 /* The command reg is active now */ -#define ESP_STAT2_WIDE 0x10 /* Interface on this adapter is wide */ -#define ESP_STAT2_F1BYTE 0x20 /* There is one byte at top of fifo */ -#define ESP_STAT2_FMSB 0x40 /* Next byte in fifo is most significant */ -#define ESP_STAT2_FEMPTY 0x80 /* FIFO is empty */ - /* The status register can be masked with ESP_STAT_PMASK and compared * with the following values to determine the current phase the ESP * (at least thinks it) is in. For our purposes we also add our own @@ -555,22 +584,24 @@ #define ESP_STEP_FINI5 0x05 #define ESP_STEP_FINI6 0x06 #define ESP_STEP_FINI7 0x07 +#define ESP_STEP_SOM 0x08 /* Synchronous Offset Max */ /* ESP chip-test register read-write */ #define ESP_TEST_TARG 0x01 /* Target test mode */ #define ESP_TEST_INI 0x02 /* Initiator test mode */ #define ESP_TEST_TS 0x04 /* Tristate test mode */ -/* ESP unique ID register read-only, found on fas236+fas100a only */ -#define ESP_UID_F100A 0x00 /* ESP FAS100A */ -#define ESP_UID_F236 0x02 /* ESP FAS236 */ +/* ESP unique ID register read-only, found on fas236+fas100a+fsc only */ +#define ESP_UID_F100A 0x00 /* FAS100A */ +#define ESP_UID_F236 0x02 /* FAS236 */ +#define ESP_UID_FSC 0xa2 /* NCR53CF9x-2 */ #define ESP_UID_REV 0x07 /* ESP revision */ #define ESP_UID_FAM 0xf8 /* ESP family */ /* ESP fifo flags register read-only */ /* Note that the following implies a 16 byte FIFO on the ESP. */ #define ESP_FF_FBYTES 0x1f /* Num bytes in FIFO */ -#define ESP_FF_ONOTZERO 0x20 /* offset ctr not zero (esp100) */ +#define ESP_FF_ONOTZERO 0x20 /* offset ctr not zero (esp100,fsc) */ #define ESP_FF_SSTEP 0xe0 /* Sequence step */ /* ESP clock conversion factor register write-only */ @@ -583,14 +614,13 @@ #define ESP_CCF_F6 0x06 /* 25.01MHz - 30MHz */ #define ESP_CCF_F7 0x07 /* 30.01MHz - 35MHz */ -/* HME only... */ -#define ESP_BUSID_RESELID 0x10 -#define ESP_BUSID_CTR32BIT 0x40 - #define ESP_BUS_TIMEOUT 275 /* In milli-seconds */ #define ESP_TIMEO_CONST 8192 +#define FSC_TIMEO_CONST 7668 #define ESP_NEG_DEFP(mhz, cfact) \ ((ESP_BUS_TIMEOUT * ((mhz) / 1000)) / (8192 * (cfact))) +#define FSC_NEG_DEFP(mhz, cfact) \ + ((ESP_BUS_TIMEOUT * ((mhz) / 1000)) / (7668 * (cfact))) #define ESP_MHZ_TO_CYCLE(mhertz) ((1000000000) / ((mhertz) / 1000)) #define ESP_TICK(ccf, cycle) ((7682 * (ccf) * (cycle) / 1000)) @@ -609,6 +639,8 @@ extern inline void esp_cmd(struct NCR_ESP *esp, struct ESP_regs *eregs, unchar cmd); extern struct NCR_ESP *esp_allocate(Scsi_Host_Template *, void *); +extern void esp_deallocate(struct NCR_ESP *); +extern void esp_release(void); extern void esp_initialize(struct NCR_ESP *); extern void esp_intr(int, void *, struct pt_regs *); #endif /* !(NCR53C9X_H) */ diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/a2091.c linux/drivers/scsi/a2091.c --- v2.3.13/linux/drivers/scsi/a2091.c Sat Apr 11 11:13:25 1998 +++ linux/drivers/scsi/a2091.c Wed Aug 18 10:00:52 1999 @@ -34,6 +34,7 @@ static void a2091_intr (int irq, void *dummy, struct pt_regs *fp) { + unsigned long flags; unsigned int status; struct Scsi_Host *instance; for (instance = first_instance; instance && @@ -41,32 +42,20 @@ { status = DMA(instance)->ISTR; if (!(status & (ISTR_INT_F|ISTR_INT_P))) - continue; + continue; - if (status & ISTR_INTS) - { - /* disable PORTS interrupt */ - custom.intena = IF_PORTS; - wd33c93_intr (instance); - /* enable PORTS interrupt */ - custom.intena = IF_SETCLR | IF_PORTS; + if (status & ISTR_INTS) { + spin_lock_irqsave(&io_request_lock, flags); + wd33c93_intr (instance); + spin_unlock_irqrestore(&io_request_lock, flags); } } } -static void do_a2091_intr (int irq, void *dummy, struct pt_regs *fp) -{ - unsigned long flags; - - spin_lock_irqsave(&io_request_lock, flags); - a2091_intr(irq, dummy, fp); - spin_unlock_irqrestore(&io_request_lock, flags); -} - static int dma_setup (Scsi_Cmnd *cmd, int dir_in) { unsigned short cntr = CNTR_PDMD | CNTR_INTEN; - unsigned long addr = VTOP(cmd->SCp.ptr); + unsigned long addr = virt_to_bus(cmd->SCp.ptr); struct Scsi_Host *instance = cmd->host; /* don't allow DMA if the physical address is bad */ @@ -85,7 +74,7 @@ } /* get the physical address of the bounce buffer */ - addr = VTOP(HDATA(instance)->dma_bounce_buffer); + addr = virt_to_bus(HDATA(instance)->dma_bounce_buffer); /* the bounce buffer may not be in the first 16M of physmem */ if (addr & A2091_XFER_MASK) { @@ -200,7 +189,7 @@ static int num_a2091 = 0; -__initfunc(int a2091_detect(Scsi_Host_Template *tpnt)) +int __init a2091_detect(Scsi_Host_Template *tpnt) { static unsigned char called = 0; struct Scsi_Host *instance; @@ -229,7 +218,8 @@ if (num_a2091++ == 0) { first_instance = instance; a2091_template = instance->hostt; - request_irq(IRQ_AMIGA_PORTS, do_a2091_intr, 0, "A2091 SCSI", a2091_intr); + request_irq(IRQ_AMIGA_PORTS, a2091_intr, SA_SHORQ, "A2091 SCSI", + a2091_intr); } DMA(instance)->CNTR = CNTR_PDMD | CNTR_INTEN; zorro_config_board(key, 0); diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/a3000.c linux/drivers/scsi/a3000.c --- v2.3.13/linux/drivers/scsi/a3000.c Sat Apr 11 11:13:25 1998 +++ linux/drivers/scsi/a3000.c Wed Aug 18 10:00:52 1999 @@ -32,34 +32,25 @@ static void a3000_intr (int irq, void *dummy, struct pt_regs *fp) { - unsigned int status = DMA(a3000_host)->ISTR; + unsigned long flags; + unsigned int status = DMA(a3000_host)->ISTR; - if (!(status & ISTR_INT_P)) - return; - if (status & ISTR_INTS) - { - /* disable PORTS interrupt */ - custom.intena = IF_PORTS; - wd33c93_intr (a3000_host); - /* enable PORTS interrupt */ - custom.intena = IF_SETCLR | IF_PORTS; - } else { - printk("Non-serviced A3000 SCSI-interrupt? ISTR = %02x\n", status); - } + if (!(status & ISTR_INT_P)) + return; + if (status & ISTR_INTS) + { + spin_lock_irqsave(&io_request_lock, flags); + wd33c93_intr (a3000_host); + spin_unlock_irqrestore(&io_request_lock, flags); + } else + printk("Non-serviced A3000 SCSI-interrupt? ISTR = %02x\n", + status); } -static void do_a3000_intr (int irq, void *dummy, struct pt_regs *fp) -{ - unsigned long flags; - - spin_lock_irqsave(&io_request_lock, flags); - a3000_intr(irq, dummy, fp); - spin_unlock_irqrestore(&io_request_lock, flags); -} static int dma_setup (Scsi_Cmnd *cmd, int dir_in) { unsigned short cntr = CNTR_PDMD | CNTR_INTEN; - unsigned long addr = VTOP(cmd->SCp.ptr); + unsigned long addr = virt_to_bus(cmd->SCp.ptr); /* * if the physical address has the wrong alignment, or if @@ -91,7 +82,7 @@ cmd->request_buffer, cmd->request_bufflen); } - addr = VTOP(HDATA(a3000_host)->dma_bounce_buffer); + addr = virt_to_bus(HDATA(a3000_host)->dma_bounce_buffer); } /* setup dma direction */ @@ -175,7 +166,7 @@ } } -__initfunc(int a3000_detect(Scsi_Host_Template *tpnt)) +int __init a3000_detect(Scsi_Host_Template *tpnt) { static unsigned char called = 0; @@ -194,7 +185,8 @@ DMA(a3000_host)->DAWR = DAWR_A3000; wd33c93_init(a3000_host, (wd33c93_regs *)&(DMA(a3000_host)->SASR), dma_setup, dma_stop, WD33C93_FS_12_15); - request_irq(IRQ_AMIGA_PORTS, do_a3000_intr, 0, "A3000 SCSI", a3000_intr); + request_irq(IRQ_AMIGA_PORTS, a3000_intr, SA_SHIRQ, "A3000 SCSI", + a3000_intr); DMA(a3000_host)->CNTR = CNTR_PDMD | CNTR_INTEN; called = 1; diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/amiga7xx.c linux/drivers/scsi/amiga7xx.c --- v2.3.13/linux/drivers/scsi/amiga7xx.c Mon Oct 5 13:43:31 1998 +++ linux/drivers/scsi/amiga7xx.c Wed Aug 18 10:00:52 1999 @@ -15,11 +15,14 @@ #include #include +#include #include #include #include #include +#include #include +#include #include "scsi.h" #include "hosts.h" @@ -33,11 +36,11 @@ S_IFDIR | S_IRUGO | S_IXUGO, 2 }; -extern ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip, - u32 base, int io_port, int irq, int dma, - long long options, int clock); +extern int ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip, + u32 base, int io_port, int irq, int dma, + long long options, int clock); -int amiga7xx_detect(Scsi_Host_Template *tpnt) +int __init amiga7xx_detect(Scsi_Host_Template *tpnt) { static unsigned char called = 0; unsigned int key; @@ -54,18 +57,13 @@ if ((key = zorro_find(ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS, 0, 0))) { cd = zorro_get_board(key); -/* - unsigned long address; - address = (unsigned long)kernel_map((unsigned long)cd->cd_BoardAddr, - cd->cd_BoardSize, KERNELMAP_NOCACHE_SER, NULL); -*/ + options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT; clock = 50000000; /* 50MHz SCSI Clock */ - ncr53c7xx_init(tpnt, 0, 710, (u32)(unsigned char *)(0x80f40000), - 0, IRQ_AMIGA_PORTS, DMA_NONE, - options, clock); + ncr53c7xx_init(tpnt, 0, 710, (u32)ZTWO_VADDR(0xf40000), 0, + IRQ_AMIGA_PORTS, DMA_NONE, options, clock); zorro_config_board(key, 0); num++; @@ -77,16 +75,15 @@ { unsigned long address; cd = zorro_get_board(key); - address = (unsigned long)kernel_map((unsigned long)cd->cd_BoardAddr, - cd->cd_BoardSize, KERNELMAP_NOCACHE_SER, NULL); + address = (unsigned long)ioremap((unsigned long)cd->cd_BoardAddr, + cd->cd_BoardSize); options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT; clock = 50000000; /* 50MHz SCSI Clock */ ncr53c7xx_init(tpnt, 0, 710, (u32)(unsigned char *)(address + 0x40000), - 0, IRQ_AMIGA_PORTS, DMA_NONE, - options, clock); + 0, IRQ_AMIGA_PORTS, DMA_NONE, options, clock); zorro_config_board(key, 0); num++; @@ -100,9 +97,8 @@ clock = 50000000; /* 50MHz SCSI Clock */ - ncr53c7xx_init(tpnt, 0, 710, (u32)(unsigned char *)ZTWO_VADDR(0xDD0040), - 0, IRQ_AMIGA_PORTS, DMA_NONE, - options, clock); + ncr53c7xx_init(tpnt, 0, 710, (u32)ZTWO_VADDR(0xDD0040), 0, + IRQ_AMIGA_PORTS, DMA_NONE, options, clock); num++; } #endif @@ -113,8 +109,8 @@ { unsigned long address; cd = zorro_get_board(key); - address = (unsigned long)kernel_map((unsigned long)cd->cd_BoardAddr, - cd->cd_BoardSize, KERNELMAP_NOCACHE_SER, NULL); + address = (unsigned long)ioremap((unsigned long)cd->cd_BoardAddr, + cd->cd_BoardSize); options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT; diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/atari_NCR5380.c linux/drivers/scsi/atari_NCR5380.c --- v2.3.13/linux/drivers/scsi/atari_NCR5380.c Tue May 13 22:41:13 1997 +++ linux/drivers/scsi/atari_NCR5380.c Wed Aug 18 10:00:52 1999 @@ -472,9 +472,9 @@ int cnt = 1; #endif - for (endaddr = VTOP(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1; + for (endaddr = virt_to_phys(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1; cmd->SCp.buffers_residual && - VTOP(cmd->SCp.buffer[1].address) == endaddr; ) { + virt_to_phys(cmd->SCp.buffer[1].address) == endaddr; ) { MER_PRINTK("VTOP(%p) == %08lx -> merging\n", cmd->SCp.buffer[1].address, endaddr); @@ -1459,9 +1459,9 @@ unsigned long timeout = jiffies + 2*NCR_TIMEOUT; while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) - && jiffies < timeout && !hostdata->connected) + && time_before(jiffies, timeout) && !hostdata->connected) ; - if (jiffies >= timeout) + if (time_after_eq(jiffies, timeout)) { printk("scsi : arbitration timeout at %d\n", __LINE__); NCR5380_write(MODE_REG, MR_BASE); @@ -1616,7 +1616,7 @@ * only wait for BSY... (Famous german words: Der Klügere gibt nach :-) */ - while ((jiffies < timeout) && !(NCR5380_read(STATUS_REG) & + while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO))); if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == @@ -1629,7 +1629,7 @@ return -1; } #else - while ((jiffies < timeout) && !(NCR5380_read(STATUS_REG) & SR_BSY)); + while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & SR_BSY)); #endif /* diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/atari_scsi.c linux/drivers/scsi/atari_scsi.c --- v2.3.13/linux/drivers/scsi/atari_scsi.c Tue May 11 15:49:26 1999 +++ linux/drivers/scsi/atari_scsi.c Wed Aug 18 10:00:52 1999 @@ -132,51 +132,51 @@ } while(0) #define SCSI_DMA_READ_P(elt) \ - (((unsigned long)tt_scsi_dma.elt##_hi << 24) | \ - ((unsigned long)tt_scsi_dma.elt##_hmd << 16) | \ - ((unsigned long)tt_scsi_dma.elt##_lmd << 8) | \ - (unsigned long)tt_scsi_dma.elt##_lo) - - -#define SCSI_DMA_SETADR(adr) \ - do { \ - unsigned long __adr = (adr); \ - st_dma.dma_lo = (unsigned char)__adr; \ - MFPDELAY(); \ - __adr >>= 8; \ - st_dma.dma_md = (unsigned char)__adr; \ - MFPDELAY(); \ - __adr >>= 8; \ - st_dma.dma_hi = (unsigned char)__adr; \ - MFPDELAY(); \ - } while(0) - -#define SCSI_DMA_GETADR() ({ \ - unsigned long __adr; \ - __adr = st_dma.dma_lo; \ - MFPDELAY(); \ - __adr |= (st_dma.dma_md & 0xff) << 8; \ - MFPDELAY(); \ - __adr |= (st_dma.dma_hi & 0xff) << 16; \ - MFPDELAY(); \ - __adr; \ -}) - -#define ENABLE_IRQ() \ - do { \ - if (IS_A_TT()) \ - atari_enable_irq( IRQ_TT_MFP_SCSI ); \ - else \ - atari_enable_irq( IRQ_MFP_FSCSI ); \ - } while(0) - -#define DISABLE_IRQ() \ - do { \ - if (IS_A_TT()) \ - atari_disable_irq( IRQ_TT_MFP_SCSI ); \ - else \ - atari_disable_irq( IRQ_MFP_FSCSI ); \ - } while(0) + (((((((unsigned long)tt_scsi_dma.elt##_hi << 8) | \ + (unsigned long)tt_scsi_dma.elt##_hmd) << 8) | \ + (unsigned long)tt_scsi_dma.elt##_lmd) << 8) | \ + (unsigned long)tt_scsi_dma.elt##_lo) + + +static inline void SCSI_DMA_SETADR(unsigned long adr) +{ + st_dma.dma_lo = (unsigned char)adr; + MFPDELAY(); + adr >>= 8; + st_dma.dma_md = (unsigned char)adr; + MFPDELAY(); + adr >>= 8; + st_dma.dma_hi = (unsigned char)adr; + MFPDELAY(); +} + +static inline unsigned long SCSI_DMA_GETADR(void) +{ + unsigned long adr; + adr = st_dma.dma_lo; + MFPDELAY(); + adr |= (st_dma.dma_md & 0xff) << 8; + MFPDELAY(); + adr |= (st_dma.dma_hi & 0xff) << 16; + MFPDELAY(); + return adr; +} + +static inline void ENABLE_IRQ(void) +{ + if (IS_A_TT()) + atari_enable_irq(IRQ_TT_MFP_SCSI); + else + atari_enable_irq(IRQ_MFP_FSCSI); +} + +static inline void DISABLE_IRQ(void) +{ + if (IS_A_TT()) + atari_disable_irq(IRQ_TT_MFP_SCSI); + else + atari_disable_irq(IRQ_MFP_FSCSI); +} #define HOSTDATA_DMALEN (((struct NCR5380_hostdata *) \ @@ -461,8 +461,8 @@ /* If the dribble buffer was used on a read operation, copy the DMA-ed * data to the original destination address. */ - memcpy( atari_dma_orig_addr, (void *)PTOV(atari_dma_startaddr), - HOSTDATA_DMALEN - atari_dma_residual ); + memcpy(atari_dma_orig_addr, phys_to_virt(atari_dma_startaddr), + HOSTDATA_DMALEN - atari_dma_residual); atari_dma_orig_addr = NULL; } @@ -476,20 +476,22 @@ static void atari_scsi_fetch_restbytes( void ) { int nr; - char *src, *dst; + char *src, *dst; + unsigned long phys_dst; /* fetch rest bytes in the DMA register */ - dst = (char *)SCSI_DMA_READ_P( dma_addr ); - if ((nr = ((long)dst & 3))) { - /* there are 'nr' bytes left for the last long address before the - DMA pointer */ - dst = (char *)( (unsigned long)dst & ~3 ); + phys_dst = SCSI_DMA_READ_P(dma_addr); + nr = phys_dst & 3; + if (nr) { + /* there are 'nr' bytes left for the last long address + before the DMA pointer */ + phys_dst ^= nr; DMA_PRINTK("SCSI DMA: there are %d rest bytes for phys addr 0x%08lx", - nr, (long)dst); - dst = (char *)PTOV(dst); /* The content of the DMA pointer - * is a physical address! */ - DMA_PRINTK(" = virt addr 0x%08lx\n", (long)dst); - for( src = (char *)&tt_scsi_dma.dma_restdata; nr > 0; --nr ) + nr, phys_dst); + /* The content of the DMA pointer is a physical address! */ + dst = phys_to_virt(phys_dst); + DMA_PRINTK(" = virt addr %p\n", dst); + for (src = (char *)&tt_scsi_dma.dma_restdata; nr != 0; --nr) *dst++ = *src++; } } @@ -665,7 +667,7 @@ "double buffer\n" ); return( 0 ); } - atari_dma_phys_buffer = VTOP( atari_dma_buffer ); + atari_dma_phys_buffer = virt_to_phys( atari_dma_buffer ); atari_dma_orig_addr = 0; } #endif @@ -764,7 +766,7 @@ } #endif -__initfunc(void atari_scsi_setup( char *str, int *ints )) +void __init atari_scsi_setup(char *str, int *ints) { /* Format of atascsi parameter is: * atascsi=,,,, @@ -772,23 +774,6 @@ * Negative values mean don't change. */ - /* Grmbl... the standard parameter parsing can't handle negative numbers - * :-( So let's do it ourselves! - */ - - int i = ints[0]+1, fact; - - while( str && (isdigit(*str) || *str == '-') && i <= 10) { - if (*str == '-') - fact = -1, ++str; - else - fact = 1; - ints[i++] = simple_strtoul( str, NULL, 0 ) * fact; - if ((str = strchr( str, ',' )) != NULL) - ++str; - } - ints[0] = i-1; - if (ints[0] < 1) { printk( "atari_scsi_setup: no arguments!\n" ); return; @@ -869,7 +854,7 @@ #ifdef CONFIG_ATARI_SCSI_RESET_BOOT -__initfunc(static void atari_scsi_reset_boot( void )) +static void __init atari_scsi_reset_boot(void) { unsigned long end; @@ -892,7 +877,8 @@ NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE ); NCR5380_read( RESET_PARITY_INTERRUPT_REG ); - for( end = jiffies + AFTER_RESET_DELAY; jiffies < end; ) + end = jiffies + AFTER_RESET_DELAY; + while (time_before(jiffies, end)) barrier(); printk( " done\n" ); @@ -913,7 +899,7 @@ unsigned long atari_scsi_dma_setup( struct Scsi_Host *instance, void *data, unsigned long count, int dir ) { - unsigned long addr = VTOP( data ); + unsigned long addr = virt_to_phys( data ); DMA_PRINTK("scsi%d: setting up dma, data = %p, phys = %lx, count = %ld, " "dir = %d\n", instance->host_no, data, addr, count, dir); @@ -1097,7 +1083,7 @@ } /* Last step: apply the hard limit on DMA transfers */ - limit = (atari_dma_buffer && !STRAM_ADDR( VTOP(cmd->SCp.ptr) )) ? + limit = (atari_dma_buffer && !STRAM_ADDR( virt_to_phys(cmd->SCp.ptr) )) ? STRAM_BUFFER_SIZE : 255*512; if (possible_len > limit) possible_len = limit; diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/blz1230.c linux/drivers/scsi/blz1230.c --- v2.3.13/linux/drivers/scsi/blz1230.c Wed Nov 11 11:50:00 1998 +++ linux/drivers/scsi/blz1230.c Wed Aug 18 10:00:52 1999 @@ -14,6 +14,8 @@ * routines in this file used to be inline! */ +#include + #include #include #include @@ -55,7 +57,7 @@ */ /***************************************************************** Detection */ -int blz1230_esp_detect(Scsi_Host_Template *tpnt) +int __init blz1230_esp_detect(Scsi_Host_Template *tpnt) { struct NCR_ESP *esp; const struct ConfigDev *esp_dev; @@ -80,12 +82,15 @@ eregs = (struct ESP_regs *)(address + BLZ1230II_ESP_ADDR); #endif - eregs->esp_cfg1 = (ESP_CONFIG1_PENABLE | 7); + esp = esp_allocate(tpnt, (void *) esp_dev); + + esp_write(eregs->esp_cfg1, (ESP_CONFIG1_PENABLE | 7)); udelay(5); - if(eregs->esp_cfg1 != (ESP_CONFIG1_PENABLE | 7)) + if(esp_read(eregs->esp_cfg1) != (ESP_CONFIG1_PENABLE | 7)){ + esp_deallocate(esp); + scsi_unregister(esp->ehost); return 0; /* Bail out if address did not hold data */ - - esp = esp_allocate(tpnt, (void *) esp_dev); + } /* Do command transfer with programmed I/O */ esp->do_pio_cmds = 1; @@ -131,24 +136,24 @@ /* Set the command buffer */ esp->esp_command = (volatile unsigned char*) cmd_buffer; - esp->esp_command_dvma = virt_to_bus((unsigned long) cmd_buffer); + esp->esp_command_dvma = virt_to_bus(cmd_buffer); esp->irq = IRQ_AMIGA_PORTS; - request_irq(IRQ_AMIGA_PORTS, esp_intr, 0, + esp->slot = key; + request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ, "Blizzard 1230 SCSI IV", esp_intr); /* Figure out our scsi ID on the bus */ esp->scsi_id = 7; - /* Check for differential SCSI-bus */ - /* What is this stuff? */ + /* We don't have a differential SCSI-bus. */ esp->diff = 0; esp_initialize(esp); zorro_config_board(key, 0); - printk("\nESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use); + printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use); esps_running = esps_in_use; return esps_in_use; } @@ -249,7 +254,7 @@ static int dma_irq_p(struct NCR_ESP *esp) { - return (esp->eregs->esp_status & ESP_STAT_INTR); + return (esp_read(esp->eregs->esp_status) & ESP_STAT_INTR); } static int dma_ports_p(struct NCR_ESP *esp) @@ -267,4 +272,30 @@ } else { dma_init_write(esp, addr, count); } +} + +#ifdef MODULE + +#define HOSTS_C + +#include "blz1230.h" + +Scsi_Host_Template driver_template = SCSI_BLZ1230; + +#include "scsi_module.c" + +#endif + +int blz1230_esp_release(struct Scsi_Host *instance) +{ +#ifdef MODULE + unsigned int key; + + key = ((struct NCR_ESP *)instance->hostdata)->slot; + esp_deallocate((struct NCR_ESP *)instance->hostdata); + esp_release(); + zorro_unconfig_board(key, 0); + free_irq(IRQ_AMIGA_PORTS, esp_intr); +#endif + return 1; } diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/blz1230.h linux/drivers/scsi/blz1230.h --- v2.3.13/linux/drivers/scsi/blz1230.h Tue Jun 22 14:43:06 1999 +++ linux/drivers/scsi/blz1230.h Wed Aug 18 10:00:52 1999 @@ -48,6 +48,7 @@ #define BLZ1230_DMA_WRITE 0x80000000 extern int blz1230_esp_detect(struct SHT *); +extern int blz1230_esp_release(struct Scsi_Host *); extern const char *esp_info(struct Scsi_Host *); extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); extern int esp_command(Scsi_Cmnd *); @@ -57,9 +58,11 @@ int hostno, int inout); #define SCSI_BLZ1230 { proc_dir: &proc_scsi_esp, \ + proc_info: esp_proc_info, \ name: "Blizzard1230 SCSI IV", \ detect: blz1230_esp_detect, \ - release: NULL, \ + release: blz1230_esp_release, \ + command: esp_command, \ queuecommand: esp_queue, \ abort: esp_abort, \ reset: esp_reset, \ @@ -67,6 +70,6 @@ this_id: 7, \ sg_tablesize: SG_ALL, \ cmd_per_lun: 1, \ - use_clustering: DISABLE_CLUSTERING } + use_clustering: ENABLE_CLUSTERING } #endif /* BLZ1230_H */ diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/blz2060.c linux/drivers/scsi/blz2060.c --- v2.3.13/linux/drivers/scsi/blz2060.c Wed Nov 11 11:50:00 1998 +++ linux/drivers/scsi/blz2060.c Wed Aug 18 10:00:52 1999 @@ -14,6 +14,8 @@ * routines in this file used to be inline! */ +#include + #include #include #include @@ -55,7 +57,7 @@ */ /***************************************************************** Detection */ -int blz2060_esp_detect(Scsi_Host_Template *tpnt) +int __init blz2060_esp_detect(Scsi_Host_Template *tpnt) { struct NCR_ESP *esp; const struct ConfigDev *esp_dev; @@ -107,24 +109,24 @@ /* Set the command buffer */ esp->esp_command = (volatile unsigned char*) cmd_buffer; - esp->esp_command_dvma = virt_to_bus((unsigned long) cmd_buffer); + esp->esp_command_dvma = virt_to_bus(cmd_buffer); esp->irq = IRQ_AMIGA_PORTS; - request_irq(IRQ_AMIGA_PORTS, esp_intr, 0, + esp->slot = key; + request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ, "Blizzard 2060 SCSI", esp_intr); /* Figure out our scsi ID on the bus */ esp->scsi_id = 7; - /* Check for differential SCSI-bus */ - /* What is this stuff? */ + /* We don't have a differential SCSI-bus. */ esp->diff = 0; esp_initialize(esp); zorro_config_board(key, 0); - printk("\nESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use); + printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use); esps_running = esps_in_use; return esps_in_use; } @@ -201,7 +203,7 @@ static int dma_irq_p(struct NCR_ESP *esp) { - return (esp->eregs->esp_status & ESP_STAT_INTR); + return (esp_read(esp->eregs->esp_status) & ESP_STAT_INTR); } static void dma_led_off(struct NCR_ESP *esp) @@ -230,4 +232,30 @@ } else { dma_init_write(esp, addr, count); } +} + +#ifdef MODULE + +#define HOSTS_C + +#include "blz2060.h" + +Scsi_Host_Template driver_template = SCSI_BLZ2060; + +#include "scsi_module.c" + +#endif + +int blz2060_esp_release(struct Scsi_Host *instance) +{ +#ifdef MODULE + unsigned int key; + + key = ((struct NCR_ESP *)instance->hostdata)->slot; + esp_deallocate((struct NCR_ESP *)instance->hostdata); + esp_release(); + zorro_unconfig_board(key, 0); + free_irq(IRQ_AMIGA_PORTS, esp_intr); +#endif + return 1; } diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/blz2060.h linux/drivers/scsi/blz2060.h --- v2.3.13/linux/drivers/scsi/blz2060.h Tue Jun 22 14:43:06 1999 +++ linux/drivers/scsi/blz2060.h Wed Aug 18 10:00:52 1999 @@ -44,6 +44,7 @@ #define BLZ2060_DMA_LED 0x02 /* HD led control 1 = off */ extern int blz2060_esp_detect(struct SHT *); +extern int blz2060_esp_release(struct Scsi_Host *); extern const char *esp_info(struct Scsi_Host *); extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); extern int esp_command(Scsi_Cmnd *); @@ -53,9 +54,10 @@ int hostno, int inout); #define SCSI_BLZ2060 { proc_dir: &proc_scsi_esp, \ + proc_info: esp_proc_info, \ name: "Blizzard2060 SCSI", \ detect: blz2060_esp_detect, \ - release: NULL, \ + release: blz2060_esp_release, \ queuecommand: esp_queue, \ abort: esp_abort, \ reset: esp_reset, \ @@ -63,6 +65,6 @@ this_id: 7, \ sg_tablesize: SG_ALL, \ cmd_per_lun: 1, \ - use_clustering: DISABLE_CLUSTERING } + use_clustering: ENABLE_CLUSTERING } #endif /* BLZ2060_H */ diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/cyberstorm.c linux/drivers/scsi/cyberstorm.c --- v2.3.13/linux/drivers/scsi/cyberstorm.c Wed Nov 11 11:50:00 1998 +++ linux/drivers/scsi/cyberstorm.c Wed Aug 18 10:00:52 1999 @@ -17,6 +17,8 @@ * routines in this file used to be inline! */ +#include + #include #include #include @@ -64,7 +66,7 @@ */ /***************************************************************** Detection */ -int cyber_esp_detect(Scsi_Host_Template *tpnt) +int __init cyber_esp_detect(Scsi_Host_Template *tpnt) { struct NCR_ESP *esp; const struct ConfigDev *esp_dev; @@ -127,10 +129,11 @@ /* Set the command buffer */ esp->esp_command = (volatile unsigned char*) cmd_buffer; - esp->esp_command_dvma = virt_to_bus((unsigned long) cmd_buffer); + esp->esp_command_dvma = virt_to_bus(cmd_buffer); esp->irq = IRQ_AMIGA_PORTS; - request_irq(IRQ_AMIGA_PORTS, esp_intr, 0, + esp->slot = key; + request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ, "CyberStorm SCSI", esp_intr); /* Figure out our scsi ID on the bus */ /* The DMA cond flag contains a hardcoded jumper bit @@ -140,15 +143,14 @@ */ esp->scsi_id = 7; - /* Check for differential SCSI-bus */ - /* What is this stuff? */ + /* We don't have a differential SCSI-bus. */ esp->diff = 0; esp_initialize(esp); zorro_config_board(key, 0); - printk("\nESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use); + printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use); esps_running = esps_in_use; return esps_in_use; } @@ -263,7 +265,7 @@ static int dma_irq_p(struct NCR_ESP *esp) { /* It's important to check the DMA IRQ bit in the correct way! */ - return ((esp->eregs->esp_status & ESP_STAT_INTR) && + return ((esp_read(esp->eregs->esp_status) & ESP_STAT_INTR) && ((((struct cyber_dma_registers *)(esp->dregs))->cond_reg) & CYBER_DMA_HNDL_INTR)); } @@ -295,4 +297,30 @@ } else { dma_init_write(esp, addr, count); } +} + +#ifdef MODULE + +#define HOSTS_C + +#include "cyberstorm.h" + +Scsi_Host_Template driver_template = SCSI_CYBERSTORM; + +#include "scsi_module.c" + +#endif + +int cyber_esp_release(struct Scsi_Host *instance) +{ +#ifdef MODULE + unsigned int key; + + key = ((struct NCR_ESP *)instance->hostdata)->slot; + esp_deallocate((struct NCR_ESP *)instance->hostdata); + esp_release(); + zorro_unconfig_board(key, 0); + free_irq(IRQ_AMIGA_PORTS, esp_intr); +#endif + return 1; } diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/cyberstorm.h linux/drivers/scsi/cyberstorm.h --- v2.3.13/linux/drivers/scsi/cyberstorm.h Tue Jun 22 14:43:06 1999 +++ linux/drivers/scsi/cyberstorm.h Wed Aug 18 10:00:52 1999 @@ -46,6 +46,7 @@ #define CYBER_SLOW_CABLE 0x08 /* If *not* set, assume SLOW_CABLE */ extern int cyber_esp_detect(struct SHT *); +extern int cyber_esp_release(struct Scsi_Host *); extern const char *esp_info(struct Scsi_Host *); extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); extern int esp_command(Scsi_Cmnd *); @@ -56,9 +57,10 @@ #define SCSI_CYBERSTORM { proc_dir: &proc_scsi_esp, \ + proc_info: esp_proc_info, \ name: "CyberStorm SCSI", \ detect: cyber_esp_detect, \ - release: NULL, \ + release: cyber_esp_release, \ queuecommand: esp_queue, \ abort: esp_abort, \ reset: esp_reset, \ @@ -66,7 +68,6 @@ this_id: 7, \ sg_tablesize: SG_ALL, \ cmd_per_lun: 1, \ - use_clustering: DISABLE_CLUSTERING } + use_clustering: ENABLE_CLUSTERING } #endif /* CYBER_ESP_H */ - diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/cyberstormII.c linux/drivers/scsi/cyberstormII.c --- v2.3.13/linux/drivers/scsi/cyberstormII.c Mon Oct 5 13:43:31 1998 +++ linux/drivers/scsi/cyberstormII.c Wed Aug 18 10:00:52 1999 @@ -13,6 +13,8 @@ * routines in this file used to be inline! */ +#include + #include #include #include @@ -54,7 +56,7 @@ */ /***************************************************************** Detection */ -int cyberII_esp_detect(Scsi_Host_Template *tpnt) +int __init cyberII_esp_detect(Scsi_Host_Template *tpnt) { struct NCR_ESP *esp; const struct ConfigDev *esp_dev; @@ -71,12 +73,15 @@ address = (unsigned long)ZTWO_VADDR(esp_dev->cd_BoardAddr); eregs = (struct ESP_regs *)(address + CYBERII_ESP_ADDR); - eregs->esp_cfg1 = (ESP_CONFIG1_PENABLE | 7); + esp = esp_allocate(tpnt, (void *) esp_dev); + + esp_write(eregs->esp_cfg1, (ESP_CONFIG1_PENABLE | 7)); udelay(5); - if(eregs->esp_cfg1 != (ESP_CONFIG1_PENABLE | 7)) + if(esp_read(eregs->esp_cfg1) != (ESP_CONFIG1_PENABLE | 7)) { + esp_deallocate(esp); + scsi_unregister(esp->ehost); return 0; /* Bail out if address did not hold data */ - - esp = esp_allocate(tpnt, (void *) esp_dev); + } /* Do command transfer with programmed I/O */ esp->do_pio_cmds = 1; @@ -118,24 +123,24 @@ /* Set the command buffer */ esp->esp_command = (volatile unsigned char*) cmd_buffer; - esp->esp_command_dvma = virt_to_bus((unsigned long) cmd_buffer); + esp->esp_command_dvma = virt_to_bus(cmd_buffer); esp->irq = IRQ_AMIGA_PORTS; - request_irq(IRQ_AMIGA_PORTS, esp_intr, 0, + esp->slot = key; + request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ, "CyberStorm SCSI Mk II", esp_intr); /* Figure out our scsi ID on the bus */ esp->scsi_id = 7; - /* Check for differential SCSI-bus */ - /* What is this stuff? */ + /* We don't have a differential SCSI-bus. */ esp->diff = 0; esp_initialize(esp); zorro_config_board(key, 0); - printk("\nESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use); + printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use); esps_running = esps_in_use; return esps_in_use; } @@ -214,7 +219,7 @@ static int dma_irq_p(struct NCR_ESP *esp) { /* It's important to check the DMA IRQ bit in the correct way! */ - return (esp->eregs->esp_status & ESP_STAT_INTR); + return (esp_read(esp->eregs->esp_status) & ESP_STAT_INTR); } static void dma_led_off(struct NCR_ESP *esp) @@ -242,4 +247,30 @@ } else { dma_init_write(esp, addr, count); } +} + +#ifdef MODULE + +#define HOSTS_C + +#include "cyberstormII.h" + +Scsi_Host_Template driver_template = SCSI_CYBERSTORMII; + +#include "scsi_module.c" + +#endif + +int cyberII_esp_release(struct Scsi_Host *instance) +{ +#ifdef MODULE + unsigned int key; + + key = ((struct NCR_ESP *)instance->hostdata)->slot; + esp_deallocate((struct NCR_ESP *)instance->hostdata); + esp_release(); + zorro_unconfig_board(key, 0); + free_irq(IRQ_AMIGA_PORTS, esp_intr); +#endif + return 1; } diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/cyberstormII.h linux/drivers/scsi/cyberstormII.h --- v2.3.13/linux/drivers/scsi/cyberstormII.h Tue Jun 22 14:43:06 1999 +++ linux/drivers/scsi/cyberstormII.h Wed Aug 18 10:00:52 1999 @@ -34,6 +34,7 @@ extern int cyberII_esp_detect(struct SHT *); +extern int cyberII_esp_release(struct Scsi_Host *); extern const char *esp_info(struct Scsi_Host *); extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); extern int esp_command(Scsi_Cmnd *); @@ -43,9 +44,10 @@ int hostno, int inout); #define SCSI_CYBERSTORMII { proc_dir: &proc_scsi_esp, \ + proc_info: esp_proc_info, \ name: "CyberStorm Mk II SCSI", \ detect: cyberII_esp_detect, \ - release: NULL, \ + release: cyberII_esp_release, \ queuecommand: esp_queue, \ abort: esp_abort, \ reset: esp_reset, \ @@ -53,7 +55,6 @@ this_id: 7, \ sg_tablesize: SG_ALL, \ cmd_per_lun: 1, \ - use_clustering: DISABLE_CLUSTERING } + use_clustering: ENABLE_CLUSTERING } #endif /* CYBERII_ESP_H */ - diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/fastlane.c linux/drivers/scsi/fastlane.c --- v2.3.13/linux/drivers/scsi/fastlane.c Wed Nov 11 11:50:00 1998 +++ linux/drivers/scsi/fastlane.c Wed Aug 18 10:00:52 1999 @@ -22,6 +22,8 @@ * routines in this file used to be inline! */ +#include + #include #include #include @@ -38,6 +40,7 @@ #include #include +#include #include #include @@ -77,7 +80,7 @@ */ /***************************************************************** Detection */ -int fastlane_esp_detect(Scsi_Host_Template *tpnt) +int __init fastlane_esp_detect(Scsi_Host_Template *tpnt) { struct NCR_ESP *esp; const struct ConfigDev *esp_dev; @@ -137,10 +140,8 @@ /* Map the physical address space into virtual kernel space */ address = (unsigned long) - kernel_map((unsigned long)esp_dev->cd_BoardAddr, - esp_dev->cd_BoardSize, - KERNELMAP_NOCACHE_SER, - NULL); + ioremap_nocache((unsigned long)esp_dev->cd_BoardAddr, + esp_dev->cd_BoardSize); if(!address){ printk("Could not remap Fastlane controller memory!"); @@ -163,17 +164,17 @@ /* Set the command buffer */ esp->esp_command = (volatile unsigned char*) cmd_buffer; - esp->esp_command_dvma = virt_to_bus((unsigned long) cmd_buffer); + esp->esp_command_dvma = virt_to_bus(cmd_buffer); esp->irq = IRQ_AMIGA_PORTS; - request_irq(IRQ_AMIGA_PORTS, esp_intr, 0, + esp->slot = key; + request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ, "Fastlane SCSI", esp_intr); /* Controller ID */ esp->scsi_id = 7; - /* Check for differential SCSI-bus */ - /* What is this stuff? */ + /* We don't have a differential SCSI-bus. */ esp->diff = 0; dma_clear(esp); @@ -181,7 +182,7 @@ zorro_config_board(key, 0); - printk("\nESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use); + printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use); esps_running = esps_in_use; return esps_in_use; } @@ -312,7 +313,7 @@ (dma_status & FASTLANE_DMA_CREQ) && #endif (!(dma_status & FASTLANE_DMA_MINT)) && - ((((struct ESP_regs *) (esp->eregs))->esp_status) & ESP_STAT_INTR)); + (esp_read(((struct ESP_regs *) (esp->eregs))->esp_status) & ESP_STAT_INTR)); } static void dma_led_off(struct NCR_ESP *esp) @@ -342,4 +343,30 @@ } else { dma_init_write(esp, addr, count); } +} + +#ifdef MODULE + +#define HOSTS_C + +#include "fastlane.h" + +Scsi_Host_Template driver_template = SCSI_FASTLANE; + +#include "scsi_module.c" + +#endif + +int fastlane_esp_release(struct Scsi_Host *instance) +{ +#ifdef MODULE + unsigned int key; + + key = ((struct NCR_ESP *)instance->hostdata)->slot; + esp_deallocate((struct NCR_ESP *)instance->hostdata); + esp_release(); + zorro_unconfig_board(key, 0); + free_irq(IRQ_AMIGA_PORTS, esp_intr); +#endif + return 1; } diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/fastlane.h linux/drivers/scsi/fastlane.h --- v2.3.13/linux/drivers/scsi/fastlane.h Tue Jun 22 14:43:08 1999 +++ linux/drivers/scsi/fastlane.h Wed Aug 18 10:00:52 1999 @@ -39,6 +39,7 @@ #define FASTLANE_DMA_ESI 0x01 /* Enable SCSI IRQ */ extern int fastlane_esp_detect(struct SHT *); +extern int fastlane_esp_release(struct Scsi_Host *); extern const char *esp_info(struct Scsi_Host *); extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); extern int esp_command(Scsi_Cmnd *); @@ -48,9 +49,10 @@ int hostno, int inout); #define SCSI_FASTLANE { proc_dir: &proc_scsi_esp, \ + proc_info: esp_proc_info, \ name: "Fastlane SCSI", \ detect: fastlane_esp_detect, \ - release: NULL, \ + release: fastlane_esp_release, \ queuecommand: esp_queue, \ abort: esp_abort, \ reset: esp_reset, \ @@ -58,6 +60,6 @@ this_id: 7, \ sg_tablesize: SG_ALL, \ cmd_per_lun: 1, \ - use_clustering: DISABLE_CLUSTERING } + use_clustering: ENABLE_CLUSTERING } #endif /* FASTLANE_H */ diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/gvp11.c linux/drivers/scsi/gvp11.c --- v2.3.13/linux/drivers/scsi/gvp11.c Sat Apr 11 11:13:25 1998 +++ linux/drivers/scsi/gvp11.c Wed Aug 18 10:00:52 1999 @@ -34,6 +34,7 @@ static void gvp11_intr (int irq, void *dummy, struct pt_regs *fp) { + unsigned long flags; unsigned int status; struct Scsi_Host *instance; @@ -44,23 +45,12 @@ if (!(status & GVP11_DMAC_INT_PENDING)) continue; - /* disable PORTS interrupt */ - custom.intena = IF_PORTS; + spin_lock_irqsave(&io_request_lock, flags); wd33c93_intr (instance); - /* enable PORTS interrupt */ - custom.intena = IF_SETCLR | IF_PORTS; + spin_unlock_irqrestore(&io_request_lock, flags); } } -static void do_gvp11_intr (int irq, void *dummy, struct pt_regs *fp) -{ - unsigned long flags; - - spin_lock_irqsave(&io_request_lock, flags); - gvp11_intr(irq, dummy, fp); - spin_unlock_irqrestore(&io_request_lock, flags); -} - static int gvp11_xfer_mask = 0; void gvp11_setup (char *str, int *ints) @@ -71,20 +61,24 @@ static int dma_setup (Scsi_Cmnd *cmd, int dir_in) { unsigned short cntr = GVP11_DMAC_INT_ENABLE; - unsigned long addr = VTOP(cmd->SCp.ptr); + unsigned long addr = virt_to_bus(cmd->SCp.ptr); int bank_mask; + static int scsi_alloc_out_of_range = 0; - /* don't allow DMA if the physical address is bad */ + /* use bounce buffer if the physical address is bad */ if (addr & HDATA(cmd->host)->dma_xfer_mask || (!dir_in && mm_end_of_chunk (addr, cmd->SCp.this_residual))) { HDATA(cmd->host)->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; - HDATA(cmd->host)->dma_bounce_buffer = - scsi_malloc (HDATA(cmd->host)->dma_bounce_len); - HDATA(cmd->host)->dma_buffer_pool = BUF_SCSI_ALLOCED; - - if (!HDATA(cmd->host)->dma_bounce_buffer) { + + if( !scsi_alloc_out_of_range ) { + HDATA(cmd->host)->dma_bounce_buffer = + scsi_malloc (HDATA(cmd->host)->dma_bounce_len); + HDATA(cmd->host)->dma_buffer_pool = BUF_SCSI_ALLOCED; + } + + if ( scsi_alloc_out_of_range || !HDATA(cmd->host)->dma_bounce_buffer) { HDATA(cmd->host)->dma_bounce_buffer = amiga_chip_alloc(HDATA(cmd->host)->dma_bounce_len); @@ -98,15 +92,17 @@ } /* check if the address of the bounce buffer is OK */ - addr = VTOP(HDATA(cmd->host)->dma_bounce_buffer); + addr = virt_to_bus(HDATA(cmd->host)->dma_bounce_buffer); if (addr & HDATA(cmd->host)->dma_xfer_mask) { /* fall back to Chip RAM if address out of range */ - if( HDATA(cmd->host)->dma_buffer_pool == BUF_SCSI_ALLOCED) + if( HDATA(cmd->host)->dma_buffer_pool == BUF_SCSI_ALLOCED) { scsi_free (HDATA(cmd->host)->dma_bounce_buffer, HDATA(cmd->host)->dma_bounce_len); - else + scsi_alloc_out_of_range = 1; + } else { amiga_chip_free (HDATA(cmd->host)->dma_bounce_buffer); + } HDATA(cmd->host)->dma_bounce_buffer = amiga_chip_alloc(HDATA(cmd->host)->dma_bounce_len); @@ -117,18 +113,14 @@ return 1; } - addr = VTOP(HDATA(cmd->host)->dma_bounce_buffer); + addr = virt_to_bus(HDATA(cmd->host)->dma_bounce_buffer); HDATA(cmd->host)->dma_buffer_pool = BUF_CHIP_ALLOCED; } if (!dir_in) { /* copy to bounce buffer for a write */ - if (cmd->use_sg) - memcpy (HDATA(cmd->host)->dma_bounce_buffer, - cmd->SCp.ptr, cmd->SCp.this_residual); - else - memcpy (HDATA(cmd->host)->dma_bounce_buffer, - cmd->request_buffer, cmd->request_bufflen); + memcpy (HDATA(cmd->host)->dma_bounce_buffer, + cmd->SCp.ptr, cmd->SCp.this_residual); } } @@ -169,41 +161,19 @@ /* copy from a bounce buffer, if necessary */ if (status && HDATA(instance)->dma_bounce_buffer) { - if (SCpnt && SCpnt->use_sg) { -#if 0 - panic ("scsi%d: incomplete s/g support", - instance->host_no); -#else - if( HDATA(instance)->dma_dir ) - memcpy (SCpnt->SCp.ptr, - HDATA(instance)->dma_bounce_buffer, - SCpnt->SCp.this_residual); - - if (HDATA(instance)->dma_buffer_pool == BUF_SCSI_ALLOCED) - scsi_free (HDATA(instance)->dma_bounce_buffer, - HDATA(instance)->dma_bounce_len); - else - amiga_chip_free(HDATA(instance)->dma_bounce_buffer); - - HDATA(instance)->dma_bounce_buffer = NULL; - HDATA(instance)->dma_bounce_len = 0; - -#endif - } else { - if (HDATA(instance)->dma_dir && SCpnt) - memcpy (SCpnt->request_buffer, - HDATA(instance)->dma_bounce_buffer, - SCpnt->request_bufflen); - - if (HDATA(instance)->dma_buffer_pool == BUF_SCSI_ALLOCED) - scsi_free (HDATA(instance)->dma_bounce_buffer, - HDATA(instance)->dma_bounce_len); - else - amiga_chip_free(HDATA(instance)->dma_bounce_buffer); - - HDATA(instance)->dma_bounce_buffer = NULL; - HDATA(instance)->dma_bounce_len = 0; - } + if (HDATA(instance)->dma_dir && SCpnt) + memcpy (SCpnt->SCp.ptr, + HDATA(instance)->dma_bounce_buffer, + SCpnt->SCp.this_residual); + + if (HDATA(instance)->dma_buffer_pool == BUF_SCSI_ALLOCED) + scsi_free (HDATA(instance)->dma_bounce_buffer, + HDATA(instance)->dma_bounce_len); + else + amiga_chip_free(HDATA(instance)->dma_bounce_buffer); + + HDATA(instance)->dma_bounce_buffer = NULL; + HDATA(instance)->dma_bounce_len = 0; } } @@ -211,7 +181,7 @@ #define CHECK_WD33C93 -__initfunc(int gvp11_detect(Scsi_Host_Template *tpnt)) +int __init gvp11_detect(Scsi_Host_Template *tpnt) { static unsigned char called = 0; struct Scsi_Host *instance; @@ -371,7 +341,7 @@ if (num_gvp11++ == 0) { first_instance = instance; gvp11_template = instance->hostt; - request_irq(IRQ_AMIGA_PORTS, do_gvp11_intr, 0, + request_irq(IRQ_AMIGA_PORTS, gvp11_intr, SA_SHIRQ, "GVP11 SCSI", gvp11_intr); } DMA(instance)->CNTR = GVP11_DMAC_INT_ENABLE; diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c --- v2.3.13/linux/drivers/scsi/hosts.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/scsi/hosts.c Wed Aug 18 10:00:52 1999 @@ -47,7 +47,7 @@ defined(CONFIG_WARPENGINE_SCSI) || \ defined(CONFIG_A4091_SCSI) || \ defined (CONFIG_GVP_TURBO_SCSI) || \ - defined (CONFIG_BLZ603E) + defined (CONFIG_BLZ603EPLUS_SCSI) #define AMIGA7XXCONFIG #endif @@ -95,6 +95,10 @@ #include "fastlane.h" #endif +#ifdef CONFIG_OKTAGON_SCSI +#include "oktagon_esp.h" +#endif + #ifdef CONFIG_ATARI_SCSI #include "atari_scsi.h" #endif @@ -327,6 +331,10 @@ #include "jazz_esp.h" #endif +#ifdef CONFIG_SUN3X_ESP +#include "sun3x_esp.h" +#endif + /* * Moved ppa driver to the end of the probe list * since it is a removable host adapter. @@ -402,6 +410,9 @@ #ifdef CONFIG_FASTLANE_SCSI SCSI_FASTLANE, #endif +#ifdef CONFIG_OKTAGON_SCSI + SCSI_OKTAGON_ESP, +#endif #endif #ifdef CONFIG_ATARI @@ -596,6 +607,9 @@ #ifdef CONFIG_SCSI_IMM IMM, #endif +#ifdef CONFIG_SUN3X_ESP + SCSI_SUN3X_ESP, +#endif #ifdef CONFIG_SCSI_DEBUG SCSI_DEBUG, #endif diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/jazz_esp.c linux/drivers/scsi/jazz_esp.c --- v2.3.13/linux/drivers/scsi/jazz_esp.c Tue Aug 4 16:56:37 1998 +++ linux/drivers/scsi/jazz_esp.c Wed Aug 18 10:00:52 1999 @@ -196,7 +196,7 @@ static int dma_irq_p(struct NCR_ESP *esp) { - return (esp->eregs->esp_status & ESP_STAT_INTR); + return (esp_read(esp->eregs->esp_status) & ESP_STAT_INTR); } static int dma_ports_p(struct NCR_ESP *esp) diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/mac_NCR5380.c linux/drivers/scsi/mac_NCR5380.c --- v2.3.13/linux/drivers/scsi/mac_NCR5380.c Fri Jan 15 14:41:04 1999 +++ linux/drivers/scsi/mac_NCR5380.c Wed Aug 18 10:00:52 1999 @@ -490,9 +490,9 @@ int cnt = 1; #endif - for (endaddr = VTOP(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1; + for (endaddr = virt_to_phys(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1; cmd->SCp.buffers_residual && - VTOP(cmd->SCp.buffer[1].address) == endaddr; ) { + virt_to_phys(cmd->SCp.buffer[1].address) == endaddr; ) { MER_PRINTK("VTOP(%p) == %08lx -> merging\n", cmd->SCp.buffer[1].address, endaddr); diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/mac_esp.c linux/drivers/scsi/mac_esp.c --- v2.3.13/linux/drivers/scsi/mac_esp.c Fri Dec 18 10:12:25 1998 +++ linux/drivers/scsi/mac_esp.c Wed Aug 18 10:00:52 1999 @@ -59,10 +59,15 @@ static void dma_setup(struct NCR_ESP * esp, __u32 addr, int count, int write); static void dma_setup_quick(struct NCR_ESP * esp, __u32 addr, int count, int write); - static int esp_dafb_dma_irq_p(struct NCR_ESP * espdev); static int esp_iosb_dma_irq_p(struct NCR_ESP * espdev); +volatile unsigned char cmd_buffer[16]; + /* This is where all commands are put + * before they are transfered to the ESP chip + * via PIO. + */ + static int esp_initialized = 0; static int setup_num_esps = -1; @@ -287,6 +292,9 @@ unsigned long timeout; #endif + if (esp_initialized > 0) + return -ENODEV; + /* what do we have in this machine... */ if (MACHW_PRESENT(MAC_SCSI_96)) { chipspresent ++; @@ -358,10 +366,13 @@ } /* chipnum == 0 */ - /* use pio for command bytes; pio for message/data: TBI */ esp->do_pio_cmds = 1; + /* Set the command buffer */ + esp->esp_command = (volatile unsigned char*) cmd_buffer; + esp->esp_command_dvma = (volatile unsigned char*) cmd_buffer; + /* various functions */ esp->dma_bytes_sent = &dma_bytes_sent; esp->dma_can_transfer = &dma_can_transfer; @@ -469,7 +480,7 @@ static int esp_dafb_dma_irq_p(struct NCR_ESP * esp) { unsigned int ret; - int sreg = esp->eregs->esp_status; + int sreg = esp_read(esp->eregs->esp_status); #ifdef DEBUG_MAC_ESP printk("mac_esp: esp_dafb_dma_irq_p dafb %d irq %d\n", @@ -510,7 +521,7 @@ static int esp_iosb_dma_irq_p(struct NCR_ESP * esp) { int ret = mac_irq_pending(IRQ_MAC_SCSI) || mac_irq_pending(IRQ_MAC_SCSIDRQ); - int sreg = esp->eregs->esp_status; + int sreg = esp_read(esp->eregs->esp_status); #ifdef DEBUG_MAC_ESP printk("mac_esp: dma_irq_p drq %d irq %d sreg %x curr %p disc %p\n", @@ -614,7 +625,7 @@ static int dma_irq_p(struct NCR_ESP * esp) { - int i = esp->eregs->esp_status; + int i = esp_read(esp->eregs->esp_status); #ifdef DEBUG_MAC_ESP printk("mac_esp: dma_irq_p status %d\n", i); @@ -629,7 +640,7 @@ * Copied from iosb_dma_irq_p() */ int ret = mac_irq_pending(IRQ_MAC_SCSI) || mac_irq_pending(IRQ_MAC_SCSIDRQ); - int sreg = esp->eregs->esp_status; + int sreg = esp_read(esp->eregs->esp_status); #ifdef DEBUG_MAC_ESP printk("mac_esp: dma_irq_p drq %d irq %d sreg %x curr %p disc %p\n", diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/mac_scsi.c linux/drivers/scsi/mac_scsi.c --- v2.3.13/linux/drivers/scsi/mac_scsi.c Fri Jan 15 14:41:04 1999 +++ linux/drivers/scsi/mac_scsi.c Wed Aug 18 10:00:52 1999 @@ -685,7 +685,7 @@ unsigned long mac_scsi_dma_setup( struct Scsi_Host *instance, void *data, unsigned long count, int dir ) { - unsigned long addr = VTOP( data ); + unsigned long addr = virt_to_phys( data ); DMA_PRINTK("scsi%d: setting up dma, data = %p, phys = %lx, count = %ld, " "dir = %d\n", instance->host_no, data, addr, count, dir); @@ -846,7 +846,7 @@ } /* Last step: apply the hard limit on DMA transfers */ - limit = (atari_dma_buffer && !STRAM_ADDR( VTOP(cmd->SCp.ptr) )) ? + limit = (atari_dma_buffer && !STRAM_ADDR( virt_to_phys(cmd->SCp.ptr) )) ? STRAM_BUFFER_SIZE : 255*512; if (possible_len > limit) possible_len = limit; diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/mca_53c9x.c linux/drivers/scsi/mca_53c9x.c --- v2.3.13/linux/drivers/scsi/mca_53c9x.c Fri Dec 18 10:12:25 1998 +++ linux/drivers/scsi/mca_53c9x.c Wed Aug 18 10:00:52 1999 @@ -156,6 +156,8 @@ "NCR 53c9x SCSI", esp_intr)) { printk("Unable to request IRQ %d.\n", esp->irq); + esp_deallocate(esp); + unregister_scsi(esp->ehost); return 0; } @@ -163,6 +165,8 @@ printk("Unable to request DMA channel %d.\n", esp->dma); free_irq(esp->irq, esp_intr); + esp_deallocate(esp); + unregister_scsi(esp->ehost); return 0; } @@ -259,7 +263,7 @@ struct NCR_ESP *esp = (struct NCR_ESP *)host->hostdata; unsigned char tmp_byte; - + esp_deallocate(esp); /* * Tell the 86C01 to stop sending interrupts */ diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c --- v2.3.13/linux/drivers/scsi/ncr53c8xx.c Thu Jul 8 15:42:21 1999 +++ linux/drivers/scsi/ncr53c8xx.c Mon Aug 16 10:33:58 1999 @@ -588,9 +588,7 @@ #endif #if defined(__i386__) || !defined(NCR_IOMAPPED) -__initfunc( -static vm_offset_t remap_pci_mem(u_long base, u_long size) -) +static vm_offset_t __init remap_pci_mem(u_long base, u_long size) { u_long page_base = ((u_long) base) & PAGE_MASK; u_long page_offs = ((u_long) base) - page_base; @@ -599,9 +597,7 @@ return (vm_offset_t) (page_remapped? (page_remapped + page_offs) : 0UL); } -__initfunc( -static void unmap_pci_mem(vm_offset_t vaddr, u_long size) -) +static void __init unmap_pci_mem(vm_offset_t vaddr, u_long size) { if (vaddr) iounmap((void *) (vaddr & PAGE_MASK)); @@ -3701,9 +3697,7 @@ **========================================================== */ -__initfunc( -void ncr_script_fill (struct script * scr, struct scripth * scrh) -) +void __init ncr_script_fill (struct script * scr, struct scripth * scrh) { int i; ncrcmd *p; @@ -3778,9 +3772,7 @@ **========================================================== */ -__initfunc( -static void ncr_script_copy_and_bind (ncb_p np, ncrcmd *src, ncrcmd *dst, int len) -) +static void __init ncr_script_copy_and_bind (ncb_p np, ncrcmd *src, ncrcmd *dst, int len) { ncrcmd opcode, new, old, tmp1, tmp2; ncrcmd *start, *end; @@ -4036,10 +4028,8 @@ ** Get target set-up from Symbios format NVRAM. */ -__initfunc( -static void - ncr_Symbios_setup_target(ncb_p np, int target, Symbios_nvram *nvram) -) +static void __init +ncr_Symbios_setup_target(ncb_p np, int target, Symbios_nvram *nvram) { tcb_p tp = &np->target[target]; Symbios_target *tn = &nvram->target[target]; @@ -4059,10 +4049,8 @@ ** Get target set-up from Tekram format NVRAM. */ -__initfunc( -static void - ncr_Tekram_setup_target(ncb_p np, int target, Tekram_nvram *nvram) -) +static void __init +ncr_Tekram_setup_target(ncb_p np, int target, Tekram_nvram *nvram) { tcb_p tp = &np->target[target]; struct Tekram_target *tn = &nvram->target[target]; @@ -4088,9 +4076,7 @@ } #endif /* SCSI_NCR_NVRAM_SUPPORT */ -__initfunc( -static int ncr_prepare_setting(ncb_p np, ncr_nvram *nvram) -) +static int __init ncr_prepare_setting(ncb_p np, ncr_nvram *nvram) { u_char burst_max; u_long period; @@ -4372,9 +4358,7 @@ #ifdef SCSI_NCR_DEBUG_NVRAM -__initfunc( -void ncr_display_Symbios_nvram(ncb_p np, Symbios_nvram *nvram) -) +void __init ncr_display_Symbios_nvram(ncb_p np, Symbios_nvram *nvram) { int i; @@ -4404,9 +4388,7 @@ static u_char Tekram_boot_delay[7] __initdata = {3, 5, 10, 20, 30, 60, 120}; -__initfunc( -void ncr_display_Tekram_nvram(ncb_p np, Tekram_nvram *nvram) -) +void __init ncr_display_Tekram_nvram(ncb_p np, Tekram_nvram *nvram) { int i, tags, boot_delay; char *rem; @@ -4465,9 +4447,8 @@ ** start the timer daemon. */ -__initfunc( -static int ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device) -) +static int __init +ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device) { struct host_data *host_data; ncb_p np; @@ -8807,9 +8788,7 @@ */ #ifndef NCR_IOMAPPED -__initfunc( -static int ncr_regtest (struct ncb* np) -) +static int __init ncr_regtest (struct ncb* np) { register volatile u_int32 data; /* @@ -8833,9 +8812,7 @@ } #endif -__initfunc( -static int ncr_snooptest (struct ncb* np) -) +static int __init ncr_snooptest (struct ncb* np) { u_int32 ncr_rd, ncr_wr, ncr_bk, host_rd, host_wr, pc; int i, err=0; @@ -9098,9 +9075,7 @@ /* * calculate NCR SCSI clock frequency (in KHz) */ -__initfunc( -static unsigned ncrgetfreq (ncb_p np, int gen) -) +static unsigned __init ncrgetfreq (ncb_p np, int gen) { unsigned ms = 0; @@ -9148,9 +9123,7 @@ /* * Get/probe NCR SCSI clock frequency */ -__initfunc( -static void ncr_getclock (ncb_p np, int mult) -) +static void __init ncr_getclock (ncb_p np, int mult) { unsigned char scntl3 = INB(nc_scntl3); unsigned char stest1 = INB(nc_stest1); @@ -9238,9 +9211,8 @@ #define ARG_SEP ',' #endif -__initfunc( -void ncr53c8xx_setup(char *str, int *ints) -) + +void __init ncr53c8xx_setup(char *str, int *ints) { #ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT char *cur = str; @@ -9351,9 +9323,7 @@ ** Returns the number of boards successfully attached. */ -__initfunc( -static void ncr_print_driver_setup(void) -) +static void __init ncr_print_driver_setup(void) { #define YesNo(y) y ? 'y' : 'n' printk ("ncr53c8xx: setup=disc:%c,specf:%d,ultra:%d,tags:%d,sync:%d," @@ -9392,10 +9362,8 @@ static ushort ncr_chip_ids[] __initdata = SCSI_NCR_CHIP_IDS; #ifdef SCSI_NCR_NVRAM_SUPPORT -__initfunc( -static int +static int __init ncr_attach_using_nvram(Scsi_Host_Template *tpnt, int nvram_index, int count, ncr_device device[]) -) { int i, j; int attach_count = 0; @@ -9476,9 +9444,7 @@ } #endif /* SCSI_NCR_NVRAM_SUPPORT */ -__initfunc( -int ncr53c8xx_detect(Scsi_Host_Template *tpnt) -) +int __init ncr53c8xx_detect(Scsi_Host_Template *tpnt) { int i, j; int chips; @@ -9605,44 +9571,16 @@ ** Return the offset immediately after the base address that has ** been read. Btw, we blindly assume that the high 32 bits of 64 bit ** base addresses are set to zero on 32 bit architectures. +** (the pci generic code now does this for us) ** */ -#if LINUX_VERSION_CODE <= LinuxVersionCode(2,1,92) -__initfunc( -static int -pci_read_base_address(u_char bus, u_char device_fn, int offset, u_long *base) -) -{ - u_int32 tmp; - - pcibios_read_config_dword(bus, device_fn, offset, &tmp); - *base = tmp; - offset += sizeof(u_int32); - if ((tmp & 0x7) == 0x4) { -#if BITS_PER_LONG > 32 - pcibios_read_config_dword(bus, device_fn, offset, &tmp); - *base |= (((u_long)tmp) << 32); -#endif - offset += sizeof(u_int32); - } - return offset; -} -#else /* LINUX_VERSION_CODE > LinuxVersionCode(2,1,92) */ -__initfunc( -static int + +static int __init pci_get_base_address(struct pci_dev *pdev, int index, u_long *base) -) { - *base = pdev->base_address[index++]; - if ((*base & 0x7) == 0x4) { -#if BITS_PER_LONG > 32 - *base |= (((u_long)pdev->base_address[index]) << 32); -#endif - ++index; - } + *base = pdev->resource[++index].start; return index; } -#endif /* ** Read and check the PCI configuration for any detected NCR @@ -9650,10 +9588,9 @@ ** been detected. */ -__initfunc( -static int ncr53c8xx_pci_init(Scsi_Host_Template *tpnt, + +static int __init ncr53c8xx_pci_init(Scsi_Host_Template *tpnt, uchar bus, uchar device_fn, ncr_device *device) -) { ushort vendor_id, device_id, command; uchar cache_line_size, latency_timer; @@ -10907,9 +10844,7 @@ static void nvram_stop(ncr_slot *np, u_char *gpreg); static void nvram_setBit(ncr_slot *np, u_char write_bit, u_char *gpreg, int bit_mode); -__initfunc( -static int ncr_get_Symbios_nvram (ncr_slot *np, Symbios_nvram *nvram) -) +static int __init ncr_get_Symbios_nvram (ncr_slot *np, Symbios_nvram *nvram) { static u_char Symbios_trailer[6] = {0xfe, 0xfe, 0, 0, 0, 0}; u_char gpcntl, gpreg; @@ -10998,9 +10933,8 @@ /* * Read Symbios NvRAM data and compute checksum. */ -__initfunc( -static u_short nvram_read_data(ncr_slot *np, u_char *data, int len, u_char *gpreg, u_char *gpcntl) -) +static u_short __init nvram_read_data(ncr_slot *np, u_char *data, int len, + u_char *gpreg, u_char *gpcntl) { int x; u_short csum; @@ -11017,9 +10951,7 @@ /* * Send START condition to NVRAM to wake it up. */ -__initfunc( -static void nvram_start(ncr_slot *np, u_char *gpreg) -) +static void __init nvram_start(ncr_slot *np, u_char *gpreg) { nvram_setBit(np, 1, gpreg, SET_BIT); nvram_setBit(np, 0, gpreg, SET_CLK); @@ -11031,9 +10963,9 @@ * WRITE a byte to the NVRAM and then get an ACK to see it was accepted OK, * GPIO0 must already be set as an output */ -__initfunc( -static void nvram_write_byte(ncr_slot *np, u_char *ack_data, u_char write_data, u_char *gpreg, u_char *gpcntl) -) +static void __init nvram_write_byte(ncr_slot *np, u_char *ack_data, + u_char write_data, u_char *gpreg, + u_char *gpcntl) { int x; @@ -11047,9 +10979,9 @@ * READ a byte from the NVRAM and then send an ACK to say we have got it, * GPIO0 must already be set as an input */ -__initfunc( -static void nvram_read_byte(ncr_slot *np, u_char *read_data, u_char ack_data, u_char *gpreg, u_char *gpcntl) -) +static void __init nvram_read_byte(ncr_slot *np, u_char *read_data, + u_char ack_data, u_char *gpreg, + u_char *gpcntl) { int x; u_char read_bit; @@ -11067,9 +10999,8 @@ * Output an ACK to the NVRAM after reading, * change GPIO0 to output and when done back to an input */ -__initfunc( -static void nvram_writeAck(ncr_slot *np, u_char write_bit, u_char *gpreg, u_char *gpcntl) -) +static void __init nvram_writeAck(ncr_slot *np, u_char write_bit, + u_char *gpreg, u_char *gpcntl) { OUTB (nc_gpcntl, *gpcntl & 0xfe); nvram_doBit(np, 0, write_bit, gpreg); @@ -11080,9 +11011,8 @@ * Input an ACK from NVRAM after writing, * change GPIO0 to input and when done back to an output */ -__initfunc( -static void nvram_readAck(ncr_slot *np, u_char *read_bit, u_char *gpreg, u_char *gpcntl) -) +static void __init nvram_readAck(ncr_slot *np, u_char *read_bit, + u_char *gpreg, u_char *gpcntl) { OUTB (nc_gpcntl, *gpcntl | 0x01); nvram_doBit(np, read_bit, 1, gpreg); @@ -11093,9 +11023,8 @@ * Read or write a bit to the NVRAM, * read if GPIO0 input else write if GPIO0 output */ -__initfunc( -static void nvram_doBit(ncr_slot *np, u_char *read_bit, u_char write_bit, u_char *gpreg) -) +static void __init nvram_doBit(ncr_slot *np, u_char *read_bit, + u_char write_bit, u_char *gpreg) { nvram_setBit(np, write_bit, gpreg, SET_BIT); nvram_setBit(np, 0, gpreg, SET_CLK); @@ -11108,9 +11037,7 @@ /* * Send STOP condition to NVRAM - puts NVRAM to sleep... ZZzzzz!! */ -__initfunc( -static void nvram_stop(ncr_slot *np, u_char *gpreg) -) +static void __init nvram_stop(ncr_slot *np, u_char *gpreg) { nvram_setBit(np, 0, gpreg, SET_CLK); nvram_setBit(np, 1, gpreg, SET_BIT); @@ -11119,9 +11046,8 @@ /* * Set/clear data/clock bit in GPIO0 */ -__initfunc( -static void nvram_setBit(ncr_slot *np, u_char write_bit, u_char *gpreg, int bit_mode) -) +static void __init nvram_setBit(ncr_slot *np, u_char write_bit, + u_char *gpreg, int bit_mode) { UDELAY (5); switch (bit_mode){ @@ -11172,9 +11098,7 @@ static void Tnvram_Stop(ncr_slot *np, u_char *gpreg); static void Tnvram_Clk(ncr_slot *np, u_char *gpreg); -__initfunc( -static int ncr_get_Tekram_nvram (ncr_slot *np, Tekram_nvram *nvram) -) +static int __init ncr_get_Tekram_nvram (ncr_slot *np, Tekram_nvram *nvram) { u_char gpcntl, gpreg; u_char old_gpcntl, old_gpreg; @@ -11209,9 +11133,8 @@ /* * Read Tekram NvRAM data and compute checksum. */ -__initfunc( -static u_short Tnvram_read_data(ncr_slot *np, u_short *data, int len, u_char *gpreg) -) +static u_short __init Tnvram_read_data(ncr_slot *np, u_short *data, int len, + u_char *gpreg) { u_char read_bit; u_short csum; @@ -11236,9 +11159,8 @@ /* * Send read command and address to NVRAM */ -__initfunc( -static void Tnvram_Send_Command(ncr_slot *np, u_short write_data, u_char *read_bit, u_char *gpreg) -) +static void __init Tnvram_Send_Command(ncr_slot *np, u_short write_data, + u_char *read_bit, u_char *gpreg) { int x; @@ -11252,9 +11174,8 @@ /* * READ a byte from the NVRAM */ -__initfunc( -static void Tnvram_Read_Word(ncr_slot *np, u_short *nvram_data, u_char *gpreg) -) +static void __init Tnvram_Read_Word(ncr_slot *np, u_short *nvram_data, + u_char *gpreg) { int x; u_char read_bit; @@ -11273,9 +11194,8 @@ /* * Read bit from NVRAM */ -__initfunc( -static void Tnvram_Read_Bit(ncr_slot *np, u_char *read_bit, u_char *gpreg) -) +static void __init Tnvram_Read_Bit(ncr_slot *np, u_char *read_bit, + u_char *gpreg) { UDELAY (2); Tnvram_Clk(np, gpreg); @@ -11285,9 +11205,8 @@ /* * Write bit to GPIO0 */ -__initfunc( -static void Tnvram_Write_Bit(ncr_slot *np, u_char write_bit, u_char *gpreg) -) +static void __init Tnvram_Write_Bit(ncr_slot *np, u_char write_bit, + u_char *gpreg) { if (write_bit & 0x01) *gpreg |= 0x02; @@ -11305,9 +11224,7 @@ /* * Send STOP condition to NVRAM - puts NVRAM to sleep... ZZZzzz!! */ -__initfunc( -static void Tnvram_Stop(ncr_slot *np, u_char *gpreg) -) +static void __init Tnvram_Stop(ncr_slot *np, u_char *gpreg) { *gpreg &= 0xef; OUTB (nc_gpreg, *gpreg); @@ -11319,9 +11236,7 @@ /* * Pulse clock bit in GPIO0 */ -__initfunc( -static void Tnvram_Clk(ncr_slot *np, u_char *gpreg) -) +static void __init Tnvram_Clk(ncr_slot *np, u_char *gpreg) { OUTB (nc_gpreg, *gpreg | 0x04); UDELAY (2); diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/oktagon_esp.c linux/drivers/scsi/oktagon_esp.c --- v2.3.13/linux/drivers/scsi/oktagon_esp.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/scsi/oktagon_esp.c Sun Aug 15 11:49:08 1999 @@ -0,0 +1,597 @@ +/* + * Oktagon_esp.c -- Driver for bsc Oktagon + * + * Written by Carsten Pluntke 1998 + * + * Based on cyber_esp.c + */ + +#include + +#if defined(CONFIG_AMIGA) || defined(CONFIG_APUS) +#define USE_BOTTOM_HALF +#endif + +#define __KERNEL_SYSCALLS__ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "scsi.h" +#include "hosts.h" +#include "NCR53C9x.h" +#include "oktagon_esp.h" + +#include +#include +#include +#include + +#ifdef USE_BOTTOM_HALF +#include +#include +#endif + +#include + +static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count); +static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp); +static void dma_dump_state(struct NCR_ESP *esp); +static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length); +static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length); +static void dma_ints_off(struct NCR_ESP *esp); +static void dma_ints_on(struct NCR_ESP *esp); +static int dma_irq_p(struct NCR_ESP *esp); +static void dma_led_off(struct NCR_ESP *esp); +static void dma_led_on(struct NCR_ESP *esp); +static int dma_ports_p(struct NCR_ESP *esp); +static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write); + +static void dma_irq_exit(struct NCR_ESP *esp); +static void dma_invalidate(struct NCR_ESP *esp); + +static void dma_mmu_get_scsi_one(struct NCR_ESP *,Scsi_Cmnd *); +static void dma_mmu_get_scsi_sgl(struct NCR_ESP *,Scsi_Cmnd *); +static void dma_mmu_release_scsi_one(struct NCR_ESP *,Scsi_Cmnd *); +static void dma_mmu_release_scsi_sgl(struct NCR_ESP *,Scsi_Cmnd *); +static void dma_advance_sg(Scsi_Cmnd *); +static int oktagon_notify_reboot(struct notifier_block *this, unsigned long code, void *x); + +void esp_bootup_reset(struct NCR_ESP *esp,struct ESP_regs *eregs); + +#ifdef USE_BOTTOM_HALF +static void dma_commit(void *opaque); + +long oktag_to_io(long *paddr, long *addr, long len); +long oktag_from_io(long *addr, long *paddr, long len); + +static struct tq_struct tq_fake_dma = { NULL, 0, dma_commit, NULL }; + +#define DMA_MAXTRANSFER 0x8000 + +#else + +/* + * No bottom half. Use transfer directly from IRQ. Find a narrow path + * between too much IRQ overhead and clogging the IRQ for too long. + */ + +#define DMA_MAXTRANSFER 0x1000 + +#endif + +static struct notifier_block oktagon_notifier = { + oktagon_notify_reboot, + NULL, + 0 +}; + +static long *paddress; +static long *address; +static long len; +static long dma_on; +static int direction; +static struct NCR_ESP *current_esp; + + +volatile unsigned char cmd_buffer[16]; + /* This is where all commands are put + * before they are trasfered to the ESP chip + * via PIO. + */ + +/***************************************************************** Detection */ +int oktagon_esp_detect(Scsi_Host_Template *tpnt) +{ + struct NCR_ESP *esp; + const struct ConfigDev *esp_dev; + int key; + unsigned long address; + struct ESP_regs *eregs; + + if((key = zorro_find(ZORRO_PROD_BSC_OKTAGON_2008, 0, 0))){ + esp_dev = zorro_get_board(key); + + /* + * It is a SCSI controller. + * Hardwire Host adapter to SCSI ID 7 + */ + + address = (unsigned long)ZTWO_VADDR(esp_dev->cd_BoardAddr); + eregs = (struct ESP_regs *)(address + OKTAGON_ESP_ADDR); + + /* This line was 5 lines lower */ + esp = esp_allocate(tpnt, (void *) esp_dev); + + /* we have to shift the registers only one bit for oktagon */ + esp->shift = 1; + + esp_write(eregs->esp_cfg1, (ESP_CONFIG1_PENABLE | 7)); + udelay(5); + if (esp_read(eregs->esp_cfg1) != (ESP_CONFIG1_PENABLE | 7)) + return 0; /* Bail out if address did not hold data */ + + /* Do command transfer with programmed I/O */ + esp->do_pio_cmds = 1; + + /* Required functions */ + esp->dma_bytes_sent = &dma_bytes_sent; + esp->dma_can_transfer = &dma_can_transfer; + esp->dma_dump_state = &dma_dump_state; + esp->dma_init_read = &dma_init_read; + esp->dma_init_write = &dma_init_write; + esp->dma_ints_off = &dma_ints_off; + esp->dma_ints_on = &dma_ints_on; + esp->dma_irq_p = &dma_irq_p; + esp->dma_ports_p = &dma_ports_p; + esp->dma_setup = &dma_setup; + + /* Optional functions */ + esp->dma_barrier = 0; + esp->dma_drain = 0; + esp->dma_invalidate = &dma_invalidate; + esp->dma_irq_entry = 0; + esp->dma_irq_exit = &dma_irq_exit; + esp->dma_led_on = &dma_led_on; + esp->dma_led_off = &dma_led_off; + esp->dma_poll = 0; + esp->dma_reset = 0; + + esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one; + esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl; + esp->dma_mmu_release_scsi_one = &dma_mmu_release_scsi_one; + esp->dma_mmu_release_scsi_sgl = &dma_mmu_release_scsi_sgl; + esp->dma_advance_sg = &dma_advance_sg; + + /* SCSI chip speed */ + /* Looking at the quartz of the SCSI board... */ + esp->cfreq = 25000000; + + /* The DMA registers on the CyberStorm are mapped + * relative to the device (i.e. in the same Zorro + * I/O block). + */ + esp->dregs = (void *)(address + OKTAGON_DMA_ADDR); + + paddress = (long *) esp->dregs; + + /* ESP register base */ + esp->eregs = eregs; + + /* Set the command buffer */ + esp->esp_command = (volatile unsigned char*) cmd_buffer; + + /* Yes, the virtual address. See below. */ + esp->esp_command_dvma = (__u32) cmd_buffer; + + esp->irq = IRQ_AMIGA_PORTS; + esp->slot = key; + request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ, + "BSC Oktagon SCSI", esp_intr); + + /* Figure out our scsi ID on the bus */ + esp->scsi_id = 7; + + /* We don't have a differential SCSI-bus. */ + esp->diff = 0; + + esp_initialize(esp); + + zorro_config_board(key, 0); + printk("ESP_Oktagon Driver 1.1" +#ifdef USE_BOTTOM_HALF + " [BOTTOM_HALF]" +#else + " [IRQ]" +#endif + " registered.\n"); + printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use); + esps_running = esps_in_use; + current_esp = esp; + register_reboot_notifier(&oktagon_notifier); + return esps_in_use; + } + return 0; +} + + +/* + * On certain configurations the SCSI equipment gets confused on reboot, + * so we have to reset it then. + */ + +static int +oktagon_notify_reboot(struct notifier_block *this, unsigned long code, void *x) +{ + struct NCR_ESP *esp; + + if((code == SYS_DOWN || code == SYS_HALT) && (esp = current_esp)) + { + esp_bootup_reset(esp,esp->eregs); + udelay(500); /* Settle time. Maybe unneccessary. */ + } + return NOTIFY_DONE; +} + + + +#ifdef USE_BOTTOM_HALF + + +/* + * The bsc Oktagon controller has no real DMA, so we have to do the 'DMA + * transfer' in the interrupt (Yikes!) or use a bottom half to not to clutter + * IRQ's for longer-than-good. + * + * FIXME + * BIG PROBLEM: 'len' is usually the buffer length, not the expected length + * of the data. So DMA may finish prematurely, further reads lead to + * 'machine check' on APUS systems (don't know about m68k systems, AmigaOS + * deliberately ignores the bus faults) and a normal copy-loop can't + * be exited prematurely just at the right moment by the dma_invalidate IRQ. + * So do it the hard way, write an own copier in assembler and + * catch the exception. + * -- Carsten + */ + + +static void dma_commit(void *opaque) +{ + long wait,len2,pos; + struct NCR_ESP *esp; + + ESPDATA(("Transfer: %ld bytes, Address 0x%08lX, Direction: %d\n", + len,(long) address,direction)); + dma_ints_off(current_esp); + + pos = 0; + wait = 1; + if(direction) /* write? (memory to device) */ + { + while(len > 0) + { + len2 = oktag_to_io(paddress, address+pos, len); + if(!len2) + { + if(wait > 1000) + { + printk("Expedited DMA exit (writing) %ld\n",len); + break; + } + mdelay(wait); + wait *= 2; + } + pos += len2; + len -= len2*sizeof(long); + } + } else { + while(len > 0) + { + len2 = oktag_from_io(address+pos, paddress, len); + if(!len2) + { + if(wait > 1000) + { + printk("Expedited DMA exit (reading) %ld\n",len); + break; + } + mdelay(wait); + wait *= 2; + } + pos += len2; + len -= len2*sizeof(long); + } + } + + /* to make esp->shift work */ + esp=current_esp; + +#if 0 + len2 = (esp_read(current_esp->eregs->esp_tclow) & 0xff) | + ((esp_read(current_esp->eregs->esp_tcmed) & 0xff) << 8); + + /* + * Uh uh. If you see this, len and transfer count registers were out of + * sync. That means really serious trouble. + */ + + if(len2) + printk("Eeeek!! Transfer count still %ld!\n",len2); +#endif + + /* + * Normally we just need to exit and wait for the interrupt to come. + * But at least one device (my Microtek ScanMaker 630) regularly mis- + * calculates the bytes it should send which is really ugly because + * it locks up the SCSI bus if not accounted for. + */ + + if(!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR)) + { + long len = 100; + long trash[10]; + + /* + * Interrupt bit was not set. Either the device is just plain lazy + * so we give it a 10 ms chance or... + */ + while(len-- && (!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR))) + udelay(100); + + + if(!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR)) + { + /* + * So we think that the transfer count is out of sync. Since we + * have all we want we are happy and can ditch the trash. + */ + + len = DMA_MAXTRANSFER; + + while(len-- && (!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR))) + oktag_from_io(trash,paddress,2); + + if(!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR)) + { + /* + * Things really have gone wrong. If we leave the system in that + * state, the SCSI bus is locked forever. I hope that this will + * turn the system in a more or less running state. + */ + printk("Device is bolixed, trying bus reset...\n"); + esp_bootup_reset(current_esp,current_esp->eregs); + } + } + } + + ESPDATA(("Transfer_finale: do_data_finale should come\n")); + + len = 0; + dma_on = 0; + dma_ints_on(current_esp); +} + +#endif + +/************************************************************* DMA Functions */ +static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count) +{ + /* Since the CyberStorm DMA is fully dedicated to the ESP chip, + * the number of bytes sent (to the ESP chip) equals the number + * of bytes in the FIFO - there is no buffering in the DMA controller. + * XXXX Do I read this right? It is from host to ESP, right? + */ + return fifo_count; +} + +static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp) +{ + unsigned long sz = sp->SCp.this_residual; + if(sz > DMA_MAXTRANSFER) + sz = DMA_MAXTRANSFER; + return sz; +} + +static void dma_dump_state(struct NCR_ESP *esp) +{ +} + +/* + * What the f$@& is this? + * + * Some SCSI devices (like my Microtek ScanMaker 630 scanner) want to transfer + * more data than requested. How much? Dunno. So ditch the bogus data into + * the sink, hoping the device will advance to the next phase sooner or later. + * + * -- Carsten + */ + +static long oktag_eva_buffer[16]; /* The data sink */ + +static void oktag_check_dma(void) +{ + struct NCR_ESP *esp; + + esp=current_esp; + if(!len) + { + address = oktag_eva_buffer; + len = 2; + /* esp_do_data sets them to zero like len */ + esp_write(current_esp->eregs->esp_tclow,2); + esp_write(current_esp->eregs->esp_tcmed,0); + } +} + +static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length) +{ + /* Zorro is noncached, everything else done using processor. */ + /* cache_clear(addr, length); */ + + if(dma_on) + panic("dma_init_read while dma process is initialized/running!\n"); + direction = 0; + address = (long *) vaddress; + current_esp = esp; + len = length; + oktag_check_dma(); + dma_on = 1; +} + +static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length) +{ + /* cache_push(addr, length); */ + + if(dma_on) + panic("dma_init_write while dma process is initialized/running!\n"); + direction = 1; + address = (long *) vaddress; + current_esp = esp; + len = length; + oktag_check_dma(); + dma_on = 1; +} + +static void dma_ints_off(struct NCR_ESP *esp) +{ + disable_irq(esp->irq); +} + +static void dma_ints_on(struct NCR_ESP *esp) +{ + enable_irq(esp->irq); +} + +static int dma_irq_p(struct NCR_ESP *esp) +{ + /* It's important to check the DMA IRQ bit in the correct way! */ + return (esp_read(esp->eregs->esp_status) & ESP_STAT_INTR); +} + +static void dma_led_off(struct NCR_ESP *esp) +{ +} + +static void dma_led_on(struct NCR_ESP *esp) +{ +} + +static int dma_ports_p(struct NCR_ESP *esp) +{ + return ((custom.intenar) & IF_PORTS); +} + +static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) +{ + /* On the Sparc, DMA_ST_WRITE means "move data from device to memory" + * so when (write) is true, it actually means READ! + */ + if(write){ + dma_init_read(esp, addr, count); + } else { + dma_init_write(esp, addr, count); + } +} + +/* + * IRQ entry when DMA transfer is ready to be started + */ + +static void dma_irq_exit(struct NCR_ESP *esp) +{ +#ifdef USE_BOTTOM_HALF + if(dma_on) + { + tq_fake_dma.sync = 0; + queue_task(&tq_fake_dma,&tq_immediate); + mark_bh(IMMEDIATE_BH); + } +#else + while(len && !dma_irq_p(esp)) + { + if(direction) + *paddress = *address++; + else + *address++ = *paddress; + len -= (sizeof(long)); + } + len = 0; + dma_on = 0; +#endif +} + +/* + * IRQ entry when DMA has just finished + */ + +static void dma_invalidate(struct NCR_ESP *esp) +{ +} + +/* + * Since the processor does the data transfer we have to use the custom + * mmu interface to pass the virtual address, not the physical. + */ + +void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd *sp) +{ + sp->SCp.have_data_in = (int) sp->SCp.ptr = + sp->request_buffer; +} + +void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd *sp) +{ + sp->SCp.ptr = + sp->SCp.buffer->address; +} + +void dma_mmu_release_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd *sp) +{ +} + +void dma_mmu_release_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd *sp) +{ +} + +void dma_advance_sg(Scsi_Cmnd *sp) +{ + sp->SCp.ptr = sp->SCp.buffer->address; +} + +#ifdef MODULE + +#define HOSTS_C + +#include "oktagon_esp.h" + +Scsi_Host_Template driver_template = SCSI_OKTAGON_ESP; + +#include "scsi_module.c" + +#endif + +int oktagon_esp_release(struct Scsi_Host *instance) +{ +#ifdef MODULE + unsigned int key; + + key = ((struct NCR_ESP *)instance->hostdata)->slot; + esp_release(); + zorro_unconfig_board(key, 0); + free_irq(IRQ_AMIGA_PORTS, esp_intr); + unregister_reboot_notifier(&oktagon_notifier); +#endif + return 1; +} diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/oktagon_esp.h linux/drivers/scsi/oktagon_esp.h --- v2.3.13/linux/drivers/scsi/oktagon_esp.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/scsi/oktagon_esp.h Thu Aug 12 10:28:34 1999 @@ -0,0 +1,57 @@ +/* oktagon_esp.h: Defines and structures for the CyberStorm SCSI Mk II driver. + * + * Copyright (C) 1996 Jesper Skov (jskov@cs.auc.dk) + */ + +#include "NCR53C9x.h" + +#ifndef OKTAGON_ESP_H +#define OKTAGON_ESP_H + +/* The controller registers can be found in the Z2 config area at these + * offsets: + */ +#define OKTAGON_ESP_ADDR 0x03000 +#define OKTAGON_DMA_ADDR 0x01000 + + +/* The CyberStorm II DMA interface */ +struct oktagon_dma_registers { + volatile unsigned char cond_reg; /* DMA cond (ro) [0x000] */ +#define ctrl_reg cond_reg /* DMA control (wo) [0x000] */ + unsigned char dmapad4[0x3f]; + volatile unsigned char dma_addr0; /* DMA address (MSB) [0x040] */ + unsigned char dmapad1[3]; + volatile unsigned char dma_addr1; /* DMA address [0x044] */ + unsigned char dmapad2[3]; + volatile unsigned char dma_addr2; /* DMA address [0x048] */ + unsigned char dmapad3[3]; + volatile unsigned char dma_addr3; /* DMA address (LSB) [0x04c] */ +}; + +extern int oktagon_esp_detect(struct SHT *); +extern int oktagon_esp_release(struct Scsi_Host *); +extern const char *esp_info(struct Scsi_Host *); +extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); +extern int esp_command(Scsi_Cmnd *); +extern int esp_abort(Scsi_Cmnd *); +extern int esp_reset(Scsi_Cmnd *, unsigned int); +extern int esp_proc_info(char *buffer, char **start, off_t offset, int length, + int hostno, int inout); + +#define SCSI_OKTAGON_ESP { \ + proc_dir: &proc_scsi_esp, \ + proc_info: &esp_proc_info, \ + name: "BSC Oktagon SCSI", \ + detect: oktagon_esp_detect, \ + release: oktagon_esp_release, \ + queuecommand: esp_queue, \ + abort: esp_abort, \ + reset: esp_reset, \ + can_queue: 7, \ + this_id: 7, \ + sg_tablesize: SG_ALL, \ + cmd_per_lun: 1, \ + use_clustering: ENABLE_CLUSTERING } + +#endif /* OKTAGON_ESP_H */ diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/oktagon_io.S linux/drivers/scsi/oktagon_io.S --- v2.3.13/linux/drivers/scsi/oktagon_io.S Wed Dec 31 16:00:00 1969 +++ linux/drivers/scsi/oktagon_io.S Thu Aug 12 10:28:34 1999 @@ -0,0 +1,195 @@ +/* -*- mode: asm -*- + * Due to problems while transferring data I've put these routines as assembly + * code. + * Since I'm no PPC assembler guru, the code is just the assembler version of + +int oktag_to_io(long *paddr,long *addr,long len) +{ + long *addr2 = addr; + for(len=(len+sizeof(long)-1)/sizeof(long);len--;) + *paddr = *addr2++; + return addr2 - addr; +} + +int oktag_from_io(long *addr,long *paddr,long len) +{ + long *addr2 = addr; + for(len=(len+sizeof(long)-1)/sizeof(long);len--;) + *addr2++ = *paddr; + return addr2 - addr; +} + + * assembled using gcc -O2 -S, with two exception catch points where data + * is moved to/from the IO register. + */ + +#include + +#ifdef CONFIG_APUS + + .file "oktagon_io.c" + +gcc2_compiled.: +/* + .section ".text" +*/ + .align 2 + .globl oktag_to_io + .type oktag_to_io,@function +oktag_to_io: + addi 5,5,3 + srwi 5,5,2 + cmpwi 1,5,0 + mr 9,3 + mr 3,4 + addi 5,5,-1 + bc 12,6,.L3 +.L5: + cmpwi 1,5,0 + lwz 0,0(3) + addi 3,3,4 + addi 5,5,-1 +exp1: stw 0,0(9) + bc 4,6,.L5 +.L3: +ret1: subf 3,4,3 + srawi 3,3,2 + blr +.Lfe1: + .size oktag_to_io,.Lfe1-oktag_to_io + .align 2 + .globl oktag_from_io + .type oktag_from_io,@function +oktag_from_io: + addi 5,5,3 + srwi 5,5,2 + cmpwi 1,5,0 + mr 9,3 + addi 5,5,-1 + bc 12,6,.L9 +.L11: + cmpwi 1,5,0 +exp2: lwz 0,0(4) + addi 5,5,-1 + stw 0,0(3) + addi 3,3,4 + bc 4,6,.L11 +.L9: +ret2: subf 3,9,3 + srawi 3,3,2 + blr +.Lfe2: + .size oktag_from_io,.Lfe2-oktag_from_io + .ident "GCC: (GNU) egcs-2.90.29 980515 (egcs-1.0.3 release)" + +/* + * Exception table. + * Second longword shows where to jump when an exception at the addr the first + * longword is pointing to is caught. + */ + +.section __ex_table,"a" + .align 2 +oktagon_except: + .long exp1,ret1 + .long exp2,ret2 + +#else + +/* +The code which follows is for 680x0 based assembler and is meant for +Linux/m68k. It was created by cross compiling the code using the +instructions given above. I then added the four labels used in the +exception handler table at the bottom of this file. +- Kevin +*/ + +#ifdef CONFIG_AMIGA + + .file "oktagon_io.c" + .version "01.01" +gcc2_compiled.: +.text + .align 2 +.globl oktag_to_io + .type oktag_to_io,@function +oktag_to_io: + link.w %a6,#0 + move.l %d2,-(%sp) + move.l 8(%a6),%a1 + move.l 12(%a6),%d1 + move.l %d1,%a0 + move.l 16(%a6),%d0 + addq.l #3,%d0 + lsr.l #2,%d0 + subq.l #1,%d0 + moveq.l #-1,%d2 + cmp.l %d0,%d2 + jbeq .L3 +.L5: +exp1: + move.l (%a0)+,(%a1) + dbra %d0,.L5 + clr.w %d0 + subq.l #1,%d0 + jbcc .L5 +.L3: +ret1: + move.l %a0,%d0 + sub.l %d1,%d0 + asr.l #2,%d0 + move.l -4(%a6),%d2 + unlk %a6 + rts + +.Lfe1: + .size oktag_to_io,.Lfe1-oktag_to_io + .align 2 +.globl oktag_from_io + .type oktag_from_io,@function +oktag_from_io: + link.w %a6,#0 + move.l %d2,-(%sp) + move.l 8(%a6),%d1 + move.l 12(%a6),%a1 + move.l %d1,%a0 + move.l 16(%a6),%d0 + addq.l #3,%d0 + lsr.l #2,%d0 + subq.l #1,%d0 + moveq.l #-1,%d2 + cmp.l %d0,%d2 + jbeq .L9 +.L11: +exp2: + move.l (%a1),(%a0)+ + dbra %d0,.L11 + clr.w %d0 + subq.l #1,%d0 + jbcc .L11 +.L9: +ret2: + move.l %a0,%d0 + sub.l %d1,%d0 + asr.l #2,%d0 + move.l -4(%a6),%d2 + unlk %a6 + rts +.Lfe2: + .size oktag_from_io,.Lfe2-oktag_from_io + .ident "GCC: (GNU) 2.7.2.1" + +/* + * Exception table. + * Second longword shows where to jump when an exception at the addr the first + * longword is pointing to is caught. + */ + +.section __ex_table,"a" + .align 2 +oktagon_except: + .long exp1,ret1 + .long exp2,ret2 + +#endif +#endif diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/pas16.c linux/drivers/scsi/pas16.c --- v2.3.13/linux/drivers/scsi/pas16.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/scsi/pas16.c Thu Aug 12 11:10:58 1999 @@ -73,7 +73,6 @@ * software after reset using the default_irq for the * current board number. * - * * 2. With command line overrides - pas16=port,irq may be * used on the LILO command line to override the defaults. * @@ -83,6 +82,11 @@ * -DPAS16_OVERRIDE={{0x388, 10}} * NOTE: Untested. * + * 4. When included as a module, with arguments passed on the command line: + * pas16_irq=xx the interrupt + * pas16_addr=xx the port + * e.g. "modprobe pas16 pas16_addr=0x388 pas16_irq=5" + * * Note that if the override methods are used, place holders must * be specified for other boards in the system. * @@ -99,7 +103,11 @@ * interrupts. Ie, for a board at the default 0x388 base port, * boot: linux pas16=0x388,255 * - * (255 is the IRQ_NONE constant in NCR5380.h) + * IRQ_NONE (255) should be specified for no interrupt, + * IRQ_AUTO (254) to autoprobe for an IRQ line if overridden + * on the command line. + * + * (IRQ_AUTO == 254, IRQ_NONE == 255 in NCR5380.h) */ #ifdef MODULE @@ -129,6 +137,8 @@ }; static int pas_maxi = 0; static int pas_wmaxi = 0; +static unsigned short pas16_addr = 0; +static int pas16_irq = 0; int scsi_irq_translate[] = @@ -385,6 +395,22 @@ tpnt->proc_dir = &proc_scsi_pas16; tpnt->proc_info = &pas16_proc_info; + if (pas16_addr != 0) { + overrides[0].io_port = pas16_addr; + /* + * This is how we avoid seeing more than + * one host adapter at the same I/O port. + * Cribbed shamelessly from pas16_setup(). + */ + for (count = 0; count < NO_BASES; ++count) + if (bases[count].io_port == pas16_addr) { + bases[count].noauto = 1; + break; + } + } + if (pas16_irq != 0) + overrides[0].irq = pas16_irq; + for (count = 0; current_override < NO_OVERRIDES; ++current_override) { io_port = 0; @@ -580,4 +606,7 @@ Scsi_Host_Template driver_template = MV_PAS16; #include "scsi_module.c" + +MODULE_PARM(pas16_addr, "h"); +MODULE_PARM(pas16_irq, "i"); #endif diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c --- v2.3.13/linux/drivers/scsi/scsi.c Mon Aug 9 14:59:22 1999 +++ linux/drivers/scsi/scsi.c Mon Aug 9 19:21:33 1999 @@ -406,6 +406,11 @@ up(SCpnt->request.sem); } +MODULE_PARM(scsi_logging_level, "i"); +MODULE_PARM_DESC(scsi_logging_level, "SCSI logging level; should be zero or nonzero"); + +#ifndef MODULE + static int __init scsi_logging_setup (char *str) { int tmp; @@ -422,12 +427,19 @@ __setup("scsi_logging=", scsi_logging_setup); +#endif + #ifdef CONFIG_SCSI_MULTI_LUN static int max_scsi_luns = 8; #else static int max_scsi_luns = 1; #endif +MODULE_PARM(max_scsi_luns, "i"); +MODULE_PARM_DESC(max_scsi_luns, "last scsi LUN (should be between 1 and 8)"); + +#ifndef MODULE + static int __init scsi_luns_setup (char *str) { int tmp; @@ -443,6 +455,9 @@ } __setup("max_scsi_luns=", scsi_luns_setup); + +#endif + /* * Detecting SCSI devices : * We scan all present host adapter's busses, from ID 0 to ID (max_id). diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/scsi_error.c linux/drivers/scsi/scsi_error.c --- v2.3.13/linux/drivers/scsi/scsi_error.c Wed Jun 16 19:26:27 1999 +++ linux/drivers/scsi/scsi_error.c Sun Aug 15 11:49:53 1999 @@ -35,7 +35,11 @@ #include "hosts.h" #include "constants.h" -#define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM)) +#ifdef MODULE + #define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM)) +#else + #define SHUTDOWN_SIGS (0UL) +#endif #ifdef DEBUG #define SENSE_TIMEOUT SCSI_TIMEOUT diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/sun3x_esp.c linux/drivers/scsi/sun3x_esp.c --- v2.3.13/linux/drivers/scsi/sun3x_esp.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/scsi/sun3x_esp.c Thu Aug 12 10:28:34 1999 @@ -0,0 +1,290 @@ +/* sun3x_esp.c: EnhancedScsiProcessor Sun3x SCSI driver code. + * + * (C) 1999 Thomas Bogendoerfer (tsbogend@alpha.franken.de) + * + * Based on David S. Miller's esp driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "scsi.h" +#include "hosts.h" +#include "NCR53C9x.h" + +#include "sun3x_esp.h" +#include +#include + +extern struct NCR_ESP *espchain; + +static void dma_barrier(struct NCR_ESP *esp); +static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count); +static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp); +static void dma_drain(struct NCR_ESP *esp); +static void dma_dump_state(struct NCR_ESP *esp); +static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length); +static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length); +static void dma_ints_off(struct NCR_ESP *esp); +static void dma_ints_on(struct NCR_ESP *esp); +static int dma_irq_p(struct NCR_ESP *esp); +static void dma_poll(struct NCR_ESP *esp, unsigned char *vaddr); +static int dma_ports_p(struct NCR_ESP *esp); +static void dma_reset(struct NCR_ESP *esp); +static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write); +static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp); +static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp); +static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp); +static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp); +static void dma_advance_sg (Scsi_Cmnd *sp); + +volatile unsigned char cmd_buffer[16]; + /* This is where all commands are put + * before they are trasfered to the ESP chip + * via PIO. + */ + +/* Detecting ESP chips on the machine. This is the simple and easy + * version. + */ +int sun3x_esp_detect(Scsi_Host_Template *tpnt) +{ + struct NCR_ESP *esp; + struct ConfigDev *esp_dev; + + esp_dev = 0; + esp = esp_allocate(tpnt, (void *) esp_dev); + + /* Do command transfer with DMA */ + esp->do_pio_cmds = 0; + + /* Required functions */ + esp->dma_bytes_sent = &dma_bytes_sent; + esp->dma_can_transfer = &dma_can_transfer; + esp->dma_dump_state = &dma_dump_state; + esp->dma_init_read = &dma_init_read; + esp->dma_init_write = &dma_init_write; + esp->dma_ints_off = &dma_ints_off; + esp->dma_ints_on = &dma_ints_on; + esp->dma_irq_p = &dma_irq_p; + esp->dma_ports_p = &dma_ports_p; + esp->dma_setup = &dma_setup; + + /* Optional functions */ + esp->dma_barrier = &dma_barrier; + esp->dma_drain = &dma_drain; + esp->dma_irq_entry = &dma_ints_off; + esp->dma_irq_exit = &dma_ints_on; + esp->dma_led_on = 0; + esp->dma_led_off = 0; + esp->dma_poll = &dma_poll; + esp->dma_reset = &dma_reset; + + /* virtual DMA functions */ + esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one; + esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl; + esp->dma_mmu_release_scsi_one = &dma_mmu_release_scsi_one; + esp->dma_mmu_release_scsi_sgl = &dma_mmu_release_scsi_sgl; + esp->dma_advance_sg = &dma_advance_sg; + + /* SCSI chip speed */ + esp->cfreq = 20000000; + esp->eregs = (struct ESP_regs *)(SUN3X_ESP_BASE); + esp->dregs = (void *)SUN3X_ESP_DMA; + + esp->esp_command = (volatile unsigned char *)cmd_buffer; + esp->esp_command_dvma = dvma_alloc(virt_to_phys(cmd_buffer), + sizeof (cmd_buffer)); + + esp->irq = 2; + request_irq(esp->irq, esp_intr, SA_INTERRUPT, "SUN3X SCSI", NULL); + + esp->scsi_id = 7; + esp->diff = 0; + + esp_initialize(esp); + + printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, + esps_in_use); + esps_running = esps_in_use; + return esps_in_use; +} + +static void dma_barrier(struct NCR_ESP *esp) +{ + struct sparc_dma_registers *dregs = + (struct sparc_dma_registers *) esp->dregs; + + while(dregs->cond_reg & DMA_PEND_READ) + udelay(1); + dregs->cond_reg &= ~(DMA_ENABLE); +} + +/* This uses various DMA csr fields and the fifo flags count value to + * determine how many bytes were successfully sent/received by the ESP. + */ +static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count) +{ + struct sparc_dma_registers *dregs = + (struct sparc_dma_registers *) esp->dregs; + + int rval = dregs->st_addr - esp->esp_command_dvma; + + return rval - fifo_count; +} + +static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp) +{ + __u32 base, end, sz; + + base = ((__u32)sp->SCp.ptr); + base &= (0x1000000 - 1); + end = (base + sp->SCp.this_residual); + if(end > 0x1000000) + end = 0x1000000; + sz = (end - base); + return sz; +} + +static void dma_drain(struct NCR_ESP *esp) +{ + struct sparc_dma_registers *dregs = + (struct sparc_dma_registers *) esp->dregs; + + if(dregs->cond_reg & DMA_FIFO_ISDRAIN) { + dregs->cond_reg |= DMA_FIFO_STDRAIN; + while(dregs->cond_reg & DMA_FIFO_ISDRAIN) + udelay(1); + } +} + +static void dma_dump_state(struct NCR_ESP *esp) +{ + struct sparc_dma_registers *dregs = + (struct sparc_dma_registers *) esp->dregs; + + ESPLOG(("esp%d: dma -- cond_reg<%08lx> addr<%p>\n", + esp->esp_id, dregs->cond_reg, dregs->st_addr)); +} + +static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length) +{ + struct sparc_dma_registers *dregs = + (struct sparc_dma_registers *) esp->dregs; + + dregs->cond_reg |= (DMA_ST_WRITE | DMA_ENABLE); + dregs->st_addr = vaddress; +} + +static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length) +{ + struct sparc_dma_registers *dregs = + (struct sparc_dma_registers *) esp->dregs; + + /* Set up the DMA counters */ + dregs->cond_reg = ((dregs->cond_reg & ~(DMA_ST_WRITE)) | DMA_ENABLE); + dregs->st_addr = vaddress; +} + +static void dma_ints_off(struct NCR_ESP *esp) +{ + DMA_INTSOFF((struct sparc_dma_registers *) esp->dregs); +} + +static void dma_ints_on(struct NCR_ESP *esp) +{ + DMA_INTSON((struct sparc_dma_registers *) esp->dregs); +} + +static int dma_irq_p(struct NCR_ESP *esp) +{ + return DMA_IRQ_P((struct sparc_dma_registers *) esp->dregs); +} + +static void dma_poll(struct NCR_ESP *esp, unsigned char *vaddr) +{ + dma_drain(esp); + + /* Wait till the first bits settle. */ + while(vaddr[0] == 0xff) + udelay(1); +} + +static int dma_ports_p(struct NCR_ESP *esp) +{ + return (((struct sparc_dma_registers *) esp->dregs)->cond_reg + & DMA_INT_ENAB); +} + +/* Resetting various pieces of the ESP scsi driver chipset/buses. */ +static void dma_reset(struct NCR_ESP *esp) +{ + struct sparc_dma_registers *dregs = + (struct sparc_dma_registers *)esp->dregs; + + /* Punt the DVMA into a known state. */ + dregs->cond_reg |= DMA_RST_SCSI; + dregs->cond_reg &= ~(DMA_RST_SCSI); + DMA_INTSON(dregs); +} + +static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) +{ + struct sparc_dma_registers *dregs = + (struct sparc_dma_registers *) esp->dregs; + unsigned long nreg = dregs->cond_reg; + + if(write) + nreg |= DMA_ST_WRITE; + else + nreg &= ~(DMA_ST_WRITE); + nreg |= DMA_ENABLE; + dregs->cond_reg = nreg; + dregs->st_addr = addr; +} + +static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp) +{ + sp->SCp.have_data_in = dvma_alloc(virt_to_phys(sp->SCp.buffer), + sp->SCp.this_residual); + sp->SCp.ptr = (char *)((unsigned long)sp->SCp.have_data_in); +} + +static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp) +{ + int sz = sp->SCp.buffers_residual; + struct mmu_sglist *sg = (struct mmu_sglist *) sp->SCp.buffer; + + while (sz >= 0) { + sg[sz].dvma_addr = dvma_alloc(virt_to_phys(sg[sz].addr), sg[sz].len); + sz--; + } + sp->SCp.ptr=(char *)((unsigned long)sp->SCp.buffer->dvma_address); +} + +static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp) +{ + dvma_free(sp->SCp.have_data_in, sp->request_bufflen); +} + +static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp) +{ + int sz = sp->use_sg - 1; + struct mmu_sglist *sg = (struct mmu_sglist *)sp->buffer; + + while(sz >= 0) { + dvma_free(sg[sz].dvma_addr,sg[sz].len); + sz--; + } +} + +static void dma_advance_sg (Scsi_Cmnd *sp) +{ + sp->SCp.ptr = (char *)((unsigned long)sp->SCp.buffer->dvma_address); +} diff -u --recursive --new-file v2.3.13/linux/drivers/scsi/sun3x_esp.h linux/drivers/scsi/sun3x_esp.h --- v2.3.13/linux/drivers/scsi/sun3x_esp.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/scsi/sun3x_esp.h Thu Aug 12 10:28:34 1999 @@ -0,0 +1,41 @@ +/* sun3x_esp.h: Defines and structures for the Sun3x ESP + * + * (C) 1995 Thomas Bogendoerfer (tsbogend@alpha.franken.de) + */ + +#ifndef _SUN3X_ESP_H +#define _SUN3X_ESP_H + +/* For dvma controller register definitions. */ +#include + +extern int sun3x_esp_detect(struct SHT *); +extern const char *esp_info(struct Scsi_Host *); +extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); +extern int esp_command(Scsi_Cmnd *); +extern int esp_abort(Scsi_Cmnd *); +extern int esp_reset(Scsi_Cmnd *, unsigned int); +extern int esp_proc_info(char *buffer, char **start, off_t offset, int length, + int hostno, int inout); + +extern struct proc_dir_entry proc_scsi_esp; + +#define DMA_PORTS_P (dregs->cond_reg & DMA_INT_ENAB) + +#define SCSI_SUN3X_ESP { \ + proc_dir: &proc_scsi_esp, \ + proc_info: &esp_proc_info, \ + name: "Sun ESP 100/100a/200", \ + detect: sun3x_esp_detect, \ + info: esp_info, \ + command: esp_command, \ + queuecommand: esp_queue, \ + abort: esp_abort, \ + reset: esp_reset, \ + can_queue: 7, \ + this_id: 7, \ + sg_tablesize: SG_ALL, \ + cmd_per_lun: 1, \ + use_clustering: DISABLE_CLUSTERING, } + +#endif /* !(_SUN3X_ESP_H) */ diff -u --recursive --new-file v2.3.13/linux/drivers/sound/Makefile linux/drivers/sound/Makefile --- v2.3.13/linux/drivers/sound/Makefile Mon Aug 9 14:59:23 1999 +++ linux/drivers/sound/Makefile Thu Aug 12 12:18:32 1999 @@ -141,19 +141,19 @@ # Translate to Rules.make lists. -L_TARGET := sound.a +O_TARGET := sounddrivers.o # This is a nice idea but needs depmod altering #MOD_LIST_NAME := SOUND_MODULES -L_OBJS := $(sort $(filter-out $(export-objs), $(obj-y))) -LX_OBJS := $(sort $(filter $(export-objs), $(obj-y))) +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) MI_OBJS := $(sort $(filter-out $(export-objs), $(int-m))) MIX_OBJS := $(sort $(filter $(export-objs), $(int-m))) ifeq ($(CONFIG_LOWLEVEL_SOUND),y) - L_OBJS += lowlevel/lowlevel.o + O_OBJS += lowlevel/lowlevel.o endif include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.3.13/linux/drivers/sound/dmasound.c linux/drivers/sound/dmasound.c --- v2.3.13/linux/drivers/sound/dmasound.c Wed Jul 21 15:46:48 1999 +++ linux/drivers/sound/dmasound.c Wed Aug 18 10:01:36 1999 @@ -131,7 +131,9 @@ static int irq_installed = 0; #endif /* MODULE */ static char **sound_buffers = NULL; +#ifdef CONFIG_PPC static char **sound_read_buffers = NULL; +#endif #ifdef CONFIG_ATARI extern void atari_microwire_cmd(int cmd); @@ -282,7 +284,9 @@ static int catchRadius = 0; static int numBufs = 4, bufSize = 32; +#ifdef CONFIG_PPC static int numReadBufs = 4, readbufSize = 32; +#endif MODULE_PARM(catchRadius, "i"); MODULE_PARM(numBufs, "i"); @@ -796,10 +800,12 @@ size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); +#ifdef CONFIG_PPC static ssize_t sound_copy_translate_read(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, ssize_t frameLeft); +#endif /* @@ -846,7 +852,9 @@ }; static struct sound_queue sq; +#ifdef CONFIG_PPC static struct sound_queue read_sq; +#endif #define sq_block_address(i) (sq.buffers[i]) #define SIGNAL_RECEIVED (signal_pending(current)) @@ -877,7 +885,7 @@ if (value < 0) return(value); - return put_user(value, addr)? -EFAULT: 0; + return put_user(value, addr); } @@ -2728,8 +2736,8 @@ start = sq_block_address(sq.front); end = start+((sq.count == index) ? sq.rear_size : sq.block_size); /* end might not be a legal virtual address. */ - DMASNDSetEnd(VTOP(end - 1) + 1); - DMASNDSetBase(VTOP(start)); + DMASNDSetEnd(virt_to_phys(end - 1) + 1); + DMASNDSetBase(virt_to_phys(start)); /* Since only an even number of samples per frame can be played, we might lose one byte here. (TO DO) */ sq.front = (sq.front+1) % sq.max_count; @@ -4031,6 +4039,7 @@ return 0; } +#ifdef CONFIG_PPC static ssize_t sound_copy_translate_read(const u_char *userPtr, size_t userCount, u_char frame[], ssize_t *frameUsed, @@ -4069,6 +4078,7 @@ else return 0; } +#endif /* @@ -4644,6 +4654,7 @@ } +#ifdef CONFIG_PPC static int sq_allocate_read_buffers(void) { int i; @@ -4680,15 +4691,12 @@ if (sound_read_buffers) { - -#if CONFIG_PPC cp = awacs_rx_cmds; for (i = 0; i < numReadBufs; i++,cp++) { st_le16(&cp->command, DBDMA_STOP); } /* We should probably wait for the thing to stop before we release the memory */ -#endif for (i = 0; i < numBufs; i++) sound.mach.dma_free (sound_read_buffers[i], bufSize << 10); @@ -4696,6 +4704,7 @@ sound_read_buffers = 0; } } +#endif static void sq_setup(int numBufs, int bufSize, char **write_buffers) @@ -4735,12 +4744,11 @@ #endif /* CONFIG_PPC */ } +#ifdef CONFIG_PPC static void read_sq_setup(int numBufs, int bufSize, char **read_buffers) { -#ifdef CONFIG_PPC int i; volatile struct dbdma_cmd *cp; -#endif /* CONFIG_PPC */ read_sq.max_count = numBufs; read_sq.max_active = numBufs; @@ -4753,14 +4761,6 @@ read_sq.syncing = 0; read_sq.active = 0; -#ifdef CONFIG_ATARI - read_sq.ignore_int = 0; -#endif /* CONFIG_ATARI */ -#ifdef CONFIG_AMIGA - read_sq.block_size_half = read_sq.block_size>>1; - read_sq.block_size_quarter = read_sq.block_size_half>>1; -#endif /* CONFIG_AMIGA */ -#ifdef CONFIG_PPC cp = awacs_rx_cmds; memset((void *) cp, 0, (numBufs + 1) * sizeof(struct dbdma_cmd)); @@ -4784,8 +4784,8 @@ out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); out_le32(&awacs_rxdma->cmdptr, virt_to_bus(awacs_rx_cmds)); -#endif /* CONFIG_PPC */ } +#endif /* CONFIG_PPC */ static void sq_play(void) @@ -4868,6 +4868,8 @@ /***********/ +#ifdef CONFIG_PPC + /* Here is how the values are used for reading. * The value 'active' simply indicates the DMA is running. This is * done so the driver semantics are DMA starts when the first read is @@ -4930,6 +4932,7 @@ } return uRead; } +#endif static int sq_open(struct inode *inode, struct file *file) { @@ -4957,6 +4960,7 @@ } +#ifdef CONFIG_PCC if (file->f_mode & FMODE_READ) { if (read_sq.busy) { rc = -EBUSY; @@ -4976,6 +4980,7 @@ read_sq_setup(numReadBufs,readbufSize<<10, sound_read_buffers); read_sq.open_mode = file->f_mode; } +#endif #ifdef CONFIG_ATARI sq.ignore_int = 1; @@ -5004,10 +5009,12 @@ sq.busy = 0; WAKE_UP(sq.open_queue); } +#ifdef CONFIG_PCC if (file->f_mode & FMODE_READ) { read_sq.busy = 0; WAKE_UP(read_sq.open_queue); } +#endif err_out: MOD_DEC_USE_COUNT; return rc; @@ -5056,16 +5063,20 @@ sound.hard = sound.dsp; sound_silence(); +#ifdef CONFIG_PPC sq_release_read_buffers(); +#endif sq_release_buffers(); MOD_DEC_USE_COUNT; /* There is probably a DOS atack here. They change the mode flag. */ /* XXX add check here */ +#ifdef CONFIG_PPC if (file->f_mode & FMODE_READ) { read_sq.busy = 0; WAKE_UP(read_sq.open_queue); } +#endif if (file->f_mode & FMODE_WRITE) { sq.busy = 0; @@ -5173,7 +5184,11 @@ static struct file_operations sq_fops = { sound_lseek, +#ifdef CONFIG_PPC sq_read, /* sq_read */ +#else + NULL, /* sq_read */ +#endif sq_write, NULL, /* sq_readdir */ NULL, /* sq_poll */ @@ -5198,12 +5213,16 @@ init_waitqueue_head(&sq.open_queue); init_waitqueue_head(&sq.sync_queue); +#ifdef CONFIG_PPC init_waitqueue_head(&read_sq.action_queue); init_waitqueue_head(&read_sq.open_queue); init_waitqueue_head(&read_sq.sync_queue); +#endif sq.busy = 0; +#ifdef CONFIG_PPC read_sq.busy = 0; +#endif /* whatever you like as startup mode for /dev/dsp, * (/dev/audio hasn't got a startup mode). note that @@ -5251,7 +5270,10 @@ static int state_open(struct inode *inode, struct file *file) { - char *buffer = state.buf, *mach = "", awacs_buf[50]; + char *buffer = state.buf, *mach = ""; +#ifdef CONFIG_PPC + char awacs_buf[50]; +#endif int len = 0; if (state.busy) diff -u --recursive --new-file v2.3.13/linux/drivers/sound/es1370.c linux/drivers/sound/es1370.c --- v2.3.13/linux/drivers/sound/es1370.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/sound/es1370.c Thu Aug 12 12:21:47 1999 @@ -106,6 +106,7 @@ * 03.08.99 0.26 adapt to Linus' new __setup/__initcall * added kernel command line option "es1370=joystick[,lineout[,micbias]]" * removed CONFIG_SOUND_ES1370_JOYPORT_BOOT kludge + * 12.08.99 0.27 module_init/__setup fixes * * some important things missing in Ensoniq documentation: * @@ -1067,9 +1068,10 @@ current->state = TASK_RUNNING; return -EBUSY; } - tmo = (count * HZ) / dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL]; + tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2 + / dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL]; tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT]; - if (!schedule_timeout(tmo ? : 1) && tmo) + if (!schedule_timeout(tmo + 1)) DBG(printk(KERN_DEBUG "es1370: dma timed out??\n");) } remove_wait_queue(&s->dma_dac1.wait, &wait); @@ -1102,9 +1104,10 @@ current->state = TASK_RUNNING; return -EBUSY; } - tmo = (count * HZ) / DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV); + tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2 + / DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV); tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT]; - if (!schedule_timeout(tmo ? : 1) && tmo) + if (!schedule_timeout(tmo + 1)) DBG(printk(KERN_DEBUG "es1370: dma timed out??\n");) } remove_wait_queue(&s->dma_dac2.wait, &wait); @@ -2300,6 +2303,16 @@ static int lineout[NR_DEVICE] = { 0, }; static int micbias[NR_DEVICE] = { 0, }; +MODULE_PARM(joystick, "1-" __MODULE_STRING(NR_DEVICE) "i"); +MODULE_PARM_DESC(joystick, "if 1 enables joystick interface (still need separate driver)"); +MODULE_PARM(lineout, "1-" __MODULE_STRING(NR_DEVICE) "i"); +MODULE_PARM_DESC(lineout, "if 1 the LINE input is converted to LINE out"); +MODULE_PARM(micbias, "1-" __MODULE_STRING(NR_DEVICE) "i"); +MODULE_PARM_DESC(micbias, "sets the +5V bias for an electret microphone"); + +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); +MODULE_DESCRIPTION("ES1370 AudioPCI Driver"); + /* --------------------------------------------------------------------- */ static struct initvol { @@ -2318,10 +2331,7 @@ { SOUND_MIXER_WRITE_OGAIN, 0x4040 } }; -#ifndef MODULE -static -#endif -int __init init_module(void) +static int __init init_es1370(void) { struct es1370_state *s; struct pci_dev *pcidev = NULL; @@ -2330,7 +2340,7 @@ if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk(KERN_INFO "es1370: version v0.26 time " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "es1370: version v0.27 time " __TIME__ " " __DATE__ "\n"); while (index < NR_DEVICE && (pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1370, pcidev))) { if (pcidev->resource[0].flags == 0 || @@ -2438,21 +2448,7 @@ return 0; } -/* --------------------------------------------------------------------- */ - -#ifdef MODULE - -MODULE_PARM(joystick, "1-" __MODULE_STRING(NR_DEVICE) "i"); -MODULE_PARM_DESC(joystick, "if 1 enables joystick interface (still need separate driver)"); -MODULE_PARM(lineout, "1-" __MODULE_STRING(NR_DEVICE) "i"); -MODULE_PARM_DESC(lineout, "if 1 the LINE input is converted to LINE out"); -MODULE_PARM(micbias, "1-" __MODULE_STRING(NR_DEVICE) "i"); -MODULE_PARM_DESC(micbias, "sets the +5V bias for an electret microphone"); - -MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); -MODULE_DESCRIPTION("ES1370 AudioPCI Driver"); - -void cleanup_module(void) +static void __exit cleanup_es1370(void) { struct es1370_state *s; @@ -2472,7 +2468,12 @@ printk(KERN_INFO "es1370: unloading\n"); } -#else /* MODULE */ +module_init(init_es1370); +module_exit(cleanup_es1370); + +/* --------------------------------------------------------------------- */ + +#ifndef MODULE /* format is: es1370=[joystick[,lineout[,micbias]]] */ @@ -2493,6 +2494,5 @@ } __setup("es1370=", es1370_setup); -__initcall(init_module); #endif /* MODULE */ diff -u --recursive --new-file v2.3.13/linux/drivers/sound/es1371.c linux/drivers/sound/es1371.c --- v2.3.13/linux/drivers/sound/es1371.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/sound/es1371.c Thu Aug 12 12:21:48 1999 @@ -3,7 +3,7 @@ /* * es1371.c -- Creative Ensoniq ES1371. * - * Copyright (C) 1998 Thomas Sailer (sailer@ife.ee.ethz.ch) + * Copyright (C) 1998-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -71,6 +71,9 @@ * 03.08.99 0.14 adapt to Linus' new __setup/__initcall * added kernel command line option "es1371=joystickaddr" * removed CONFIG_SOUND_ES1371_JOYPORT_BOOT kludge + * 10.08.99 0.15 (Re)added S/PDIF module option for cards revision >= 4. + * Initial version by Dave Platt . + * module_init/__setup fixes * */ @@ -145,6 +148,7 @@ static const unsigned sample_size[] = { 1, 2, 2, 4 }; static const unsigned sample_shift[] = { 0, 1, 1, 2 }; +#define CTRL_SPDIFEN_B 0x04000000 #define CTRL_JOY_SHIFT 24 #define CTRL_JOY_MASK 3 #define CTRL_JOY_200 0x00000000 /* joystick base address */ @@ -180,6 +184,9 @@ #define STAT_INTR 0x80000000 /* wired or of all interrupt bits */ +#define STAT_EN_SPDIF 0x00040000 /* enable S/PDIF circuitry */ +#define STAT_TS_SPDIF 0x00020000 /* test S/PDIF circuitry */ +#define STAT_TESTMODE 0x00010000 /* test ASIC */ #define STAT_SYNC_ERR 0x00000100 /* 1 = codec sync error */ #define STAT_VC 0x000000c0 /* CCB int source, 0=DAC1, 1=DAC2, 2=ADC, 3=undef */ #define STAT_SH_VC 6 @@ -1481,9 +1488,9 @@ current->state = TASK_RUNNING; return -EBUSY; } - tmo = (count * HZ) / s->dac1rate; + tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2 / s->dac1rate; tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT]; - if (!schedule_timeout(tmo ? : 1) && tmo) + if (!schedule_timeout(tmo + 1)) printk(KERN_DEBUG "es1371: dma timed out??\n"); } remove_wait_queue(&s->dma_dac1.wait, &wait); @@ -1516,9 +1523,9 @@ current->state = TASK_RUNNING; return -EBUSY; } - tmo = (count * HZ) / s->dac2rate; + tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2 / s->dac2rate; tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT]; - if (!schedule_timeout(tmo ? : 1) && tmo) + if (!schedule_timeout(tmo + 1)) printk(KERN_DEBUG "es1371: dma timed out??\n"); } remove_wait_queue(&s->dma_dac2.wait, &wait); @@ -2697,6 +2704,15 @@ #define NR_DEVICE 5 static int joystick[NR_DEVICE] = { 0, }; +static int spdif[NR_DEVICE] = { 0, }; + +MODULE_PARM(joystick, "1-" __MODULE_STRING(NR_DEVICE) "i"); +MODULE_PARM_DESC(joystick, "sets address and enables joystick interface (still need separate driver)"); +MODULE_PARM(spdif, "1-" __MODULE_STRING(NR_DEVICE) "i"); +MODULE_PARM_DESC(spdif, "if 1 the output is in S/PDIF digital mode"); + +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); +MODULE_DESCRIPTION("ES1371 AudioPCI97 Driver"); /* --------------------------------------------------------------------- */ @@ -2719,19 +2735,18 @@ { SOUND_MIXER_WRITE_IGAIN, 0x4040 } }; -#ifndef MODULE -static -#endif -int __init init_module(void) +static int __init init_es1371(void) { struct es1371_state *s; struct pci_dev *pcidev = NULL; mm_segment_t fs; int i, val, val2, index = 0; + u8 revision; + unsigned cssr; if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk(KERN_INFO "es1371: version v0.14 time " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "es1371: version v0.15 time " __TIME__ " " __DATE__ "\n"); while (index < NR_DEVICE && (pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1371, pcidev))) { if (pcidev->resource[0].flags == 0 || @@ -2784,6 +2799,18 @@ } } s->sctrl = 0; + cssr = 0; + /* check to see if s/pdif mode is being requested */ + pci_read_config_byte(pcidev, PCI_REVISION_ID, &revision); + if (spdif[index]) { + if (revision >= 4) { + printk(KERN_INFO "es1371: enabling S/PDIF output\n"); + cssr |= STAT_EN_SPDIF; + s->ctrl |= CTRL_SPDIFEN_B; + } else { + printk(KERN_ERR "es1371: revision %d does not support S/PDIF\n", revision); + } + } /* initialize the chips */ outl(s->ctrl, s->io+ES1371_REG_CONTROL); outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); @@ -2858,6 +2885,8 @@ mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val); } set_fs(fs); + /* turn on S/PDIF output driver if requested */ + outl(cssr, s->io+ES1371_REG_STATUS); /* queue it for later freeing */ s->next = devs; devs = s; @@ -2883,17 +2912,7 @@ return 0; } -/* --------------------------------------------------------------------- */ - -#ifdef MODULE - -MODULE_PARM(joystick, "1-" __MODULE_STRING(NR_DEVICE) "i"); -MODULE_PARM_DESC(joystick, "sets address and enables joystick interface (still need separate driver)"); - -MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); -MODULE_DESCRIPTION("ES1371 AudioPCI97 Driver"); - -void cleanup_module(void) +static void __exit cleanup_es1371(void) { struct es1371_state *s; @@ -2913,23 +2932,27 @@ printk(KERN_INFO "es1371: unloading\n"); } -#else /* MODULE */ +module_init(init_es1371); +module_exit(cleanup_es1371); + +/* --------------------------------------------------------------------- */ + +#ifndef MODULE /* format is: es1371=[joystick] */ static int __init es1371_setup(char *str) { static unsigned __initdata nr_dev = 0; - int ints[11]; if (nr_dev >= NR_DEVICE) return 0; - get_option(&str, &joystick[nr_dev]); + if (get_option(&str, &joystick[nr_dev]) == 2) + get_option(&str, &spdif[nr_dev]); nr_dev++; return 1; } __setup("es1371=", es1371_setup); -__initcall(init_module); #endif /* MODULE */ diff -u --recursive --new-file v2.3.13/linux/drivers/sound/esssolo1.c linux/drivers/sound/esssolo1.c --- v2.3.13/linux/drivers/sound/esssolo1.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/sound/esssolo1.c Thu Aug 12 12:21:48 1999 @@ -39,13 +39,26 @@ * 15.06.99 0.4 Fix bad allocation bug. * Thanks to Deti Fliegl * 28.06.99 0.5 Add pci_set_master - * + * 12.08.99 0.6 Fix MIDI UART crashing the driver + * Changed mixer semantics from OSS documented + * behaviour to OSS "code behaviour". + * Recording might actually work now. + * The real DDMA controller address register is at PCI config + * 0x60, while the register at 0x18 is used as a placeholder + * register for BIOS address allocation. This register + * is supposed to be copied into 0x60, according + * to the Solo1 datasheet. When I do that, I can access + * the DDMA registers except the mask bit, which + * is stuck at 1. When I copy the contents of 0x18 +0x10 + * to the DDMA base register, everything seems to work. + * The fun part is that the Windows Solo1 driver doesn't + * seem to do these tricks. + * Bugs remaining: plops and clicks when starting/stopping playback * */ /*****************************************************************************/ -#include #include #include #include @@ -69,6 +82,10 @@ /* --------------------------------------------------------------------- */ +#undef OSS_DOCUMENTED_MIXER_SEMANTICS + +/* --------------------------------------------------------------------- */ + #ifndef PCI_VENDOR_ID_ESS #define PCI_VENDOR_ID_ESS 0x125d #endif @@ -78,9 +95,12 @@ #define SOLO1_MAGIC ((PCI_VENDOR_ID_ESS<<16)|PCI_DEVICE_ID_ESS_SOLO1) +#define DDMABASE_OFFSET 0x10 /* chip bug workaround kludge */ +#define DDMABASE_EXTENT 16 + #define IOBASE_EXTENT 16 #define SBBASE_EXTENT 16 -#define VCBASE_EXTENT 16 +#define VCBASE_EXTENT (DDMABASE_EXTENT+DDMABASE_OFFSET) #define MPUBASE_EXTENT 4 #define GPBASE_EXTENT 4 @@ -98,16 +118,15 @@ /* --------------------------------------------------------------------- */ -#define DEBUGREC - -/* --------------------------------------------------------------------- */ - struct solo1_state { /* magic */ unsigned int magic; - /* we keep sb cards in a linked list */ + /* we keep the cards in a linked list */ struct solo1_state *next; + + /* pcidev is needed to turn off the DDMA controller at driver shutdown */ + struct pci_dev *pcidev; /* soundcore stuff */ int dev_audio; @@ -116,10 +135,10 @@ int dev_dmfm; /* hardware resources */ - unsigned long iobase, sbbase, vcbase, mpubase, gpbase; /* long for SPARC */ + unsigned long iobase, sbbase, vcbase, ddmabase, mpubase, gpbase; /* long for SPARC */ unsigned int irq; - /* mixer registers; there is no HW readback */ + /* mixer registers */ struct { unsigned short vol[10]; unsigned int recsrc; @@ -302,6 +321,8 @@ spin_lock_irqsave(&s->lock, flags); if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) { s->ena |= FMODE_WRITE; + write_mixer(s, 0x78, 0x12); + udelay(10); write_mixer(s, 0x78, 0x13); } spin_unlock_irqrestore(&s->lock, flags); @@ -326,47 +347,24 @@ && s->dma_adc.ready) { s->ena |= FMODE_READ; write_ctrl(s, 0xb8, 0xf); -#ifdef DEBUGREC +#if 0 printk(KERN_DEBUG "solo1: DMAbuffer: 0x%08lx\n", (long)s->dma_adc.rawbuf); printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x stat: 0x%02x\n", - inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase), inb(s->vcbase+8)); -#endif - outb(0, s->vcbase+0xd); /* master reset */ -#ifdef DEBUGREC - printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x stat: 0x%02x (a. clr)\n", - inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase), inb(s->vcbase+8)); -#endif - outb(1, s->vcbase+0xf); /* mask */ -#ifdef DEBUGREC - printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x stat: 0x%02x (a. mask)\n", - inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase), inb(s->vcbase+8)); -#endif - outb(0x54/*0x14*/, s->vcbase+0xb); /* DMA_MODE_READ | DMA_MODE_AUTOINIT */ -#ifdef DEBUGREC - printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x stat: 0x%02x (a. wrmode)\n", - inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase), inb(s->vcbase+8)); -#endif - outl(virt_to_bus(s->dma_adc.rawbuf), s->vcbase); -#ifdef DEBUGREC - printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x stat: 0x%02x (a. wrbase)\n", - inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase), inb(s->vcbase+8)); -#endif - outw(s->dma_adc.dmasize-1, s->vcbase+4); -#ifdef DEBUGREC - printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x stat: 0x%02x (a. wrcnt)\n", - inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase), inb(s->vcbase+8)); -#endif - outb(0, s->vcbase+0xf); -#ifdef DEBUGREC - printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x stat: 0x%02x (a. clrmask)\n", - inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase), inb(s->vcbase+8)); + inb(s->ddmabase+0xf), inw(s->ddmabase+4), inl(s->ddmabase), inb(s->ddmabase+8)); #endif + outb(0, s->ddmabase+0xd); /* master reset */ + outb(1, s->ddmabase+0xf); /* mask */ + outb(0x54/*0x14*/, s->ddmabase+0xb); /* DMA_MODE_READ | DMA_MODE_AUTOINIT */ + outl(virt_to_bus(s->dma_adc.rawbuf), s->ddmabase); + outw(s->dma_adc.dmasize-1, s->ddmabase+4); + outb(0, s->ddmabase+0xf); } spin_unlock_irqrestore(&s->lock, flags); -#ifdef DEBUGREC - printk(KERN_DEBUG "solo1: start DMA: reg B8: 0x%02x DMAstat: 0x%02x DMAcnt: 0x%04x DMAmask: 0x%02x SBstat: 0x%02x\n", - read_ctrl(s, 0xb8), inb(s->vcbase+8), inw(s->vcbase+4), inb(s->vcbase+0xf), inb(s->sbbase+0xc)); - +#if 0 + printk(KERN_DEBUG "solo1: start DMA: reg B8: 0x%02x SBstat: 0x%02x\n" + KERN_DEBUG "solo1: DMA: stat: 0x%02x cnt: 0x%04x mask: 0x%02x\n", + read_ctrl(s, 0xb8), inb(s->sbbase+0xc), + inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->ddmabase+0xf)); printk(KERN_DEBUG "solo1: A1: 0x%02x A2: 0x%02x A4: 0x%02x A5: 0x%02x A8: 0x%02x\n" KERN_DEBUG "solo1: B1: 0x%02x B2: 0x%02x B4: 0x%02x B7: 0x%02x B8: 0x%02x B9: 0x%02x\n", read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), @@ -456,16 +454,16 @@ va = virt_to_bus(s->dma_adc.rawbuf); if ((va & ~((1<<24)-1))) panic("solo1: buffer above 16M boundary"); - outb(0, s->vcbase+0xd); /* clear */ - outb(1, s->vcbase+0xf); /* mask */ - //outb(0, s->vcbase+8); /* enable (enable is active low!) */ - outb(0x54, s->vcbase+0xb); /* DMA_MODE_READ | DMA_MODE_AUTOINIT */ - outl(va, s->vcbase); - outw(s->dma_adc.dmasize-1, s->vcbase+4); + outb(0, s->ddmabase+0xd); /* clear */ + outb(1, s->ddmabase+0xf); /* mask */ + /*outb(0, s->ddmabase+8);*/ /* enable (enable is active low!) */ + outb(0x54, s->ddmabase+0xb); /* DMA_MODE_READ | DMA_MODE_AUTOINIT */ + outl(va, s->ddmabase); + outw(s->dma_adc.dmasize-1, s->ddmabase+4); c = - s->dma_adc.fragsamples; write_ctrl(s, 0xa4, c); write_ctrl(s, 0xa5, c >> 8); - outb(0, s->vcbase+0xf); + outb(0, s->ddmabase+0xf); s->dma_adc.ready = 1; return 0; } @@ -513,12 +511,12 @@ /* update ADC pointer */ if (s->ena & FMODE_READ) { - hwptr = (s->dma_adc.dmasize - 1 - inw(s->vcbase+4)) % s->dma_adc.dmasize; + hwptr = (s->dma_adc.dmasize - 1 - inw(s->ddmabase+4)) % s->dma_adc.dmasize; diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize; s->dma_adc.hwptr = hwptr; s->dma_adc.total_bytes += diff; s->dma_adc.count += diff; -#ifdef DEBUGREC +#if 0 printk(KERN_DEBUG "solo1: rd: hwptr %u swptr %u dmasize %u count %u\n", s->dma_adc.hwptr, s->dma_adc.swptr, s->dma_adc.dmasize, s->dma_adc.count); #endif @@ -633,16 +631,28 @@ SOUND_MASK_MIC, SOUND_MASK_MIC, SOUND_MASK_CD, SOUND_MASK_VOLUME, SOUND_MASK_MIC, 0, SOUND_MASK_LINE, 0 }; - static const unsigned char mixtable[SOUND_MIXER_NRDEVICES] = { - [SOUND_MIXER_PCM] = 0x7c, /* voice */ - [SOUND_MIXER_SYNTH] = 0x36, /* FM */ - [SOUND_MIXER_CD] = 0x38, /* CD */ - [SOUND_MIXER_LINE] = 0x3e, /* Line */ - [SOUND_MIXER_LINE1] = 0x3a, /* AUX */ - [SOUND_MIXER_MIC] = 0x1a, /* Mic */ - [SOUND_MIXER_LINE2] = 0x6d /* Mono in */ + static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = { + [SOUND_MIXER_PCM] = 1, /* voice */ + [SOUND_MIXER_SYNTH] = 2, /* FM */ + [SOUND_MIXER_CD] = 3, /* CD */ + [SOUND_MIXER_LINE] = 4, /* Line */ + [SOUND_MIXER_LINE1] = 5, /* AUX */ + [SOUND_MIXER_MIC] = 6, /* Mic */ + [SOUND_MIXER_LINE2] = 7, /* Mono in */ + [SOUND_MIXER_SPEAKER] = 8, /* Speaker */ + [SOUND_MIXER_RECLEV] = 9, /* Recording level */ + [SOUND_MIXER_VOLUME] = 10 /* Master Volume */ }; - unsigned char l, r, rl, rr; + static const unsigned char mixreg[] = { + 0x7c, /* voice */ + 0x36, /* FM */ + 0x38, /* CD */ + 0x3e, /* Line */ + 0x3a, /* AUX */ + 0x1a, /* Mic */ + 0x6d /* Mono in */ + }; + unsigned char l, r, rl, rr, vidx; int i, val; VALIDATE_STATE(s); @@ -657,16 +667,6 @@ val = (read_mixer(s, 0x7d) & 0x08) ? 1 : 0; return put_user(val, (int *)arg); } - if (cmd == SOUND_MIXER_PRIVATE1) { - /* enable/disable/query mixer preamp */ - get_user_ret(val, (int *)arg, -EFAULT); - if (val != -1) { - val = val ? 0xff : 0xf7; - write_mixer(s, 0x7d, (read_mixer(s, 0x7d) | 0x08) & val); - } - val = (read_mixer(s, 0x7d) & 0x08) ? 1 : 0; - return put_user(val, (int *)arg); - } if (cmd == SOUND_MIXER_PRIVATE2) { /* enable/disable/query spatializer */ get_user_ret(val, (int *)arg, -EFAULT); @@ -720,36 +720,11 @@ case SOUND_MIXER_CAPS: return put_user(SOUND_CAP_EXCL_INPUT, (int *)arg); - case SOUND_MIXER_VOLUME: - rl = read_mixer(s, 0x60); - rr = read_mixer(s, 0x62); - l = (rl * 3 + 11) / 2; - if (rl & 0x40) - l = 0; - r = (rr * 3 + 11) / 2; - if (rr & 0x40) - r = 0; - return put_user((((unsigned int)r) << 8) | l, (int *)arg); - - case SOUND_MIXER_SPEAKER: - rl = read_mixer(s, 0x3c); - l = (rl & 7) * 14 + 2; - return put_user(l * 0x101, (int *)arg); - - case SOUND_MIXER_RECLEV: - rl = read_ctrl(s, 0xb4); - r = ((rl & 0xf) * 13 + 5) / 2; - l = (((rl >> 4) & 0xf) * 13 + 5) / 2; - return put_user((((unsigned int)r) << 8) | l, (int *)arg); - default: i = _IOC_NR(cmd); - if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i]) + if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i])) return -EINVAL; - rl = read_mixer(s, mixtable[i]); - r = ((rl & 0xf) * 13 + 5) / 2; - l = (((rl >> 4) & 0xf) * 13 + 5) / 2; - return put_user((((unsigned int)r) << 8) | l, (int *)arg); + return put_user(s->mix.vol[vidx-1], (int *)arg); } } if (_IOC_DIR(cmd) != (_IOC_READ|_IOC_WRITE)) @@ -757,21 +732,21 @@ s->mix.modcnt++; switch (_IOC_NR(cmd)) { case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ - - { - static const unsigned char regs[] = { - 0x1c, 0x1a, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x60, 0x62, 0x6d, 0x7c - }; - int i; - - for (i = 0; i < sizeof(regs); i++) - printk(KERN_DEBUG "solo1: mixer reg 0x%02x: 0x%02x\n", - regs[i], read_mixer(s, regs[i])); - printk(KERN_DEBUG "solo1: ctrl reg 0x%02x: 0x%02x\n", - 0xb4, read_ctrl(s, 0xb4)); - } - - get_user_ret(val, (int *)arg, -EFAULT); +#if 0 + { + static const unsigned char regs[] = { + 0x1c, 0x1a, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x60, 0x62, 0x6d, 0x7c + }; + int i; + + for (i = 0; i < sizeof(regs); i++) + printk(KERN_DEBUG "solo1: mixer reg 0x%02x: 0x%02x\n", + regs[i], read_mixer(s, regs[i])); + printk(KERN_DEBUG "solo1: ctrl reg 0x%02x: 0x%02x\n", + 0xb4, read_ctrl(s, 0xb4)); + } +#endif + get_user_ret(val, (int *)arg, -EFAULT); i = hweight32(val); if (i == 0) return 0; @@ -810,7 +785,12 @@ } write_mixer(s, 0x60, rl); write_mixer(s, 0x62, rr); - return put_user((((unsigned int)r) << 8) | l, (int *)arg); +#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS + s->mix.vol[9] = ((unsigned int)r << 8) | l; +#else + s->mix.vol[9] = val; +#endif + return put_user(s->mix.vol[9], (int *)arg); case SOUND_MIXER_SPEAKER: get_user_ret(val, (int *)arg, -EFAULT); @@ -822,7 +802,12 @@ rl = (l - 2) / 14; l = rl * 14 + 2; write_mixer(s, 0x3c, rl); - return put_user(l * 0x101, (int *)arg); +#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS + s->mix.vol[7] = l * 0x101; +#else + s->mix.vol[7] = val; +#endif + return put_user(s->mix.vol[7], (int *)arg); case SOUND_MIXER_RECLEV: get_user_ret(val, (int *)arg, -EFAULT); @@ -841,11 +826,16 @@ r = (rl * 13 + 5) / 2; l = (rr * 13 + 5) / 2; write_ctrl(s, 0xb4, (rl << 4) | rr); - return put_user((((unsigned int)r) << 8) | l, (int *)arg); +#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS + s->mix.vol[8] = ((unsigned int)r << 8) | l; +#else + s->mix.vol[8] = val; +#endif + return put_user(s->mix.vol[8], (int *)arg); default: i = _IOC_NR(cmd); - if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i]) + if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i])) return -EINVAL; get_user_ret(val, (int *)arg, -EFAULT); l = (val << 1) & 0x1fe; @@ -862,8 +852,13 @@ rr = (r - 5) / 13; r = (rl * 13 + 5) / 2; l = (rr * 13 + 5) / 2; - write_mixer(s, mixtable[i], (rl << 4) | rr); - return put_user((((unsigned int)r) << 8) | l, (int *)arg); + write_mixer(s, mixreg[vidx-1], (rl << 4) | rr); +#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS + s->mix.vol[vidx-1] = ((unsigned int)r << 8) | l; +#else + s->mix.vol[vidx-1] = val; +#endif + return put_user(s->mix.vol[vidx-1], (int *)arg); } } @@ -919,10 +914,8 @@ NULL, /* fsync */ NULL, /* fasync */ NULL, /* check_media_change */ -#if 0 NULL, /* revalidate */ NULL, /* lock */ -#endif }; /* --------------------------------------------------------------------- */ @@ -931,7 +924,8 @@ { DECLARE_WAITQUEUE(wait, current); unsigned long flags; - int count, tmo; + int count; + unsigned tmo; if (s->dma_dac.mapped) return 0; @@ -950,12 +944,12 @@ current->state = TASK_RUNNING; return -EBUSY; } - tmo = (count * HZ) / s->rate; + tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->rate; if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE)) tmo >>= 1; if (s->channels > 1) tmo >>= 1; - if (!schedule_timeout(tmo ? : 1) && tmo) + if (!schedule_timeout(tmo + 1)) printk(KERN_DEBUG "solo1: dma timed out??\n"); } remove_wait_queue(&s->dma_dac.wait, &wait); @@ -996,7 +990,7 @@ cnt = count; #ifdef DEBUGREC printk(KERN_DEBUG "solo1_read: reg B8: 0x%02x DMAstat: 0x%02x DMAcnt: 0x%04x SBstat: 0x%02x cnt: %u\n", - read_ctrl(s, 0xb8), inb(s->vcbase+8), inw(s->vcbase+4), inb(s->sbbase+0xc), cnt); + read_ctrl(s, 0xb8), inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->sbbase+0xc), cnt); #endif if (cnt <= 0) { start_adc(s); @@ -1007,12 +1001,10 @@ KERN_DEBUG "solo1_read: SBstat: 0x%02x cnt: %u\n", read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), read_ctrl(s, 0xb9), - inl(s->vcbase), inw(s->vcbase+4), inb(s->vcbase+8), inb(s->vcbase+15), inb(s->sbbase+0xc), cnt); + inl(s->ddmabase), inw(s->ddmabase+4), inb(s->ddmabase+8), inb(s->ddmabase+15), inb(s->sbbase+0xc), cnt); #endif - if (inb(s->vcbase+15) & 1) { + if (inb(s->ddmabase+15) & 1) printk(KERN_ERR "solo1: cannot start recording, DDMA mask bit stuck at 1\n"); - return -EIO; - } if (file->f_flags & O_NONBLOCK) return ret ? ret : -EAGAIN; interruptible_sleep_on(&s->dma_adc.wait); @@ -1023,7 +1015,7 @@ KERN_DEBUG "solo1_read: SBstat: 0x%02x cnt: %u\n", read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), read_ctrl(s, 0xb9), - inl(s->vcbase), inw(s->vcbase+4), inb(s->vcbase+8), inb(s->vcbase+15), inb(s->sbbase+0xc), cnt); + inl(s->ddmabase), inw(s->ddmabase+4), inb(s->ddmabase+8), inb(s->ddmabase+15), inb(s->sbbase+0xc), cnt); #endif if (signal_pending(current)) return ret ? ret : -ERESTARTSYS; @@ -1042,7 +1034,7 @@ start_adc(s); #ifdef DEBUGREC printk(KERN_DEBUG "solo1_read: reg B8: 0x%02x DMAstat: 0x%02x DMAcnt: 0x%04x SBstat: 0x%02x\n", - read_ctrl(s, 0xb8), inb(s->vcbase+8), inw(s->vcbase+4), inb(s->sbbase+0xc)); + read_ctrl(s, 0xb8), inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->sbbase+0xc)); #endif } return ret; @@ -1304,7 +1296,7 @@ if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) return ret; start_adc(s); - if (inb(s->vcbase+15) & 1) + if (inb(s->ddmabase+15) & 1) printk(KERN_ERR "solo1: cannot start recording, DDMA mask bit stuck at 1\n"); } else stop_adc(s); @@ -1466,8 +1458,8 @@ } if (file->f_mode & FMODE_READ) { stop_adc(s); - outb(1, s->vcbase+0xf); /* mask DMA channel */ - //outb(0, s->vcbase+0xd); /* DMA master clear */ + outb(1, s->ddmabase+0xf); /* mask DMA channel */ + outb(0, s->ddmabase+0xd); /* DMA master clear */ dealloc_dmabuf(&s->dma_adc); } s->open_mode &= ~(FMODE_READ | FMODE_WRITE); @@ -1533,10 +1525,8 @@ NULL, /* fsync */ NULL, /* fasync */ NULL, /* check_media_change */ -#if 0 NULL, /* revalidate */ NULL, /* lock */ -#endif }; /* --------------------------------------------------------------------- */ @@ -1550,7 +1540,7 @@ if (!(s->mpubase)) return; wake = 0; - while (inb(s->mpubase+1) & 0x80) { + while (!(inb(s->mpubase+1) & 0x80)) { ch = inb(s->mpubase); if (s->midi.icnt < MIDIINBUF) { s->midi.ibuf[s->midi.iwr] = ch; @@ -1562,7 +1552,7 @@ if (wake) wake_up(&s->midi.iwait); wake = 0; - while ((inb(s->mpubase+1) & 0x40) && s->midi.ocnt > 0) { + while (!(inb(s->mpubase+1) & 0x40) && s->midi.ocnt > 0) { outb(s->midi.obuf[s->midi.ord], s->mpubase); s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF; s->midi.ocnt--; @@ -1577,22 +1567,12 @@ { struct solo1_state *s = (struct solo1_state *)dev_id; unsigned int intsrc; - - static unsigned lim = 0; /* fastpath out, to ease interrupt sharing */ intsrc = inb(s->iobase+7); /* get interrupt source(s) */ if (!intsrc) return; (void)inb(s->sbbase+0xe); /* clear interrupt */ -#ifdef DEBUGREC - if (intsrc & 0x10 && lim < 20) { - lim++; - printk(KERN_DEBUG "solo1: audio1int reg B8: 0x%02x DMAstat: 0x%02x DMAcnt: 0x%04x SBstat: 0x%02x\n", - read_ctrl(s, 0xb8), inb(s->vcbase+8), inw(s->vcbase+4), inb(s->sbbase+0xc)); - } - //printk(KERN_DEBUG "solo1: interrupt 0x%02x\n", intsrc); -#endif spin_lock(&s->lock); /* clear audio interrupts first */ if (intsrc & 0x20) @@ -1849,10 +1829,8 @@ NULL, /* fsync */ NULL, /* fasync */ NULL, /* check_media_change */ -#if 0 NULL, /* revalidate */ NULL, /* lock */ -#endif }; /* --------------------------------------------------------------------- */ @@ -2025,10 +2003,8 @@ NULL, /* fsync */ NULL, /* fasync */ NULL, /* check_media_change */ -#if 0 NULL, /* revalidate */ NULL, /* lock */ -#endif }; /* --------------------------------------------------------------------- */ @@ -2060,11 +2036,10 @@ struct pci_dev *pcidev = NULL; mm_segment_t fs; int i, val, index = 0; - u16 ddmabase; if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk(KERN_INFO "solo1: version v0.5 time " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "solo1: version v0.6 time " __TIME__ " " __DATE__ "\n"); while (index < NR_DEVICE && (pcidev = pci_find_device(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_SOLO1, pcidev))) { if (pcidev->resource[0].start == 0 || @@ -2090,35 +2065,32 @@ init_waitqueue_head(&s->midi.owait); init_MUTEX(&s->open_sem); s->magic = SOLO1_MAGIC; + s->pcidev = pcidev; s->iobase = pcidev->resource[0].start; s->sbbase = pcidev->resource[1].start; s->vcbase = pcidev->resource[2].start; + s->ddmabase = s->vcbase + DDMABASE_OFFSET; s->mpubase = pcidev->resource[3].start; s->gpbase = pcidev->resource[4].start; s->irq = pcidev->irq; if (check_region(s->iobase, IOBASE_EXTENT) || check_region(s->sbbase, SBBASE_EXTENT) || - check_region(s->vcbase, VCBASE_EXTENT) || + check_region(s->ddmabase, DDMABASE_EXTENT) || check_region(s->mpubase, MPUBASE_EXTENT)) { printk(KERN_ERR "solo1: io ports in use\n"); goto err_region; } request_region(s->iobase, IOBASE_EXTENT, "ESS Solo1"); request_region(s->sbbase, SBBASE_EXTENT, "ESS Solo1"); - request_region(s->vcbase, VCBASE_EXTENT, "ESS Solo1"); + request_region(s->ddmabase, DDMABASE_EXTENT, "ESS Solo1"); request_region(s->mpubase, MPUBASE_EXTENT, "ESS Solo1"); if (request_irq(s->irq, solo1_interrupt, SA_SHIRQ, "ESS Solo1", s)) { printk(KERN_ERR "solo1: irq %u in use\n", s->irq); goto err_irq; } /* initialize DDMA base address */ - /* use PCI config reg, and not vcbase, we need the bus view */ - pci_read_config_word(pcidev, 0x18, &ddmabase); - pci_write_config_word(pcidev, 0x60, (ddmabase & (~0xf)) | 1); -#ifdef DEBUGREC - printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x stat: 0x%02x\n", - inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase), inb(s->vcbase+8)); -#endif + printk(KERN_DEBUG "solo1: ddma base address: 0x%lx\n", s->ddmabase); + pci_write_config_word(pcidev, 0x60, (s->ddmabase & (~0xf)) | 1); /* set DMA policy to DDMA, IRQ emulation off (CLKRUN disabled for now) */ pci_write_config_dword(pcidev, 0x50, 0); /* disable legacy audio address decode */ @@ -2147,21 +2119,9 @@ write_mixer(s, 0x52, 0); write_mixer(s, 0x14, 0); /* DAC1 minimum volume */ write_mixer(s, 0x71, 0x20); /* enable new 0xA1 reg format */ -#ifdef DEBUGREC - printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x stat: 0x%02x\n", - inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase), inb(s->vcbase+8)); -#endif - outb(0, s->vcbase+0xd); /* DMA master clear */ -#ifdef DEBUGREC - printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x stat: 0x%02x\n", - inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase), inb(s->vcbase+8)); -#endif - outb(1, s->vcbase+0xf); /* mask channel */ -#ifdef DEBUGREC - printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x stat: 0x%02x\n", - inb(s->vcbase+0xf), inw(s->vcbase+4), inl(s->vcbase), inb(s->vcbase+8)); -#endif - //outb(0, s->vcbase+0x8); /* enable controller (enable is low active!!) */ + outb(0, s->ddmabase+0xd); /* DMA master clear */ + outb(1, s->ddmabase+0xf); /* mask channel */ + /*outb(0, s->ddmabase+0x8);*/ /* enable controller (enable is low active!!) */ pci_set_master(pcidev); /* enable bus mastering */ @@ -2173,6 +2133,8 @@ val = initvol[i].vol; mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val); } + val = 1; /* enable mic preamp */ + mixer_ioctl(s, SOUND_MIXER_PRIVATE1, (unsigned long)&val); set_fs(fs); /* queue it for later freeing */ s->next = devs; @@ -2192,7 +2154,7 @@ err_irq: release_region(s->iobase, IOBASE_EXTENT); release_region(s->sbbase, SBBASE_EXTENT); - release_region(s->vcbase, VCBASE_EXTENT); + release_region(s->ddmabase, DDMABASE_EXTENT); release_region(s->mpubase, MPUBASE_EXTENT); err_region: kfree_s(s, sizeof(struct solo1_state)); @@ -2215,13 +2177,14 @@ devs = devs->next; /* stop DMA controller */ outb(0, s->iobase+6); - outb(0, s->vcbase+0xd); /* DMA master clear */ + outb(0, s->ddmabase+0xd); /* DMA master clear */ outb(3, s->sbbase+6); /* reset sequencer and FIFO */ synchronize_irq(); + pci_write_config_word(s->pcidev, 0x60, 0); /* turn off DDMA controller address space */ free_irq(s->irq, s); release_region(s->iobase, IOBASE_EXTENT); release_region(s->sbbase, SBBASE_EXTENT); - release_region(s->vcbase, VCBASE_EXTENT); + release_region(s->ddmabase, DDMABASE_EXTENT); release_region(s->mpubase, MPUBASE_EXTENT); unregister_sound_dsp(s->dev_audio); unregister_sound_mixer(s->dev_mixer); diff -u --recursive --new-file v2.3.13/linux/drivers/sound/lowlevel/awe_compat-fbsd.h linux/drivers/sound/lowlevel/awe_compat-fbsd.h --- v2.3.13/linux/drivers/sound/lowlevel/awe_compat-fbsd.h Mon Aug 9 14:59:23 1999 +++ linux/drivers/sound/lowlevel/awe_compat-fbsd.h Wed Dec 31 16:00:00 1969 @@ -1,173 +0,0 @@ -/* - * sound/awe_compat.h - * - * Compat defines for the AWE32/SB32/AWE64 wave table synth driver. - * version 0.4.3; Nov. 1, 1998 - * - * Copyright (C) 1996-1998 Takashi Iwai - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef AWE_COMPAT_H_DEF -#define AWE_COMPAT_H_DEF - -/*================================================================ - * version check - *================================================================*/ - -/* FreeBSD version check */ -#include - -#define AWE_OBSOLETE_VOXWARE -#if __FreeBSD__ >= 2 -# include -# if __FreeBSD_version >= 300000 -# undef AWE_OBSOLETE_VOXWARE -# endif -#endif -#ifdef __linux__ -# include -#endif - - -/*================================================================ - * INCLUDE OTHER HEADER FILES - *================================================================*/ - -/* reading configuration of sound driver */ - -#ifdef AWE_OBSOLETE_VOXWARE - -#include -#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_AWE32) -#define CONFIG_AWE32_SYNTH -#endif - -#else /* AWE_OBSOLETE_VOXWARE */ - -#ifdef HAS_LOWLEVEL_H -#include "lowlevel.h" -#endif - -#include -#if defined(CONFIGURE_SOUNDCARD) && defined(CONFIG_AWE32) -# define CONFIG_AWE32_SYNTH -#endif - -#endif /* AWE_OBSOLETE_VOXWARE */ - - -/*================================================================ - * include AWE header files - *================================================================*/ - -#if defined(CONFIG_AWE32_SYNTH) || defined(CONFIG_AWE32_SYNTH_MODULE) - -#include -#include -#include - -#ifdef AWE_HAS_GUS_COMPATIBILITY -/* include finetune table */ -#ifdef AWE_OBSOLETE_VOXWARE -# define SEQUENCER_C -#endif -#include -#include -#endif /* AWE_HAS_GUS_COMPATIBILITY */ - - -/*---------------------------------------------------------------- - * compatibility macros for AWE32 driver - *----------------------------------------------------------------*/ - -/* redefine following macros */ -#undef IOCTL_IN -#undef IOCTL_OUT -#undef OUTW -#undef COPY_FROM_USER -#undef COPY_TO_USER -#undef GET_BYTE_FROM_USER -#undef GET_SHORT_FROM_USER -#undef IOCTL_TO_USER - -/* inline is not checked yet.. maybe it'll work */ -#define INLINE /*inline*/ - -#define KERN_WARNING /**/ - -/*---------------------------------------------------------------- - * memory management for freebsd - *----------------------------------------------------------------*/ - -/* i/o requests; nothing */ -#define awe_check_port() 0 /* always false */ -#define awe_request_region() /* nothing */ -#define awe_release_region() /* nothing */ - -#define AWE_DYNAMIC_BUFFER - -#define my_malloc_init(ptr) /* nothing */ -#define my_malloc_memptr() 0 -#define my_malloc(size) malloc(size, M_TEMP, M_WAITOK) -#define my_free(ptr) if (ptr) {free(ptr, M_TEMP);} - -#define INIT_TABLE(buffer,index,nums,type) {buffer=NULL; index=0;} - -/*---------------------------------------------------------------- - * i/o interfaces for freebsd - *----------------------------------------------------------------*/ - -/* according to linux rule; the arguments are swapped */ -#define OUTW(data,addr) outw(addr, data) - -#define COPY_FROM_USER(target,source,offs,count) \ - uiomove(((caddr_t)(target)),(count),((struct uio *)(source))) -#define COPY_TO_USER(target,source,offs,count) \ - uiomove(((caddr_t)(source)),(count),((struct uio *)(target))) -#define GET_BYTE_FROM_USER(target,addr,offs) \ - uiomove(((char*)&(target)), 1, ((struct uio *)(addr))) -#define GET_SHORT_FROM_USER(target,addr,offs) \ - uiomove(((char*)&(target)), 2, ((struct uio *)(addr))) -#define IOCTL_TO_USER(target,offs,source,count) \ - memcpy(&((target)[offs]), (source), (count)) -#define IO_WRITE_CHECK(cmd) (cmd & IOC_IN) -#define IOCTL_IN(arg) (*(int*)(arg)) -#define IOCTL_OUT(arg,val) (*(int*)(arg) = (val)) -#define BZERO(target,len) bzero((caddr_t)target, len) -#define MEMCPY(dst,src,len) bcopy((caddr_t)src, (caddr_t)dst, len) - -#ifndef AWE_OBSOLETE_VOXWARE -# define printk printf -# define RET_ERROR(err) -err -#endif - - -/* old style device tables (not modulized) */ -#define sound_alloc_synthdev() \ - (num_synths >= MAX_SYNTH_DEV ? -1 : num_synths++) -#define sound_alloc_mixerdev() \ - (num_mixers >= MAX_MIXER_DEV ? -1 : num_mixers++) -#define sound_alloc_mididev() \ - (num_midis >= MAX_MIXER_DEV ? -1 : num_midis++) -#define sound_unload_synthdev(dev) /**/ -#define sound_unload_mixerdev(dev) /**/ -#define sound_unload_mididev(dev) /**/ - - -#endif /* CONFIG_AWE32_SYNTH */ - -#endif /* AWE_COMPAT_H_DEF */ diff -u --recursive --new-file v2.3.13/linux/drivers/sound/lowlevel/awe_compat-linux.h linux/drivers/sound/lowlevel/awe_compat-linux.h --- v2.3.13/linux/drivers/sound/lowlevel/awe_compat-linux.h Wed Dec 16 12:52:01 1998 +++ linux/drivers/sound/lowlevel/awe_compat-linux.h Wed Dec 31 16:00:00 1969 @@ -1,248 +0,0 @@ -/* - * sound/awe_compat.h - * - * Compat defines for the AWE32/SB32/AWE64 wave table synth driver. - * version 0.4.3; Oct. 1, 1998 - * - * Copyright (C) 1996-1998 Takashi Iwai - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef AWE_COMPAT_H_DEF -#define AWE_COMPAT_H_DEF - -/*================================================================ - * version check - *================================================================*/ - -#include "awe_config.h" - -#define ASC_LINUX_VERSION(V,P,S) (((V) * 65536) + ((P) * 256) + (S)) - -#ifndef LINUX_VERSION_CODE -#include -#endif - -/* linux version check */ -#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0) -#define AWE_OBSOLETE_VOXWARE -#endif - -#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,0) -#define AWE_NEW_KERNEL_INTERFACE -#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,80) -#define AWE_MODULE_SUPPORT -#endif -#endif - -#ifdef AWE_OBSOLETE_VOXWARE -#include "soundvers.h" -#else -#include "../soundvers.h" -#endif - -#if defined(SOUND_INTERNAL_VERSION) && SOUND_INTERNAL_VERSION >= 0x30803 -/* OSS/Free-3.8 */ -#define AWE_NO_PATCHMGR -#define AWE_OSS38 -#define HAS_LOWLEVEL_H -#endif - -/*================================================================ - * INCLUDE OTHER HEADER FILES - *================================================================*/ - -/* set up module */ - -#if defined(AWE_MODULE_SUPPORT) && defined(MODULE) -#include -#include -#include -#include "../soundmodule.h" -#endif - - -/* reading configuration of sound driver */ - -#ifdef AWE_OBSOLETE_VOXWARE - -#include "sound_config.h" -#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_AWE32) -#define CONFIG_AWE32_SYNTH -#endif - -#else /* AWE_OBSOLETE_VOXWARE */ - -#ifdef HAS_LOWLEVEL_H -#include "lowlevel.h" -#endif - -#include "../sound_config.h" - -#endif /* AWE_OBSOLETE_VOXWARE */ - - -/*================================================================ - * include AWE header files - *================================================================*/ - -#if defined(CONFIG_AWE32_SYNTH) || defined(CONFIG_AWE32_SYNTH_MODULE) - -#include "awe_hw.h" -#include "awe_version.h" -#include - -#ifdef AWE_HAS_GUS_COMPATIBILITY -/* include finetune table */ -#ifdef AWE_OBSOLETE_VOXWARE -# include "tuning.h" -#else -# include "../tuning.h" -#endif -#include -#endif /* AWE_HAS_GUS_COMPATIBILITY */ - - -/*---------------------------------------------------------------- - * compatibility macros for AWE32 driver - *----------------------------------------------------------------*/ - -/* redefine following macros */ -#undef IOCTL_IN -#undef IOCTL_OUT -#undef OUTW -#undef COPY_FROM_USER -#undef COPY_TO_USER -#undef GET_BYTE_FROM_USER -#undef GET_SHORT_FROM_USER -#undef IOCTL_TO_USER - -/* use inline prefix */ -#define INLINE inline - -/*---------------------------------------------------------------- - * memory management for linux - *----------------------------------------------------------------*/ - -#ifdef AWE_OBSOLETE_VOXWARE -/* old type linux system */ - -/* i/o requests; nothing */ -#define awe_check_port() 0 /* always false */ -#define awe_request_region() /* nothing */ -#define awe_release_region() /* nothing */ - -static int _mem_start; /* memory pointer for permanent buffers */ - -#define my_malloc_init(memptr) _mem_start = (memptr) -#define my_malloc_memptr() _mem_start -#define my_free(ptr) /* do nothing */ - -/* allocate buffer only once */ -#define INIT_TABLE(buffer,index,nums,type) {\ -PERMANENT_MALLOC(buffer, char*, size, _mem_start); index = (nums);\ -} - -#else - -#define AWE_DYNAMIC_BUFFER - -#define my_malloc_init(ptr) /* nothing */ -#define my_malloc_memptr() 0 -#define my_malloc(size) vmalloc(size) -#define my_free(ptr) if (ptr) {vfree(ptr);} - -/* do not allocate buffer at beginning */ -#define INIT_TABLE(buffer,index,nums,type) {buffer=NULL; index=0;} - -/* old type macro */ -#define RET_ERROR(err) -err - -#endif - -/*---------------------------------------------------------------- - * i/o interfaces for linux - *----------------------------------------------------------------*/ - -#define OUTW(data,addr) outw(data, addr) - -#ifdef AWE_NEW_KERNEL_INTERFACE -#define COPY_FROM_USER(target,source,offs,count) \ - copy_from_user(target, (source)+(offs), count) -#define GET_BYTE_FROM_USER(target,addr,offs) \ - get_user(target, (unsigned char*)&((addr)[offs])) -#define GET_SHORT_FROM_USER(target,addr,offs) \ - get_user(target, (unsigned short*)&((addr)[offs])) -#ifdef AWE_OSS38 -#define IOCTL_TO_USER(target,offs,source,count) \ - memcpy(target, (source)+(offs), count) -#define IO_WRITE_CHECK(cmd) (_SIOC_DIR(cmd) & _IOC_WRITE) -#else -#define IOCTL_TO_USER(target,offs,source,count) \ - copy_to_user(target, (source)+(offs), count) -#define IO_WRITE_CHECK(cmd) (_IOC_DIR(cmd) & _IOC_WRITE) -#endif /* AWE_OSS38 */ -#define COPY_TO_USER IOCTL_TO_USER -#define IOCTL_IN(arg) (*(int*)(arg)) -#define IOCTL_OUT(arg,val) (*(int*)(arg) = (val)) - -#else /* old type i/o */ -#define COPY_FROM_USER(target,source,offs,count) \ - memcpy_fromfs(target, (source)+(offs), (count)) -#define GET_BYTE_FROM_USER(target,addr,offs) \ - *((char *)&(target)) = get_fs_byte((addr)+(offs)) -#define GET_SHORT_FROM_USER(target,addr,offs) \ - *((short *)&(target)) = get_fs_word((addr)+(offs)) -#ifdef AWE_OSS38 -#define IOCTL_TO_USER(target,offs,source,count) \ - memcpy(target, (source)+(offs), count) -#define COPY_TO_USER(target,offs,source,count) \ - memcpy_tofs(target, (source)+(offs), (count)) -#define IOCTL_IN(arg) (*(int*)(arg)) -#define IOCTL_OUT(arg,val) (*(int*)(arg) = (val)) -#define IO_WRITE_CHECK(cmd) (_SIOC_DIR(cmd) & _IOC_WRITE) -#else /* AWE_OSS38 */ -#define IOCTL_TO_USER(target,offs,source,count) \ - memcpy_tofs(target, (source)+(offs), (count)) -#define COPY_TO_USER IOCTL_TO_USER -#define IOCTL_IN(arg) get_fs_long((long *)(arg)) -#define IOCTL_OUT(arg,ret) snd_ioctl_return((int *)arg, ret) -#define IO_WRITE_CHECK(cmd) (cmd & IOC_IN) -#endif /* AWE_OSS38 */ - -#endif /* AWE_NEW_KERNEL_INTERFACE */ - -#define BZERO(target,len) memset(target, 0, len) -#define MEMCPY(dst,src,len) memcpy(dst, src, len) - -/* old style device tables (not modulized) */ -#ifndef AWE_MODULE_SUPPORT - -#define sound_alloc_synthdev() \ - (num_synths >= MAX_SYNTH_DEV ? -1 : num_synths++) -#define sound_alloc_mixerdev() \ - (num_mixers >= MAX_MIXER_DEV ? -1 : num_mixers++) -#define sound_alloc_mididev() \ - (num_midis >= MAX_MIXER_DEV ? -1 : num_midis++) -#define sound_unload_synthdev(dev) /**/ -#define sound_unload_mixerdev(dev) /**/ -#define sound_unload_mididev(dev) /**/ - -#endif /* AWE_MODULE_SUPPORT */ - -#endif /* CONFIG_AWE32_SYNTH */ - -#endif /* AWE_COMPAT_H_DEF */ diff -u --recursive --new-file v2.3.13/linux/drivers/sound/sonicvibes.c linux/drivers/sound/sonicvibes.c --- v2.3.13/linux/drivers/sound/sonicvibes.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/sound/sonicvibes.c Thu Aug 12 12:21:48 1999 @@ -73,6 +73,7 @@ * 28.06.99 0.16 Add pci_set_master * 03.08.99 0.17 adapt to Linus' new __setup/__initcall * added kernel command line options "sonicvibes=reverb" and "sonicvibesdmaio=dmaioaddr" + * 12.08.99 0.18 module_init/__setup fixes * */ @@ -1268,9 +1269,9 @@ current->state = TASK_RUNNING; return -EBUSY; } - tmo = (count * HZ) / s->ratedac; + tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac; tmo >>= sample_shift[(s->fmt >> SV_CFMT_ASHIFT) & SV_CFMT_MASK]; - if (!schedule_timeout(tmo ? : 1) && tmo) + if (!schedule_timeout(tmo + 1)) printk(KERN_DEBUG "sv: dma timed out??\n"); } remove_wait_queue(&s->dma_dac.wait, &wait); @@ -2297,6 +2298,19 @@ static unsigned dmaio = 0xac00; +MODULE_PARM(reverb, "1-" __MODULE_STRING(NR_DEVICE) "i"); +MODULE_PARM_DESC(reverb, "if 1 enables the reverb circuitry. NOTE: your card must have the reverb RAM"); +#if 0 +MODULE_PARM(wavetable, "1-" __MODULE_STRING(NR_DEVICE) "i"); +MODULE_PARM_DESC(wavetable, "if 1 the wavetable synth is enabled"); +#endif + +MODULE_PARM(dmaio, "i"); +MODULE_PARM_DESC(dmaio, "if the motherboard BIOS did not allocate DDMA io, allocate them starting at this address"); + +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); +MODULE_DESCRIPTION("S3 SonicVibes Driver"); + /* --------------------------------------------------------------------- */ static struct initvol { @@ -2314,10 +2328,7 @@ { SOUND_MIXER_WRITE_PCM, 0x4040 } }; -#ifndef MODULE -static -#endif -int __init init_module(void) +static int __init init_sonicvibes(void) { struct sv_state *s; struct pci_dev *pcidev = NULL; @@ -2326,7 +2337,7 @@ if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk(KERN_INFO "sv: version v0.17 time " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "sv: version v0.18 time " __TIME__ " " __DATE__ "\n"); #if 0 if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT))) printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n"); @@ -2499,24 +2510,7 @@ return 0; } -/* --------------------------------------------------------------------- */ - -#ifdef MODULE - -MODULE_PARM(reverb, "1-" __MODULE_STRING(NR_DEVICE) "i"); -MODULE_PARM_DESC(reverb, "if 1 enables the reverb circuitry. NOTE: your card must have the reverb RAM"); -#if 0 -MODULE_PARM(wavetable, "1-" __MODULE_STRING(NR_DEVICE) "i"); -MODULE_PARM_DESC(wavetable, "if 1 the wavetable synth is enabled"); -#endif - -MODULE_PARM(dmaio, "i"); -MODULE_PARM_DESC(dmaio, "if the motherboard BIOS did not allocate DDMA io, allocate them starting at this address"); - -MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); -MODULE_DESCRIPTION("S3 SonicVibes Driver"); - -void cleanup_module(void) +static void __exit cleanup_sonicvibes(void) { struct sv_state *s; @@ -2545,7 +2539,12 @@ printk(KERN_INFO "sv: unloading\n"); } -#else /* MODULE */ +module_init(init_sonicvibes); +module_exit(cleanup_sonicvibes); + +/* --------------------------------------------------------------------- */ + +#ifndef MODULE /* format is: sonicvibes=[reverb] sonicvibesdmaio=dmaioaddr */ @@ -2555,12 +2554,12 @@ if (nr_dev >= NR_DEVICE) return 0; - - ( (get_option(&str, &reverb [nr_dev]) == 2) #if 0 - && get_option(&str, &wavetable[nr_dev]) + if (get_option(&str, &reverb[nr_dev]) == 2) + get_option(&str, &wavetable[nr_dev]); +#else + get_option(&str, &reverb[nr_dev]); #endif - }; nr_dev++; return 1; @@ -2568,16 +2567,14 @@ static int __init sonicvibesdmaio_setup(char *str) { - int ints[11]; + int io; - get_options(str, ints); - if (ints[0] >= 1) - dmaio = ints[1]; + if (get_option(&str, &io)) + dmaio = io; return 1; } __setup("sonicvibes=", sonicvibes_setup); __setup("sonicvibesdmaio=", sonicvibesdmaio_setup); -__initcall(init_module); #endif /* MODULE */ diff -u --recursive --new-file v2.3.13/linux/drivers/usb/Makefile linux/drivers/usb/Makefile --- v2.3.13/linux/drivers/usb/Makefile Mon Aug 9 14:59:23 1999 +++ linux/drivers/usb/Makefile Fri Aug 13 11:54:47 1999 @@ -15,6 +15,7 @@ L_TARGET := usb.a M_OBJS := L_OBJS := +MOD_LIST_NAME := USB_MODULES ifeq ($(CONFIG_USB),y) L_OBJS +=usbcore.o diff -u --recursive --new-file v2.3.13/linux/drivers/usb/README.ohci_hcd linux/drivers/usb/README.ohci_hcd --- v2.3.13/linux/drivers/usb/README.ohci_hcd Mon May 10 10:18:34 1999 +++ linux/drivers/usb/README.ohci_hcd Wed Aug 18 16:22:23 1999 @@ -1,13 +1,13 @@ The OHCI HCD layer is a simple but nearly complete implementation of what the USB people would call a HCD for the OHCI. - (ISO comming soon, Bulk disabled, INT u. CTRL transfers enabled) + (ISO comming soon, Bulk, INT u. CTRL transfers enabled) It is based on Linus Torvalds UHCI code and Gregory Smith OHCI fragments (0.03 source tree). The layer (functions) on top of it, is for interfacing to the alternate-usb device-drivers. - Roman Weissgaerber - + * v4.0 1999/08/18 removed all dummy eds, unlink unused eds, code cleanup, bulk transfers * v2.1 1999/05/09 ep_addr correction, code cleanup * v0.2.0 1999/05/04 * everything has been moved into 2 files (ohci-hcd.c, ohci-hub-root.c and headers) @@ -21,16 +21,14 @@ * v0.1.0 1999/04/27 initial release to remove the module try: -killall root-hub -: rmmod usb-ohci-hcd Features: - virtual root hub, all basic hub descriptors and commands (state: complete) this is an option now (v0.2.0) #define CONFIG_USB_OHCI_VROOTHUB includes the virtual hub code, (VROOTHUB) - default is without. - (at the moment: the Virtual Root Hub option is not recommended) + default is with. + (at the moment: the Virtual Root Hub is included automatically) files: ohci-root-hub.c, ohci-root-hub.h @@ -41,6 +39,7 @@ In the HCD layer the EDs has to be allocated manually either by calling a subroutine or by sending a USB root hub vendor specific command to the virtual root hub. At the alternate linux usb stack EDs will be added (allocated) at their first use. + ED will be unlinked from the HC chains if they are not bussy. files: ohci-hcd.c ohci-hcd.h routines: (do not use for drivers, use the top layer alternate usb commands instead) @@ -49,10 +48,10 @@ int interval, int load, f_handler handler, int ep_size, int speed) adds an endpoint, (if the endpoint already exists some parameters will be updated) - int usb_ohci_rm_ep(struct usb_ohci_ed *ed, struct ohci * ohci) + int usb_ohci_rm_ep( ) removes an endpoint and all pending TDs of that EP - usb_ohci_rm_function( struct ohci * ohci, union ep_addr_ ep_addr) + usb_ohci_rm_function( ) removes all Endpoints of a function (device) - Transfer Descriptors (TD): handling and allocation of TDs is transparent to the upper layers @@ -62,7 +61,7 @@ There is one basic command for all types of bus transfers (INT, BULK, ISO, CTRL): - int ohci_trans_req(struct ohci * ohci, int ep_addr, int ctrl_len, void *ctrl, void * data, int data_len, __OHCI_BAG lw0, __OHCI_BAG lw1) + int ohci_trans_req(struct ohci * ohci, hcd_ed, int ctrl_len, void *ctrl, void * data, int data_len, __OHCI_BAG lw0, __OHCI_BAG lw1) CTRL: ctrl, ctrl_len ... cmd buffer data, data_len ... data buffer (in or out) @@ -95,18 +94,5 @@ - Done list handling: returns the requests (callback f_handler in ED) and does some error handling, root-hub request dequeuing (files: ohci-done-list.c in ohci-hcd.c now(v0.2.0)) - -ep_addr union or int is for addressing devices&endpoints: -__u8 ep_addr.bep.ep ... bit 3..0 endpoint address - bit 4 0 - bit 6,5 type: eg. 10 CTRL, 11 BULK, 01 INT, 00 ISO - bit 7 direction 1 IN, 0 OUT - -__u8 ep_addr.bep.fa ... bit 6..0 function address - bit 7 0 - -(__u8 ep_addr.bep.hc ... host controller nr) not used -(__u8 ep_addr.bep.host ... host nr) not used - diff -u --recursive --new-file v2.3.13/linux/drivers/usb/audio.c linux/drivers/usb/audio.c --- v2.3.13/linux/drivers/usb/audio.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/usb/audio.c Mon Aug 16 23:19:13 1999 @@ -6,6 +6,7 @@ #include #include "usb.h" +#define AUDIO_DEBUG 1 static int usb_audio_probe(struct usb_device *dev); static void usb_audio_disconnect(struct usb_device *dev); @@ -35,23 +36,23 @@ static int usb_audio_probe(struct usb_device *dev) { - struct usb_interface_descriptor *interface; + struct usb_interface_descriptor *intf_desc; struct usb_endpoint_descriptor *endpoint; struct usb_audio *aud; + int bEndpointAddress = 0; int i; int na=0; - interface = &dev->config[0].altsetting[0].interface[0]; for (i=0; iconfig[0].bNumInterfaces; i++) { - endpoint = &interface->endpoint[i]; + intf_desc = &dev->config->interface[i].altsetting[0]; - if(interface->bInterfaceClass != 1) + if(intf_desc->bInterfaceClass != 1) continue; printk(KERN_INFO "USB audio device detected.\n"); - switch(interface->bInterfaceSubClass) { + switch(intf_desc->bInterfaceSubClass) { case 0x01: printk(KERN_INFO "audio: Control device.\n"); break; @@ -74,8 +75,6 @@ aud->dev = dev; dev->private = aud; - endpoint = &interface->endpoint[0]; - // if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) { // printk (KERN_INFO " Failed usb_set_configuration: Audio\n"); // break; @@ -83,11 +82,11 @@ // usb_set_protocol(dev, 0); // usb_set_idle(dev, 0, 0); - usb_request_irq(dev, - usb_rcvctrlpipe(dev, endpoint->bEndpointAddress), - usb_audio_irq, - endpoint->bInterval, - aud); +// usb_request_irq(dev, +// usb_rcvctrlpipe(dev, bEndpointAddress), +// usb_audio_irq, +// endpoint->bInterval, +// aud); list_add(&aud->list, &usb_audio_list); @@ -123,10 +122,16 @@ void usb_audio_interface(struct usb_interface_descriptor *interface, u8 *data) { +#ifdef AUDIO_DEBUG + printk(KERN_DEBUG "usb_audio_interface.\n"); +#endif } void usb_audio_endpoint(struct usb_endpoint_descriptor *interface, u8 *data) { +#ifdef AUDIO_DEBUG + printk(KERN_DEBUG "usb_audio_interface.\n"); +#endif } #ifdef MODULE diff -u --recursive --new-file v2.3.13/linux/drivers/usb/hub.c linux/drivers/usb/hub.c --- v2.3.13/linux/drivers/usb/hub.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/usb/hub.c Mon Aug 16 23:19:13 1999 @@ -199,7 +199,7 @@ static int hub_probe(struct usb_device *dev) { - struct usb_interface_descriptor *interface; + struct usb_interface_descriptor *intf_desc; struct usb_endpoint_descriptor *endpoint; struct usb_hub *hub; unsigned long flags; @@ -212,20 +212,20 @@ if (dev->config[0].bNumInterfaces != 1) return -1; - interface = &dev->config[0].altsetting[0].interface[0]; + intf_desc = &dev->config[0].interface[0].altsetting[0]; /* Is it a hub? */ - if (interface->bInterfaceClass != 9) + if (intf_desc->bInterfaceClass != 9) return -1; - if ((interface->bInterfaceSubClass != 0) && - (interface->bInterfaceSubClass != 1)) + if ((intf_desc->bInterfaceSubClass != 0) && + (intf_desc->bInterfaceSubClass != 1)) return -1; /* Multiple endpoints? What kind of mutant ninja-hub is this? */ - if (interface->bNumEndpoints != 1) + if (intf_desc->bNumEndpoints != 1) return -1; - endpoint = &interface->endpoint[0]; + endpoint = &intf_desc->endpoint[0]; /* Output endpoint? Curiousier and curiousier.. */ if (!(endpoint->bEndpointAddress & USB_DIR_IN)) diff -u --recursive --new-file v2.3.13/linux/drivers/usb/mouse.c linux/drivers/usb/mouse.c --- v2.3.13/linux/drivers/usb/mouse.c Wed Jul 28 14:47:42 1999 +++ linux/drivers/usb/mouse.c Mon Aug 16 23:19:13 1999 @@ -256,7 +256,7 @@ static int mouse_probe(struct usb_device *dev) { - struct usb_interface_descriptor *interface; + struct usb_interface_descriptor *intf_desc; struct usb_endpoint_descriptor *endpoint; struct mouse_state *mouse = &static_mouse_state; @@ -269,19 +269,19 @@ return -1; /* Is it a mouse interface? */ - interface = &dev->config[0].altsetting[0].interface[0]; - if (interface->bInterfaceClass != 3) + intf_desc = &dev->config[0].interface[0].altsetting[0]; + if (intf_desc->bInterfaceClass != 3) return -1; - if (interface->bInterfaceSubClass != 1) + if (intf_desc->bInterfaceSubClass != 1) return -1; - if (interface->bInterfaceProtocol != 2) + if (intf_desc->bInterfaceProtocol != 2) return -1; /* Multiple endpoints? What kind of mutant ninja-mouse is this? */ - if (interface->bNumEndpoints != 1) + if (intf_desc->bNumEndpoints != 1) return -1; - endpoint = &interface->endpoint[0]; + endpoint = &intf_desc->endpoint[0]; /* Output endpoint? Curiousier and curiousier.. */ if (!(endpoint->bEndpointAddress & 0x80)) diff -u --recursive --new-file v2.3.13/linux/drivers/usb/ohci-hcd.c linux/drivers/usb/ohci-hcd.c --- v2.3.13/linux/drivers/usb/ohci-hcd.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/usb/ohci-hcd.c Wed Aug 18 16:22:23 1999 @@ -17,8 +17,8 @@ * [ $Log: ohci.c,v $ ] * [ Revision 1.1 1999/04/05 08:32:30 greg ] * - * - * v2.1 1999/05/09 ep_addr correction, code clean up + * v3.0 1999/06/25 + * v2.1 1999/05/09 code clean up * v2.0 1999/05/04 * virtual root hub is now an option, * memory allocation based on kmalloc and kfree now, Bus error handling, @@ -31,7 +31,6 @@ * ohci-hcd.c */ -/* #define OHCI_DBG */ /* printk some debug information */ #include @@ -59,188 +58,233 @@ static int handle_apm_event(apm_event_t event); static int apm_resume = 0; #endif - - -static DECLARE_WAIT_QUEUE_HEAD(bulk_wakeup); -static DECLARE_WAIT_QUEUE_HEAD(control_wakeup); -static DECLARE_WAIT_QUEUE_HEAD(root_hub); - -static __u8 cc_to_status[16] = { /* mapping of the OHCI CC to the UHCI status codes; first guess */ -/* Activ, Stalled, Data Buffer Err, Babble Detected : NAK recvd, CRC/Timeout, Bitstuff, reservd */ -/* No Error */ 0x00, -/* CRC Error */ 0x04, -/* Bit Stuff */ 0x02, -/* Data Togg */ 0x40, -/* Stall */ 0x40, -/* DevNotResp */ 0x04, -/* PIDCheck */ 0x04, -/* UnExpPID */ 0x40, -/* DataOver */ 0x20, -/* DataUnder */ 0x20, -/* reservd */ 0x40, -/* reservd */ 0x40, -/* BufferOver */ 0x20, -/* BuffUnder */ 0x20, -/* Not Access */ 0x80, -/* Not Access */ 0x80 - }; +static int ohci_link_ed(struct ohci * ohci, struct usb_ohci_ed *ed); +static DECLARE_WAIT_QUEUE_HEAD(op_wakeup); +void usb_pipe_to_hcd_ed(struct usb_device *usb_dev, unsigned int pipe, struct usb_hcd_ed *hcd_ed) +{ + hcd_ed->endpoint = usb_pipeendpoint(pipe); + hcd_ed->out = usb_pipeout(pipe); + hcd_ed->function = usb_pipedevice(pipe); + hcd_ed->type = usb_pipetype(pipe); + hcd_ed->slow = usb_pipeslow(pipe); + hcd_ed->maxpack = usb_maxpacket(usb_dev, pipe, usb_pipeout(pipe)); + OHCI_DEBUG(printk("******* hcd_ed: endpoint: %4x, function: %4x, out: %4x, type: %4x, slow: %4x, maxpack: %4x\n", hcd_ed->endpoint, hcd_ed->function, hcd_ed->out, hcd_ed->type, hcd_ed->slow, hcd_ed->maxpack); ) +} + + /******** **** Interface functions ***********************************************/ -static int sohci_int_handler(void * ohci_in, unsigned int ep_addr, int ctrl_len, void * ctrl, void * data, int data_len, int status, __OHCI_BAG lw0, __OHCI_BAG lw1) +static int sohci_blocking_handler(void * ohci_in, struct usb_ohci_ed *ed, void * data, int data_len, int status, __OHCI_BAG lw0, __OHCI_BAG lw1) +{ + if(lw0 != NULL) { + ((struct ohci_state * )lw0)->status = status; + ((struct ohci_state * )lw0)->len = data_len; + } + if(lw1 != NULL) { + add_wait_queue(&op_wakeup, lw1); + wake_up(&op_wakeup); + } + + OHCI_DEBUG( { int i; printk("USB HC bh <<<: %x: ", ed->hwINFO);) + OHCI_DEBUG( printk(" data(%d):", data_len);) + OHCI_DEBUG( for(i=0; i < data_len; i++ ) printk(" %02x", ((__u8 *) data)[i]);) + OHCI_DEBUG( printk(" ret_status: %x\n", status); }) + + return 0; +} + +static int sohci_int_handler(void * ohci_in, struct usb_ohci_ed *ed, void * data, int data_len, int status, __OHCI_BAG lw0, __OHCI_BAG lw1) { struct ohci * ohci = ohci_in; usb_device_irq handler=(void *) lw0; void *dev_id = (void *) lw1; int ret; - - OHCI_DEBUG({ int i; printk("USB HC IRQ <<<: %x: data(%d):", ep_addr, data_len);) + + OHCI_DEBUG({ int i; printk("USB HC IRQ <<<: %x: data(%d):", ed->hwINFO, data_len);) OHCI_DEBUG( for(i=0; i < data_len; i++ ) printk(" %02x", ((__u8 *) data)[i]);) OHCI_DEBUG( printk(" ret_status: %x\n", status); }) - - ret = handler(cc_to_status[status & 0xf], data, data_len, dev_id); + + ret = handler(status, data, data_len, dev_id); if(ret == 0) return 0; /* 0 .. do not requeue */ if(status > 0) return -1; /* error occured do not requeue ? */ - ohci_trans_req(ohci, ep_addr, 0, NULL, data, 8, (__OHCI_BAG) handler, (__OHCI_BAG) dev_id); /* requeue int request */ + ohci_trans_req(ohci, ed, 0, NULL, data, (ed->hwINFO >> 16) & 0x3f, (__OHCI_BAG) handler, (__OHCI_BAG) dev_id, INT_IN, sohci_int_handler); /* requeue int request */ + return 0; } - -static int sohci_ctrl_handler(void * ohci_in, unsigned int ep_addr, int ctrl_len, void * ctrl, void * data, int data_len, int status, __OHCI_BAG lw0, __OHCI_BAG lw) -{ - *(int * )lw0 = status; - wake_up(&control_wakeup); - - OHCI_DEBUG( { int i; printk("USB HC CTRL<<<: %x: ctrl(%d):", ep_addr, ctrl_len);) - OHCI_DEBUG( for(i=0; i < 8; i++ ) printk(" %02x", ((__u8 *) ctrl)[i]);) - OHCI_DEBUG( printk(" data(%d):", data_len);) - OHCI_DEBUG( for(i=0; i < data_len; i++ ) printk(" %02x", ((__u8 *) data)[i]);) - OHCI_DEBUG( printk(" ret_status: %x\n", status); }) - return 0; -} - -static int sohci_bulk_handler(void * ohci_in, unsigned int ep_addr, int ctrl_len, void * ctrl, void * data, int data_len, int status, __OHCI_BAG lw0, __OHCI_BAG lw) -{ - *(int * )lw0 = status; - wake_up(&bulk_wakeup); - - OHCI_DEBUG( { int i; printk("USB HC BULK<<<: %x:", ep_addr, ctrl_len);) - OHCI_DEBUG( printk(" data(%d):", data_len);) - OHCI_DEBUG( for(i=0; i < data_len; i++ ) printk(" %02x", ((__u8 *) data)[i]);) - OHCI_DEBUG( printk(" ret_status: %x\n", status); }) - return 0; -} - -static int sohci_request_irq(struct usb_device *usb_dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id) + +static void * sohci_request_irq(struct usb_device *usb_dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id) { struct ohci * ohci = usb_dev->bus->hcpriv; - union ep_addr_ ep_addr; - - ep_addr.iep = 0; - ep_addr.bep.ep = ((pipe >> 15) & 0x0f) /* endpoint address */ - | (pipe & 0x80) /* direction */ - | (1 << 5); /* type = int*/ - ep_addr.bep.fa = ((pipe >> 8) & 0x7f); /* device address */ + struct ohci_device * dev = usb_to_ohci(usb_dev); + struct usb_hcd_ed hcd_ed; + struct usb_ohci_ed * ed; + +#ifdef VROOTHUB + if(usb_pipedevice(pipe) == ohci->rh.devnum) + return root_hub_request_irq(usb_dev, pipe, handler, period, dev_id); +#endif + + usb_pipe_to_hcd_ed(usb_dev, pipe, &hcd_ed); + hcd_ed.type = INT; + ed = usb_ohci_add_ep(usb_dev, &hcd_ed, period, 1); + + OHCI_DEBUG( printk("USB HC IRQ>>>: %x: every %d ms\n", ed->hwINFO, period);) + + ohci_trans_req(ohci, ed, 0, NULL, dev->data, hcd_ed.maxpack, (__OHCI_BAG) handler, (__OHCI_BAG) dev_id, INT_IN, sohci_int_handler); + if (ED_STATE(ed) != ED_OPER) ohci_link_ed(ohci, ed); + return ed; + +} - OHCI_DEBUG( printk("USB HC IRQ >>>: %x: every %d ms\n", ep_addr.iep, period);) +static int sohci_release_irq(struct usb_device *usb_dev, void * ed) +{ + // struct usb_device *usb_dev = ((struct ohci_device *) ((unsigned int)ed & 0xfffff000))->usb; + struct ohci * ohci = usb_dev->bus->hcpriv; - usb_ohci_add_ep(ohci, ep_addr.iep, period, 1, sohci_int_handler, 1 << ((pipe & 0x03) + 3) , (pipe >> 26) & 0x01); + OHCI_DEBUG( printk("USB HC RM_IRQ>>>:%4x\n", (unsigned int) ed);) - ohci_trans_req(ohci, ep_addr.iep, 0, NULL, ((struct ohci_device *) usb_dev->hcpriv)->data, 8, (__OHCI_BAG) handler, (__OHCI_BAG) dev_id); + if(ed == NULL) return 0; + +#ifdef VROOTHUB + if(ed == ohci->rh.int_addr) + return root_hub_release_irq(usb_dev, ed); +#endif + ED_setSTATE((struct usb_ohci_ed *)ed, ED_STOP); + + usb_ohci_rm_ep(usb_dev, (struct usb_ohci_ed *) ed, NULL, NULL, NULL, 0); + return 0; } - -static int sohci_control_msg(struct usb_device *usb_dev, unsigned int pipe, void *cmd, void *data, int len) +static int sohci_control_msg(struct usb_device *usb_dev, unsigned int pipe, devrequest *cmd, void *data, int len) { DECLARE_WAITQUEUE(wait, current); + struct ohci_state state = {0, TD_NOTACCESSED}; struct ohci * ohci = usb_dev->bus->hcpriv; - int status; - union ep_addr_ ep_addr; + struct usb_hcd_ed hcd_ed; + struct usb_ohci_ed *ed; + +#ifdef VROOTHUB + if(usb_pipedevice(pipe) == ohci->rh.devnum) + return root_hub_control_msg(usb_dev, pipe, cmd, data, len); +#endif - ep_addr.iep = 0; - ep_addr.bep.ep = ((pipe >> 15) & 0x0f) /* endpoint address */ - | (pipe & 0x80) /* direction */ - | (1 << 6); /* type = ctrl*/ - ep_addr.bep.fa = ((pipe >> 8) & 0x7f); /* device address */ + usb_pipe_to_hcd_ed(usb_dev, pipe, &hcd_ed); + hcd_ed.type = CTRL; + + ed = usb_ohci_add_ep(usb_dev, &hcd_ed, 0, 1); - status = 0xf; /* CC not Accessed */ - OHCI_DEBUG( { int i; printk("USB HC CTRL>>>: %x: ctrl(%d):", ep_addr.iep, 8);) + OHCI_DEBUG( { int i; printk("USB HC CTRL>>>: %x: ctrl(%d):", ed->hwINFO, 8);) OHCI_DEBUG( for(i=0; i < 8; i++ ) printk(" %02x", ((__u8 *) cmd)[i]);) OHCI_DEBUG( printk(" data(%d):", len);) OHCI_DEBUG( for(i=0; i < len; i++ ) printk(" %02x", ((__u8 *) data)[i]);) OHCI_DEBUG( printk("\n"); }) - - usb_ohci_add_ep(ohci, ep_addr.iep, 0, 1, sohci_ctrl_handler, 1 << ((pipe & 0x03) + 3) , (pipe >> 26) & 0x01); - current->state = TASK_UNINTERRUPTIBLE; - add_wait_queue(&control_wakeup, &wait); - - ohci_trans_req(ohci, ep_addr.iep, 8, cmd, data, len, (__OHCI_BAG) &status, 0); - - schedule_timeout(HZ/10); + + ohci_trans_req(ohci, ed, 8, cmd, data, len, (__OHCI_BAG) &state, (__OHCI_BAG) &wait, (usb_pipeout(pipe))?CTRL_OUT:CTRL_IN, sohci_blocking_handler); - remove_wait_queue(&control_wakeup, &wait); - - OHCI_DEBUG(printk("USB HC status::: %x\n", cc_to_status[status & 0x0f]);) - - return cc_to_status[status & 0x0f]; + OHCI_DEBUG(printk("USB HC trans req ed %x: %x :", ed->hwINFO, (unsigned int ) ed); ) + OHCI_DEBUG({ int i; for( i= 0; i<8 ;i++) printk(" %4x", ((unsigned int *) ed)[i]) ; printk("\n"); }; ) + if (ED_STATE(ed) != ED_OPER) ohci_link_ed(ohci, ed); + schedule_timeout(HZ/10); + + if(state.status == TD_NOTACCESSED) { + current->state = TASK_UNINTERRUPTIBLE; + usb_ohci_rm_ep(usb_dev, ed, sohci_blocking_handler, NULL, NULL, 0); + schedule(); + state.status = USB_ST_TIMEOUT; + } + remove_wait_queue(&op_wakeup, &wait); + return state.status; } -static int sohci_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len) +static int sohci_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, unsigned long *rval) { DECLARE_WAITQUEUE(wait, current); + struct ohci_state state = {0, TD_NOTACCESSED}; struct ohci * ohci = usb_dev->bus->hcpriv; - int status; - union ep_addr_ ep_addr; - - ep_addr.iep = 0; - ep_addr.bep.ep = ((pipe >> 15) & 0x0f) /* endpoint address */ - | (pipe & 0x80) /* direction */ - | (11 << 5); /* type = bulk*/ - ep_addr.bep.fa = ((pipe >> 8) & 0x7f); /* device address */ + struct usb_hcd_ed hcd_ed; + struct usb_ohci_ed *ed; - status = 0xf; /* CC not Accessed */ - OHCI_DEBUG( { int i; printk("USB HC BULK>>>: %x:", ep_addr.iep);) + usb_pipe_to_hcd_ed(usb_dev, pipe, &hcd_ed); + hcd_ed.type = BULK; + ed = usb_ohci_add_ep(usb_dev, &hcd_ed, 0, 1); + OHCI_DEBUG( { int i; printk("USB HC BULK>>>: %x: ", ed->hwINFO);) OHCI_DEBUG( printk(" data(%d):", len);) OHCI_DEBUG( for(i=0; i < len; i++ ) printk(" %02x", ((__u8 *) data)[i]);) OHCI_DEBUG( printk("\n"); }) - - usb_ohci_add_ep(ohci, ep_addr.iep, 0, 1, sohci_bulk_handler, 1 << ((pipe & 0x03) + 3) , (pipe >> 26) & 0x01); - - current->state = TASK_UNINTERRUPTIBLE; - add_wait_queue(&bulk_wakeup, &wait); + current->state = TASK_UNINTERRUPTIBLE; - ohci_trans_req(ohci, ep_addr.iep, 0, NULL, data, len, (__OHCI_BAG) &status, 0); - + ohci_trans_req(ohci, ed, 0, NULL, data, len, (__OHCI_BAG) &state, (__OHCI_BAG) &wait,(usb_pipeout(pipe))?BULK_OUT:BULK_IN, sohci_blocking_handler); + if (ED_STATE(ed) != ED_OPER) ohci_link_ed(ohci, ed); + schedule_timeout(HZ/10); - remove_wait_queue(&bulk_wakeup, &wait); - - OHCI_DEBUG(printk("USB HC status::: %x\n", cc_to_status[status & 0x0f]);) - - return cc_to_status[status & 0x0f]; + if(state.status == TD_NOTACCESSED) { + current->state = TASK_UNINTERRUPTIBLE; + usb_ohci_rm_ep(usb_dev, ed, sohci_blocking_handler, NULL, NULL, 0); + schedule(); + state.status = USB_ST_TIMEOUT; + } + remove_wait_queue(&op_wakeup, &wait); + *rval = state.len; + return state.status; +} + +static void * sohci_request_bulk(struct usb_device *usb_dev, unsigned int pipe, usb_device_irq handler, void *data, int len, void *dev_id) +{ + struct ohci * ohci = usb_dev->bus->hcpriv; + struct usb_hcd_ed hcd_ed; + struct usb_ohci_ed * ed; + + usb_pipe_to_hcd_ed(usb_dev, pipe, &hcd_ed); + hcd_ed.type = BULK; + ed = usb_ohci_add_ep(usb_dev, &hcd_ed, 0, 1); + + OHCI_DEBUG( printk("USB HC BULK_RQ>>>: %x \n", ed->hwINFO);) + + ohci_trans_req(ohci, ed, 0, NULL, data, len, (__OHCI_BAG) handler, (__OHCI_BAG) dev_id, (usb_pipeout(pipe))?BULK_OUT:BULK_IN, sohci_int_handler); + if (ED_STATE(ed) != ED_OPER) ohci_link_ed(ohci, ed); + + return ed; +} + +static int sohci_terminate_bulk(struct usb_device *usb_dev, void * ed) +{ + DECLARE_WAITQUEUE(wait, current); + + OHCI_DEBUG( printk("USB HC TERM_BULK>>>:%4x\n", (unsigned int) ed);) + + current->state = TASK_UNINTERRUPTIBLE; + usb_ohci_rm_ep(usb_dev, (struct usb_ohci_ed *) ed, sohci_blocking_handler, NULL, &wait, SEND); + schedule(); + remove_wait_queue(&op_wakeup, &wait); + return 1; } static int sohci_usb_deallocate(struct usb_device *usb_dev) { + int cnt; + DECLARE_WAITQUEUE(wait, current); struct ohci_device *dev = usb_to_ohci(usb_dev); - union ep_addr_ ep_addr; - - ep_addr.iep = 0; OHCI_DEBUG(printk("USB HC dealloc %x\n", usb_dev->devnum);) - - /* wait_ms(20); */ - - if(usb_dev->devnum >=0) { - ep_addr.bep.fa = usb_dev->devnum; - usb_ohci_rm_function(((struct ohci_device *)usb_dev->hcpriv)->ohci, ep_addr.iep); + + if(usb_dev->devnum >= 0) { + current->state = TASK_UNINTERRUPTIBLE; + cnt = usb_ohci_rm_function(usb_dev, sohci_blocking_handler, NULL, &wait); + if(cnt > 0) { + schedule(); + remove_wait_queue(&op_wakeup, &wait); + } } - + USB_FREE(dev); + usb_destroy_configuration(usb_dev); USB_FREE(usb_dev); return 0; @@ -251,7 +295,6 @@ struct usb_device *usb_dev; struct ohci_device *dev; - USB_ALLOC(usb_dev, sizeof(*usb_dev)); if (!usb_dev) return NULL; @@ -260,13 +303,14 @@ USB_ALLOC(dev, sizeof(*dev)); if (!dev) { + usb_destroy_configuration(usb_dev); USB_FREE(usb_dev); return NULL; } /* Initialize "dev" */ memset(dev, 0, sizeof(*dev)); - + usb_dev->hcpriv = dev; dev->usb = usb_dev; @@ -279,14 +323,35 @@ return usb_dev; } - static void *sohci_alloc_isochronous (struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int maxsze, usb_device_irq completed, void *dev_id) { - return NULL; + struct ohci * ohci = usb_dev->bus->hcpriv; + struct ohci_device * dev = usb_to_ohci(usb_dev); + struct usb_hcd_ed hcd_ed; + struct usb_ohci_ed * ed; + struct usb_ohci_td * td; + + usb_pipe_to_hcd_ed(usb_dev, pipe, &hcd_ed); + hcd_ed.type = ISO; + ed = usb_ohci_add_ep(usb_dev, &hcd_ed, 1, 1); + + OHCI_DEBUG( printk("USB HC ISO>>>: %x: \n", ed->hwINFO);) + + td = ohci_trans_req(ohci, ed, 0, NULL, dev->data, len, (__OHCI_BAG) completed, (__OHCI_BAG) dev_id, (usb_pipeout(pipe))?ISO_OUT:ISO_IN, sohci_int_handler); + return td; } -static void sohci_delete_isochronous (struct usb_device *dev, void *_isodesc) +static void sohci_delete_isochronous (struct usb_device *usb_dev, void *td) { + // struct ohci * ohci = usb_dev->bus->hcpriv; + DECLARE_WAITQUEUE(wait, current); + + OHCI_DEBUG( printk("USB HC RM_ISO>>>:%4x\n", (unsigned int) td);) + + current->state = TASK_UNINTERRUPTIBLE; + usb_ohci_rm_ep(usb_dev, ((struct usb_ohci_td *) td)->ed, sohci_blocking_handler, NULL, &wait, SEND); + schedule(); + remove_wait_queue(&op_wakeup, &wait); return; } @@ -305,14 +370,15 @@ return USB_ST_NOTSUPPORTED; } - struct usb_operations sohci_device_operations = { sohci_usb_allocate, sohci_usb_deallocate, sohci_control_msg, sohci_bulk_msg, sohci_request_irq, - NULL, /* FIXME: should be release_irq/remove_irq */ + sohci_release_irq, + sohci_request_bulk, + sohci_terminate_bulk, sohci_alloc_isochronous, sohci_delete_isochronous, sohci_sched_isochronous, @@ -325,357 +391,358 @@ *** ED handling functions ************************************/ - - +/* just for debugging; prints all 32 branches of the int ed tree inclusive iso eds*/ +void print_int_eds(struct ohci * ohci) {int i; __u32 * ed_p; + for(i= 0; i < 32; i++) { + OHCI_DEBUG(printk("unlnk_branch int %2d(%2x): ", i,i); ) + ed_p = &(ohci->hc_area->hcca.int_table[i]); + while (*ed_p != 0) { + OHCI_DEBUG(printk("ed: %4x; ", (((struct usb_ohci_ed *)bus_to_virt(*ed_p))->hwINFO));) + ed_p = &(((struct usb_ohci_ed *)bus_to_virt(*ed_p))->hwNextED); + } + OHCI_DEBUG(printk("\n");) + } +} + /* - * search for the right place to insert an interrupt ed into the int tree - * do some load ballancing + * search for the right branch to insert an interrupt ed into the int tree + * do some load ballancing + * returns the branch and + * sets the interval to interval = 2^integer(ld(interval)) * */ -static int usb_ohci_int_ballance(struct ohci * ohci, int interval, int load) { +static int usb_ohci_int_ballance(struct ohci * ohci, int * interval, int load) { int i,j; j = 0; /* search for the least loaded interrupt endpoint branch of all 32 branches */ for(i=0; i< 32; i++) if(ohci->ohci_int_load[j] > ohci->ohci_int_load[i]) j=i; - - if(interval < 1) interval = 1; - if(interval > 32) interval = 32; - for(i= 0; ((interval >> i) > 1 ); interval &= (0xfffe << i++ )); /* interval = 2^int(ld(interval)) */ - - for(i=j%interval; i< 32; i+=interval) ohci->ohci_int_load[i] += load; - j = interval + (j % interval); + for(i= 0; ((*interval >> i) > 1 ) && (i < 5); i++ ); /* interval = 2^int(ld(interval)) */ + *interval = 1 << i; + + j = j % (*interval); + for(i=j; i< 32; i+=(*interval)) ohci->ohci_int_load[i] += load; + - OHCI_DEBUG(printk("USB HC new int ed on pos : %x \n",j);) + OHCI_DEBUG(printk("USB HC new int ed on pos %d of interval %d \n",j, *interval);) return j; } -/* get the ed from the endpoint / device adress */ - -struct usb_ohci_ed * ohci_find_ep(struct ohci *ohci, unsigned int ep_addr_in) { - -union ep_addr_ ep_addr; -struct usb_ohci_ed *tmp; -unsigned int mask; - -mask = 0; -ep_addr.iep = ep_addr_in; - -#ifdef VROOTHUB - if(ep_addr.bep.fa == ohci->root_hub_funct_addr) { - if((ep_addr.bep.ep & 0x0f) == 0) - return &ohci->ed_rh_ep0; /* root hub ep0 */ - else - return &ohci->ed_rh_epi; /* root hub int ep */ - } -#endif +/* the int tree is a binary tree + * in order to process it sequentielly the indexes of the branches have to be mapped + * the mapping reverses the bits of a word of num_bits length + * */ +static int rev(int num_bits, int word) { + int i; + int wout = 0; - tmp = ohci->ed_func_ep0[ep_addr.bep.fa]; - mask = ((((ep_addr.bep.ep >> 5) & 0x03)==2)?0x7f:0xff); - ep_addr.bep.ep &= mask; /* mask out direction of ctrl ep */ - - while (tmp != NULL) { - if (tmp->ep_addr.iep == ep_addr.iep) - return tmp; - tmp = tmp->ed_list; - } - return NULL; + for(i = 0; i < num_bits; i++) wout |= (((word >> i) & 1) << (num_bits - i - 1)); + return wout; } - -spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED; -/* add a new endpoint ep_addr */ -struct usb_ohci_ed *usb_ohci_add_ep(struct ohci * ohci, unsigned int ep_addr_in, int interval, int load, f_handler handler, int ep_size, int speed) { - - struct usb_ohci_ed * ed; - struct usb_ohci_td * td; - union ep_addr_ ep_addr; - - - int int_junk; - - struct usb_ohci_ed *tmp; - ep_addr.iep = ep_addr_in ; - ep_addr.bep.ep &= ((((ep_addr.bep.ep >> 5) & 0x03)==2)?0x7f:0xff); /* mask out direction of ctrl ep */ +/* get the ed from the endpoint / usb_device address */ - spin_lock(&usb_ed_lock); - - tmp = ohci_find_ep(ohci, ep_addr.iep); - if (tmp != NULL) { - -#ifdef VROOTHUB - if(ep_addr.bep.fa == ohci->root_hub_funct_addr) { - if((ep_addr.bep.ep & 0x0f) != 0) { /* root hub int ep */ - ohci->ed_rh_epi.handler = handler; - ohci_init_rh_int_timer(ohci, interval); - } - else { /* root hub ep0 */ - ohci->ed_rh_ep0.handler = handler; - } - } - - else -#endif - - { - tmp->hw.info = ep_addr.bep.fa | ((ep_addr.bep.ep & 0xf) <<7) - - | (((ep_addr.bep.ep & 0x60) == 0)? 0x8000 : 0) - | (speed << 13) - | ep_size <<16; - - tmp->handler = handler; - } - spin_unlock(&usb_ed_lock); - return tmp; /* ed already in use */ - } - - - OHCI_ALLOC(td, sizeof(td)); /* dummy td; end of td list for ed */ - OHCI_ALLOC(ed, sizeof(ed)); - td->prev_td = NULL; - - ed->hw.tail_td = virt_to_bus(&td->hw); - ed->hw.head_td = ed->hw.tail_td; - ed->hw.info = ep_addr.bep.fa | ((ep_addr.bep.ep & 0xf) <<7) - /* | ((ep_addr.bep.port & 0x80)? 0x1000 : 0x0800 ) */ - | (((ep_addr.bep.ep & 0x60) == 0)? 0x8000 : 0) - | (speed << 13) - | ep_size <<16; - - ed->handler = handler; - - switch((ep_addr.bep.ep >> 5) & 0x03) { - case CTRL: - ed->hw.next_ed = 0; - if(ohci->ed_controltail == NULL) { - writel(virt_to_bus(&ed->hw), &ohci->regs->ed_controlhead); - } - else { - ohci->ed_controltail->hw.next_ed = virt_to_bus(&ed->hw); - } - ed->ed_prev = ohci->ed_controltail; - ohci->ed_controltail = ed; - break; - case BULK: - ed->hw.next_ed = 0; - if(ohci->ed_bulktail == NULL) { - writel(virt_to_bus(&ed->hw), &ohci->regs->ed_bulkhead); - } - else { - ohci->ed_bulktail->hw.next_ed = virt_to_bus(&ed->hw); - } - ed->ed_prev = ohci->ed_bulktail; - ohci->ed_bulktail = ed; - break; - case INT: - int_junk = usb_ohci_int_ballance(ohci, interval, load); - ed->hw.next_ed = ohci->hc_area->ed[int_junk].next_ed; - ohci->hc_area->ed[int_junk].next_ed = virt_to_bus(&ed->hw); - ed->ed_prev = (struct usb_ohci_ed *) &ohci->hc_area->ed[int_junk]; - break; - case ISO: - ed->hw.next_ed = 0; - ohci->ed_isotail->hw.next_ed = virt_to_bus(&ed->hw); - ed->ed_prev = ohci->ed_isotail; - ohci->ed_isotail = ed; - break; - } - ed->ep_addr = ep_addr; - - /* Add it to the "hash"-table of known endpoint descriptors */ - - ed->ed_list = ohci->ed_func_ep0[ed->ep_addr.bep.fa]; - ohci->ed_func_ep0[ed->ep_addr.bep.fa] = ed; - - spin_unlock(&usb_ed_lock); - - OHCI_DEBUG(printk("USB HC new ed %x: %x :", ep_addr.iep, (unsigned int ) ed); ) - OHCI_DEBUG({ int i; for( i= 0; i<8 ;i++) printk(" %4x", ((unsigned int *) ed)[i]) ; printk("\n"); }; ) - return 0; +struct usb_ohci_ed * ohci_find_ep(struct usb_device *usb_dev, struct usb_hcd_ed *hcd_ed) { + return &(usb_to_ohci(usb_dev)->ed[hcd_ed->endpoint << 1 | ((hcd_ed->type == CTRL)? 0:hcd_ed->out)]); } -/***** - * Request the removal of an endpoint - * - * put the ep on the rm_list and request a stop of the bulk or ctrl list - * real removal is done at the next start of frame hardware interrupt - */ -int usb_ohci_rm_ep(struct ohci * ohci, struct usb_ohci_ed *ed) -{ - unsigned int flags; - struct usb_ohci_ed *tmp; - - OHCI_DEBUG(printk("USB HC remove ed %x: %x :\n", ed->ep_addr.iep, (unsigned int ) ed); ) - - spin_lock_irqsave(&usb_ed_lock, flags); - - tmp = ohci->ed_func_ep0[ed->ep_addr.bep.fa]; - if (tmp == NULL) { - spin_unlock_irqrestore(&usb_ed_lock, flags); - return 0; - } - - if(tmp == ed) { - ohci->ed_func_ep0[ed->ep_addr.bep.fa] = ed->ed_list; - } - else { - while (tmp->ed_list != ed) { - if (tmp->ed_list == NULL) { - spin_unlock_irqrestore(&usb_ed_lock, flags); - return 0; - } - tmp = tmp->ed_list; - } - tmp->ed_list = ed->ed_list; - } - ed->ed_list = ohci->ed_rm_list; - ohci->ed_rm_list = ed; - ed->hw.info |= OHCI_ED_SKIP; - - switch((ed->ep_addr.bep.ep >> 5) & 0x03) { - case CTRL: - writel_mask(~(0x01<<4), &ohci->regs->control); /* stop CTRL list */ - break; - case BULK: - writel_mask(~(0x01<<5), &ohci->regs->control); /* stop BULK list */ - break; - } - +/* link an ed into one of the HC chains */ +static int ohci_link_ed(struct ohci * ohci, struct usb_ohci_ed *ed) { - writel( OHCI_INTR_SF, &ohci->regs->intrenable); /* enable sof interrupt */ - - spin_unlock_irqrestore(&usb_ed_lock, flags); - - return 1; + int int_branch; + int i; + int inter; + int interval; + int load; + __u32 * ed_p; + + ED_setSTATE(ed, ED_OPER); + + switch(ED_TYPE(ed)) { + case CTRL: + ed->hwNextED = 0; + if(ohci->ed_controltail == NULL) { + writel(virt_to_bus(ed), &ohci->regs->ed_controlhead); + } + else { + ohci->ed_controltail->hwNextED = virt_to_bus(ed); + } + ed->ed_prev = ohci->ed_controltail; + ohci->ed_controltail = ed; + break; + + case BULK: + ed->hwNextED = 0; + if(ohci->ed_bulktail == NULL) { + writel(virt_to_bus(ed), &ohci->regs->ed_bulkhead); + } + else { + ohci->ed_bulktail->hwNextED = virt_to_bus(ed); + } + ed->ed_prev = ohci->ed_bulktail; + ohci->ed_bulktail = ed; + break; + + case INT: + interval = ed->int_period; + load = ed->int_load; + int_branch = usb_ohci_int_ballance(ohci, &interval, load); + ed->int_interval = interval; + ed->int_branch = int_branch; + + for( i= 0; i < rev(6, interval); i += inter) { + inter = 1; + for(ed_p = &(ohci->hc_area->hcca.int_table[rev(5,i)+int_branch]); + (*ed_p != 0) && (((struct usb_ohci_ed *)bus_to_virt(*ed_p))->int_interval >= interval); + ed_p = &(((struct usb_ohci_ed *)bus_to_virt(*ed_p))->hwNextED)) + inter = rev(6,((struct usb_ohci_ed *)bus_to_virt(*ed_p))->int_interval); + ed->hwNextED = *ed_p; + *ed_p = virt_to_bus(ed); + OHCI_DEBUG(printk("int_link i: %2x, inter: %2x, ed: %4x\n", i, inter, ed->hwINFO);) + } + break; + + case ISO: + if(ohci->ed_isotail != NULL) { + ohci->ed_isotail->hwNextED = virt_to_bus(ed); + ed->ed_prev = ohci->ed_isotail; + } + else { + for( i= 0; i < 32; i += inter) { + inter = 1; + for(ed_p = &(ohci->hc_area->hcca.int_table[rev(5,i)]); + *ed_p != 0; + ed_p = &(((struct usb_ohci_ed *)bus_to_virt(*ed_p))->hwNextED)) + inter = rev(6,((struct usb_ohci_ed *)bus_to_virt(*ed_p))->int_interval); + *ed_p = virt_to_bus(ed); + } + ed->ed_prev = NULL; + } + ed->hwNextED = 0; + ohci->ed_isotail = ed; + break; + } + + + return 1; } -/* we have requested to stop the bulk or CTRL list, - * now we can remove the eds on the rm_list */ - -static int ohci_rm_eds(struct ohci * ohci) { - - unsigned int flags; - struct usb_ohci_ed *ed; - struct usb_ohci_ed *ed_tmp; - struct usb_ohci_td *td; - __u32 td_hw_tmp; - __u32 td_hw; - - spin_lock_irqsave(&usb_ed_lock, flags); - - ed = ohci->ed_rm_list; +/* unlink an ed from one of the HC chains. + * just the link to the ed is unlinked. + * the link from the ed still points to another operational ed or 0 + * so the HC can eventually finish the processing of the unlinked ed + * */ +static int ohci_unlink_ed(struct ohci * ohci, struct usb_ohci_ed *ed) { - while (ed != NULL) { + int int_branch; + int i; + int inter; + int interval; + __u32 * ed_p; + - switch((ed->ep_addr.bep.ep >> 5) & 0x03) { + switch(ED_TYPE(ed)) { case CTRL: if(ed->ed_prev == NULL) { - writel(ed->hw.next_ed, &ohci->regs->ed_controlhead); + writel(ed->hwNextED, &ohci->regs->ed_controlhead); } else { - ed->ed_prev->hw.next_ed = ed->hw.next_ed; + ed->ed_prev->hwNextED = ed->hwNextED; } if(ohci->ed_controltail == ed) { ohci->ed_controltail = ed->ed_prev; } + else { + ((struct usb_ohci_ed *)bus_to_virt(ed->hwNextED))->ed_prev = ed->ed_prev; + } break; + case BULK: if(ed->ed_prev == NULL) { - writel(ed->hw.next_ed, &ohci->regs->ed_bulkhead); + writel(ed->hwNextED, &ohci->regs->ed_bulkhead); } else { - ed->ed_prev->hw.next_ed = ed->hw.next_ed; + ed->ed_prev->hwNextED = ed->hwNextED; } if(ohci->ed_bulktail == ed) { ohci->ed_bulktail = ed->ed_prev; } + else { + ((struct usb_ohci_ed *)bus_to_virt(ed->hwNextED))->ed_prev = ed->ed_prev; + } break; + case INT: - ed->ed_prev->hw.next_ed = ed->hw.next_ed; - break; + int_branch = ed->int_branch; + interval = ed->int_interval; + + for( i= 0; i < rev(6,interval); i += inter) { + for(ed_p = &(ohci->hc_area->hcca.int_table[rev(5,i)+int_branch]), inter = 1; + (*ed_p != 0) && (*ed_p != ed->hwNextED); + ed_p = &(((struct usb_ohci_ed *)bus_to_virt(*ed_p))->hwNextED), + inter = rev(6, ((struct usb_ohci_ed *)bus_to_virt(*ed_p))->int_interval)) { + if(((struct usb_ohci_ed *)bus_to_virt(*ed_p)) == ed) { + *ed_p = ed->hwNextED; + break; + } + } + OHCI_DEBUG(printk("int_link i: %2x, inter: %2x, ed: %4x\n", i, inter, ed->hwINFO);) + } + for(i=int_branch; i< 32; i+=interval) ohci->ohci_int_load[i] -= ed->int_load; + break; + case ISO: - ed->ed_prev->hw.next_ed = ed->hw.next_ed; - if(ohci->ed_isotail == ed) { - ohci->ed_isotail = ed->ed_prev; - } - break; + if(ohci->ed_isotail == ed) + ohci->ed_isotail = ed->ed_prev; + if(ed->hwNextED != 0) + ((struct usb_ohci_ed *)bus_to_virt(ed->hwNextED))->ed_prev = ed->ed_prev; + + if(ed->ed_prev != NULL) { + ed->ed_prev->hwNextED = ed->hwNextED; + } + else { + for( i= 0; i < 32; i += inter) { + inter = 1; + for(ed_p = &(ohci->hc_area->hcca.int_table[rev(5,i)]); + *ed_p != 0; + ed_p = &(((struct usb_ohci_ed *)bus_to_virt(*ed_p))->hwNextED)) { + inter = rev(6,((struct usb_ohci_ed *)bus_to_virt(*ed_p))->int_interval); + if(((struct usb_ohci_ed *)bus_to_virt(*ed_p)) == ed) { + *ed_p = ed->hwNextED; + break; + } + } + } + } + break; } - - if(ed->hw.next_ed != 0) ((struct usb_ohci_ed *) bus_to_virt(ed->hw.next_ed))->ed_prev = ed->ed_prev; - + ED_setSTATE(ed, ED_UNLINK); + return 1; +} -/* tds directly connected to ed */ - - td_hw = ed->hw.head_td & 0xfffffff0; - while(td_hw != 0) { - td = bus_to_virt(td_hw); - td_hw_tmp = td_hw; - td_hw = td->hw.next_td; - OHCI_FREE(td); /* free pending tds */ - if(td_hw_tmp == ed->hw.tail_td) break; - - } - - /* mark TDs on the hc done list (if there are any) */ - td_hw = readl(&ohci->regs->donehead) & 0xfffffff0; - while(td_hw != 0) { - td = bus_to_virt(td_hw); - td_hw = td->hw.next_td; - if(td->ep == ed) td->ep = 0; - } - - /* mark TDs on the hcca done list (if there are any) */ - td_hw = ohci->hc_area->hcca.done_head & 0xfffffff0 ; - - while(td_hw != 0) { - td = bus_to_virt(td_hw); - td_hw = td->hw.next_td; - if(td->ep == ed) td->ep = 0; - } - - ed_tmp = ed; - ed = ed->ed_list; - OHCI_FREE(ed_tmp); /* free ed */ - } - writel(0, &ohci->regs->ed_controlcurrent); /* reset CTRL list */ - writel(0, &ohci->regs->ed_bulkcurrent); /* reset BULK list */ - writel_set((0x03<<4), &ohci->regs->control); /* start CTRL u. (BULK list) */ +spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED; - spin_unlock_irqrestore(&usb_ed_lock, flags); - - ohci->ed_rm_list = NULL; - OHCI_DEBUG(printk("USB HC after rm ed control: %4x intrstat: %4x intrenable: %4x\n", readl(&ohci->regs->control),readl(&ohci->regs->intrstatus),readl(&ohci->regs->intrenable));) +/* add/reinit an endpoint; this should be done once at the usb_set_configuration command, + * but the USB stack is a little bit stateless so we do it at every transaction + * if the state of the ed is ED_NEW then a dummy td is added and the state is changed to ED_UNLINK + * in all other cases the state is left unchanged + * the ed info fields are setted anyway even though they should not change + * */ +struct usb_ohci_ed *usb_ohci_add_ep(struct usb_device * usb_dev, struct usb_hcd_ed * hcd_ed, int interval, int load) { + + // struct ohci * ohci = usb_dev->bus->hcpriv; + struct usb_ohci_td * td; + struct usb_ohci_ed * ed; + + int ed_state; + spin_lock(&usb_ed_lock); + + ed = ohci_find_ep(usb_dev, hcd_ed); - return 0; + ed_state = ED_STATE(ed); /* store state of ed */ + + if (ed_state == ED_NEW) { + OHCI_ALLOC(td, sizeof(*td)); /* dummy td; end of td list for ed */ + ed->hwTailP = virt_to_bus(td); + ed->hwHeadP = ed->hwTailP; + ed_state = ED_UNLINK; + } + + ed->hwINFO = hcd_ed->function + | hcd_ed->endpoint << 7 + | (hcd_ed->type == ISO? 0x8000 : 0) + | (hcd_ed->type == CTRL? 0:(hcd_ed->out == 1? 0x800 : 0x1000 )) + | hcd_ed->slow << 13 + | hcd_ed->maxpack << 16 + | hcd_ed->type << 27 + // | 1 << 14 + | ed_state << 29 ; + + if (ED_TYPE(ed) == INT && ed_state == ED_UNLINK) { + ed->int_period = interval; + ed->int_load = load; + } + + spin_unlock(&usb_ed_lock); + return ed; } -/* remove all endpoints of a function (device) */ -int usb_ohci_rm_function( struct ohci * ohci, unsigned int ep_addr_in) -{ - struct usb_ohci_ed *ed; - struct usb_ohci_ed *tmp; - union ep_addr_ ep_addr; +/***** + * Request the removal of an endpoint + * + * put the ep on the rm_list and request a stop of the bulk or ctrl list + * real removal is done at the next start of frame (SOF) hardware interrupt + * the dummy td carries the essential information (handler, proc queue, ...) + */ +int usb_ohci_rm_ep(struct usb_device * usb_dev, struct usb_ohci_ed *ed, f_handler handler, __OHCI_BAG lw0, __OHCI_BAG lw1, int send) +{ + unsigned int flags; + + struct ohci * ohci = usb_dev->bus->hcpriv; + struct usb_ohci_td *td; - ep_addr.iep = ep_addr_in; + OHCI_DEBUG(printk("USB HC remove ed %x: %x :\n", ed->hwINFO, (unsigned int ) ed); ) - for(ed = ohci->ed_func_ep0[ep_addr.bep.fa]; ed != NULL;) { - tmp = ed; - ed = ed->ed_list; - usb_ohci_rm_ep(ohci, tmp); - } - + spin_lock_irqsave(&usb_ed_lock, flags); + ed->hwINFO |= OHCI_ED_SKIP; + writel( OHCI_INTR_SF, &ohci->regs->intrenable); /* enable sof interrupt */ + + if(ED_STATE(ed) == ED_OPER) ohci_unlink_ed(ohci, ed); + + td = (struct usb_ohci_td *) bus_to_virt(ed->hwTailP); + td->lw0 = lw0; + td->lw1 = lw1; + td->ed = ed; + td->hwINFO = TD_CC; + td->handler = handler; + td->type = send; + + ED_setSTATE(ed, ED_DEL); + ed->ed_prev = ohci->ed_rm_list; + ohci->ed_rm_list = ed; + + switch(ED_TYPE(ed)) { + case CTRL: + writel_mask(~(0x01<<4), &ohci->regs->control); /* stop CTRL list */ + break; + case BULK: + writel_mask(~(0x01<<5), &ohci->regs->control); /* stop BULK list */ + break; + } - - return 1; -} + spin_unlock_irqrestore(&usb_ed_lock, flags); + return 1; +} + +/* remove all endpoints of a function (device) + * just the last ed sends a reply + * the last ed is ed0 as there always should be an ep0 + * */ +int usb_ohci_rm_function(struct usb_device * usb_dev, f_handler handler,__OHCI_BAG tw0, __OHCI_BAG tw1) +{ + struct usb_ohci_ed *ed; + int i; + int cnt = 0; + + + for(i = NUM_EDS - 1 ; i >= 0; i--) { + ed = &(usb_to_ohci(usb_dev)->ed[i]); + if(ED_STATE(ed) != ED_NEW) { + OHCI_DEBUG(printk("USB RM FUNCTION ed: %4x;\n", ed->hwINFO);) + usb_ohci_rm_ep(usb_dev, ed, handler, tw0, tw1, i==0?SEND:0); + cnt++; + } + } + OHCI_DEBUG(printk("USB RM FUNCTION %d eds removed;\n", cnt);) + return cnt; +} @@ -684,259 +751,292 @@ ************************************/ -#define FILL_TD(TD_PT, HANDLER, INFO, DATA, LEN, LW0, LW1) \ - td_pt = (TD_PT); \ - td_pt1 = (struct usb_ohci_td *) bus_to_virt(usb_ep->hw.tail_td); \ - td_pt1->ep = usb_ep; \ +#define FILL_TD(INFO, DATA, LEN, LW0, LW1, TYPE, HANDLER) \ + OHCI_ALLOC(td_pt, sizeof(*td_pt)); \ + td_ret = (struct usb_ohci_td *) bus_to_virt(usb_ed->hwTailP & 0xfffffff0); \ + td_pt1 = td_ret; \ + td_pt1->ed = ed; \ + td_pt1->buffer_start = (DATA); \ + td_pt1->type = (TYPE); \ td_pt1->handler = (HANDLER); \ + td_pt1->lw0 = (LW0); \ + td_pt1->lw1 = (LW1); \ + td_pt1->hwINFO = (INFO); \ + td_pt1->hwCBP = (((DATA)==NULL)||((LEN)==0))?0:virt_to_bus(DATA); \ + td_pt1->hwBE = (((DATA)==NULL)||((LEN)==0))?0:virt_to_bus((DATA) + (LEN) - 1); \ + td_pt1->hwNextTD = virt_to_bus(td_pt); \ + td_pt->hwNextTD = 0; \ + usb_ed->hwTailP = td_pt1->hwNextTD + +#define FILL_ISO_TD(INFO, DATA, LEN, LW0, LW1, TYPE, HANDLER) \ + OHCI_ALLOC(td_pt, sizeof(*td_pt)); \ + td_ret = (struct usb_ohci_td *) bus_to_virt(usb_ed->hwTailP); \ + td_pt1 = td_ret; \ + td_pt1->ed = ed; \ td_pt1->buffer_start = (DATA); \ + td_pt1->type = (TYPE); \ + td_pt1->handler = (HANDLER); \ td_pt1->lw0 = (LW0); \ td_pt1->lw1 = (LW1); \ - td_pt1->hw.info = (INFO); \ - td_pt1->hw.cur_buf = virt_to_bus(DATA); \ - td_pt1->hw.buf_end = td_pt1->hw.cur_buf + (LEN) - 1; \ - td_pt1->hw.next_td = virt_to_bus(td_pt); \ - usb_ep->hw.tail_td = virt_to_bus(td_pt); \ - td_pt->prev_td = td_pt1; \ - td_pt->hw.next_td = 0 - + td_pt1->hwINFO = (INFO); \ + td_pt1->hwCBP = (virt_to_bus(DATA) & 0xfffff000); \ + td_pt1->hwBE = virt_to_bus((DATA) + (LEN) - 1); \ + td_pt1->hwNextTD = virt_to_bus(td_pt); \ + td_pt1->hwPSW[0] = virt_to_bus(DATA) & 0xfff; \ + usb_ed->hwTailP = virt_to_bus(td_pt); \ + td_pt->hwNextTD = 0 + spinlock_t usb_req_lock = SPIN_LOCK_UNLOCKED; -int ohci_trans_req(struct ohci * ohci, unsigned int ep_addr, int ctrl_len, void *ctrl, void * data, int data_len, __OHCI_BAG lw0, __OHCI_BAG lw1) { +struct usb_ohci_td * ohci_trans_req(struct ohci * ohci, struct usb_ohci_ed * ed, int ctrl_len, + void *ctrl, void * data, int data_len, __OHCI_BAG lw0, __OHCI_BAG lw1, unsigned int ed_type, f_handler handler) { - int ed_type; + unsigned int flags; - struct usb_ohci_td *td_pt; - struct usb_ohci_td *td_pt1; - struct usb_ohci_td *td_pt_a1, *td_pt_a2, *td_pt_a3; - struct usb_ohci_ed *usb_ep; - f_handler handler; + volatile struct usb_ohci_ed *usb_ed = ed; + volatile struct usb_ohci_td *td_pt; + volatile struct usb_ohci_td *td_pt1 = NULL; - - td_pt_a1 =NULL; - td_pt_a2 =NULL; - td_pt_a3 =NULL; - - usb_ep = ohci_find_ep(ohci, ep_addr); - if(usb_ep == NULL ) return -1; /* not known ep */ - - handler = usb_ep->handler; + struct usb_ohci_td *td_ret = NULL; + + int cnt = 0; -#ifdef VROOTHUB - if(usb_ep == &ohci->ed_rh_ep0) { /* root hub ep 0 control endpoint */ - root_hub_control_msg(ohci, 8, ctrl, data, data_len, lw0, lw1, handler); - return 0; - } - - if(usb_ep == &ohci->ed_rh_epi) { /* root hub interrupt endpoint */ + + if(usb_ed == NULL ) return NULL; /* not known ep */ - root_hub_int_req(ohci, 8, ctrl, data, data_len, lw0, lw1, handler); - return 0; - } -#endif - /* struct usb_ohci_ed * usb_ep = usb_ohci_add_ep(pipe, ohci, interval, 1); */ - - ed_type = ((((union ep_addr_)ep_addr).bep.ep >> 5) & 0x07); - switch(ed_type) { - case BULK_IN: - case BULK_OUT: - case INT_IN: - case INT_OUT: - OHCI_ALLOC(td_pt_a1, sizeof(td_pt_a1)); - break; - - case CTRL_IN: - case CTRL_OUT: - OHCI_ALLOC(td_pt_a1, sizeof(td_pt_a1)); - OHCI_ALLOC(td_pt_a3, sizeof(td_pt_a3)); - if(data_len > 0) { - OHCI_ALLOC(td_pt_a2, sizeof(td_pt_a2)); - } - break; - - case ISO_IN: - case ISO_OUT: - - } - spin_lock_irqsave(&usb_req_lock, flags); switch(ed_type) { - case BULK_IN: - FILL_TD( td_pt_a1, handler, TD_CC | TD_R | TD_DP_IN | TD_T_TOGGLE, data, data_len, lw0, lw1 ); + case BULK_IN: + while(data_len > 4096) + { + FILL_TD( TD_CC | TD_R | TD_DP_IN | TD_T_TOGGLE, data, 4096, NULL, NULL, BULK_IN | ADD_LEN|(cnt++?0:ST_ADDR), NULL); + data += 4096; data_len -= 4096; + } + FILL_TD( TD_CC | TD_R | TD_DP_IN | TD_T_TOGGLE, data, data_len, lw0, lw1, BULK_IN |ADD_LEN|SEND|(cnt++?0:ST_ADDR), handler); writel( OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */ break; case BULK_OUT: - FILL_TD( td_pt_a1, handler, TD_CC | TD_DP_OUT | TD_T_TOGGLE, data, data_len, lw0, lw1 ); + while(data_len > 4096) + { + FILL_TD( TD_CC | TD_DP_OUT | TD_T_TOGGLE, data, 4096, NULL, NULL, BULK_OUT | ADD_LEN|(cnt++?0:ST_ADDR), NULL); + data += 4096; data_len -= 4096; + } + FILL_TD( TD_CC | TD_DP_OUT | TD_T_TOGGLE, data, data_len, lw0, lw1, BULK_OUT |ADD_LEN|SEND|(cnt++?0:ST_ADDR), handler); writel( OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */ break; case INT_IN: - FILL_TD( td_pt_a1, handler, TD_CC | TD_R | TD_DP_IN | TD_T_TOGGLE, data, data_len, lw0, lw1 ); + FILL_TD( TD_CC | TD_R | TD_DP_IN | TD_T_TOGGLE, data, data_len, lw0, lw1, INT_IN | ST_ADDR|ADD_LEN|SEND, handler); break; case INT_OUT: - FILL_TD( td_pt_a1, handler, TD_CC | TD_DP_OUT | TD_T_TOGGLE, data, data_len, lw0, lw1 ); + FILL_TD( TD_CC | TD_DP_OUT | TD_T_TOGGLE, data, data_len, lw0, lw1, INT_OUT | ST_ADDR|ADD_LEN|SEND, handler); break; - case CTRL_IN: - FILL_TD( td_pt_a1, NULL, TD_CC | TD_DP_SETUP | TD_T_DATA0, ctrl, ctrl_len, 0, 0 ); - if(data_len > 0) { - FILL_TD( td_pt_a2, NULL, TD_CC | TD_R | TD_DP_IN | TD_T_DATA1, data, data_len, 0, 0 ); + case CTRL_IN: + FILL_TD( TD_CC | TD_DP_SETUP | TD_T_DATA0, ctrl, ctrl_len, 0, 0, CTRL_SETUP |ST_ADDR, NULL); + if(data_len > 0) { + FILL_TD( TD_CC | TD_R | TD_DP_IN | TD_T_DATA1, data, data_len, 0, 0, CTRL_DATA_IN | ST_ADDR|ADD_LEN, NULL); } - FILL_TD( td_pt_a3, handler, TD_CC | TD_DP_OUT | TD_T_DATA1, NULL, 0, lw0, lw1 ); + FILL_TD( TD_CC | TD_DP_OUT | TD_T_DATA1, NULL, 0, lw0, lw1, CTRL_STATUS_OUT |SEND, handler); writel( OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */ break; - case CTRL_OUT: - FILL_TD( td_pt_a1, NULL, TD_CC | TD_DP_SETUP | TD_T_DATA0, ctrl, ctrl_len, 0, 0 ); - if(data_len > 0) { - FILL_TD( td_pt_a2, NULL, TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1, data, data_len, 0, 0 ); - } - FILL_TD( td_pt_a3, handler, TD_CC | TD_DP_IN | TD_T_DATA1, NULL, 0, lw0, lw1 ); + case CTRL_OUT: + FILL_TD( TD_CC | TD_DP_SETUP | TD_T_DATA0, ctrl, ctrl_len, 0, 0, CTRL_SETUP |ST_ADDR, NULL); + if(data_len > 0) { + FILL_TD( TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1, data, data_len, 0, 0, CTRL_DATA_OUT | ST_ADDR|ADD_LEN, NULL); + } + FILL_TD( TD_CC | TD_DP_IN | TD_T_DATA1, NULL, 0, lw0, lw1, CTRL_STATUS_IN |SEND, handler); writel( OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */ break; case ISO_IN: + FILL_ISO_TD( TD_CC|TD_ISO|(ctrl_len & 0xffff), data, data_len, lw0, lw1, ISO_IN | ST_ADDR|ADD_LEN|SEND, handler); + break; + case ISO_OUT: + FILL_ISO_TD( TD_CC|TD_ISO|(ctrl_len & 0xffff), data, data_len, lw0, lw1, ISO_OUT | ST_ADDR|ADD_LEN|SEND, handler); break; } - - - - td_pt1 = (struct usb_ohci_td *) bus_to_virt(usb_ep->hw.tail_td); - - - if(td_pt_a3 != NULL) td_pt_a3->prev_td = NULL; - else if (td_pt_a2 != NULL) td_pt_a2->prev_td = NULL; - else if (td_pt_a1 != NULL) td_pt_a1->prev_td = NULL; - - spin_unlock_irqrestore(&usb_req_lock, flags); - return 0; + spin_unlock_irqrestore(&usb_req_lock, flags); + return td_ret; } /****** *** Done List handling functions ************************************/ +/* the HC halts an ED if an error occurs; + * on error move all pending tds of a transaction (from ed) onto the done list + * * */ +static struct usb_ohci_td * ohci_append_error_tds(struct usb_ohci_td * td_list, struct usb_ohci_td * td_rev) { + + struct usb_ohci_td * tdl; + struct usb_ohci_td * tdx; + struct usb_ohci_td * tdt; + int cc; + + tdl = (struct usb_ohci_td *) bus_to_virt( td_list->ed->hwHeadP & 0xfffffff0); + tdt = (struct usb_ohci_td *) bus_to_virt( td_list->ed->hwTailP); + cc = TD_CC_GET(td_list->hwINFO); + + for ( tdx = tdl; tdx != tdt; tdx = tdx->next_dl_td) { + if(tdx->type & SEND) break; + tdx->next_dl_td = bus_to_virt(tdx->hwNextTD & 0xfffffff0); + } + tdx->next_dl_td = td_rev; + td_list->ed->hwHeadP = (tdx->hwNextTD & 0xfffffff0) | (td_list->ed->hwHeadP & 0x2); + TD_CC_SET(tdx->hwINFO, cc); + return tdl; +} /* replies to the request have to be on a FIFO basis so * we reverse the reversed done-list */ static struct usb_ohci_td * ohci_reverse_done_list(struct ohci * ohci) { - __u32 td_list_hc; - struct usb_ohci_td * td_list = NULL; - struct usb_ohci_td * td_rev = NULL; + __u32 td_list_hc; + struct usb_ohci_td * td_rev = NULL; + struct usb_ohci_td * td_list = NULL; td_list_hc = ohci->hc_area->hcca.done_head & 0xfffffff0; - ohci->hc_area->hcca.done_head = 0; - - while(td_list_hc) { + ohci->hc_area->hcca.done_head = 0; + + + while(td_list_hc) { td_list = (struct usb_ohci_td *) bus_to_virt(td_list_hc); - td_list->next_dl_td = td_rev; + if(TD_CC_GET(td_list->hwINFO) && !(td_list->type & SEND)) + td_list->next_dl_td = ohci_append_error_tds(td_list, td_rev); + else + td_list->next_dl_td = td_rev; td_rev = td_list; - td_list_hc = td_list->hw.next_td & 0xfffffff0; - } + td_list_hc = td_list->hwNextTD & 0xfffffff0; + + + } return td_list; } -/* all done requests are replied here */ -static int usb_ohci_done_list(struct ohci * ohci) { +/* there are some pending requests to remove some of the eds + * we process every td including the dummy td of these eds + * and link them to a list + * */ +static struct usb_ohci_td * usb_ohci_del_list(struct ohci * ohci) { + struct usb_ohci_ed * ed; + struct usb_ohci_td * td; + struct usb_ohci_td * td_tmp = NULL; + struct usb_ohci_td * td_list = NULL; + __u32 * td_hw; + + for(ed = ohci->ed_rm_list; ed != NULL; ed = ed->ed_prev) { + OHCI_DEBUG(printk("USB HC ed_rm_list: %4x :\n", ed->hwINFO);) + + + for( td_hw = &(ed->hwHeadP); (*td_hw & 0xfffffff0) != ed->hwTailP; td_hw = &(td->hwNextTD)) { + td = (struct usb_ohci_td *)bus_to_virt(*td_hw & 0xfffffff0); + if((ED_STATE(ed) == ED_DEL) || (td->type & DEL)) { + *td_hw = td->hwNextTD; + if(td_list == NULL) + td_list = td; + else + td_tmp->next_dl_td = td; + td_tmp = td; + OHCI_DEBUG(printk("USB HC ed_rm_list: td: %4x\n", (unsigned int) td);) + td->next_dl_td = NULL; + } + } + if(ED_STATE(ed) == ED_DEL) { /* send dummy td */ + td = (struct usb_ohci_td *)bus_to_virt(*td_hw & 0xfffffff0); + td->ed = ed; + if(td_list == NULL) + td_list = td; + else + td_tmp->next_dl_td = td; + td_tmp = td; + td->type |= DEL_ED; + OHCI_DEBUG(printk("USB HC ed_rm_list: dummy (ED_DEL) td: %4x\n", (unsigned int) td);) + ED_setSTATE(td->ed, ED_DEL| ED_NEW); + td->next_dl_td = NULL; + } + } + + writel(0, &ohci->regs->ed_controlcurrent); /* reset CTRL list */ + writel(0, &ohci->regs->ed_bulkcurrent); /* reset BULK list */ + writel_set((0x03<<4), &ohci->regs->control); /* start CTRL u. BULK list */ - struct usb_ohci_td * td = NULL; - struct usb_ohci_td * td_list; - struct usb_ohci_td * td_list_next = NULL; - struct usb_ohci_td * td_err = NULL; - __u32 td_hw; - - - td_list = ohci_reverse_done_list(ohci); - - while(td_list) { - td_list_next = td_list->next_dl_td; - td = td_list; - - if(td->ep == NULL) { /* removed ep */ - OHCI_FREE(td_list); - break; - } + ohci->ed_rm_list = NULL; - /* the HC halts an ED if an error occurs; put all pendings TDs of an halted ED on the - * done list; they are marked with an 0xf CC_error code - */ - - if(TD_CC_GET(td_list->hw.info) != TD_CC_NOERROR) { /* on error move all pending tds of an ed into the done list */ - printk("******* USB BUS error %x @ep %x\n", TD_CC_GET(td_list->hw.info), td_list->ep->ep_addr.iep); - td_err= td_list; - td_hw = td_list->ep->hw.head_td & 0xfffffff0; - while(td_hw != 0) { - if(td_hw == td_list->ep->hw.tail_td) break; - td = bus_to_virt(td_hw); - td_err->next_dl_td = td; - td_err= td; - td_hw = td->hw.next_td; - } - td_list->ep->hw.head_td = td_list->ep->hw.tail_td; - td->next_dl_td = td_list_next; - td_list_next = td_list->next_dl_td; - - } - /* send the reply */ - if(td_list->handler != NULL) { - if(td_list->prev_td == NULL) { - td_list->handler((void *) ohci, - td_list->ep->ep_addr.iep, - 0, - NULL, - td_list->buffer_start, - td_list->hw.buf_end-virt_to_bus(td_list->buffer_start)+1, - TD_CC_GET(td_list->hw.info), - td_list->lw0, - td_list->lw1); - OHCI_FREE(td_list); - } - else { - if(td_list->prev_td->prev_td == NULL) { /* cntrl 2 Transactions dataless */ - td_list->handler((void *) ohci, - td_list->ep->ep_addr.iep, - td_list->prev_td->hw.buf_end-virt_to_bus(td_list->prev_td->buffer_start)+1, - td_list->prev_td->buffer_start, - NULL, - 0, - (TD_CC_GET(td_list->prev_td->hw.info) > 0) ? TD_CC_GET(td_list->prev_td->hw.info) : TD_CC_GET(td_list->hw.info), - td_list->lw0, - td_list->lw1); - OHCI_FREE(td_list->prev_td); - OHCI_FREE(td_list); - } - else { /* cntrl 3 Transactions */ - td_list->handler((void *) ohci, - td_list->ep->ep_addr.iep, - td_list->prev_td->prev_td->hw.buf_end-virt_to_bus(td_list->prev_td->prev_td->buffer_start)+1, - td_list->prev_td->prev_td->buffer_start, - td_list->prev_td->buffer_start, - td_list->prev_td->hw.buf_end-virt_to_bus(td_list->prev_td->buffer_start)+1, - (TD_CC_GET(td_list->prev_td->prev_td->hw.info) > 0) ? TD_CC_GET(td_list->prev_td->prev_td->hw.info) - : (TD_CC_GET(td_list->prev_td->hw.info) > 0) ? TD_CC_GET(td_list->prev_td->hw.info) : TD_CC_GET(td_list->hw.info), + + return td_list; +} + + +/* all tds ever alive go through this loop + * requests are replied here + * the handler is the + * interface handler (blocking/non blocking) the real reply-handler + * is called in the non blocking interface routine + * */ +static int usb_ohci_done_list(struct ohci * ohci, struct usb_ohci_td * td_list) { + + struct usb_ohci_td * td_list_next = NULL; + + int cc; + int i; + + while(td_list) { + td_list_next = td_list->next_dl_td; + + if(td_list->type & ST_ADDR) { /* remember start address of data buffer */ + td_list->ed->buffer_start = td_list->buffer_start; + td_list->ed->len = 0; + } + + if(td_list->type & ADD_LEN) { /* accumulate length of multi td transfers */ + if(td_list->hwINFO & TD_ISO) { + for(i= 0; i <= ((td_list->hwINFO >> 24) & 0x7); i++) + if((td_list->hwPSW[i] >> 12) < 0xE) td_list->ed->len += (td_list->hwPSW[i] & 0x3ff); + } + else { + if(td_list->hwBE != 0) { + if(td_list->hwCBP == 0) + td_list->ed->len += (bus_to_virt(td_list->hwBE) - td_list->buffer_start + 1); + else + td_list->ed->len += (bus_to_virt(td_list->hwCBP) - td_list->buffer_start); + } + } + } + /* error code of transfer */ + cc = (ED_STATE(td_list->ed) == ED_DEL || (td_list->type & DEL))? USB_ST_REMOVED : TD_CC_GET(td_list->hwINFO); + + if(td_list->type & DEL_ED) ED_setSTATE(td_list->ed, ED_NEW); /* remove ed */ + + if((td_list->type & SEND) && (ED_STATE(td_list->ed) != ED_STOP)) { /* send the reply */ + td_list->handler((void *) ohci, + td_list->ed, + td_list->ed->buffer_start, + td_list->ed->len, + cc, td_list->lw0, td_list->lw1); - OHCI_FREE(td_list->prev_td->prev_td); - OHCI_FREE(td_list->prev_td); - OHCI_FREE(td_list); - - } - } - - } - td_list = td_list_next; - } - return 0; + OHCI_DEBUG(if(cc != TD_CC_NOERROR) printk("******* USB BUS error %x @ep %x\n", TD_CC_GET(td_list->hwINFO), td_list->ed->hwINFO);) + + } + + if(((td_list->ed->hwHeadP & 0xfffffff0) == td_list->ed->hwTailP) && (ED_STATE(td_list->ed) > ED_UNLINK)) + ohci_unlink_ed(ohci, td_list->ed); /* unlink eds if they are not busy */ + + OHCI_FREE(td_list); + td_list = td_list_next; + } + return 0; } @@ -946,28 +1046,21 @@ ************************************/ - +/* reset the HC not the BUS */ void reset_hc(struct ohci *ohci) { - int retries = 5; + int timeout = 30; - int fminterval; - + if(readl(&ohci->regs->control) & 0x100) { /* SMM owns the HC */ writel(0x08, &ohci->regs->cmdstatus); /* request ownership */ printk("USB HC TakeOver from SMM\n"); - do { - wait_ms(100); - if(--retries) { - printk("USB HC TakeOver timed out!\n"); - break; - } - } - while(readl(&ohci->regs->control) & 0x100); + if(readl(&ohci->regs->control) & 0x100) + printk("USB HC TakeOver failed!\n"); } writel((1<<31), &ohci->regs->intrdisable); /* Disable HC interrupts */ - OHCI_DEBUG(printk("USB HC reset_hc: %x ; retries: %d\n", readl(&ohci->regs->control), 5-retries);) - fminterval = readl(&ohci->regs->fminterval) & 0x3fff; + OHCI_DEBUG(printk("USB HC reset_hc: %x ; \n", readl(&ohci->regs->control));) + writel(1, &ohci->regs->cmdstatus); /* HC Reset */ while ((readl(&ohci->regs->cmdstatus) & 0x01) != 0) { /* 10us Reset */ if (--timeout == 0) { @@ -975,507 +1068,237 @@ return; } udelay(1); - } - /* set the timing */ - fminterval |= (((fminterval -210) * 6)/7)<<16; - writel(fminterval, &ohci->regs->fminterval); - writel(((fminterval&0x3fff)*9)/10, &ohci->regs->periodicstart); + } } - +static struct ohci *__ohci; /* - * Reset and start an OHCI controller - */ -void start_hc(struct ohci *ohci) + * Start an OHCI controller, set the BUS operational + * set and enable interrupts + * connect the virtual root hub + * * */ + +int start_hc(struct ohci *ohci) { - /* int fminterval; */ unsigned int mask; - int port_nr; - /* fminterval = readl(&ohci->regs->fminterval) & 0x3fff; - reset_hc(ohci); */ - - + int fminterval; + + /* + * Tell the controller where the control and bulk lists are + * The lists are empty now. + */ + writel(0, &ohci->regs->ed_controlhead); + writel(0, &ohci->regs->ed_bulkhead); + writel(virt_to_bus(&ohci->hc_area->hcca), &ohci->regs->hcca); /* a reset clears this */ - - /* Choose the interrupts we care about now, others later on demand */ - mask = OHCI_INTR_MIE | OHCI_INTR_WDH; - /* | OHCI_INTR_SO | OHCI_INTR_UE |OHCI_INTR_RHSC |OHCI_INTR_SF| - OHCI_INTR_FNO */ - - if(readl(&ohci->regs->roothub.a) & 0x100) /* global power on */ - writel( 0x10000, &ohci->regs->roothub.status); /* root hub power on */ - else { /* port power on */ - for(port_nr=0; port_nr < (ohci->regs->roothub.a & 0xff); port_nr++) - writel(0x100, &ohci->regs->roothub.portstatus[port_nr]); - } - wait_ms(50); - - writel((0x00), &ohci->regs->control); /* USB Reset BUS */ - wait_ms(10); - - writel((0xB7), &ohci->regs->control); /* USB Operational */ + + writel((0xB7), &ohci->regs->control); /* USB Operational */ - OHCI_DEBUG(printk("USB HC rstart_hc_operational: %x\n", readl(&ohci->regs->control)); ) + fminterval = 0x2edf; + writel(((fminterval)*9)/10, &ohci->regs->periodicstart); + fminterval |= ((((fminterval -210) * 6)/7)<<16); + writel(fminterval, &ohci->regs->fminterval); + writel(0x628, &ohci->regs->lsthresh); + OHCI_DEBUG(printk("USB HC fminterval: %x \n", readl( &(ohci->regs->fminterval) )); ) + OHCI_DEBUG(printk("USB HC periodicstart: %x \n", readl( &(ohci->regs->periodicstart) )); ) + OHCI_DEBUG(printk("USB HC lsthresh: %x \n", readl( &(ohci->regs->lsthresh) )); ) + OHCI_DEBUG(printk("USB HC control: %x\n", readl(&ohci->regs->control)); ) OHCI_DEBUG(printk("USB HC roothubstata: %x \n", readl( &(ohci->regs->roothub.a) )); ) OHCI_DEBUG(printk("USB HC roothubstatb: %x \n", readl( &(ohci->regs->roothub.b) )); ) OHCI_DEBUG(printk("USB HC roothubstatu: %x \n", readl( &(ohci->regs->roothub.status) )); ) OHCI_DEBUG(printk("USB HC roothubstat1: %x \n", readl( &(ohci->regs->roothub.portstatus[0]) )); ) OHCI_DEBUG(printk("USB HC roothubstat2: %x \n", readl( &(ohci->regs->roothub.portstatus[1]) )); ) - - /* control_wakeup = NULL; */ + /* Choose the interrupts we care about now, others later on demand */ + mask = OHCI_INTR_MIE | OHCI_INTR_WDH | OHCI_INTR_SO; + writel(mask, &ohci->regs->intrenable); writel(mask, &ohci->regs->intrstatus); #ifdef VROOTHUB - { - + { + /* connect the virtual root hub */ struct usb_device * usb_dev; struct ohci_device *dev; - struct ohci_device *tmp_root_hub= usb_to_ohci(ohci->bus->root_hub); - usb_dev = sohci_usb_allocate(tmp_root_hub->usb); - dev = usb_dev->hcpriv; + - dev->ohci = ohci; + usb_dev = sohci_usb_allocate(NULL); + if (!usb_dev) return -1; + dev = usb_to_ohci(usb_dev); + usb_dev->bus = ohci->bus; + ohci->bus->root_hub = usb_dev; + dev->ohci = ohci; usb_connect(usb_dev); - - tmp_root_hub->usb->children[0] = usb_dev; - - usb_new_device(usb_dev); + if(usb_new_device(usb_dev) != 0) { + sohci_usb_deallocate(usb_dev); + return -1; } -#endif - - + } +#endif + return 0; } - - - +/* an interrupt happens */ static void ohci_interrupt(int irq, void *__ohci, struct pt_regs *r) { - struct ohci *ohci = __ohci; - struct ohci_regs *regs = ohci->regs; - - int ints; + struct ohci *ohci = __ohci; + struct ohci_regs *regs = ohci->regs; + int ints; - - if((ohci->hc_area->hcca.done_head != 0) && !(ohci->hc_area->hcca.done_head & 0x01)) { - ints = OHCI_INTR_WDH; - } - else { - if((ints = (readl(®s->intrstatus) & readl(®s->intrenable))) == 0) - return; - } + if((ohci->hc_area->hcca.done_head != 0) && !(ohci->hc_area->hcca.done_head & 0x01)) { + ints = OHCI_INTR_WDH; + } + else { + if((ints = (readl(®s->intrstatus) & readl(®s->intrenable))) == 0) + return; + } - ohci->intrstatus |= ints; - OHCI_DEBUG(printk("USB HC interrupt: %x (%x) \n", ints, readl(&ohci->regs->intrstatus));) + OHCI_DEBUG(printk("USB HC interrupt: %x (%x) \n", ints, readl(®s->intrstatus));) - /* ints &= ~(OHCI_INTR_WDH); WH Bit will be set by done list subroutine */ - /* if(ints & OHCI_INTR_FNO) { - writel(OHCI_INTR_FNO, ®s->intrstatus); - if (waitqueue_active(&ohci_tasks)) wake_up(&ohci_tasks); - } */ - if(ints & OHCI_INTR_WDH) { - writel(OHCI_INTR_WDH, ®s->intrdisable); - ohci->intrstatus &= (~OHCI_INTR_WDH); - usb_ohci_done_list(ohci); /* prepare out channel list */ - writel(OHCI_INTR_WDH, &ohci->regs->intrstatus); - writel(OHCI_INTR_WDH, &ohci->regs->intrenable); - - } + if(ints & OHCI_INTR_WDH) { + writel(OHCI_INTR_WDH, ®s->intrdisable); + usb_ohci_done_list(ohci, ohci_reverse_done_list(ohci)); + writel(OHCI_INTR_WDH, ®s->intrenable); + } - if(ints & OHCI_INTR_SF) { - writel(OHCI_INTR_SF, ®s->intrdisable); - writel(OHCI_INTR_SF, &ohci->regs->intrstatus); - ohci->intrstatus &= (~OHCI_INTR_SF); - if(ohci->ed_rm_list != NULL) { - ohci_rm_eds(ohci); - } - } -#ifndef VROOTHUB - if(ints & OHCI_INTR_RHSC) { - writel(OHCI_INTR_RHSC, ®s->intrdisable); - writel(OHCI_INTR_RHSC, &ohci->regs->intrstatus); - wake_up(&root_hub); - - } - #endif - - writel(OHCI_INTR_MIE, ®s->intrenable); - -} - -#ifndef VROOTHUB -/* - * This gets called if the connect status on the root - * hub (and the root hub only) changes. - */ -static void ohci_connect_change(struct ohci *ohci, unsigned int port_nr) -{ - struct usb_device *usb_dev; - struct ohci_device *dev; - struct ohci_device *tmp_root_hub=usb_to_ohci(ohci->bus->root_hub); - OHCI_DEBUG(printk("uhci_connect_change: called for %d stat %x\n", port_nr,readl(&ohci->regs->roothub.portstatus[port_nr]) );) - - /* - * Even if the status says we're connected, - * the fact that the status bits changed may - * that we got disconnected and then reconnected. - * - * So start off by getting rid of any old devices.. - */ - usb_disconnect(&tmp_root_hub->usb->children[port_nr]); - - if(!(readl(&ohci->regs->roothub.portstatus[port_nr]) & RH_PS_CCS)) { - writel(RH_PS_CCS, &ohci->regs->roothub.portstatus[port_nr]); - return; /* nothing connected */ + if(ints & OHCI_INTR_SO) { + printk("**** USB Schedule overrun "); + writel(OHCI_INTR_SO, ®s->intrenable); } - /* - * Ok, we got a new connection. Allocate a device to it, - * and find out what it wants to do.. - */ - usb_dev = sohci_usb_allocate(tmp_root_hub->usb); - dev = usb_dev->hcpriv; - dev->ohci = ohci; - usb_connect(dev->usb); - tmp_root_hub->usb->children[port_nr] = usb_dev; - wait_ms(200); /* wait for powerup */ - /* reset port/device */ - writel(RH_PS_PRS, &ohci->regs->roothub.portstatus[port_nr]); /* reset port */ - while(!(readl( &ohci->regs->roothub.portstatus[port_nr]) & RH_PS_PRSC)) wait_ms(10); /* reset active ? */ - writel(RH_PS_PES, &ohci->regs->roothub.portstatus[port_nr]); /* enable port */ - wait_ms(10); - /* Get speed information */ - usb_dev->slow = (readl( &ohci->regs->roothub.portstatus[port_nr]) & RH_PS_LSDA) ? 1 : 0; - /* - * Ok, all the stuff specific to the root hub has been done. - * The rest is generic for any new USB attach, regardless of - * hub type. - */ - usb_new_device(usb_dev); + if(ints & OHCI_INTR_SF) { + writel(OHCI_INTR_SF, ®s->intrdisable); + if(ohci->ed_rm_list != NULL) { + usb_ohci_done_list(ohci, usb_ohci_del_list(ohci)); + } + } + writel(ints, ®s->intrstatus); + writel(OHCI_INTR_MIE, ®s->intrenable); } -#endif - - - -/* - * Allocate the resources required for running an OHCI controller. - * Host controller interrupts must not be running while calling this - * function. - * - * The mem_base parameter must be the usable -virtual- address of the - * host controller's memory mapped I/O registers. - * - * This is where OHCI triumphs over UHCI, because good is dumb. - * Note how much simpler this function is than in uhci.c. - * - * OHCI hardware takes care of most of the scheduling of different - * transfer types with the correct prioritization for us. - */ +/* allocate OHCI */ static struct ohci *alloc_ohci(void* mem_base) { - int i,j; + int i; struct ohci *ohci; struct ohci_hc_area *hc_area; struct usb_bus *bus; - struct ohci_device *dev; - struct usb_device *usb; - /* - * Here we allocate some dummy EDs as well as the - * OHCI host controller communications area. The HCCA is just - * a nice pool of memory with pointers to endpoint descriptors - * for the different interrupts. - * - * The first page of memory contains the HCCA and ohci structure - */ hc_area = (struct ohci_hc_area *) __get_free_pages(GFP_KERNEL, 1); if (!hc_area) return NULL; + memset(hc_area, 0, sizeof(*hc_area)); ohci = &hc_area->ohci; ohci->irq = -1; - ohci->regs = mem_base; - + ohci->regs = mem_base; ohci->hc_area = hc_area; - /* Tell the controller where the HCCA is */ - writel(virt_to_bus(&hc_area->hcca), &ohci->regs->hcca); - - - /* - * Initialize the ED polling "tree", full tree; - * dummy eds ed[i] (hc should skip them) - * i == 0 is the end of the iso list; - * 1 is the 1ms node, - * 2,3 2ms nodes, - * 4,5,6,7 4ms nodes, - * 8 ... 15 8ms nodes, - * 16 ... 31 16ms nodes, - * 32 ... 63 32ms nodes - * Sequenzes: - * 32-16- 8-4-2-1-0 - * 33-17- 9-5-3-1-0 - * 34-18-10-6-2-1-0 - * 35-19-11-7-3-1-0 - * 36-20-12-4-2-1-0 - * 37-21-13-5-3-1-0 - * 38-22-14-6-2-1-0 - * 39-23-15-7-3-1-0 - * 40-24- 8-4-2-1-0 - * 41-25- 9-5-3-1-0 - * 42-26-10-6-2-1-0 - * : : - * 63-31-15-7-3-1-0 - */ - hc_area->ed[ED_ISO].info |= OHCI_ED_SKIP; /* place holder, so skip it */ - hc_area->ed[ED_ISO].next_ed = 0x0000; /* end of iso list */ - - hc_area->ed[1].next_ed = virt_to_bus(&(hc_area->ed[ED_ISO])); - hc_area->ed[1].info |= OHCI_ED_SKIP; /* place holder, skip it */ - - j=1; - for (i = 2; i < (NUM_INTS * 2); i++) { - if (i >= NUM_INTS) - hc_area->hcca.int_table[i - NUM_INTS] = virt_to_bus(&(hc_area->ed[i])); - - if( i == j*4) j *= 2; - hc_area->ed[i].next_ed = virt_to_bus(&(hc_area->ed[j+ i%j])); - hc_area->ed[i].info |= OHCI_ED_SKIP; /* place holder, skip it */ - } - - + __ohci = ohci; /* * for load ballancing of the interrupt branches */ for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0; - + for (i = 0; i < NUM_INTS; i++) hc_area->hcca.int_table[i] = 0; + /* * Store the end of control and bulk list eds. So, we know where we can add * elements to these lists. */ - ohci->ed_isotail = (struct usb_ohci_ed *) &(hc_area->ed[ED_ISO]); - ohci->ed_controltail = NULL; - ohci->ed_bulktail = NULL; - - /* - * Tell the controller where the control and bulk lists are - * The lists are empty now. - */ - writel(0, &ohci->regs->ed_controlhead); - writel(0, &ohci->regs->ed_bulkhead); - - - USB_ALLOC(bus, sizeof(*bus)); - if (!bus) + ohci->ed_isotail = NULL; + ohci->ed_controltail = NULL; + ohci->ed_bulktail = NULL; + + bus = usb_alloc_bus(&sohci_device_operations); + if (!bus) { + free_pages((unsigned int) ohci->hc_area, 1); return NULL; - - memset(bus, 0, sizeof(*bus)); + } ohci->bus = bus; bus->hcpriv = (void *) ohci; - bus->op = &sohci_device_operations; - - - usb = sohci_usb_allocate(NULL); - if (!usb) - return NULL; - - dev = usb_to_ohci(usb); - usb->bus = bus; - bus->root_hub = usb; - dev->ohci = ohci; - - /* Initialize the root hub */ - - usb->maxchild = readl(&ohci->regs->roothub.a) & 0xff; - usb_init_root_hub(usb); - + return ohci; } /* * De-allocate all resources.. - */ - + * */ static void release_ohci(struct ohci *ohci) { - int i; - struct ohci_device *tmp_root_hub=usb_to_ohci(ohci->bus->root_hub); - union ep_addr_ ep_addr; - ep_addr.iep = 0; OHCI_DEBUG(printk("USB HC release ohci \n");); - + /* stop hc */ + + + + /* disconnect all devices */ + if(ohci->bus->root_hub) usb_disconnect(&ohci->bus->root_hub); + + reset_hc(__ohci); + writel(OHCI_USB_RESET, &ohci->regs->control); + wait_ms(10); + if (ohci->irq >= 0) { free_irq(ohci->irq, ohci); ohci->irq = -1; } - /* stop hc */ - writel(OHCI_USB_SUSPEND, &ohci->regs->control); - - /* deallocate all EDs and TDs */ - for(i=0; i < 128; i ++) { - ep_addr.bep.fa = i; - usb_ohci_rm_function(ohci, ep_addr.iep); - } - ohci_rm_eds(ohci); /* remove eds */ - - /* disconnect all devices */ - if(ohci->bus->root_hub) - for(i = 0; i < tmp_root_hub->usb->maxchild; i++) - usb_disconnect(tmp_root_hub->usb->children + i); - usb_deregister_bus(ohci->bus); - USB_FREE(tmp_root_hub->usb); - USB_FREE(tmp_root_hub); - USB_FREE(ohci->bus); + usb_free_bus(ohci->bus); /* unmap the IO address space */ iounmap(ohci->regs); - free_pages((unsigned int) ohci->hc_area, 1); - + free_pages((unsigned int) ohci->hc_area, 1); } -static int ohci_roothub_thread(void * __ohci) -{ - struct ohci *ohci = (struct ohci *)__ohci; - lock_kernel(); - - /* - * This thread doesn't need any user-level access, - * so get rid of all our resources.. - */ - printk("ohci_roothub_thread at %p\n", &ohci_roothub_thread); - exit_mm(current); - exit_files(current); - exit_fs(current); - - - strcpy(current->comm, "root-hub"); - - - start_hc(ohci); - writel( 0x10000, &ohci->regs->roothub.status); - wait_ms(50); /* root hub power on */ - usb_register_bus(ohci->bus); - do { -#ifdef CONFIG_APM - if (apm_resume) { - apm_resume = 0; - start_hc(ohci); - continue; - } -#endif - - OHCI_DEBUG(printk("USB RH tasks: int: %x\n",ohci->intrstatus);); -#ifndef VROOTHUB - /* if (ohci->intrstatus & OHCI_INTR_RHSC) */ - { - int port_nr; - for(port_nr=0; port_nr< ohci->root_hub->usb->maxchild; port_nr++) - if(readl(&ohci->regs->roothub.portstatus[port_nr]) & (RH_PS_CSC | RH_PS_PRSC)) { - ohci_connect_change(ohci, port_nr); - writel(0xffff0000, &ohci->regs->roothub.portstatus[port_nr]); - } - ohci->intrstatus &= ~(OHCI_INTR_RHSC); - writel(OHCI_INTR_RHSC, &ohci->regs->intrenable); - } -#endif - - interruptible_sleep_on(&root_hub); - - } while (!signal_pending(current)); - -#ifdef VROOTHUB - ohci_del_rh_int_timer(ohci); -#endif - - - cleanup_drivers(); - /* reset_hc(ohci); */ - - release_ohci(ohci); - MOD_DEC_USE_COUNT; - - printk("ohci_control_thread exiting\n"); - - return 0; -} /* * Increment the module usage count, start the control thread and * return success. - */ + * */ static int found_ohci(int irq, void* mem_base) { - int retval; struct ohci *ohci; OHCI_DEBUG(printk("USB HC found ohci: irq= %d membase= %x \n", irq, (int)mem_base);) - /* Allocate the running OHCI structures */ + ohci = alloc_ohci(mem_base); if (!ohci) { - return -ENOMEM; + return -ENOMEM; } - + reset_hc(ohci); - - retval = -EBUSY; - if (request_irq(irq, ohci_interrupt, SA_SHIRQ, "ohci-usb", ohci) == 0) { - int pid; - - MOD_INC_USE_COUNT; - ohci->irq = irq; - - pid = kernel_thread(ohci_roothub_thread, ohci, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); - if (pid >= 0) - return 0; - - - MOD_DEC_USE_COUNT; - retval = pid; - } + writel(OHCI_USB_RESET, &ohci->regs->control); + wait_ms(10); + usb_register_bus(ohci->bus); + if (request_irq(irq, ohci_interrupt, SA_SHIRQ, "ohci-usb", ohci) == 0) { + ohci->irq = irq; + start_hc(ohci); + return 0; + } release_ohci(ohci); - return retval; + return -EBUSY; } static int start_ohci(struct pci_dev *dev) { - unsigned int mem_base = dev->resource[0].flags; - - /* If its OHCI, its memory */ - if (mem_base & PCI_BASE_ADDRESS_SPACE_IO) - return -ENODEV; - - /* Get the memory address and map it for IO */ - mem_base = dev->resource[0].start; - - /* - * FIXME ioremap_nocache isn't implemented on all CPUs (such - * as the Alpha) [?] What should I use instead... - * - * The iounmap() is done on in release_ohci. - */ + unsigned int mem_base = dev->resource[0].start; + mem_base = (unsigned int) ioremap_nocache(mem_base, 4096); if (!mem_base) { printk("Error mapping OHCI memory\n"); return -EFAULT; } - return found_ohci(dev->irq, (void *) mem_base); } - #ifdef CONFIG_APM static int handle_apm_event(apm_event_t event) { @@ -1497,10 +1320,7 @@ break; } down = 0; - if (waitqueue_active(&root_hub)) { - apm_resume = 1; - wake_up(&root_hub); - } +// start_hc(ohci); break; } return 0; @@ -1508,41 +1328,34 @@ #endif #define PCI_CLASS_SERIAL_USB_OHCI 0x0C0310 -#define PCI_CLASS_SERIAL_USB_OHCI_PG 0x10 - int ohci_hcd_init(void) { - int retval; - struct pci_dev *dev = NULL; + struct pci_dev *dev = NULL; - retval = -ENODEV; - - dev = NULL; - while((dev = pci_find_class(PCI_CLASS_SERIAL_USB_OHCI, dev))) { /* OHCI */ - retval = start_ohci(dev); - if (retval < 0) break; - + while((dev = pci_find_class(PCI_CLASS_SERIAL_USB_OHCI, dev))) { + if (start_ohci(dev) < 0) return -ENODEV; + } #ifdef CONFIG_APM - apm_register_callback(&handle_apm_event); + apm_register_callback(&handle_apm_event); #endif return 0; - } - return retval; } #ifdef MODULE -int init_module(void){ +int init_module(void) +{ return ohci_hcd_init(); } void cleanup_module(void) -{ +{ # ifdef CONFIG_APM apm_unregister_callback(&handle_apm_event); # endif + release_ohci(__ohci); } #endif //MODULE diff -u --recursive --new-file v2.3.13/linux/drivers/usb/ohci-hcd.h linux/drivers/usb/ohci-hcd.h --- v2.3.13/linux/drivers/usb/ohci-hcd.h Mon May 31 09:01:50 1999 +++ linux/drivers/usb/ohci-hcd.h Wed Aug 18 16:22:23 1999 @@ -5,7 +5,7 @@ * * The OHCI HCD layer is a simple but nearly complete implementation of what the * USB people would call a HCD for the OHCI. - * (ISO comming soon, Bulk disabled, INT u. CTRL transfers enabled) + * (ISO comming soon, Bulk, INT u. CTRL transfers enabled) * The layer on top of it, is for interfacing to the alternate-usb device-drivers. * * [ This is based on Linus' UHCI code and gregs OHCI fragments (0.03c source tree). ] @@ -15,23 +15,26 @@ * [ $Log: ohci.c,v $ ] * [ Revision 1.1 1999/04/05 08:32:30 greg ] * - * + * v4.0 1999/08/18 * v2.1 1999/05/09 ep_addr correction, code clean up * v2.0 1999/05/04 * v1.0 1999/04/27 * ohci-hcd.h */ + +// #define OHCI_DBG /* printk some debug information */ + #include -#ifdef CONFIG_USB_OHCI_VROOTHUB +// #ifdef CONFIG_USB_OHCI_VROOTHUB #define VROOTHUB -#endif +// #endif /* enables virtual root hub * (root hub will be managed by the hub controller * hub.c of the alternate usb driver) - * last time I did more testing without virtual root hub - * -> the virtual root hub could be more unstable now */ + * must be on now + */ @@ -44,57 +47,63 @@ /* for readl writel functions */ #include #include - +struct usb_ohci_ed; /* for ED and TD structures */ typedef void * __OHCI_BAG; -typedef int (*f_handler )(void * ohci, unsigned int ep_addr, int cmd_len, void *cmd, void *data, int data_len, int status, __OHCI_BAG lw0, __OHCI_BAG lw1); +typedef int (*f_handler )(void * ohci, struct usb_ohci_ed *ed, void *data, int data_len, int status, __OHCI_BAG lw0, __OHCI_BAG lw1); + + +/* ED States */ +#define ED_NEW 0x00 +#define ED_UNLINK 0x01 +#define ED_OPER 0x02 +#define ED_STOP 0x03 +#define ED_DEL 0x04 +#define ED_RH 0x07 /* marker for RH ED */ + +#define ED_STATE(ed) (((ed)->hwINFO >> 29) & 0x7) +#define ED_setSTATE(ed,state) (ed)->hwINFO = ((ed)->hwINFO & ~(0x7 << 29)) | (((state)& 0x7) << 29) +#define ED_TYPE(ed) (((ed)->hwINFO >> 27) & 0x3) -struct ep_address { - __u8 ep; /* bit 7: IN/-OUT, 6,5: type 10..CTRL 00..ISO 11..BULK 10..INT, 3..0: ep nr */ - __u8 fa; /* function address */ - __u8 hc; - __u8 host; -}; +struct usb_ohci_ed { + __u32 hwINFO; + __u32 hwTailP; + __u32 hwHeadP; + __u32 hwNextED; + + void * buffer_start; + unsigned int len; + struct usb_ohci_ed *ed_prev; + __u8 int_period; + __u8 int_branch; + __u8 int_load; + __u8 int_interval; + +} __attribute((aligned(32))); -union ep_addr_ { - unsigned int iep; - struct ep_address bep; +struct usb_hcd_ed { + int endpoint; + int function; + int out; + int type; + int slow; + int maxpack; }; -/* - * ED and TD descriptors has to be 16-byte aligned - */ -struct ohci_hw_ed { - __u32 info; - __u32 tail_td; /* TD Queue tail pointer */ - __u32 head_td; /* TD Queue head pointer */ - __u32 next_ed; /* Next ED */ -} __attribute((aligned(16))); - - -struct usb_ohci_ed { - struct ohci_hw_ed hw; - /* struct ohci * ohci; */ - f_handler handler; - union ep_addr_ ep_addr; - struct usb_ohci_ed *ed_list; - struct usb_ohci_ed *ed_prev; -} __attribute((aligned(32))); +struct ohci_state { + int len; + int status; +}; - /* OHCI Hardware fields */ -struct ohci_hw_td { - __u32 info; - __u32 cur_buf; /* Current Buffer Pointer */ - __u32 next_td; /* Next TD Pointer */ - __u32 buf_end; /* Memory Buffer End Pointer */ -} __attribute((aligned(16))); + /* TD info field */ #define TD_CC 0xf0000000 -#define TD_CC_GET(td_p) ((td_p >>28) & 0x04) +#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f) +#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28) #define TD_EC 0x0C000000 #define TD_T 0x03000000 #define TD_T_DATA0 0x02000000 @@ -108,6 +117,9 @@ #define TD_DP_IN 0x00100000 #define TD_DP_OUT 0x00080000 +#define TD_ISO 0x00010000 +#define TD_DEL 0x00020000 + /* CC Codes */ #define TD_CC_NOERROR 0x00 #define TD_CC_CRC 0x01 @@ -124,20 +136,25 @@ #define TD_NOTACCESSED 0x0F +#define MAXPSW 2 -struct usb_ohci_td { - struct ohci_hw_td hw; - void * buffer_start; - f_handler handler; - struct usb_ohci_td *prev_td; - struct usb_ohci_ed *ep; - struct usb_ohci_td *next_dl_td; - __OHCI_BAG lw0; - __OHCI_BAG lw1; +struct usb_ohci_td { + __u32 hwINFO; + __u32 hwCBP; /* Current Buffer Pointer */ + __u32 hwNextTD; /* Next TD Pointer */ + __u32 hwBE; /* Memory Buffer End Pointer */ + __u16 hwPSW[MAXPSW]; + + __u32 type; + void * buffer_start; + f_handler handler; + struct usb_ohci_ed *ed; + struct usb_ohci_td *next_dl_td; + __OHCI_BAG lw0; + __OHCI_BAG lw1; } __attribute((aligned(32))); - /* TD types */ #define BULK 0x03 #define INT 0x01 @@ -153,30 +170,21 @@ #define ISO_IN 0x04 #define ISO_OUT 0x00 -struct ohci_rep_td { - int cmd_len; - void * cmd; - void * data; - int data_len; - f_handler handler; - struct ohci_rep_td *next_td; - int ep_addr; - __OHCI_BAG lw0; - __OHCI_BAG lw1; - __u32 status; -} __attribute((aligned(32))); +#define CTRL_SETUP 0x102 +#define CTRL_DATA_IN 0x206 +#define CTRL_DATA_OUT 0x202 +#define CTRL_STATUS_IN 0x306 +#define CTRL_STATUS_OUT 0x302 + + +#define SEND 0x00001000 +#define ST_ADDR 0x00002000 +#define ADD_LEN 0x00004000 +#define DEL 0x00008000 +#define DEL_ED 0x00040000 #define OHCI_ED_SKIP (1 << 14) -#define OHCI_ED_MPS (0x7ff << 16) -#define OHCI_ED_F_NORM (0) -#define OHCI_ED_F_ISOC (1 << 15) -#define OHCI_ED_S_LOW (1 << 13) -#define OHCI_ED_S_HIGH (0) -#define OHCI_ED_D (3 << 11) -#define OHCI_ED_D_IN (2 << 11) -#define OHCI_ED_D_OUT (1 << 11) -#define OHCI_ED_EN (0xf << 7) -#define OHCI_ED_FA (0x7f) + /* @@ -194,18 +202,6 @@ } __attribute((aligned(256))); - -#define ED_INT_1 1 -#define ED_INT_2 2 -#define ED_INT_4 4 -#define ED_INT_8 8 -#define ED_INT_16 16 -#define ED_INT_32 32 -#define ED_CONTROL 64 -#define ED_BULK 65 -#define ED_ISO 0 /* same as 1ms interrupt queue */ - - /* * This is the maximum number of root hub ports. I don't think we'll * ever see more than two as that's the space available on an ATX @@ -286,9 +282,19 @@ /* * Control register masks */ +#define OHCI_USB_RESET 0 #define OHCI_USB_OPER (2 << 6) #define OHCI_USB_SUSPEND (3 << 6) +struct virt_root_hub { + int devnum; /* Address of Root Hub endpoint */ + usb_device_irq handler; + void * dev_id; + void * int_addr; + int send; + int interval; + struct timer_list rh_int_timer; +}; /* * This is the full ohci controller description * @@ -298,78 +304,54 @@ struct ohci { - int irq; - struct ohci_regs *regs; /* OHCI controller's memory */ - struct ohci_hc_area *hc_area; /* hcca, int ed-tree, ohci itself .. */ - int root_hub_funct_addr; /* Address of Root Hub endpoint */ - int ohci_int_load[32]; /* load of the 32 Interrupt Chains (for load ballancing)*/ - struct usb_ohci_ed * ed_rm_list; /* list of all endpoints to be removed */ - struct usb_ohci_ed * ed_bulktail; /* last endpoint of bulk list */ - struct usb_ohci_ed * ed_controltail; /* last endpoint of control list */ - struct usb_ohci_ed * ed_isotail; /* last endpoint of iso list */ - struct usb_ohci_ed ed_rh_ep0; - struct usb_ohci_ed ed_rh_epi; - struct ohci_rep_td *td_rh_epi; - int intrstatus; - struct usb_ohci_ed *ed_func_ep0[128]; /* "hash"-table for ep to ed mapping */ - struct ohci_rep_td *repl_queue; /* for internal requests */ - int rh_int_interval; - int rh_int_timer; - struct usb_bus *bus; - - + int irq; + struct ohci_regs *regs; /* OHCI controller's memory */ + struct ohci_hc_area *hc_area; /* hcca, int ed-tree, ohci itself .. */ + + int ohci_int_load[32]; /* load of the 32 Interrupt Chains (for load ballancing)*/ + struct usb_ohci_ed * ed_rm_list; /* list of all endpoints to be removed */ + struct usb_ohci_ed * ed_bulktail; /* last endpoint of bulk list */ + struct usb_ohci_ed * ed_controltail; /* last endpoint of control list */ + struct usb_ohci_ed * ed_isotail; /* last endpoint of iso list */ + int intrstatus; + struct ohci_rep_td *repl_queue; /* for internal requests */ + int rh_int_interval; + int rh_int_timer; + struct usb_bus *bus; + struct virt_root_hub rh; }; -/* - * Warning: This constant must not be so large as to cause the - * ohci_device structure to exceed one 4096 byte page. Or "weird - * things will happen" as the alloc_ohci() function assumes that - * its less than one page at the moment. (FIXME) - */ -#define NUM_TDS 4 /* num of preallocated transfer descriptors */ -#define NUM_EDS 80 /* num of preallocated endpoint descriptors */ -struct ohci_hc_area { +#define NUM_TDS 0 /* num of preallocated transfer descriptors */ +#define NUM_EDS 32 /* num of preallocated endpoint descriptors */ +struct ohci_hc_area { struct ohci_hcca hcca; /* OHCI mem. mapped IO area 256 Bytes*/ - - struct ohci_hw_ed ed[NUM_EDS]; /* Endpoint Descriptors 80 * 16 : 1280 Bytes */ - struct ohci_hw_td td[NUM_TDS]; /* Transfer Descriptors 2 * 32 : 64 Bytes */ - struct ohci ohci; + struct ohci ohci; }; struct ohci_device { struct usb_device *usb; struct ohci *ohci; + struct usb_ohci_ed ed[NUM_EDS]; unsigned long data[16]; }; -#define ohci_to_usb(uhci) ((ohci)->usb) +#define ohci_to_usb(ohci) ((ohci)->usb) #define usb_to_ohci(usb) ((struct ohci_device *)(usb)->hcpriv) -/* Debugging code */ -/*void show_ed(struct ohci_ed *ed); -void show_td(struct ohci_td *td); -void show_status(struct ohci *ohci); */ - /* hcd */ -int ohci_trans_req(struct ohci * ohci, unsigned int ep_addr, int cmd_len, void *cmd, void * data, int data_len, __OHCI_BAG lw0, __OHCI_BAG lw1); -struct usb_ohci_ed *usb_ohci_add_ep(struct ohci * ohci, unsigned int ep_addr, int interval, int load, f_handler handler, int ep_size, int speed); -int usb_ohci_rm_function(struct ohci * ohci, unsigned int ep_addr); -int usb_ohci_rm_ep(struct ohci * ohci, struct usb_ohci_ed *ed); -struct usb_ohci_ed * ohci_find_ep(struct ohci *ohci, unsigned int ep_addr_in); - +struct usb_ohci_td * ohci_trans_req(struct ohci * ohci, struct usb_ohci_ed * ed, int cmd_len, void *cmd, void * data, int data_len, __OHCI_BAG lw0, __OHCI_BAG lw1, unsigned int type, f_handler handler); +struct usb_ohci_ed *usb_ohci_add_ep(struct usb_device * usb_dev, struct usb_hcd_ed * hcd_ed, int interval, int load); +int usb_ohci_rm_function(struct usb_device * usb_dev, f_handler handler, __OHCI_BAG lw0, __OHCI_BAG lw1); +int usb_ohci_rm_ep(struct usb_device * usb_dev, struct usb_ohci_ed *ed, f_handler handler, __OHCI_BAG lw0, __OHCI_BAG lw1, int send); +struct usb_ohci_ed * ohci_find_ep(struct usb_device * usb_dev, struct usb_hcd_ed *hcd_ed); + /* roothub */ -int ohci_del_rh_int_timer(struct ohci * ohci); -int ohci_init_rh_int_timer(struct ohci * ohci, int interval); -int root_hub_int_req(struct ohci * ohci, int cmd_len, void * ctrl, void * data, int data_len, __OHCI_BAG lw0, __OHCI_BAG lw1, f_handler handler); -int root_hub_send_irq(struct ohci * ohci, void * data, int data_len ); -int root_hub_control_msg(struct ohci *ohci, int cmd_len, void *rh_cmd, void *rh_data, int len, __OHCI_BAG lw0, __OHCI_BAG lw1, f_handler handler); -int queue_reply(struct ohci * ohci, unsigned int ep_addr, int cmd_len,void * cmd, void * data,int len, __OHCI_BAG lw0, __OHCI_BAG lw1, f_handler handler); -int send_replies(struct ohci * ohci); - - +int root_hub_control_msg(struct usb_device *usb_dev, unsigned int pipe, devrequest *cmd, void *data, int len); +int root_hub_release_irq(struct usb_device *usb_dev, void * ed); +void * root_hub_request_irq(struct usb_device *usb_dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id); /* Root-Hub Register info */ @@ -388,10 +370,10 @@ #ifdef OHCI_DBG -#define OHCI_FREE(x) kfree(x); printk("OHCI FREE: %d\n", -- __ohci_free_cnt) -#define OHCI_ALLOC(x,size) (x) = kmalloc(size, GFP_KERNEL); printk("OHCI ALLO: %d\n", ++ __ohci_free_cnt) -#define USB_FREE(x) kfree(x); printk("USB FREE: %d\n", -- __ohci_free1_cnt) -#define USB_ALLOC(x,size) (x) = kmalloc(size, GFP_KERNEL); printk("USB ALLO: %d\n", ++ __ohci_free1_cnt) +#define OHCI_FREE(x) kfree(x); printk("OHCI FREE: %d: %4x\n", -- __ohci_free_cnt, (unsigned int) x) +#define OHCI_ALLOC(x,size) (x) = kmalloc(size, GFP_KERNEL); printk("OHCI ALLO: %d: %4x\n", ++ __ohci_free_cnt,(unsigned int) x) +#define USB_FREE(x) kfree(x); printk("USB FREE: %d: %4x\n", -- __ohci_free1_cnt, (unsigned int) x) +#define USB_ALLOC(x,size) (x) = kmalloc(size, GFP_KERNEL); printk("USB ALLO: %d: %4x\n", ++ __ohci_free1_cnt, (unsigned int) x) static int __ohci_free_cnt = 0; static int __ohci_free1_cnt = 0; #else diff -u --recursive --new-file v2.3.13/linux/drivers/usb/ohci-root-hub.c linux/drivers/usb/ohci-root-hub.c --- v2.3.13/linux/drivers/usb/ohci-root-hub.c Mon May 10 10:18:34 1999 +++ linux/drivers/usb/ohci-root-hub.c Wed Aug 18 16:22:23 1999 @@ -3,11 +3,27 @@ * * (C) Copyright 1999 Roman Weissgaerber (weissg@vienna.at) * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * * The Root Hub is build into the HC (UHCI or OHCI) hardware. * This piece of code lets it look like it resides on the usb * like the other hubs. * (for anyone who wants to do a control operation on the root hub) - * + * + * v4.0 1999/08/18 * v2.1 1999/05/09 * v2.0 1999/05/04 * v1.0 1999/04/27 @@ -16,7 +32,6 @@ */ - #include #include #include @@ -31,7 +46,6 @@ #include "ohci-root-hub.h" - static __u8 root_hub_dev_des[] = { 0x12, /* __u8 bLength; */ @@ -85,7 +99,7 @@ 0x05, /* __u8 ep_bDescriptorType; Endpoint */ 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ 0x03, /* __u8 ep_bmAttributes; Interrupt */ - 0x40, /* __u16 ep_wMaxPacketSize; 64 Bytes */ + 0x08, /* __u16 ep_wMaxPacketSize; 8 Bytes */ 0x00, 0xff /* __u8 ep_bInterval; 255 ms */ }; @@ -108,385 +122,128 @@ }; */ +#define OK(x) len = (x); req_reply = 0; break +#define WR_RH_STAT(x) writel((x), &ohci->regs->roothub.status) +#define WR_RH_PORTSTAT(x) writel((x), &ohci->regs->roothub.portstatus[wIndex-1]) +#define RD_RH_STAT readl(&ohci->regs->roothub.status) +#define RD_RH_PORTSTAT readl(&ohci->regs->roothub.portstatus[wIndex-1]) -int root_hub_control_msg(struct ohci *ohci, int cmd_len, void *rh_cmd, void *rh_data, int leni, __OHCI_BAG lw0, __OHCI_BAG lw1, f_handler handler) +int root_hub_control_msg(struct usb_device *usb_dev, unsigned int pipe, devrequest * cmd, void *data, int leni) { - - __u32 stat; - __u32 rep_handler; - int req_reply=0; - union ep_addr_ ep_addr; - union ep_addr_ ep_addr_ret; - __u8 * cmd = rh_cmd; - __u8 * data = rh_data; - int i; + struct ohci * ohci = usb_dev->bus->hcpriv; + __u8 data_buf[16]; + int req_reply=4; + int len =leni; - __u8 bmRequestType = cmd[0]; - __u8 bRequest = cmd[1]; - __u16 wValue = cmd[3] << 8 | cmd [2]; - __u16 wIndex = cmd[5] << 8 | cmd [4]; - __u16 wLength = cmd[7] << 8 | cmd [6]; -printk("USB root hub: adr: %8x cmd(%8x): ", ohci->root_hub_funct_addr, 8); -for(i=0;i<8;i++) - printk("%2x", ((char *)rh_cmd)[i]); + __u16 bmRType_bReq = cmd->requesttype | (cmd->request << 8); + __u16 wValue = cpu_to_le16(cmd->value); + __u16 wIndex = cpu_to_le16(cmd->index); + __u16 wLength = cpu_to_le16(cmd->length); + + OHCI_DEBUG(printk("USB root hub: adr: %2x cmd(%1x): ", ohci->rh.devnum, 8);) + OHCI_DEBUG({ int i; for(i=0;i<8;i++) printk(" %02x", ((unsigned char *)cmd)[i]);}) + OHCI_DEBUG(printk(" ; \n");) -printk(" ; \n"); - - ep_addr_ret.iep = 0; - ep_addr_ret.bep.fa = ohci->root_hub_funct_addr; - ep_addr_ret.bep.ep = (bmRequestType & 0x80) | 0x40; - - switch (bmRequestType | bRequest << 8) { - /* Request Destination: - without flags: Device, - RH_INTERFACE: interface, - RH_ENDPOINT: endpoint, - RH_CLASS means HUB here, - RH_OTHER | RH_CLASS almost ever means HUB_PORT here - */ + switch (bmRType_bReq) { + /* Request Destination: + without flags: Device, + RH_INTERFACE: interface, + RH_ENDPOINT: endpoint, + RH_CLASS means HUB here, + RH_OTHER | RH_CLASS almost ever means HUB_PORT here + */ - case RH_GET_STATUS: - len = 2; - data[0] = 0x01; - data[1] = 0x00; - req_reply = RH_ACK; - break; - case RH_GET_STATUS | RH_INTERFACE: - len = 2; - data[0] = 0x00; - data[1] = 0x00; - req_reply = RH_ACK; - break; - case RH_GET_STATUS | RH_ENDPOINT: - len = 2; - data[0] = 0x00; - data[1] = 0x00; - req_reply = RH_ACK; - break; - case RH_GET_STATUS | RH_CLASS: /* HUB_STATUS */ - stat = readl(&ohci->regs->roothub.status) & 0x7fff7fff; /* bit 31 u. 15 has other meaning */ - data[0] = stat & 0xff; - data[1] = (stat >> 8) & 0xff; - data[2] = (stat >> 16) & 0xff; - data[3] = (stat >> 24) & 0xff; - len = 4; - req_reply = RH_ACK; - break; - case RH_GET_STATUS | RH_OTHER | RH_CLASS: /* PORT_STATUS */ - stat = readl(&ohci->regs->roothub.portstatus[wIndex-1]); - data[0] = stat & 0xff; - data[1] = (stat >> 8) & 0xff; - data[2] = (stat >> 16) & 0xff; - data[3] = (stat >> 24) & 0xff; - len = 4; - req_reply = RH_ACK; - printk("rh: stat %4x wIndex %4x;\n", stat , wIndex); - break; - - case RH_CLEAR_FEATURE: - switch (wValue) { - case (RH_DEVICE_REMOTE_WAKEUP): - default: - } - break; - - case RH_CLEAR_FEATURE | RH_ENDPOINT: - switch (wValue) { - case (RH_ENDPOINT_STALL): - len=0; - req_reply = RH_ACK; - break; - default: - } - break; - - case RH_CLEAR_FEATURE | RH_CLASS: - switch (wValue) { - /* case (RH_C_HUB_LOCAL_POWER): OHCI says: no switching of this one */ - case (RH_C_HUB_OVER_CURRENT): - writel(RH_PS_OCIC, &ohci->regs->roothub.status); - len=0; - req_reply = RH_ACK; - break; - default: - } - break; - case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: - switch (wValue) { - case (RH_PORT_ENABLE): - writel(RH_PS_CCS, &ohci->regs->roothub.portstatus[wIndex-1]); - len=0; - req_reply = RH_ACK; - break; - case (RH_PORT_SUSPEND): - writel(RH_PS_POCI, &ohci->regs->roothub.portstatus[wIndex-1]); - len=0; - req_reply = RH_ACK; - break; - case (RH_PORT_POWER): - writel(RH_PS_LSDA, &ohci->regs->roothub.portstatus[wIndex-1]); - len=0; - req_reply = RH_ACK; - break; - case (RH_C_PORT_CONNECTION): - writel(RH_PS_CSC, &ohci->regs->roothub.portstatus[wIndex-1]); - len=0; - req_reply = RH_ACK; - break; - case (RH_C_PORT_ENABLE): - writel(RH_PS_PESC, &ohci->regs->roothub.portstatus[wIndex-1]); - len=0; - req_reply = RH_ACK; - break; - case (RH_C_PORT_SUSPEND): - writel(RH_PS_PSSC, &ohci->regs->roothub.portstatus[wIndex-1]); - len=0; - req_reply = RH_ACK; - break; - case (RH_C_PORT_OVER_CURRENT): - writel(RH_PS_OCIC, &ohci->regs->roothub.portstatus[wIndex-1]); - len=0; - req_reply = RH_ACK; - break; - case (RH_C_PORT_RESET): - writel(RH_PS_PRSC, &ohci->regs->roothub.portstatus[wIndex-1]); - len=0; - req_reply = RH_ACK; - break; - /* - case (RH_PORT_CONNECTION): - case (RH_PORT_OVER_CURRENT): - case (RH_PORT_RESET): - case (RH_PORT_LOW_SPEED): - */ - default: - } - break; - case RH_SET_FEATURE: - switch (wValue) { - case (RH_DEVICE_REMOTE_WAKEUP): - default: - } - break; - - case RH_SET_FEATURE | RH_ENDPOINT: - switch (wValue) { - case (RH_ENDPOINT_STALL): - default: - } - break; - - case RH_SET_FEATURE | RH_CLASS: - switch (wValue) { - /* case (RH_C_HUB_LOCAL_POWER): Root Hub has no local Power - case (RH_C_HUB_OVER_CURRENT): */ - default: - } - break; - case RH_SET_FEATURE | RH_OTHER | RH_CLASS: - switch (wValue) { - case (RH_PORT_SUSPEND): - writel(RH_PS_PSS, &ohci->regs->roothub.portstatus[wIndex-1]); - len=0; - req_reply = RH_ACK; - break; - case (RH_PORT_RESET): - if((readl(&ohci->regs->roothub.portstatus[wIndex-1]) &1) != 0) /* BUG IN HUP CODE *********/ - writel(RH_PS_PRS, &ohci->regs->roothub.portstatus[wIndex-1]); - len=0; - req_reply = RH_ACK; - break; - case (RH_PORT_POWER): - writel(RH_PS_PPS, &ohci->regs->roothub.portstatus[wIndex-1]); - len=0; - req_reply = RH_ACK; - break; - case (RH_PORT_ENABLE): - writel(RH_PS_PES, &ohci->regs->roothub.portstatus[wIndex-1]); - len=0; - req_reply = RH_ACK; - break; - /* - case (RH_PORT_CONNECTION): - case (RH_PORT_OVER_CURRENT): - case (RH_PORT_LOW_SPEED): - case (RH_C_PORT_CONNECTION): - case (RH_C_PORT_ENABLE): - case (RH_C_PORT_SUSPEND): - case (RH_C_PORT_OVER_CURRENT): - case (RH_C_PORT_RESET): - */ - default: - } - break; - - case RH_SET_ADDRESS: - ohci->root_hub_funct_addr = wValue; - /* ohci->ed_func_ep0[wValue] = &ohci->ed_rh_ep0; - ohci->ed_func_ep0[wValue]->ep_addr.bep.fa = wValue; - ohci->ed_func_ep0[wValue]->ed_list = &ohci->ed_rh_epi; */ - ohci->ed_rh_epi.ed_list = NULL; - ohci->ed_rh_epi.ep_addr.bep.fa = wValue; - ohci->ed_rh_epi.ep_addr.bep.ep = 0xa1; /* Int in port 1 */ - ohci->ed_func_ep0[0]= NULL; - len = 0; - req_reply = RH_ACK; - break; - - case RH_GET_DESCRIPTOR: - switch ((wValue & 0xff00) >> 8) { - case (0x01): /* device descriptor */ - len = min(sizeof(root_hub_dev_des), wLength); - memcpy(data, root_hub_dev_des, len); - req_reply = RH_ACK; - break; - case (0x02): /* configuration descriptor */ - len = min(sizeof(root_hub_config_des), wLength); - memcpy(data, root_hub_config_des, len); - req_reply = RH_ACK; - break; - case (0x03): /* string descriptors */ - default: - } - break; - case RH_GET_DESCRIPTOR | RH_CLASS: - data[1] = 0x29; - stat = readl(&ohci->regs->roothub.a); - data[2] = stat & 0xff; /* number of ports */ - data[0] = (data[2] / 8) * 2 + 9; /* length of descriptor */ - if(data[0] > wLength) { - req_reply = RH_REQ_ERR; - break; - } - data[3] = (stat >> 8) & 0xff; - data[4] = (stat >> 16) & 0xff; - data[5] = (stat >> 24) & 0xff; - data[6] = 0; /* Root Hub needs no current from bus */ - stat = readl(&ohci->regs->roothub.b); - if(data[2] <= 8) { /* less than 8 Ports */ - data[7] = stat & 0xff; - data[8] = (stat >> 16) & 0xff; /* 0xff for USB Rev. 1.1 ?, stat >> 16 for USB Rev. 1.0 */ - } - else { - data[7] = stat & 0xff; - data[8] = (stat >> 8) & 0xff; - data[9] = (stat >> 16) & 0xff; /* 0xff for USB Rev. 1.1?, stat >> 16 for USB Rev. 1.0 */ - data[10] = (stat >> 24) & 0xff; /* 0xff for USB Rev. 1.1?, stat >> 24 for USB Rev. 1.0 */ - } - len = data[0]; - req_reply = RH_ACK; - break; - - case RH_SET_DESCRIPTOR: - break; - - case RH_GET_CONFIGURATION: - len = 1; - data[0] = 0x01; - req_reply = RH_ACK; - break; - - case RH_SET_CONFIGURATION: /* start it up */ - writel( 0x10000, &ohci->regs->roothub.status); - /*writel( OHCI_INTR_RHSC, &ohci->regs->intrenable);*/ - len = 0; - req_reply = RH_ACK; - break; - /* Optional or meaningless requests - case RH_GET_STATE | RH_OTHER | RH_CLASS: - case RH_GET_INTERFACE | RH_INTERFACE: - case RH_SET_INTERFACE | RH_INTERFACE: - case RH_SYNC_FRAME | RH_ENDPOINT: - */ - - /* Vendor Requests, we are the vendor! - Will the USB-Consortium give us a Vendor Id - for a virtual hub-device :-) ? - We could use these requests for configuration purposes on the HCD Driver, not used in the altenate usb !*/ - - case RH_SET_FEATURE | RH_VENDOR: /* remove all endpoints of device wIndex = Dev << 8 */ - switch(wValue) { - case RH_REMOVE_EP: - ep_addr.iep = 0; - ep_addr.bep.ep = wIndex & 0xff; - ep_addr.bep.fa = (wIndex << 8) & 0xff00; - usb_ohci_rm_function(ohci, ep_addr.iep); - len=0; - req_reply = RH_ACK; - break; - } - break; - case RH_SET_FEATURE | RH_ENDPOINT | RH_VENDOR: /* remove endpoint wIndex = Dev << 8 | EP */ - switch(wValue) { - case RH_REMOVE_EP: - ep_addr.iep = 0; - ep_addr.bep.ep = wIndex & 0xff; - ep_addr.bep.fa = (wIndex << 8) & 0xff00; - usb_ohci_rm_ep(ohci, ohci_find_ep(ohci, ep_addr.iep)); - len=0; - req_reply = RH_ACK; - break; - } - break; - case RH_SET_EP | RH_ENDPOINT | RH_VENDOR: - ep_addr.bep.ep = data[0]; - ep_addr.bep.fa = data[1]; - ep_addr.bep.hc = data[2]; - ep_addr.bep.host = data[3]; - rep_handler = data[7] << 24 |data[6] << 16 | data[5] << 8 | data[4]; - /* struct usb_ohci_ed *usb_ohci_add_ep(union ep_addr_ ep_addr, - struct ohci * ohci, int interval, int load, int (*handler)(int, void*), int ep_size, int speed) */ - usb_ohci_add_ep(ohci, ep_addr.iep, data[8], data[9], (f_handler) rep_handler, data[11] << 8 | data[10] , data[12]); - len=0; - req_reply = RH_ACK; - break; - - default: - } - printk("USB HC roothubstat1: %x \n", readl( &(ohci->regs->roothub.portstatus[0]) )); - printk("USB HC roothubstat2: %x \n", readl( &(ohci->regs->roothub.portstatus[1]) )); - - /* if (req_reply == RH_ACK) len; */ - queue_reply(ohci, ep_addr_ret.iep, 8, rh_cmd, data, len, lw0, lw1, handler); - return 0; -} - -int root_hub_int_req(struct ohci * ohci, int cmd_len, void * ctrl, void * data, int data_len, __OHCI_BAG lw0, __OHCI_BAG lw1, f_handler handler){ + case RH_GET_STATUS: *(__u16 *)data = cpu_to_le16(1); OK(2); + case RH_GET_STATUS | RH_INTERFACE: *(__u16 *)data = cpu_to_le16(0); OK(2); + case RH_GET_STATUS | RH_ENDPOINT: *(__u16 *)data = cpu_to_le16(0); OK(2); + case RH_GET_STATUS | RH_CLASS: *(__u32 *)data = cpu_to_le32(RD_RH_STAT & 0x7fff7fff); OK(4); + case RH_GET_STATUS | RH_OTHER | RH_CLASS: *(__u32 *)data = cpu_to_le32(RD_RH_PORTSTAT); OK(4); + + case RH_CLEAR_FEATURE | RH_ENDPOINT: + switch (wValue) { + case (RH_ENDPOINT_STALL): OK(0); + } + break; + + case RH_CLEAR_FEATURE | RH_CLASS: + switch (wValue) { + case (RH_C_HUB_OVER_CURRENT): WR_RH_STAT(RH_PS_OCIC); OK(0); + } + break; + + case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: + switch (wValue) { + case (RH_PORT_ENABLE): WR_RH_PORTSTAT(RH_PS_CCS ); OK(0); + case (RH_PORT_SUSPEND): WR_RH_PORTSTAT(RH_PS_POCI); OK(0); + case (RH_PORT_POWER): WR_RH_PORTSTAT(RH_PS_LSDA); OK(0); + case (RH_C_PORT_CONNECTION): WR_RH_PORTSTAT(RH_PS_CSC ); OK(0); + case (RH_C_PORT_ENABLE): WR_RH_PORTSTAT(RH_PS_PESC); OK(0); + case (RH_C_PORT_SUSPEND): WR_RH_PORTSTAT(RH_PS_PSSC); OK(0); + case (RH_C_PORT_OVER_CURRENT): WR_RH_PORTSTAT(RH_PS_OCIC); OK(0); + case (RH_C_PORT_RESET): WR_RH_PORTSTAT(RH_PS_PRSC); OK(0); + } + break; + + case RH_SET_FEATURE | RH_OTHER | RH_CLASS: + switch (wValue) { + case (RH_PORT_SUSPEND): WR_RH_PORTSTAT(RH_PS_PSS ); OK(0); + case (RH_PORT_RESET): if((RD_RH_PORTSTAT &1) != 0) WR_RH_PORTSTAT(RH_PS_PRS ); /* BUG IN HUP CODE *********/ OK(0); + case (RH_PORT_POWER): WR_RH_PORTSTAT(RH_PS_PPS ); OK(0); + case (RH_PORT_ENABLE): WR_RH_PORTSTAT(RH_PS_PES ); OK(0); + } + break; + + case RH_SET_ADDRESS: ohci->rh.devnum = wValue; OK(0); + + case RH_GET_DESCRIPTOR: + switch ((wValue & 0xff00) >> 8) { + case (0x01): /* device descriptor */ + len = min(leni, min(sizeof(root_hub_dev_des), wLength)); + memcpy(data, root_hub_dev_des, len); OK(len); + case (0x02): /* configuration descriptor */ + len = min(leni, min(sizeof(root_hub_config_des), wLength)); + memcpy(data, root_hub_config_des, len); OK(len); + case (0x03): /* string descriptors */ + default: + } + break; + + case RH_GET_DESCRIPTOR | RH_CLASS: + *(__u8 *)(data_buf+1) = 0x29; + *(__u32 *)(data_buf+2) = cpu_to_le32(readl(&ohci->regs->roothub.a)); + *(__u8 *)data_buf = (*(__u8 *)(data_buf+2) / 8) * 2 + 9; /* length of descriptor */ + + len = min(leni, min(*(__u8 *)data_buf, wLength)); + *(__u8 *)(data_buf+6) = 0; /* Root Hub needs no current from bus */ + if(*(__u8 *)(data_buf+2) < 8) { /* less than 8 Ports */ + *(__u8 *) (data_buf+7) = readl(&ohci->regs->roothub.b) & 0xff; + *(__u8 *) (data_buf+8) = (readl(&ohci->regs->roothub.b) & 0xff0000) >> 16; + } + else { + *(__u32 *) (data_buf+7) = cpu_to_le32(readl(&ohci->regs->roothub.b)); + } + memcpy(data, data_buf, len); + OK(len); + + case RH_GET_CONFIGURATION: *(__u8 *)data = 0x01; OK(1); - struct ohci_rep_td *td; - struct ohci_rep_td *tmp; - union ep_addr_ ep_addr; - - td = kmalloc(sizeof(td),GFP_KERNEL); - tmp = ohci->td_rh_epi; - td->next_td = NULL; - if(tmp == NULL) { /* queue td */ - ohci->td_rh_epi = td; - } - else { - while(tmp->next_td != NULL) tmp = tmp->next_td; - tmp->next_td = td; - } - ep_addr.iep = 0; - ep_addr.bep.fa = ohci->root_hub_funct_addr; - ep_addr.bep.ep = 0xA1; /* INT IN EP endpoint 1 */ - td->cmd_len = 0; - td->cmd = NULL; - td->data = data; - td->data_len = data_len; - td->handler = handler; - td->next_td = NULL; - td->ep_addr = ep_addr.iep; - td->lw0 = lw0; - td->lw1 = lw1; - ohci_init_rh_int_timer(ohci, 255); - return 0; + case RH_SET_CONFIGURATION: WR_RH_STAT( 0x10000); OK(0); + } + + OHCI_DEBUG(printk("USB HC roothubstat1: %x \n", readl( &(ohci->regs->roothub.portstatus[0]) ));) + OHCI_DEBUG(printk("USB HC roothubstat2: %x \n", readl( &(ohci->regs->roothub.portstatus[1]) ));) + + OHCI_DEBUG( { int i; printk("USB HC RH bh <<<: 1: ");) + OHCI_DEBUG( printk(" data(%d):", len);) + OHCI_DEBUG( { for(i=0; i < len; i++ ) printk(" %02x", ((__u8 *) data)[i]);) + OHCI_DEBUG( printk(" ret_status: %x\n", req_reply); }) + + return req_reply; } - -/* prepare Interrupt pipe transaction data; HUP INTERRUPT ENDPOINT */ -int root_hub_send_irq(struct ohci * ohci, void * rh_data, int rh_len ) { +/* prepare Interrupt pipe transaction data; HUB INTERRUPT ENDPOINT */ +static int root_hub_send_irq(struct ohci * ohci, void * rh_data, int rh_len ) { int num_ports; int i; @@ -496,12 +253,12 @@ __u8 * data = rh_data; num_ports = readl(&ohci->regs->roothub.a) & 0xff; - data[0] = (readl(&ohci->regs->roothub.status) & 0x00030000)>0?1:0; - ret = data[0]; + *(__u8 *)data = (readl(&ohci->regs->roothub.status) & 0x00030000)>0?1:0; + ret = *(__u8 *)data; for(i=0; i < num_ports; i++) { - data[i/8] |= ((readl(&ohci->regs->roothub.portstatus[i]) & 0x001f0000)>0?1:0) << ((i+1) % 8); - ret += data[i/8]; + *(__u8 *)(data+i/8) |= ((readl(&ohci->regs->roothub.portstatus[i]) & 0x001f0000)>0?1:0) << ((i+1) % 8); + ret += *(__u8 *)(data+i/8); } len = i/8 + 1; @@ -510,95 +267,79 @@ return RH_NACK; } - - - -static struct timer_list rh_int_timer; +static int ohci_init_rh_int_timer(struct usb_device * usb_dev, int interval); /* Virtual Root Hub INTs are polled by this timer every "intervall" ms */ static void rh_int_timer_do(unsigned long ptr) { int len; int interval; - struct ohci * ohci = (struct ohci *) ptr; - struct ohci_rep_td *td = ohci->td_rh_epi; + int ret; + + struct usb_device * usb_dev = (struct usb_device *) ptr; + struct ohci * ohci = usb_dev->bus->hcpriv; + struct ohci_device * dev = usb_to_ohci(usb_dev); - if(td != NULL) { /* if ther is a TD handle the INT request */ - - len = root_hub_send_irq(ohci, td->data, td->data_len ); - if(len > 0) { - ohci->td_rh_epi = td->next_td; - td->next_td = ohci->repl_queue; - ohci->repl_queue = td; - send_replies(ohci); + + if(ohci->rh.send) { + len = root_hub_send_irq(ohci, dev->data, 1 ); + + if(len > 0) { + OHCI_DEBUG({ int i; printk("USB HC IRQ <<<: RH data(%d):", len);) + OHCI_DEBUG( for(i=0; i < len; i++ ) printk(" %02x", ((__u8 *) dev->data)[i]);) + OHCI_DEBUG( printk(" ret_status: %x\n", 0); }) + + ret = ohci->rh.handler(0, dev->data, len, ohci->rh.dev_id); + if(ret <= 0)ohci->rh.send = 0; /* 0 .. do not requeue */ } } - interval = ohci->rh_int_interval; - init_timer(& rh_int_timer); - rh_int_timer.function = rh_int_timer_do; - rh_int_timer.data = (unsigned long) ohci; - rh_int_timer.expires = jiffies + (HZ * (interval<30?30: interval)) /1000; - add_timer(&rh_int_timer); + interval = ohci->rh.interval; + ohci_init_rh_int_timer(usb_dev, interval); } /* Root Hub INTs are polled by this timer */ -int ohci_init_rh_int_timer(struct ohci * ohci, int interval) { +static int ohci_init_rh_int_timer(struct usb_device * usb_dev, int interval) { + struct ohci * ohci = usb_dev->bus->hcpriv; - if(!(ohci->rh_int_timer)) { - ohci->rh_int_timer = 1; - ohci->rh_int_interval = interval; - init_timer(& rh_int_timer); - rh_int_timer.function = rh_int_timer_do; - rh_int_timer.data = (unsigned long) ohci; - rh_int_timer.expires = jiffies + (HZ * (interval<30?30: interval)) /1000; - add_timer(&rh_int_timer); - } + ohci->rh.interval = interval; + init_timer(& ohci->rh.rh_int_timer); + ohci->rh.rh_int_timer.function = rh_int_timer_do; + ohci->rh.rh_int_timer.data = (unsigned long) usb_dev; + ohci->rh.rh_int_timer.expires = jiffies + (HZ * (interval<30?30: interval)) /1000; + add_timer(&ohci->rh.rh_int_timer); + return 0; } -int ohci_del_rh_int_timer(struct ohci * ohci) { - del_timer(&rh_int_timer); +static int ohci_del_rh_int_timer(struct ohci * ohci) { + del_timer(&ohci->rh.rh_int_timer); return 0; } -/* for root hub replies, queue the reply, (it will be sent immediately now) */ - -int queue_reply(struct ohci * ohci, unsigned int ep_addr, int cmd_len,void * cmd, void * data,int len, __OHCI_BAG lw0, __OHCI_BAG lw1, f_handler handler) { - - struct ohci_rep_td *td; - int status = 0; -printk("queue_reply ep: %x len: %x\n", ep_addr, len); -td = kmalloc(sizeof(td), GFP_KERNEL); - - if (len < 0) { status = len; len = 0;} - td->cmd_len = cmd_len; - td->cmd = cmd; - td->data = data; - td->data_len = len; - td->handler = handler; - td->next_td = ohci->repl_queue; ohci->repl_queue = td; - td->ep_addr = ep_addr; - td->lw0 = lw0; - td->lw1 = lw1; - td->status = status; - send_replies(ohci); -return 0; +void * root_hub_request_irq(struct usb_device *usb_dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id) +{ + struct ohci * ohci = usb_dev->bus->hcpriv; + + OHCI_DEBUG( printk("USB HC-RH IRQ>>>: RH every %d ms\n", period);) + ohci->rh.handler = handler; + ohci->rh.dev_id = dev_id; + ohci->rh.send = 1; + ohci->rh.interval = period; + ohci_init_rh_int_timer(usb_dev, period); + return ohci->rh.int_addr = usb_to_ohci(usb_dev); } -/* for root hub replies; send the reply */ -int send_replies(struct ohci * ohci) { - struct ohci_rep_td *td; - struct ohci_rep_td *tmp; - - td = ohci->repl_queue; ohci->repl_queue = NULL; - while ( td != NULL) { - td->handler((void *) ohci, td->ep_addr,td->cmd_len,td->cmd, td->data, td->data_len, td->status, td->lw0, td->lw1); - tmp = td; - td = td->next_td; - - kfree(tmp); - } +int root_hub_release_irq(struct usb_device *usb_dev, void * ed) +{ + // struct usb_device *usb_dev = ((struct ohci_device *) ((unsigned int)ed & 0xfffff000))->usb; + struct ohci * ohci = usb_dev->bus->hcpriv; + + OHCI_DEBUG( printk("USB HC-RH RM_IRQ>>>:\n");) + ohci->rh.send = 0; + ohci_del_rh_int_timer(ohci); return 0; } + + #endif diff -u --recursive --new-file v2.3.13/linux/drivers/usb/ohci.c linux/drivers/usb/ohci.c --- v2.3.13/linux/drivers/usb/ohci.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/usb/ohci.c Wed Aug 18 16:22:23 1999 @@ -266,7 +266,7 @@ int_ed = &root_hub->ed[ms_to_ed_int(period)]; /* decide on what the status field should look like */ - req_status = ed_set_maxpacket(usb_maxpacket(ohci_to_usb(dev), pipe)) + req_status = ed_set_maxpacket(usb_maxpacket(ohci_to_usb(dev), pipe, usb_pipeout(pipe))) | ed_set_speed(usb_pipeslow(pipe)) | (usb_pipe_endpdev(pipe) & 0x7ff) | ed_set_type_isoc(isoc); @@ -943,7 +943,7 @@ struct ohci_device *dev = usb_to_ohci(usb); struct ohci_td *td; struct ohci_ed *interrupt_ed; /* endpoint descriptor for this irq */ - int maxps = usb_maxpacket(usb, pipe); + int maxps = usb_maxpacket(usb, pipe, usb_pipeout(pipe)); unsigned long flags; /* Get an ED and TD */ @@ -1011,7 +1011,7 @@ * * This function can NOT be called from an interrupt. */ -int ohci_release_irq(void* handle) +int ohci_release_irq(struct usb_device *usb, void* handle) { struct ohci_device *dev; struct ohci_td *int_td; @@ -1120,8 +1120,8 @@ * device number (function address), and type of TD. * */ - ohci_fill_ed(dev, control_ed, usb_maxpacket(usb,pipe), usb_pipeslow(pipe), - usb_pipe_endpdev(pipe), 0 /* normal TDs */); + ohci_fill_ed(dev, control_ed, usb_maxpacket(usb, pipe, usb_pipeout(pipe)), + usb_pipeslow(pipe), usb_pipe_endpdev(pipe), 0 /* normal TDs */); /* * Build the control TD @@ -1398,7 +1398,7 @@ /* Set the max packet size, device speed, endpoint number, usb * device number (function address), and type of TD. */ ohci_fill_ed(dev, bulk_ed, - usb_maxpacket(usb_dev, pipe), + usb_maxpacket(usb_dev, pipe, usb_pipeout(pipe)), usb_pipeslow(pipe), usb_pipe_endpdev(pipe), 0 /* bulk uses normal TDs */); @@ -1480,7 +1480,7 @@ if (bytes_transferred_p) *bytes_transferred_p = 0; - if (usb_endpoint_halted(usb_dev, usb_pipeendpoint(pipe)) + if (usb_endpoint_halted(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) && usb_clear_halt(usb_dev, usb_pipeendpoint(pipe) | (pipe & 0x80))) return USB_ST_STALL; @@ -1979,6 +1979,23 @@ return td_list; } /* ohci_reverse_donelist() */ +/* + * Look at the ed (and td if necessary) + * and return its direction as 0 = IN, 1 = OUT. + */ +int ed_get_dir (struct ohci_ed *ed, struct ohci_td *td) +{ + __u32 status; + + status = le32_to_cpu(ed->status) & OHCI_ED_D; /* keep only the Direction bits */ + if (status == OHCI_ED_D_IN) return 0; + if (status == OHCI_ED_D_OUT) return 1; + + /* but if status == 0 or 3, look at the td for the Direction */ + status = le32_to_cpu(td->info) & OHCI_TD_D; /* keep only the Direction bits */ + if (status == OHCI_TD_D_IN) return 0; + return 1; +} /* * Collect this interrupt's goodies off of the list of finished TDs @@ -2017,7 +2034,7 @@ if (cc == USB_ST_STALL) { /* mark endpoint as halted */ - usb_endpoint_halt(ed->ohci_dev->usb, ed_get_en(ed)); + usb_endpoint_halt(ed->ohci_dev->usb, ed_get_en(ed), ed_get_dir(ed, td)); } if (cc != 0 && ohci_ed_halted(ed) && !td_endofchain(*td)) { diff -u --recursive --new-file v2.3.13/linux/drivers/usb/printer.c linux/drivers/usb/printer.c --- v2.3.13/linux/drivers/usb/printer.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/usb/printer.c Wed Aug 18 16:22:23 1999 @@ -266,7 +266,7 @@ return -1; } - interface = dev->config->altsetting->interface; + interface = &dev->config[0].interface[0].altsetting[0]; /* Lets be paranoid (for the moment)*/ if (interface->bInterfaceClass != 7 || diff -u --recursive --new-file v2.3.13/linux/drivers/usb/proc_usb.c linux/drivers/usb/proc_usb.c --- v2.3.13/linux/drivers/usb/proc_usb.c Wed Jul 28 14:47:42 1999 +++ linux/drivers/usb/proc_usb.c Mon Aug 16 23:19:13 1999 @@ -213,7 +213,7 @@ const int active, char *buf, int *len) { int i, j; - struct usb_alternate_setting *as; + struct usb_interface *intf; if (!config) { /* getting these some in 2.3.7; none in 2.3.6 */ *len += sprintf (buf + *len, "(null Cfg. desc.)\n"); @@ -223,13 +223,13 @@ if (usb_dump_config_descriptor (config, active, buf, len) < 0) return -1; - for (i = 0; i < config->num_altsetting; i++) { - as = config->altsetting + i; - if ((as) == NULL) + for (i = 0; i < config->bNumInterfaces; i++) { + intf = config->interface + i; + if ((intf) == NULL) break; - for (j = 0; j < config->bNumInterfaces; j++) - if (usb_dump_interface (as->interface + j, buf, len) < 0) + for (j = 0; j < intf->num_altsetting; j++) + if (usb_dump_interface (intf->altsetting + j, buf, len) < 0) return -1; } diff -u --recursive --new-file v2.3.13/linux/drivers/usb/uhci.c linux/drivers/usb/uhci.c --- v2.3.13/linux/drivers/usb/uhci.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/usb/uhci.c Wed Aug 18 16:22:23 1999 @@ -63,7 +63,10 @@ #define UHCI_DEBUG /* - * Map status to standard result codes + * Map status to standard result codes. + * + * is ((td->status >> 16) & 0xff) [a.k.a. uhci_status_bits(td->status)] + * is True for output TDs and False for input TDs. */ static int uhci_map_status(int status, int dir_out) { @@ -109,19 +112,19 @@ /* locate the first failing td, if any */ do { - status = (tmp->status >> 16) & 0xff; + status = uhci_status_bits(tmp->status); if (status) { /* must reset the toggle on first error */ if (uhci_debug) { printk(KERN_DEBUG "Set toggle from %x rval %ld\n", (unsigned int)tmp, rval ? *rval : 0); } - usb_settoggle(dev->usb, usb_pipeendpoint(tmp->info), - usb_pipeout(tmp->info), (tmp->info >> 19) & 1); + usb_settoggle(dev->usb, uhci_endpoint(tmp->info), + uhci_packetout(tmp->info), uhci_toggle(tmp->info)); break; } else { if (rval) - *rval += (tmp->status & 0x3ff) + 1; + *rval += uhci_actual_length(tmp->status); } if ((tmp->link & UHCI_PTR_TERM) || (tmp->link & UHCI_PTR_QH)) @@ -153,7 +156,8 @@ if (status & 0x40) { /* endpoint has stalled - mark it halted */ - usb_endpoint_halt(dev->usb, usb_pipeendpoint(tmp->info)); + usb_endpoint_halt(dev->usb, uhci_endpoint(tmp->info), + uhci_packetout(tmp->info)); return USB_ST_STALL; } @@ -162,7 +166,7 @@ if (!rval) return USB_ST_DATAUNDERRUN; } - return uhci_map_status(status, usb_pipeout(tmp->info)); + return uhci_map_status(status, uhci_packetout(tmp->info)); } /* @@ -431,9 +435,8 @@ td->link = UHCI_PTR_TERM; /* Terminate */ td->status = status; /* In */ - td->info = destination | ((usb_maxpacket(usb_dev, pipe) - 1) << 21) | - (usb_gettoggle(usb_dev, usb_pipeendpoint(pipe), - usb_pipeout(pipe)) << 19); + td->info = destination | ((usb_maxpacket(usb_dev, pipe, usb_pipeout(pipe)) - 1) << 21) | + (usb_gettoggle(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) << TD_TOKEN_TOGGLE); td->buffer = virt_to_bus(dev->data); td->qh = qh; td->dev = dev; @@ -463,7 +466,7 @@ * * This function can NOT be called from an interrupt. */ -int uhci_release_irq(void *handle) +int uhci_release_irq(struct usb_device *usb, void *handle) { struct uhci_td *td; struct uhci_qh *qh; @@ -506,14 +509,14 @@ for (i = 0; i < isodesc->num; i++) { struct uhci_td *td = &isodesc->td[i]; char *cdata = uhci_ptr_to_virt(td->buffer); - int n = (td->status + 1) & 0x7FF; + int n = uhci_actual_length(td->status); if ((cdata != data) && (n)) memmove(data, cdata, n); #ifdef UHCI_DEBUG /* Debugging */ - if ((td->status >> 16) & 0xFF) + if (uhci_status_bits(td->status)) printk(KERN_DEBUG "error: %d %X\n", i, (td->status >> 16)); #endif @@ -782,15 +785,15 @@ struct uhci_td *first, *td, *prevtd; unsigned long destination, status; int ret, count; - int maxsze = usb_maxpacket(usb_dev, pipe); + int maxsze = usb_maxpacket(usb_dev, pipe, usb_pipeout(pipe)); __u32 nextlink; first = td = uhci_td_alloc(dev); if (!td) return -ENOMEM; - /* The "pipe" thing contains the destination in bits 8--18, 0x2D is SETUP */ - destination = (pipe & PIPE_DEVEP_MASK) | 0x2D; + /* The "pipe" thing contains the destination in bits 8--18. */ + destination = (pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; /* 3 errors */ status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_SPD | (3 << 27); @@ -804,11 +807,11 @@ /* * If direction is "send", change the frame from SETUP (0x2D) - * to OUT (0xE1). Else change it from SETUP to IN (0x69) + * to OUT (0xE1). Else change it from SETUP to IN (0x69). */ - destination ^= (0x2D ^ 0x69); /* SETUP -> IN */ + destination ^= (USB_PID_SETUP ^ USB_PID_IN); /* SETUP -> IN */ if (usb_pipeout(pipe)) - destination ^= (0xE1 ^ 0x69); /* IN -> OUT */ + destination ^= (USB_PID_OUT ^ USB_PID_IN); /* IN -> OUT */ prevtd = td; td = uhci_td_alloc(dev); @@ -828,7 +831,7 @@ pktsze = maxsze; /* Alternate Data0/1 (start with Data1) */ - destination ^= 1 << 19; + destination ^= 1 << TD_TOKEN_TOGGLE; td->status = status; /* Status */ td->info = destination | ((pktsze - 1) << 21); /* pktsze bytes of data */ @@ -848,8 +851,8 @@ /* * Build the final TD for control status */ - destination ^= (0xE1 ^ 0x69); /* OUT -> IN */ - destination |= 1 << 19; /* End in Data1 */ + destination ^= (USB_PID_OUT ^ USB_PID_IN); /* OUT -> IN */ + destination |= 1 << TD_TOKEN_TOGGLE; /* End in Data1 */ td->status = status | TD_CTRL_IOC; /* no limit on errors on final packet */ td->info = destination | (UHCI_NULL_DATA_SIZE << 21); /* 0 bytes of data */ @@ -962,13 +965,13 @@ struct uhci_td *first, *td, *prevtd; unsigned long destination, status; int ret; - int maxsze = usb_maxpacket(usb_dev, pipe); + int maxsze = usb_maxpacket(usb_dev, pipe, usb_pipeout(pipe)); - if (usb_endpoint_halted(usb_dev, usb_pipeendpoint(pipe)) && - usb_clear_halt(usb_dev, usb_pipeendpoint(pipe) | (pipe & 0x80))) + if (usb_endpoint_halted(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) && + usb_clear_halt(usb_dev, usb_pipeendpoint(pipe) | (pipe & USB_DIR_IN))) return USB_ST_STALL; - /* The "pipe" thing contains the destination in bits 8--18 */ + /* The "pipe" thing contains the destination in bits 8--18. */ destination = (pipe & PIPE_DEVEP_MASK) | usb_packetid (pipe); /* 3 errors */ @@ -991,7 +994,8 @@ td->status = status; /* Status */ td->info = destination | ((pktsze-1) << 21) | - (usb_gettoggle(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) << 19); /* pktsze bytes of data */ + (usb_gettoggle(usb_dev, usb_pipeendpoint(pipe), + usb_pipeout(pipe)) << TD_TOKEN_TOGGLE); /* pktsze bytes of data */ td->buffer = virt_to_bus(data); td->backptr = &prevtd->link; @@ -1049,10 +1053,10 @@ struct uhci_td *first, *td, *prevtd; struct uhci_qh *bulk_qh = uhci_qh_alloc(dev); unsigned long destination, status; - int maxsze = usb_maxpacket(usb_dev, pipe); + int maxsze = usb_maxpacket(usb_dev, pipe, usb_pipeout(pipe)); - /* The "pipe" thing contains the destination in bits 8--18, 0x69 is IN */ - destination = (pipe & 0x0007ff00) | usb_packetid(pipe); + /* The "pipe" thing contains the destination in bits 8--18. */ + destination = (pipe & PIPE_DEVEP_MASK) | usb_packetid(pipe); /* Infinite errors is 0 */ status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_SPD; @@ -1069,7 +1073,7 @@ td->status = status; /* Status */ td->info = destination | ((pktsze-1) << 21) | - (usb_gettoggle(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) << 19); /* pktsze bytes of data */ + (usb_gettoggle(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) << TD_TOKEN_TOGGLE); /* pktsze bytes of data */ td->buffer = virt_to_bus(data); td->backptr = &prevtd->link; td->qh = bulk_qh; @@ -1336,7 +1340,7 @@ list_del(&td->irq_list); INIT_LIST_HEAD(&td->irq_list); - if (td->completed(uhci_map_status(status, 0), + if (td->completed(uhci_map_status(uhci_status_bits(status), uhci_packetout(td->info)), bus_to_virt(td->buffer), -1, td->dev_id)) { list_add(&td->irq_list, &uhci->interrupt_list); @@ -1344,11 +1348,12 @@ if (!(td->status & TD_CTRL_IOS)) { struct usb_device *usb_dev = td->dev->usb; - usb_dotoggle(usb_dev, usb_pipeendpoint(td->info), usb_pipeout(td->info)); - td->info &= ~(1 << 19); /* clear data toggle */ - td->info |= usb_gettoggle(usb_dev, usb_pipeendpoint(td->info), usb_pipeout(td->info)) << 19; /* toggle between data0 and data1 */ + usb_dotoggle(usb_dev, uhci_endpoint(td->info), uhci_packetout(td->info)); + td->info &= ~(1 << TD_TOKEN_TOGGLE); /* clear data toggle */ + td->info |= usb_gettoggle(usb_dev, uhci_endpoint(td->info), + uhci_packetout(td->info)) << TD_TOKEN_TOGGLE; /* toggle between data0 and data1 */ td->status = (td->status & 0x2F000000) | TD_CTRL_ACTIVE | TD_CTRL_IOC; - /* The HC removes it, so readd it */ + /* The HC removes it, so re-add it */ uhci_insert_td_in_qh(td->qh, td); } } else if (td->flags & UHCI_TD_REMOVE) { @@ -1356,7 +1361,7 @@ /* marked for removal */ td->flags &= ~UHCI_TD_REMOVE; - usb_dotoggle(usb_dev, usb_pipeendpoint(td->info), usb_pipeout(td->info)); + usb_dotoggle(usb_dev, uhci_endpoint(td->info), uhci_packetout(td->info)); uhci_remove_qh(td->qh->skel, td->qh); uhci_qh_free(td->qh); uhci_td_free(td); @@ -1433,7 +1438,7 @@ /* Don't clobber the frame */ td->link = uhci->fl->frame[0]; td->status = TD_CTRL_IOC; - td->info = (15 << 21) | 0x7f69; /* (ignored) input packet, 16 bytes, device 127 */ + td->info = (15 << 21) | (0x7f << 8) | USB_PID_IN; /* (ignored) input packet, 16 bytes, device 127 */ td->buffer = 0; td->qh = NULL; diff -u --recursive --new-file v2.3.13/linux/drivers/usb/uhci.h linux/drivers/usb/uhci.h --- v2.3.13/linux/drivers/usb/uhci.h Mon Aug 9 14:59:23 1999 +++ linux/drivers/usb/uhci.h Tue Aug 17 16:47:26 1999 @@ -77,6 +77,9 @@ __u32 frame[1024]; } __attribute__((aligned(4096))); +/* + * for TD : + */ #define TD_CTRL_SPD (1 << 29) /* Short Packet Detect */ #define TD_CTRL_LS (1 << 26) /* Low Speed Device */ #define TD_CTRL_IOS (1 << 25) /* Isochronous Select */ @@ -88,10 +91,35 @@ #define TD_CTRL_NAK (1 << 19) /* NAK Received */ #define TD_CTRL_CRCTIME (1 << 18) /* CTC/Time Out Error */ #define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */ +#define TD_CTRL_ACTLEN_MASK 0x7ff /* actual length, encoded as n - 1 */ + +#define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \ + TD_CTRL_BABBLE | TD_CTRL_CRCTIME | TD_CTRL_BITSTUFF) + +#define uhci_status_bits(ctrl_sts) ((ctrl_sts >> 16) & 0xff) +#define uhci_actual_length(ctrl_sts) ((ctrl_sts + 1) & TD_CTRL_ACTLEN_MASK) /* 1-based */ #define uhci_ptr_to_virt(x) bus_to_virt(x & ~UHCI_PTR_BITS) +/* + * for TD : + */ #define UHCI_TD_REMOVE 0x0001 /* Remove when done */ + +/* + * for TD : (a.k.a. Token) + */ +#define TD_TOKEN_TOGGLE 19 + +#define uhci_maxlen(token) ((token) >> 21) +#define uhci_toggle(token) (((token) >> TD_TOKEN_TOGGLE) & 1) +#define uhci_endpoint(token) (((token) >> 15) & 0xf) +#define uhci_devaddr(token) (((token) >> 8) & 0x7f) +#define uhci_devep(token) (((token) >> 8) & 0x7ff) +#define uhci_packetid(token) ((token) & 0xff) +#define uhci_packetout(token) (uhci_packetid(token) != USB_PID_IN) +#define uhci_packetin(token) (uhci_packetid(token) == USB_PID_IN) + /* * The documentation says "4 words for hardware, 4 words for software". diff -u --recursive --new-file v2.3.13/linux/drivers/usb/usb-debug.c linux/drivers/usb/usb-debug.c --- v2.3.13/linux/drivers/usb/usb-debug.c Wed Jul 21 15:46:48 1999 +++ linux/drivers/usb/usb-debug.c Mon Aug 16 23:19:13 1999 @@ -13,28 +13,28 @@ usb_show_endpoint_descriptor(endpoint); } -static void usb_show_interface(struct usb_interface_descriptor *interface) +static void usb_show_interface(struct usb_interface_descriptor *altsetting) { int i; - usb_show_interface_descriptor(interface); - for (i = 0 ; i < interface->bNumEndpoints; i++) - usb_show_endpoint(interface->endpoint + i); + usb_show_interface_descriptor(altsetting); + for (i = 0 ; i < altsetting->bNumEndpoints; i++) + usb_show_endpoint(altsetting->endpoint + i); } static void usb_show_config(struct usb_config_descriptor *config) { int i, j; - struct usb_alternate_setting *as; + struct usb_interface *intf; usb_show_config_descriptor(config); - for (i = 0; i < config->num_altsetting; i++) { - as = config->altsetting + i; - if ((as) == NULL) + for (i = 0; i < config->bNumInterfaces; i++) { + intf = config->interface + i; + if ((intf) == NULL) break; - printk("\n Alternate Setting: %d\n", i); - for (j = 0 ; j < config->bNumInterfaces; j++) - usb_show_interface(as->interface + j); + printk("\n Interface: %d\n", i); + for (j = 0 ; j < intf->num_altsetting; j++) + usb_show_interface(intf->altsetting + j); } } @@ -99,7 +99,7 @@ void usb_show_interface_descriptor(struct usb_interface_descriptor * desc) { - printk(" Interface:\n"); + printk(" Alternate Setting: %2d\n", desc->bAlternateSetting); printk(" bLength = %4d%s\n", desc->bLength, desc->bLength == USB_DT_INTERFACE_SIZE ? "" : " (!!!)"); printk(" bDescriptorType = %02x\n", desc->bDescriptorType); @@ -113,10 +113,13 @@ void usb_show_endpoint_descriptor(struct usb_endpoint_descriptor * desc) { + char *bLengthCommentString = (USB_DT_AUCLSTEP_SIZE == desc->bLength) ? + " (!Audio)" : " (!!!)"; + char *EndpointType[4] = { "Control", "Isochronous", "Bulk", "Interrupt" }; printk(" Endpoint:\n"); printk(" bLength = %4d%s\n", desc->bLength, - desc->bLength == USB_DT_ENDPOINT_SIZE ? "" : " (!!!)"); + desc->bLength == USB_DT_ENDPOINT_SIZE ? "" : bLengthCommentString); printk(" bDescriptorType = %02x\n", desc->bDescriptorType); printk(" bEndpointAddress = %02x (%s)\n", desc->bEndpointAddress, (desc->bEndpointAddress & 0x80) ? "in" : "out"); @@ -124,6 +127,10 @@ EndpointType[3 & desc->bmAttributes]); printk(" wMaxPacketSize = %04x\n", desc->wMaxPacketSize); printk(" bInterval = %02x\n", desc->bInterval); + if (USB_DT_AUCLSTEP_SIZE == desc->bLength) { + printk(" bRefresh = %04x\n", desc->bRefresh); + printk(" bSynchAddress = %02x\n", desc->bSynchAddress); + } } void usb_show_hub_descriptor(struct usb_hub_descriptor * desc) diff -u --recursive --new-file v2.3.13/linux/drivers/usb/usb.c linux/drivers/usb/usb.c --- v2.3.13/linux/drivers/usb/usb.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/usb/usb.c Wed Aug 18 16:22:23 1999 @@ -329,7 +329,7 @@ return parsed;// + ptr[parsed]; } -static int usb_parse_interface(struct usb_device *dev, struct usb_interface_descriptor *interface, unsigned char *ptr, int len) +static int usb_parse_altsetting(struct usb_device *dev, struct usb_interface_descriptor *altsetting, unsigned char *ptr, int len) { int i; int parsed = usb_expect_descriptor(ptr, len, USB_DT_INTERFACE, USB_DT_INTERFACE_SIZE); @@ -338,35 +338,35 @@ if (parsed < 0) return parsed; - memcpy(interface, ptr + parsed, *ptr); + memcpy(altsetting, ptr + parsed, *ptr); len -= ptr[parsed]; parsed += ptr[parsed]; while((i=usb_check_descriptor(ptr+parsed, len, 0x24)) >= 0) { - usb_audio_interface(interface, ptr+parsed+i); + usb_audio_interface(altsetting, ptr+parsed+i); len -= ptr[parsed+i]; parsed += ptr[parsed+i]; } - if (interface->bNumEndpoints > USB_MAXENDPOINTS) { + if (altsetting->bNumEndpoints > USB_MAXENDPOINTS) { printk(KERN_WARNING "usb: too many endpoints.\n"); return -1; } - interface->endpoint = (struct usb_endpoint_descriptor *) - kmalloc(interface->bNumEndpoints * sizeof(struct usb_endpoint_descriptor), GFP_KERNEL); - if (!interface->endpoint) { + altsetting->endpoint = (struct usb_endpoint_descriptor *) + kmalloc(altsetting->bNumEndpoints * sizeof(struct usb_endpoint_descriptor), GFP_KERNEL); + if (!altsetting->endpoint) { printk(KERN_WARNING "usb: out of memory.\n"); return -1; } - memset(interface->endpoint, 0, interface->bNumEndpoints*sizeof(struct usb_endpoint_descriptor)); + memset(altsetting->endpoint, 0, altsetting->bNumEndpoints*sizeof(struct usb_endpoint_descriptor)); - for (i = 0; i < interface->bNumEndpoints; i++) { + for (i = 0; i < altsetting->bNumEndpoints; i++) { // if(((USB_DT_HID << 8) | 9) == *(unsigned short*)(ptr + parsed)) { // parsed += 9; /* skip over the HID descriptor for now */ // len -= 9; // } - retval = usb_parse_endpoint(dev, interface->endpoint + i, ptr + parsed, len); + retval = usb_parse_endpoint(dev, altsetting->endpoint + i, ptr + parsed, len); if (retval < 0) return retval; parsed += retval; @@ -377,10 +377,13 @@ static int usb_parse_config(struct usb_device *dev, struct usb_config_descriptor *config, unsigned char *ptr, int len) { - int i, j; + int i; int retval; - struct usb_alternate_setting *as; + struct usb_interface *intf; + struct usb_interface_descriptor as; /* This is needing for copying. */ int parsed = usb_expect_descriptor(ptr, len, USB_DT_CONFIG, 9); + unsigned short bNumInterfaces; + unsigned short bIntfaceNum = 0, bAltSetting = 0; if (parsed < 0) return parsed; @@ -389,65 +392,65 @@ len -= *ptr; parsed += *ptr; le16_to_cpus(&config->wTotalLength); + bNumInterfaces = config->bNumInterfaces; - if (config->bNumInterfaces > USB_MAXINTERFACES) { + if (bNumInterfaces > USB_MAXINTERFACES) { printk(KERN_WARNING "usb: too many interfaces.\n"); return -1; - } - config->altsetting = (struct usb_alternate_setting *) - kmalloc(USB_MAXALTSETTING * sizeof(struct usb_alternate_setting), GFP_KERNEL); - if (!config->altsetting) { + config->interface = (struct usb_interface *) + kmalloc(bNumInterfaces * sizeof(struct usb_interface), GFP_KERNEL); + if (!config->interface) { printk(KERN_WARNING "usb: out of memory.\n"); return -1; } - config->act_altsetting = 0; - config->num_altsetting = 1; + memset(config->interface, + 0, (bNumInterfaces) * sizeof(struct usb_interface)); - config->altsetting->interface = (struct usb_interface_descriptor *) - kmalloc(config->bNumInterfaces * sizeof(struct usb_interface_descriptor), GFP_KERNEL); - if (!config->altsetting->interface) { - printk(KERN_WARNING "usb: out of memory.\n"); - return -1; + for (i = 0; i < bNumInterfaces; i++) { + intf = (config->interface) +i; + /* We have at least one interface */ + intf->num_altsetting = 1; + intf->altsetting = (struct usb_interface_descriptor*) + kmalloc((USB_MAXALTSETTING +1) * sizeof(struct usb_interface_descriptor), GFP_KERNEL); + if (!config->interface[i].altsetting) { + printk(KERN_WARNING "usb: out of memory.\n"); + return -1; + } + memset(intf->altsetting, + 0, (USB_MAXALTSETTING+1) * sizeof(struct usb_interface_descriptor)); } - memset(config->altsetting->interface, - 0, config->bNumInterfaces*sizeof(struct usb_interface_descriptor)); - - for (i = 0; i < config->bNumInterfaces; i++) { - retval = usb_parse_interface(dev, config->altsetting->interface + i, ptr + parsed, len); + + /* Ok, we now have allocated the necessary structures, now decide + * where to put the parsed interface descriptors - sort by + * bAltSetting and bInterfaceNumber. + */ + while (len > 0) { + retval = usb_parse_altsetting(dev, &as, ptr + parsed, len); if (retval < 0) return parsed; // HACK -// return retval; + // return retval; parsed += retval; len -= retval; - } - - printk("parsed = %d len = %d\n", parsed, len); - - // now parse for additional alternate settings - for (j = 1; j < USB_MAXALTSETTING; j++) { - retval = usb_expect_descriptor(ptr + parsed, len, USB_DT_INTERFACE, 9); - if (retval) - break; - config->num_altsetting++; - as = config->altsetting + j; - as->interface = (struct usb_interface_descriptor *) - kmalloc(config->bNumInterfaces * sizeof(struct usb_interface_descriptor), GFP_KERNEL); - if (!as->interface) { - printk(KERN_WARNING "usb: out of memory.\n"); + bIntfaceNum = as.bInterfaceNumber; + if (bIntfaceNum > config->bNumInterfaces) { + printk(KERN_WARNING "usb: bInterfaceNumber %2u exceeding config->bNumINterfaces.\n", bIntfaceNum); + return -1; + } + bAltSetting = as.bAlternateSetting; + if (bAltSetting > USB_MAXALTSETTING) { + printk(KERN_WARNING "usb: illegal bAlternateSetting %2u.\n", bAltSetting); return -1; } - memset(as->interface, 0, config->bNumInterfaces * sizeof(struct usb_interface_descriptor)); - for (i = 0; i < config->bNumInterfaces; i++) { - retval = usb_parse_interface(dev, as->interface + i, - ptr + parsed, len); - if (retval < 0) - return parsed; - parsed += retval; - len -= retval; + if (bAltSetting > config->interface[bIntfaceNum].num_altsetting) { + config->interface[bIntfaceNum].num_altsetting = bAltSetting +1; } + memcpy( &(config->interface[bIntfaceNum].altsetting[bAltSetting]), + &as, sizeof(struct usb_interface_descriptor)); } + + printk("parsed = %d len = %d\n", parsed, len); return parsed; } @@ -484,44 +487,36 @@ { int c, a, i; struct usb_config_descriptor *cf; - struct usb_alternate_setting *as; - struct usb_interface_descriptor *ifp; + struct usb_interface *intf; + struct usb_interface_descriptor *as; if (!dev->config) return; for (c = 0; c < dev->descriptor.bNumConfigurations; c++) { cf = &dev->config[c]; - if (!cf->altsetting) + if (!cf->interface) break; - for (a = 0; a < cf->num_altsetting; a++) { - as = &cf->altsetting[a]; - if (as->interface == NULL) + for (a = 0; a < cf->bNumInterfaces; a++) { + intf = &cf->interface[a]; + if (intf->altsetting == NULL) break; - for(i=0;ibNumInterfaces;i++) { - ifp = &as->interface[i]; - if(ifp->endpoint==NULL) + for(i=0; i <= USB_MAXALTSETTING ;i++) { + as = &intf->altsetting[i]; + if(as->endpoint==NULL) break; - kfree(ifp->endpoint); + kfree(as->endpoint); } - kfree(as->interface); + kfree(intf->altsetting); } - kfree(cf->altsetting); + kfree(cf->interface); } kfree(dev->config); - for (i = 1; i < USB_MAXSTRINGS; ++i) { - if (dev->stringindex[i]) { - kfree(dev->stringindex[i]); - dev->stringindex[i] = 0; - } - } -#if 0 - if (dev->stringindex) - kfree(dev->stringindex); - if (dev->stringtable) - kfree(dev->stringtable); -#endif + if (dev->string) { + kfree(dev->string); + dev->string = 0; + } } void usb_init_root_hub(struct usb_device *dev) @@ -708,29 +703,39 @@ static void usb_set_maxpacket(struct usb_device *dev) { - int i; - int act_as = dev->actconfig->act_altsetting; - struct usb_alternate_setting *as = dev->actconfig->altsetting + act_as; + int i, j; + struct usb_interface *intf; for (i=0; iactconfig->bNumInterfaces; i++) { - struct usb_interface_descriptor *ip = &as->interface[i]; - struct usb_endpoint_descriptor *ep = ip->endpoint; - int e; - - for (e=0; ebNumEndpoints; e++) { - dev->epmaxpacket[ep[e].bEndpointAddress & 0x0f] = - ep[e].wMaxPacketSize; + intf = (dev->actconfig->interface) +i; + for (j = 0; j < intf->num_altsetting; j++) { + struct usb_interface_descriptor *as = intf->altsetting +j; + struct usb_endpoint_descriptor *ep = as->endpoint; + int e; + + for (e=0; ebNumEndpoints; e++) { + if (usb_endpoint_out(ep[e].bEndpointAddress)) + dev->epmaxpacketout[ep[e].bEndpointAddress & 0x0f] = + ep[e].wMaxPacketSize; + else + dev->epmaxpacketin[ep[e].bEndpointAddress & 0x0f] = + ep[e].wMaxPacketSize; + } } } } +/* + * endp: endpoint number in bits 0-3; + * direction flag in bit 7 (1 = IN, 0 = OUT) + */ int usb_clear_halt(struct usb_device *dev, int endp) { devrequest dr; int result; __u16 status; - //if (!usb_endpoint_halted(dev, endp)) + //if (!usb_endpoint_halted(dev, endp & 0x0f, usb_endpoint_out(endp))) // return 0; dr.requesttype = USB_RT_ENDPOINT; @@ -741,11 +746,11 @@ result = dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0); - /* dont clear if failed */ + /* don't clear if failed */ if (result) return result; -#if 1 /* lets be really tough */ +#if 1 /* let's be really tough */ dr.requesttype = 0x80 | USB_RT_ENDPOINT; dr.request = USB_REQ_GET_STATUS; dr.length = 2; @@ -758,11 +763,11 @@ if (status & 1) return 1; /* still halted */ #endif - usb_endpoint_running(dev, endp & 0x0f); + usb_endpoint_running(dev, endp & 0x0f, usb_endpoint_out(endp)); /* toggle is reset on clear */ - usb_settoggle(dev, endp & 0x0f, ((endp >> 7) & 1) ^ 1, 0); + usb_settoggle(dev, endp & 0x0f, usb_endpoint_out(endp), 0); return 0; } @@ -781,7 +786,7 @@ return -1; dev->ifnum = interface; - dev->actconfig->act_altsetting = alternate; + dev->actconfig->interface[interface].act_altsetting = alternate; usb_set_maxpacket(dev); return 0; } @@ -874,62 +879,6 @@ return parse; } -#if 0 -int usb_get_stringtable(struct usb_device *dev) -{ - int i; - int maxindex; - int langid; - unsigned char buffer[256]; - int totalchars; - struct usb_string_descriptor *sd = (struct usb_string_descriptor *)buffer; - char *string; - __u8 bLengths[USB_MAXSTRINGS+1]; - int j; - - dev->maxstring = 0; - if(usb_get_string(dev, 0, 0, buffer, 2) || - usb_get_string(dev, 0, 0, buffer, sd->bLength)) - return -1; - /* we are going to assume that the first ID is good */ - langid = le16_to_cpup(&sd->wData[0]); - - /* whip through and find total length and max index */ - for (maxindex = 1, totalchars = 0; maxindex<=USB_MAXSTRINGS; maxindex++) { - if(usb_get_string(dev, langid, maxindex, buffer, 2)) - break; - totalchars += (sd->bLength - 2)/2 + 1; - bLengths[maxindex] = sd->bLength; - } - if (--maxindex <= 0) - return -1; - - /* get space for strings and index */ - dev->stringindex = kmalloc(sizeof(char *) * (maxindex+1), GFP_KERNEL); - if (!dev->stringindex) - return -1; - dev->stringtable = kmalloc(totalchars, GFP_KERNEL); - if (!dev->stringtable) { - kfree(dev->stringindex); - dev->stringindex = NULL; - return -1; - } - - /* fill them in */ - memset(dev->stringindex, 0, sizeof(char *) * (maxindex+1)); - for (i=1, string = dev->stringtable; i <= maxindex; i++) { - if (usb_get_string(dev, langid, i, buffer, bLengths[i])) - continue; - dev->stringindex[i] = string; - for (j=0; j < (bLengths[i] - 2)/2; j++) { - *string++ = le16_to_cpup(&sd->wData[j]); - } - *string++ = '\0'; - } - dev->maxstring = maxindex; - return 0; -} -#endif char *usb_string(struct usb_device *dev, int index) { @@ -940,10 +889,10 @@ struct usb_string_descriptor desc; } u; - if (index <= 0 || index >= USB_MAXSTRINGS) + if (index <= 0) return 0; - if (dev->stringindex[index] != 0) - return dev->stringindex[index]; + if (dev->string) + kfree (dev->string); if (dev->string_langid == 0) { /* read string descriptor 0 */ @@ -968,7 +917,7 @@ ptr[i] = le16_to_cpup(&u.desc.wData[i]); ptr[i] = 0; - dev->stringindex[index] = ptr; + dev->string = ptr; return ptr; } @@ -985,7 +934,8 @@ dev->devnum); dev->maxpacketsize = 0; /* Default to 8 byte max packet size */ - dev->epmaxpacket[0] = 8; + dev->epmaxpacketin [0] = 8; + dev->epmaxpacketout[0] = 8; /* We still haven't set the Address yet */ addr = dev->devnum; @@ -998,7 +948,8 @@ return 1; } - dev->epmaxpacket[0] = dev->descriptor.bMaxPacketSize0; + dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0; + dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0; switch (dev->descriptor.bMaxPacketSize0) { case 8: dev->maxpacketsize = 0; break; case 16: dev->maxpacketsize = 1; break; @@ -1090,7 +1041,7 @@ int usb_release_irq(struct usb_device *dev, void* handle) { - return dev->bus->op->release_irq(handle); + return dev->bus->op->release_irq(dev, handle); } #ifdef CONFIG_PROC_FS diff -u --recursive --new-file v2.3.13/linux/drivers/usb/usb.h linux/drivers/usb/usb.h --- v2.3.13/linux/drivers/usb/usb.h Mon Aug 9 14:59:23 1999 +++ linux/drivers/usb/usb.h Wed Aug 18 16:22:23 1999 @@ -61,6 +61,7 @@ #define USB_DT_CONFIG_SIZE 9 #define USB_DT_INTERFACE_SIZE 9 #define USB_DT_ENDPOINT_SIZE 7 +#define USB_DT_AUCLSTEP_SIZE 9 /* Audio Classes are special */ #define USB_DT_HUB_NONVAR_SIZE 7 /* @@ -167,10 +168,9 @@ */ #define USB_MAXCONFIG 8 -#define USB_MAXALTSETTING 5 +#define USB_MAXALTSETTING 6 #define USB_MAXINTERFACES 32 #define USB_MAXENDPOINTS 32 -#define USB_MAXSTRINGS 32 struct usb_device_descriptor { __u8 bLength; @@ -197,6 +197,8 @@ __u8 bmAttributes; __u16 wMaxPacketSize; __u8 bInterval; + __u8 bRefresh; + __u8 bSynchAddress; void *audio; }; @@ -216,9 +218,10 @@ void *audio; }; -/* hack for alternate settings */ -struct usb_alternate_setting { - struct usb_interface_descriptor *interface; +struct usb_interface { + struct usb_interface_descriptor *altsetting; + int act_altsetting; /* active alternate setting */ + int num_altsetting; /* number of alternate settings */ }; /* Configuration descriptor information.. */ @@ -231,9 +234,7 @@ __u8 iConfiguration; __u8 bmAttributes; __u8 MaxPower; - int act_altsetting; /* active alternate setting */ - int num_altsetting; /* number of alternate settings */ - struct usb_alternate_setting *altsetting; + struct usb_interface *interface; }; /* String descriptor */ @@ -289,7 +290,7 @@ int (*control_msg)(struct usb_device *, unsigned int, devrequest *, void *, int); int (*bulk_msg)(struct usb_device *, unsigned int, void *, int,unsigned long *); void* (*request_irq)(struct usb_device *, unsigned int, usb_device_irq, int, void *); - int (*release_irq)(void* handle); + int (*release_irq)(struct usb_device *, void* handle); void *(*request_bulk)(struct usb_device *, unsigned int, usb_device_irq, void *, int, void *); int (*terminate_bulk)(struct usb_device *, void *); @@ -319,16 +320,18 @@ int slow; /* Slow device? */ int maxpacketsize; /* Maximum packet size; encoded as 0,1,2,3 = 8,16,32,64 */ unsigned int toggle[2]; /* one bit for each endpoint ([0] = IN, [1] = OUT) */ - unsigned int halted; /* endpoint halts */ + unsigned int halted[2]; /* endpoint halts; one bit per endpoint # & direction; */ + /* [0] = IN, [1] = OUT */ struct usb_config_descriptor *actconfig;/* the active configuration */ - int epmaxpacket[16]; /* endpoint specific maximums */ + int epmaxpacketin[16]; /* INput endpoint specific maximums */ + int epmaxpacketout[16]; /* OUTput endpoint specific maximums */ int ifnum; /* active interface number */ - struct usb_bus *bus; /* Bus we're apart of */ + struct usb_bus *bus; /* Bus we're part of */ struct usb_driver *driver; /* Driver */ struct usb_device_descriptor descriptor;/* Descriptor */ struct usb_config_descriptor *config; /* All of the configs */ struct usb_device *parent; - char *stringindex[USB_MAXSTRINGS]; /* pointers to strings */ + char *string; /* pointer to the last string read from the device */ int string_langid; /* language ID for strings */ /* @@ -397,7 +400,7 @@ * unsigned int. The encoding is: * * - max size: bits 0-1 (00 = 8, 01 = 16, 10 = 32, 11 = 64) - * - direction: bit 7 (0 = Host-to-Device, 1 = Device-to-Host) + * - direction: bit 7 (0 = Host-to-Device [Out], 1 = Device-to-Host [In]) * - device: bits 8-14 * - endpoint: bits 15-18 * - Data0/1: bit 19 @@ -410,8 +413,10 @@ * appropriately. */ -#define usb_maxpacket(dev,pipe) ((dev)->epmaxpacket[usb_pipeendpoint(pipe)]) -#define usb_packetid(pipe) (((pipe) & 0x80) ? 0x69 : 0xE1) +#define usb_maxpacket(dev, pipe, out) (out \ + ? (dev)->epmaxpacketout[usb_pipeendpoint(pipe)] \ + : (dev)->epmaxpacketin [usb_pipeendpoint(pipe)] ) +#define usb_packetid(pipe) (((pipe) & USB_DIR_IN) ? USB_PID_IN : USB_PID_OUT) #define usb_pipeout(pipe) ((((pipe) >> 7) & 1) ^ 1) #define usb_pipein(pipe) (((pipe) >> 7) & 1) @@ -433,10 +438,11 @@ #define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << ep)) #define usb_settoggle(dev, ep, out, bit) ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << ep)) | ((bit) << ep)) -/* Endpoint halt */ -#define usb_endpoint_halt(dev, ep) ((dev)->halted |= (1 << (ep))) -#define usb_endpoint_running(dev, ep) ((dev)->halted &= ~(1 << (ep))) -#define usb_endpoint_halted(dev, ep) ((dev)->halted & (1 << (ep))) +/* Endpoint halt control/status */ +#define usb_endpoint_out(ep_dir) (((ep_dir >> 7) & 1) ^ 1) +#define usb_endpoint_halt(dev, ep, out) ((dev)->halted[out] |= (1 << (ep))) +#define usb_endpoint_running(dev, ep, out) ((dev)->halted[out] &= ~(1 << (ep))) +#define usb_endpoint_halted(dev, ep, out) ((dev)->halted[out] & (1 << (ep))) static inline unsigned int __create_pipe(struct usb_device *dev, unsigned int endpoint) { @@ -450,13 +456,13 @@ /* Create various pipes... */ #define usb_sndctrlpipe(dev,endpoint) ((2 << 30) | __create_pipe(dev,endpoint)) -#define usb_rcvctrlpipe(dev,endpoint) ((2 << 30) | __create_pipe(dev,endpoint) | 0x80) +#define usb_rcvctrlpipe(dev,endpoint) ((2 << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) #define usb_sndisocpipe(dev,endpoint) ((0 << 30) | __create_pipe(dev,endpoint)) -#define usb_rcvisocpipe(dev,endpoint) ((0 << 30) | __create_pipe(dev,endpoint) | 0x80) +#define usb_rcvisocpipe(dev,endpoint) ((0 << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) #define usb_sndbulkpipe(dev,endpoint) ((3 << 30) | __create_pipe(dev,endpoint)) -#define usb_rcvbulkpipe(dev,endpoint) ((3 << 30) | __create_pipe(dev,endpoint) | 0x80) +#define usb_rcvbulkpipe(dev,endpoint) ((3 << 30) | __create_pipe(dev,endpoint) | USB_DIR_IN) #define usb_snddefctrl(dev) ((2 << 30) | __default_pipe(dev)) -#define usb_rcvdefctrl(dev) ((2 << 30) | __default_pipe(dev) | 0x80) +#define usb_rcvdefctrl(dev) ((2 << 30) | __default_pipe(dev) | USB_DIR_IN) /* * Send and receive control messages.. diff -u --recursive --new-file v2.3.13/linux/drivers/usb/usb_scsi.c linux/drivers/usb/usb_scsi.c --- v2.3.13/linux/drivers/usb/usb_scsi.c Wed Jul 28 14:47:42 1999 +++ linux/drivers/usb/usb_scsi.c Mon Aug 9 20:38:13 1999 @@ -130,7 +130,7 @@ static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length) { - int max_size = usb_maxpacket(us->pusb_dev, pipe) * 16; + int max_size = usb_maxpacket(us->pusb_dev, pipe, usb_pipeout(pipe)) * 16; int this_xfer; int result; unsigned long partial; diff -u --recursive --new-file v2.3.13/linux/drivers/usb/uss720.c linux/drivers/usb/uss720.c --- v2.3.13/linux/drivers/usb/uss720.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/usb/uss720.c Thu Aug 12 11:50:15 1999 @@ -29,12 +29,12 @@ * usb_request_irq crashes somewhere within ohci.c * for no apparent reason (that is for me, anyway) * ECP currently untested + * 0.3 10.08.99 fixing merge errors * */ /*****************************************************************************/ -#include #include #include #include @@ -187,10 +187,6 @@ * Access functions. */ -static void parport_uss720_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ -} - static int uss720_irq(int usbstatus, void *buffer, int len, void *dev_id) { struct parport *pp = (struct parport *)dev_id; @@ -653,16 +649,13 @@ /* --------------------------------------------------------------------- */ -#define __exit -#define module_exit(x) void cleanup_module(void) { x(); } -#define module_init(x) int init_module(void) { return x(); } - -/* --------------------------------------------------------------------- */ +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch"); +MODULE_DESCRIPTION("USB Parport Cable driver for Cables using the Lucent Technologies USS720 Chip"); static int __init uss720_init(void) { usb_register(&uss720_driver); - printk(KERN_INFO "uss720: USB<->IEEE1284 cable driver v0.2 registered.\n" + printk(KERN_INFO "uss720: USB<->IEEE1284 cable driver v0.3 registered.\n" KERN_INFO "uss720: (C) 1999 by Thomas Sailer, \n"); return 0; } diff -u --recursive --new-file v2.3.13/linux/drivers/video/Config.in linux/drivers/video/Config.in --- v2.3.13/linux/drivers/video/Config.in Mon Aug 9 14:59:23 1999 +++ linux/drivers/video/Config.in Wed Aug 18 10:10:06 1999 @@ -6,6 +6,7 @@ define_bool CONFIG_DUMMY_CONSOLE y if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_PCI" = "y" ]; then + tristate 'Cirrus Logic suport (experimental)' CONFIG_FB_CLGEN bool 'Permedia2 support (experimental)' CONFIG_FB_PM2 if [ "$CONFIG_FB_PM2" = "y" ]; then if [ "$CONFIG_PCI" = "y" ]; then @@ -43,7 +44,6 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then bool 'Amiga CyberVision3D support (experimental)' CONFIG_FB_VIRGE tristate 'Amiga RetinaZ3 support' CONFIG_FB_RETINAZ3 - tristate 'Amiga CLgen driver' CONFIG_FB_CLGEN bool 'Amiga FrameMaster II/Rainbow II support (experimental)' CONFIG_FB_FM2 fi fi diff -u --recursive --new-file v2.3.13/linux/drivers/video/Makefile linux/drivers/video/Makefile --- v2.3.13/linux/drivers/video/Makefile Mon Aug 9 14:59:23 1999 +++ linux/drivers/video/Makefile Wed Aug 18 10:10:06 1999 @@ -37,7 +37,7 @@ ifeq ($(CONFIG_FB),y) L_OBJS += fonts.o - OX_OBJS += fbcon.o fbcmap.o fbmem.o + OX_OBJS += fbcon.o fbcmap.o fbmem.o modedb.o ifeq ($(CONFIG_FONT_8x8),y) L_OBJS += font_8x8.o endif diff -u --recursive --new-file v2.3.13/linux/drivers/video/S3triofb.c linux/drivers/video/S3triofb.c --- v2.3.13/linux/drivers/video/S3triofb.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/video/S3triofb.c Thu Aug 12 10:22:33 1999 @@ -99,7 +99,7 @@ * Interface to the low level console driver */ -void s3triofb_init(void); +int s3triofb_init(void); static int s3triofbcon_switch(int con, struct fb_info *info); static int s3triofbcon_updatevar(int con, struct fb_info *info); static void s3triofbcon_blank(int blank, struct fb_info *info); @@ -288,7 +288,7 @@ return -EINVAL; } -void __init s3triofb_init(void) +int __init s3triofb_init(void) { #ifdef __powerpc__ /* We don't want to be called like this. */ @@ -296,6 +296,7 @@ #else /* !__powerpc__ */ /* To be merged with cybervision */ #endif /* !__powerpc__ */ + return 0; } void __init s3trio_resetaccel(void){ @@ -721,9 +722,9 @@ s3trio_setcolreg, &fb_info); } -void s3triofb_setup(char *options, int *ints) { +int s3triofb_setup(char *options) { - return; + return 0; } diff -u --recursive --new-file v2.3.13/linux/drivers/video/acornfb.c linux/drivers/video/acornfb.c --- v2.3.13/linux/drivers/video/acornfb.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/video/acornfb.c Thu Aug 12 10:22:33 1999 @@ -1728,14 +1728,14 @@ { NULL, NULL } }; -void __init -acornfb_setup(char *options, int *ints) +int __init +acornfb_setup(char *options) { struct options *optp; char *opt; if (!options || !*options) - return; + return 0; acornfb_init_fbinfo(); @@ -1759,6 +1759,7 @@ printk(KERN_ERR "acornfb: unknown parameter: %s\n", opt); } + return 0; } /* @@ -1802,7 +1803,7 @@ printk("acornfb: freed %dK memory\n", mb_freed); } -void __init +int __init acornfb_init(void) { unsigned long size; @@ -1904,5 +1905,7 @@ VIDC_NAME, init_var.xres, init_var.yres, h_sync / 1000, h_sync % 1000, v_sync); - register_framebuffer(&fb_info); + if (register_framebuffer(&fb_info) < 0) + return -EINVAL; + return 0; } diff -u --recursive --new-file v2.3.13/linux/drivers/video/amifb.c linux/drivers/video/amifb.c --- v2.3.13/linux/drivers/video/amifb.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/video/amifb.c Wed Aug 18 10:10:29 1999 @@ -805,138 +805,86 @@ * */ -static struct fb_videomode amifb_predefined[] __initdata = { +static struct fb_videomode ami_modedb[] __initdata = { /* * AmigaOS Video Modes + * + * If you change these, make sure to update DEFMODE_* as well! */ { - "ntsc", { /* 640x200, 15 kHz, 60 Hz (NTSC) */ - 640, 200, 640, 200, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_HIRES, 106, 86, 44, 16, 76, 2, - FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - } + /* 640x200, 15 kHz, 60 Hz (NTSC) */ + "ntsc", 60, 640, 200, TAG_HIRES, 106, 86, 44, 16, 76, 2, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { - "ntsc-lace", { /* 640x400, 15 kHz, 60 Hz interlaced (NTSC) */ - 640, 400, 640, 400, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_HIRES, 106, 86, 88, 33, 76, 4, - FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP - } + /* 640x400, 15 kHz, 60 Hz interlaced (NTSC) */ + "ntsc-lace", 60, 640, TAG_HIRES, 106, 86, 88, 33, 76, 4, + FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP }, { - "pal", { /* 640x256, 15 kHz, 50 Hz (PAL) */ - 640, 256, 640, 256, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_HIRES, 106, 86, 40, 14, 76, 2, - FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - } + /* 640x256, 15 kHz, 50 Hz (PAL) */ + "pal", 50, 640, 256, TAG_HIRES, 106, 86, 40, 14, 76, 2, + FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { - "pal-lace", { /* 640x512, 15 kHz, 50 Hz interlaced (PAL) */ - 640, 512, 640, 512, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_HIRES, 106, 86, 80, 29, 76, 4, - FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP - } + /* 640x512, 15 kHz, 50 Hz interlaced (PAL) */ + "pal-lace", 50, 640, 512, TAG_HIRES, 106, 86, 80, 29, 76, 4, + FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP }, { - "multiscan", { /* 640x480, 29 kHz, 57 Hz */ - 640, 480, 640, 480, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_SHRES, 96, 112, 29, 8, 72, 8, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - } + /* 640x480, 29 kHz, 57 Hz */ + "multiscan", 57, 640, 480, TAG_SHRES, 96, 112, 29, 8, 72, 8, + 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { - "multiscan-lace", { /* 640x960, 29 kHz, 57 Hz interlaced */ - 640, 960, 640, 960, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_SHRES, 96, 112, 58, 16, 72, 16, - 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP - } + /* 640x960, 29 kHz, 57 Hz interlaced */ + "multiscan-lace", 57, 640, 960, TAG_SHRES, 96, 112, 58, 16, 72, 16, + 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP }, { - "euro36", { /* 640x200, 15 kHz, 72 Hz */ - 640, 200, 640, 200, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_HIRES, 92, 124, 6, 6, 52, 5, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - } + /* 640x200, 15 kHz, 72 Hz */ + "euro36", 72, 640, 200, TAG_HIRES, 92, 124, 6, 6, 52, 5, + 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { - "euro36-lace", { /* 640x400, 15 kHz, 72 Hz interlaced */ - 640, 400, 640, 400, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_HIRES, 92, 124, 12, 12, 52, 10, - 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP - } + /* 640x400, 15 kHz, 72 Hz interlaced */ + "euro36-lace", 72, 640, 400, TAG_HIRES, 92, 124, 12, 12, 52, 10, + 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP }, { - "euro72", { /* 640x400, 29 kHz, 68 Hz */ - 640, 400, 640, 400, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_SHRES, 164, 92, 9, 9, 80, 8, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - } + /* 640x400, 29 kHz, 68 Hz */ + "euro72", 68, 640, 400, TAG_SHRES, 164, 92, 9, 9, 80, 8, + 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { - "euro72-lace", { /* 640x800, 29 kHz, 68 Hz interlaced */ - 640, 800, 640, 800, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_SHRES, 164, 92, 18, 18, 80, 16, - 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP - } + /* 640x800, 29 kHz, 68 Hz interlaced */ + "euro72-lace", 68, 640, 800, TAG_SHRES, 164, 92, 18, 18, 80, 16, + 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP }, { - "super72", { /* 800x300, 23 kHz, 70 Hz */ - 800, 300, 800, 300, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_SHRES, 212, 140, 10, 11, 80, 7, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - } + /* 800x300, 23 kHz, 70 Hz */ + "super72", 70, 800, 300, TAG_SHRES, 212, 140, 10, 11, 80, 7, + 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { - "super72-lace", { /* 800x600, 23 kHz, 70 Hz interlaced */ - 800, 600, 800, 600, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_SHRES, 212, 140, 20, 22, 80, 14, - 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP - } + /* 800x600, 23 kHz, 70 Hz interlaced */ + "super72-lace", 70, 800, 600, TAG_SHRES, 212, 140, 20, 22, 80, 14, + 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP }, { - "dblntsc", { /* 640x200, 27 kHz, 57 Hz doublescan */ - 640, 200, 640, 200, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_SHRES, 196, 124, 18, 17, 80, 4, - 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP - } + /* 640x200, 27 kHz, 57 Hz doublescan */ + "dblntsc", 57, 640, 200, TAG_SHRES, 196, 124, 18, 17, 80, 4, + 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP }, { - "dblntsc-ff", { /* 640x400, 27 kHz, 57 Hz */ - 640, 400, 640, 400, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_SHRES, 196, 124, 36, 35, 80, 7, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - } + /* 640x400, 27 kHz, 57 Hz */ + "dblntsc-ff", 57, 640, 400, TAG_SHRES, 196, 124, 36, 35, 80, 7, + 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { - "dblntsc-lace", { /* 640x800, 27 kHz, 57 Hz interlaced */ - 640, 800, 640, 800, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_SHRES, 196, 124, 72, 70, 80, 14, - 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP - } + /* 640x800, 27 kHz, 57 Hz interlaced */ + "dblntsc-lace", 57, 640, 800, TAG_SHRES, 196, 124, 72, 70, 80, 14, + 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP }, { - "dblpal", { /* 640x256, 27 kHz, 47 Hz doublescan */ - 640, 256, 640, 256, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_SHRES, 196, 124, 14, 13, 80, 4, - 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP - } + /* 640x256, 27 kHz, 47 Hz doublescan */ + "dblpal", 47, 640, 256, TAG_SHRES, 196, 124, 14, 13, 80, 4, + 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP }, { - "dblpal-ff", { /* 640x512, 27 kHz, 47 Hz */ - 640, 512, 640, 512, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_SHRES, 196, 124, 28, 27, 80, 7, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - } + /* 640x512, 27 kHz, 47 Hz */ + "dblpal-ff", 47, 640, 512, TAG_SHRES, 196, 124, 28, 27, 80, 7, + 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { - "dblpal-lace", { /* 640x1024, 27 kHz, 47 Hz interlaced */ - 640, 1024, 640, 1024, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_SHRES, 196, 124, 56, 54, 80, 14, - 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP - } + /* 640x1024, 27 kHz, 47 Hz interlaced */ + "dblpal-lace", 47, 640, 1024, TAG_SHRES, 196, 124, 56, 54, 80, 14, + 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP }, /* @@ -944,19 +892,13 @@ */ { - "vga", { /* 640x480, 31 kHz, 60 Hz (VGA) */ - 640, 480, 640, 480, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_SHRES, 64, 96, 30, 9, 112, 2, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - } + /* 640x480, 31 kHz, 60 Hz (VGA) */ + "vga", 60, 640, 480, TAG_SHRES, 64, 96, 30, 9, 112, 2, + 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { - "vga70", { /* 640x400, 31 kHz, 70 Hz (VGA) */ - 640, 400, 640, 400, 0, 0, 4, 0, - {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_SHRES, 64, 96, 35, 12, 112, 2, - FB_SYNC_VERT_HIGH_ACT | FB_SYNC_COMP_HIGH_ACT, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - } + /* 640x400, 31 kHz, 70 Hz (VGA) */ + "vga70", 70, 640, 400, TAG_SHRES, 64, 96, 35, 12, 112, 2, + FB_SYNC_VERT_HIGH_ACT | FB_SYNC_COMP_HIGH_ACT, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, #if 0 @@ -967,41 +909,36 @@ */ { - "a2024-10", { /* 1024x800, 10 Hz */ - 1024, 800, 1024, 800, 0, 0, 2, 0, - {0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_HIRES, 0, 0, 0, 0, 0, 0, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - } + /* 1024x800, 10 Hz */ + "a2024-10", 10, 1024, 800, TAG_HIRES, 0, 0, 0, 0, 0, 0, + 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP }, { - "a2024-15", { /* 1024x800, 15 Hz */ - 1024, 800, 1024, 800, 0, 0, 2, 0, - {0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0}, - 0, 0, -1, -1, 0, TAG_HIRES, 0, 0, 0, 0, 0, 0, - 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP - } + /* 1024x800, 15 Hz */ + "a2024-15", 10, 1024, 800, TAG_HIRES, 0, 0, 0, 0, 0, 0, + 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP } #endif }; -#define NUM_TOTAL_MODES arraysize(amifb_predefined) +#define NUM_TOTAL_MODES arraysize(ami_modedb) -static int amifb_ilbm = 0; /* interleaved or normal bitplanes */ -static int amifb_inverse = 0; -static int amifb_usermode __initdata = 0; -static int amifb_userdepth __initdata = -1; +static const char *mode_option __initdata = NULL; +static int round_down_bpp = 1; /* for mode probing */ /* * Some default modes */ -#define DEFMODE_PAL "pal" /* for PAL OCS/ECS */ -#define DEFMODE_NTSC "ntsc" /* for NTSC OCS/ECS */ -#define DEFMODE_AMBER_PAL "pal-lace" /* for flicker fixed PAL (A3000) */ -#define DEFMODE_AMBER_NTSC "ntsc-lace" /* for flicker fixed NTSC (A3000) */ -#define DEFMODE_AGA "vga70" /* for AGA */ -static struct fb_var_screeninfo amifb_default; +#define DEFMODE_PAL 2 /* "pal" for PAL OCS/ECS */ +#define DEFMODE_NTSC 0 /* "ntsc" for NTSC OCS/ECS */ +#define DEFMODE_AMBER_PAL 3 /* "pal-lace" for flicker fixed PAL (A3000) */ +#define DEFMODE_AMBER_NTSC 1 /* "ntsc-lace" for flicker fixed NTSC (A3000) */ +#define DEFMODE_AGA 19 /* "vga70" for AGA */ + + +static int amifb_ilbm = 0; /* interleaved or normal bitplanes */ +static int amifb_inverse = 0; /* @@ -1162,7 +1099,7 @@ * Interface used by the world */ -void amifb_setup(char *options, int *ints); +int amifb_setup(char*); static int amifb_open(struct fb_info *info, int user); static int amifb_release(struct fb_info *info, int user); @@ -1193,7 +1130,7 @@ * Interface to the low level console driver */ -void amifb_init(void); +int amifb_init(void); static int amifbcon_switch(int con, struct fb_info *info); static int amifbcon_updatevar(int con, struct fb_info *info); static void amifbcon_blank(int blank, struct fb_info *info); @@ -1205,8 +1142,6 @@ static void do_install_cmap(int con, struct fb_info *info); static int flash_cursor(void); static void amifb_interrupt(int irq, void *dev_id, struct pt_regs *fp); -static void get_video_mode(const char *name); -static void check_default_mode(void); static u_long chipalloc(u_long size); static char *strtoke(char *s,const char *ct); @@ -1259,7 +1194,7 @@ amifb_pan_display, amifb_ioctl }; -void __init amifb_setup(char *options, int *ints) +int __init amifb_setup(char *options) { char *this_opt; char mcap_spec[80]; @@ -1268,11 +1203,9 @@ fb_info.fontname[0] = '\0'; if (!options || !*options) - return; + return 0; for (this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ",")) { - char *p; - if (!strcmp(this_opt, "inverse")) { amifb_inverse = 1; fb_invert_cmaps(); @@ -1284,54 +1217,8 @@ strcpy(fb_info.fontname, this_opt+5); else if (!strncmp(this_opt, "fstart:", 7)) min_fstrt = simple_strtoul(this_opt+7, NULL, 0); - else if (!strncmp(this_opt, "depth:", 6)) - amifb_userdepth = simple_strtoul(this_opt+6, NULL, 0); - else if (!strncmp(this_opt, "size:", 5)) { - p = this_opt + 5; - if (*p != ';') - amifb_default.xres = simple_strtoul(p, NULL, 0); - if (!(p = strchr(p, ';'))) - continue; - if (*++p != ';') - amifb_default.yres = simple_strtoul(p, NULL, 0); - if (!(p = strchr(p, ';'))) - continue; - if (*++p != ';') - amifb_default.xres_virtual = simple_strtoul(p, NULL, 0); - if (!(p = strchr(p, ';'))) - continue; - if (*++p != ';') - amifb_default.yres_virtual = simple_strtoul(p, NULL, 0); - if (!(p = strchr(p, ';'))) - continue; - if (*++p) - amifb_default.bits_per_pixel = simple_strtoul(p, NULL, 0); - } else if (!strncmp(this_opt, "timing:", 7)) { - p = this_opt + 7; - if (*p != ';') - amifb_default.left_margin = simple_strtoul(p, NULL, 0); - if (!(p = strchr(p, ';'))) - continue; - if (*++p != ';') - amifb_default.right_margin = simple_strtoul(p, NULL, 0); - if (!(p = strchr(p, ';'))) - continue; - if (*++p != ';') - amifb_default.upper_margin = simple_strtoul(p, NULL, 0); - if (!(p = strchr(p, ';'))) - continue; - if (*++p) - amifb_default.lower_margin = simple_strtoul(p, NULL, 0); - } else if (!strncmp(this_opt, "sync:", 5)) { - p = this_opt + 5; - if (*p != ';') - amifb_default.hsync_len = simple_strtoul(p, NULL, 0); - if (!(p = strchr(p, ';'))) - continue; - if (*++p) - amifb_default.vsync_len = simple_strtoul(p, NULL, 0); - } else - get_video_mode(this_opt); + else + mode_option = this_opt; } if (min_fstrt < 48) @@ -1374,6 +1261,7 @@ cap_invalid: ; } + return 0; } /* @@ -1714,13 +1602,15 @@ * Initialisation */ -void __init amifb_init(void) +int __init amifb_init(void) { int tag, i; u_long chipptr; + u_int defmode; + struct fb_var_screeninfo var; if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_VIDEO)) - return; + return -ENXIO; /* * TODO: where should we put this? The DMI Resolver doesn't have a @@ -1731,7 +1621,7 @@ if (amifb_resolver){ custom.dmacon = DMAF_MASTER | DMAF_RASTER | DMAF_COPPER | DMAF_BLITTER | DMAF_SPRITE; - return; + return 0; } #endif @@ -1747,9 +1637,8 @@ maxdepth[TAG_HIRES] = 4; maxdepth[TAG_LORES] = 6; maxfmode = TAG_FMODE_1; - if (!amifb_usermode) /* Set the Default Video Mode */ - get_video_mode(amiga_vblank == 50 ? - DEFMODE_PAL : DEFMODE_NTSC); + defmode = amiga_vblank == 50 ? DEFMODE_PAL + : DEFMODE_NTSC; videomemorysize = VIDEOMEMSIZE_OCS; break; #endif /* CONFIG_FB_AMIGA_OCS */ @@ -1762,14 +1651,12 @@ maxdepth[TAG_HIRES] = 4; maxdepth[TAG_LORES] = 6; maxfmode = TAG_FMODE_1; - if (!amifb_usermode) { /* Set the Default Video Mode */ - if (AMIGAHW_PRESENT(AMBER_FF)) - get_video_mode(amiga_vblank == 50 ? - DEFMODE_AMBER_PAL : DEFMODE_AMBER_NTSC); - else - get_video_mode(amiga_vblank == 50 ? - DEFMODE_PAL : DEFMODE_NTSC); - } + if (AMIGAHW_PRESENT(AMBER_FF)) + defmode = amiga_vblank == 50 ? DEFMODE_AMBER_PAL + : DEFMODE_AMBER_NTSC; + else + defmode = amiga_vblank == 50 ? DEFMODE_PAL + : DEFMODE_NTSC; if (amiga_chip_avail()-CHIPRAM_SAFETY_LIMIT > VIDEOMEMSIZE_ECS_1M) videomemorysize = VIDEOMEMSIZE_ECS_2M; @@ -1786,8 +1673,7 @@ maxdepth[TAG_HIRES] = 8; maxdepth[TAG_LORES] = 8; maxfmode = TAG_FMODE_4; - if (!amifb_usermode) /* Set the Default Video Mode */ - get_video_mode(DEFMODE_AGA); + defmode = DEFMODE_AGA; if (amiga_chip_avail()-CHIPRAM_SAFETY_LIMIT > VIDEOMEMSIZE_AGA_1M) videomemorysize = VIDEOMEMSIZE_AGA_2M; @@ -1802,7 +1688,7 @@ strcat(amifb_name, "Unknown"); goto default_chipset; #else /* CONFIG_FB_AMIGA_OCS */ - return; + return -ENXIO; #endif /* CONFIG_FB_AMIGA_OCS */ break; } @@ -1823,23 +1709,13 @@ * Replace the Tag Values with the Real Pixel Clock Values */ - if (amifb_userdepth != -1) - amifb_default.bits_per_pixel = amifb_userdepth; for (i = 0; i < NUM_TOTAL_MODES; i++) { - struct fb_var_screeninfo *var = &amifb_predefined[i].var; - tag = var->pixclock; + struct fb_videomode *mode = &ami_modedb[i]; + tag = mode->pixclock; if (tag == TAG_SHRES || tag == TAG_HIRES || tag == TAG_LORES) { - var->pixclock = pixclock[tag]; - if (var->bits_per_pixel > maxdepth[tag]) - var->bits_per_pixel = maxdepth[tag]; + mode->pixclock = pixclock[tag]; } } - tag = amifb_default.pixclock; - if (tag == TAG_SHRES || tag == TAG_HIRES || tag == TAG_LORES) { - amifb_default.pixclock = pixclock[tag]; - if (amifb_default.bits_per_pixel > maxdepth[tag]) - amifb_default.bits_per_pixel = maxdepth[tag]; - } /* * These monitor specs are for a typical Amiga monitor (e.g. A1960) @@ -1861,6 +1737,11 @@ fb_info.blank = &amifbcon_blank; fb_info.flags = FBINFO_FLAG_DEFAULT; + if (!fb_find_mode(&var, &fb_info, mode_option, ami_modedb, + NUM_TOTAL_MODES, &ami_modedb[defmode], 4)) + panic("Can't find any usable video mode"); + + round_down_bpp = 0; chipptr = chipalloc(videomemorysize+ SPRITEMEMSIZE+ DUMMYSPRITEMEMSIZE+ @@ -1903,9 +1784,7 @@ ami_init_copper(); - check_default_mode(); - - if (request_irq(IRQ_AMIGA_AUTO_3, amifb_interrupt, IRQ_FLG_LOCK, + if (request_irq(IRQ_AMIGA_AUTO_3, amifb_interrupt, 0, "fb vertb handler", NULL)) panic("Couldn't add vblank interrupt\n"); ami_intena_vals[IRQ_AMIGA_VERTB] = IF_COPER; @@ -1913,10 +1792,10 @@ custom.intena = IF_VERTB; custom.intena = IF_SETCLR | IF_COPER; - amifb_set_var(&amifb_default, -1, &fb_info); + amifb_set_var(&var, -1, &fb_info); if (register_framebuffer(&fb_info) < 0) - return; + return -EINVAL; printk("fb%d: %s frame buffer device, using %ldK of video memory\n", GET_FB_IDX(fb_info.node), fb_info.modename, @@ -1924,6 +1803,8 @@ /* TODO: This driver cannot be unloaded yet */ MOD_INC_USE_COUNT; + + return 0; } static int amifbcon_switch(int con, struct fb_info *info) @@ -2049,43 +1930,6 @@ } /* - * Get a Video Mode - */ - -static void __init get_video_mode(const char *name) -{ - int i; - - for (i = 0; i < NUM_TOTAL_MODES; i++) { - if (!strcmp(name, amifb_predefined[i].name)) { - amifb_default = amifb_predefined[i].var; - amifb_usermode = i; - return; - } - } -} - - /* - * Probe the Video Modes - */ - -static void __init check_default_mode(void) -{ - struct amifb_par par; - int mode; - - if (!ami_decode_var(&amifb_default, &par)) - return; - printk("Can't use default video mode. Probing video modes...\n"); - for (mode = 0; mode < NUM_TOTAL_MODES; mode++) - if (!ami_decode_var(&amifb_predefined[mode].var, &par)) { - amifb_default = amifb_predefined[mode].var; - return; - } - panic("Can't find any usable video mode"); -} - - /* * Allocate, Clear and Align a Block of Chip Memory */ @@ -2214,8 +2058,12 @@ if (par->bpp < 1) par->bpp = 1; if (par->bpp > maxdepth[clk_shift]) { - DPRINTK("invalid bpp\n"); - return -EINVAL; + if (round_down_bpp && maxdepth[clk_shift]) + par->bpp = maxdepth[clk_shift]; + else { + DPRINTK("invalid bpp\n"); + return -EINVAL; + } } } else if (var->nonstd == FB_NONSTD_HAM) { if (par->bpp < 6) @@ -3519,8 +3367,7 @@ #ifdef MODULE int init_module(void) { - amifb_init(); - return 0; + return amifb_init(); } void cleanup_module(void) diff -u --recursive --new-file v2.3.13/linux/drivers/video/atafb.c linux/drivers/video/atafb.c --- v2.3.13/linux/drivers/video/atafb.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/video/atafb.c Thu Aug 12 10:22:33 1999 @@ -2745,14 +2745,14 @@ do_install_cmap(currcon, info); } -void __init atafb_init(void) +int __init atafb_init(void) { int pad; int detected_mode; unsigned long mem_req; if (!MACH_IS_ATARI) - return; + return -ENXIO; do { #ifdef ATAFB_EXT @@ -2858,7 +2858,7 @@ do_install_cmap(0, &fb_info); if (register_framebuffer(&fb_info) < 0) - return; + return -EINVAL; printk("Determined %dx%d, depth %d\n", disp.var.xres, disp.var.yres, disp.var.bits_per_pixel); @@ -2871,6 +2871,8 @@ /* TODO: This driver cannot be unloaded yet */ MOD_INC_USE_COUNT; + + return 0; } /* a strtok which returns empty strings, too */ @@ -2895,7 +2897,7 @@ return sbegin; } -void __init atafb_setup( char *options, int *ints ) +int __init atafb_setup( char *options ) { char *this_opt; int temp; @@ -2910,7 +2912,7 @@ fb_info.fontname[0] = '\0'; if (!options || !*options) - return; + return 0; for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) { if (!*this_opt) continue; @@ -3146,13 +3148,13 @@ user_invalid: ; } + return 0; } #ifdef MODULE int init_module(void) { - atafb_init(); - return 0; + return atafb_init(); } void cleanup_module(void) diff -u --recursive --new-file v2.3.13/linux/drivers/video/atyfb.c linux/drivers/video/atyfb.c --- v2.3.13/linux/drivers/video/atyfb.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/video/atyfb.c Wed Aug 18 10:10:06 1999 @@ -386,11 +386,11 @@ * Interface used by the world */ -void atyfb_init(void); +int atyfb_init(void); #ifdef CONFIG_FB_OF void atyfb_of_init(struct device_node *dp); #endif -void atyfb_setup(char *options, int *ints); +int atyfb_setup(char*); static int currcon = 0; @@ -411,6 +411,7 @@ static u32 default_vram __initdata = 0; static int default_pll __initdata = 0; static int default_mclk __initdata = 0; +static const char *mode_option __initdata = NULL; #if defined(CONFIG_PPC) static int default_vmode __initdata = VMODE_NVRAM; @@ -479,10 +480,10 @@ #if defined(__powerpc__) temp = info->ati_regbase; - asm("lwbrx %0,%1,%2" : "=r"(val) : "b" (regindex), "r" (temp)); + asm volatile("lwbrx %0,%1,%2" : "=r"(val) : "b" (regindex), "r" (temp)); #elif defined(__sparc_v9__) temp = info->ati_regbase + regindex; - asm("lduwa [%1] %2, %0" : "=r" (val) : "r" (temp), "i" (ASI_PL)); + asm volatile("lduwa [%1] %2, %0" : "=r" (val) : "r" (temp), "i" (ASI_PL)); #else temp = info->ati_regbase+regindex; val = le32_to_cpu(*((volatile u32 *)(temp))); @@ -497,11 +498,11 @@ #if defined(__powerpc__) temp = info->ati_regbase; - asm("stwbrx %0,%1,%2" : : "r" (val), "b" (regindex), "r" (temp) : + asm volatile("stwbrx %0,%1,%2" : : "r" (val), "b" (regindex), "r" (temp) : "memory"); #elif defined(__sparc_v9__) temp = info->ati_regbase + regindex; - asm("stwa %0, [%1] %2" : : "r" (val), "r" (temp), "i" (ASI_PL) : "memory"); + asm volatile("stwa %0, [%1] %2" : : "r" (val), "r" (temp), "i" (ASI_PL) : "memory"); #else temp = info->ati_regbase+regindex; *((volatile u32 *)(temp)) = cpu_to_le32(val); @@ -2218,7 +2219,6 @@ static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg, int con, struct fb_info *info2) { - struct fb_info_aty *info = (struct fb_info_aty *)info2; #ifdef __sparc__ struct fbtype fbtyp; struct display *disp; @@ -2734,32 +2734,55 @@ info->total_vram -= GUI_RESERVE; } + disp = &info->disp; + + strcpy(info->fb_info.modename, atyfb_name); + info->fb_info.node = -1; + info->fb_info.fbops = &atyfb_ops; + info->fb_info.disp = disp; + strcpy(info->fb_info.fontname, fontname); + info->fb_info.changevar = NULL; + info->fb_info.switch_con = &atyfbcon_switch; + info->fb_info.updatevar = &atyfbcon_updatevar; + info->fb_info.blank = &atyfbcon_blank; + info->fb_info.flags = FBINFO_FLAG_DEFAULT; + +#ifdef MODULE + var = default_var; +#else /* !MODULE */ #if defined(CONFIG_PPC) - if (default_vmode == VMODE_NVRAM) { - default_vmode = nvram_read_byte(NV_VMODE); + if (mode_option) { + if (!mac_find_mode(&var, &info->fb_info, mode_option, 8)) + var = default_var; + } else { + if (default_vmode == VMODE_NVRAM) { + default_vmode = nvram_read_byte(NV_VMODE); + if (default_vmode <= 0 || default_vmode > VMODE_MAX) + default_vmode = VMODE_CHOOSE; + } + if (default_vmode == VMODE_CHOOSE) { + if (Gx == LG_CHIP_ID) + /* G3 PowerBook with 1024x768 LCD */ + default_vmode = VMODE_1024_768_60; + else { + sense = read_aty_sense(info); + default_vmode = mac_map_monitor_sense(sense); + } + } if (default_vmode <= 0 || default_vmode > VMODE_MAX) - default_vmode = VMODE_CHOOSE; + default_vmode = VMODE_640_480_60; + if (default_cmode == CMODE_NVRAM) + default_cmode = nvram_read_byte(NV_CMODE); + if (default_cmode < CMODE_8 || default_cmode > CMODE_32) + default_cmode = CMODE_8; + if (mac_vmode_to_var(default_vmode, default_cmode, &var)) + var = default_var; } - if (default_vmode == VMODE_CHOOSE) { - if (Gx == LG_CHIP_ID) - /* G3 PowerBook with 1024x768 LCD */ - default_vmode = VMODE_1024_768_60; - else { - sense = read_aty_sense(info); - default_vmode = mac_map_monitor_sense(sense); - } - } - if (default_vmode <= 0 || default_vmode > VMODE_MAX) - default_vmode = VMODE_640_480_60; - if (default_cmode == CMODE_NVRAM) - default_cmode = nvram_read_byte(NV_CMODE); - if (default_cmode < CMODE_8 || default_cmode > CMODE_32) - default_cmode = CMODE_8; - if (mac_vmode_to_var(default_vmode, default_cmode, &var)) - var = default_var; #else /* !CONFIG_PPC */ - var = default_var; + if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8)) + var = default_var; #endif /* !CONFIG_PPC */ +#endif /* !MODULE */ if (noaccel) var.accel_flags &= ~FB_ACCELF_TEXT; else @@ -2777,19 +2800,6 @@ return 0; } - disp = &info->disp; - - strcpy(info->fb_info.modename, atyfb_name); - info->fb_info.node = -1; - info->fb_info.fbops = &atyfb_ops; - info->fb_info.disp = disp; - strcpy(info->fb_info.fontname, fontname); - info->fb_info.changevar = NULL; - info->fb_info.switch_con = &atyfbcon_switch; - info->fb_info.updatevar = &atyfbcon_updatevar; - info->fb_info.blank = &atyfbcon_blank; - info->fb_info.flags = FBINFO_FLAG_DEFAULT; - #ifdef __sparc__ atyfb_save_palette(&info->fb_info, 0); #endif @@ -2821,7 +2831,7 @@ return 1; } -void __init atyfb_init(void) +int __init atyfb_init(void) { #if defined(CONFIG_FB_OF) /* We don't want to be called like this. */ @@ -2841,7 +2851,7 @@ /* Do not attach when we have a serial console. */ if (!con_is_present()) - return; + return -ENXIO; #else u16 tmp; #endif @@ -2854,7 +2864,7 @@ info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC); if (!info) { printk("atyfb_init: can't alloc fb_info_aty\n"); - return; + return -ENXIO; } memset(info, 0, sizeof(struct fb_info_aty)); @@ -2890,7 +2900,7 @@ if (!info->mmap_map) { printk("atyfb_init: can't alloc mmap_map\n"); kfree(info); - return; + return -ENXIO; } memset(info->mmap_map, 0, j * sizeof(*info->mmap_map)); @@ -2904,14 +2914,12 @@ io = (rp->flags & IORESOURCE_IOPORT); + size = rp->end - base + 1; + pci_read_config_dword(pdev, breg, &pbase); - pci_write_config_dword(pdev, breg, 0xffffffff); - pci_read_config_dword(pdev, breg, &size); - pci_write_config_dword(pdev, breg, pbase); if (io) size &= ~1; - size = ~(size) + 1; /* * Map the framebuffer a second time, this time without @@ -3071,7 +3079,7 @@ if(!info->ati_regbase) { kfree(info); - return; + return -ENOMEM; } info->ati_regbase_phys += 0xc00; @@ -3098,7 +3106,7 @@ if(!info->frame_buffer) { kfree(info); - return; + return -ENXIO; } #endif /* __sparc__ */ @@ -3107,7 +3115,7 @@ if (info->mmap_map) kfree(info->mmap_map); kfree(info); - return; + return -ENXIO; } #ifdef __sparc__ @@ -3145,7 +3153,7 @@ info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC); if (!info) { printk("atyfb_init: can't alloc fb_info_aty\n"); - return; + return -ENOMEM; } memset(info, 0, sizeof(struct fb_info_aty)); @@ -3161,10 +3169,11 @@ if (!aty_init(info, "ISA bus")) { kfree(info); /* This is insufficient! kernel_map has added two large chunks!! */ - return; + return -ENXIO; } } #endif + return 0; } #ifdef CONFIG_FB_OF @@ -3252,12 +3261,12 @@ #endif /* CONFIG_FB_OF */ -void __init atyfb_setup(char *options, int *ints) +int __init atyfb_setup(char *options) { char *this_opt; if (!options || !*options) - return; + return 0; for (this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ",")) { @@ -3320,6 +3329,7 @@ } #endif } + return 0; } #ifdef CONFIG_ATARI diff -u --recursive --new-file v2.3.13/linux/drivers/video/chipsfb.c linux/drivers/video/chipsfb.c --- v2.3.13/linux/drivers/video/chipsfb.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/video/chipsfb.c Thu Aug 12 10:22:33 1999 @@ -112,7 +112,7 @@ /* * Exported functions */ -void chips_init(void); +int chips_init(void); void chips_of_init(struct device_node *dp); static int chips_open(struct fb_info *info, int user); @@ -645,7 +645,7 @@ all_chips = p; } -void __init chips_init(void) +int __init chips_init(void) { #ifndef CONFIG_FB_OF struct device_node *dp; @@ -654,6 +654,7 @@ if (dp != 0) chips_of_init(dp); #endif /* CONFIG_FB_OF */ + return 0; } void __init chips_of_init(struct device_node *dp) diff -u --recursive --new-file v2.3.13/linux/drivers/video/clgenfb.c linux/drivers/video/clgenfb.c --- v2.3.13/linux/drivers/video/clgenfb.c Mon Aug 9 14:59:23 1999 +++ linux/drivers/video/clgenfb.c Wed Aug 18 10:10:06 1999 @@ -1,7 +1,38 @@ /* - * Based on retz3fb.c and clgen.c + * drivers/video/clgenfb.c - driver for Cirrus Logic chipsets + * + * Copyright 1999 Jeff Garzik + * + * Contributors (thanks, all!) + * + * Jeff Rugen: + * Major contributions; Motorola PowerStack (PPC and PCI) support, + * GD54xx, 1280x1024 mode support, change MCLK based on VCLK. + * + * Geert Uytterhoeven: + * Excellent code review. + * + * Lars Hecking: + * Amiga updates and testing. + * + * Original clgenfb author: Frank Neumann + * + * Based on retz3fb.c and clgen.c: + * Copyright (C) 1997 Jes Sorensen + * Copyright (C) 1996 Frank Neumann + * + *************************************************************** + * + * Format this code with GNU indent '-kr -i8 -pcs' options. + * + * 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 archive + * for more details. + * */ - + +#define CLGEN_VERSION "1.9.4.1" + #include #include #include @@ -11,12 +42,22 @@ #include #include #include -#include #include -#include #include #include #include +#ifdef CONFIG_ZORRO +#include +#endif +#ifdef CONFIG_PCI +#include +#endif +#ifdef CONFIG_AMIGA +#include +#endif +#ifdef CONFIG_FB_OF +#include +#endif #include