]> git.neil.brown.name Git - history.git/commitdiff
Import 2.3.19pre1 2.3.19pre1
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:27:24 +0000 (15:27 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:27:24 +0000 (15:27 -0500)
98 files changed:
CREDITS
Documentation/CodingStyle
Documentation/networking/README.sb1000
MAINTAINERS
arch/i386/defconfig
arch/i386/kernel/i8259.c
arch/i386/kernel/mtrr.c
arch/i386/kernel/setup.c
arch/i386/mm/init.c
drivers/atm/ambassador.c
drivers/char/bttv.c
drivers/char/bttv.h
drivers/char/buz.c
drivers/char/cyclades.c
drivers/char/pcxx.c
drivers/char/radio-aimslab.c
drivers/char/radio-aztech.c
drivers/char/radio-gemtek.c
drivers/char/radio-miropcm20.c
drivers/char/radio-rtrack2.c
drivers/char/radio-sf16fmi.c
drivers/char/radio-terratec.c
drivers/char/radio-trust.c [new file with mode: 0644]
drivers/char/radio-zoltrix.c
drivers/char/random.c
drivers/char/saa5249.c
drivers/net/3c527.c
drivers/net/defxx.c
drivers/net/e2100.c
drivers/net/irda/Config.in
drivers/net/irda/actisys.c
drivers/net/irda/irport.c
drivers/net/irda/irtty.c
drivers/net/irda/pc87108.c
drivers/net/irda/smc-ircc.c
drivers/net/irda/toshoboe.c
drivers/net/irda/uircc.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/pcnet32.c
drivers/net/sb1000.c
drivers/net/slip.c
drivers/net/tlan.c
drivers/pci/quirks.c
drivers/scsi/a2091.c
drivers/scsi/eata.c
drivers/scsi/eata.h
drivers/scsi/ips.c
drivers/scsi/ips.h
drivers/scsi/wd33c93.h
drivers/sound/opl3sa.c
drivers/sound/sb_audio.c
drivers/sound/sb_card.c
drivers/sound/sb_common.c
fs/nfs/nfsroot.c
fs/partitions/acorn.c
fs/partitions/msdos.c
fs/proc/fd.c
include/asm-i386/e820.h
include/linux/cyclades.h
include/linux/irda.h
include/linux/videodev.h
include/net/irda/ircomm_tty.h
include/net/irda/ircomm_tty_attach.h
include/net/irda/irda.h
include/net/irda/irda_device.h
include/net/irda/irlap.h
include/net/irda/irlpt_cli.h [deleted file]
include/net/irda/irlpt_cli_fsm.h [deleted file]
include/net/irda/irlpt_common.h [deleted file]
include/net/irda/irlpt_server.h [deleted file]
include/net/irda/irlpt_server_fsm.h [deleted file]
include/net/irda/irttp.h
include/net/irda/irvtd.h [deleted file]
include/net/irda/toshoboe.h
net/irda/Config.in
net/irda/af_irda.c
net/irda/compressors/Config.in
net/irda/ircomm/Config.in
net/irda/ircomm/Makefile
net/irda/ircomm/ircomm_event.c
net/irda/ircomm/ircomm_param.c
net/irda/ircomm/ircomm_ttp.c
net/irda/ircomm/ircomm_tty.c
net/irda/ircomm/ircomm_tty_attach.c
net/irda/ircomm/ircomm_tty_ioctl.c
net/irda/irda_device.c
net/irda/irlan/Config.in
net/irda/irlan/irlan_common.c
net/irda/irlap.c
net/irda/irlap_event.c
net/irda/irlap_frame.c
net/irda/irlmp.c
net/irda/irlmp_event.c
net/irda/irmod.c
net/irda/irttp.c
net/irda/qos.c
net/irda/timer.c
net/irda/wrapper.c

diff --git a/CREDITS b/CREDITS
index dcc37e6986e00b2307db57a404ba61ac8b33c665..6fb36135aef8b01bde3c9236337bca9f2360957a 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -157,12 +157,6 @@ S: 633 South 550 East
 S: Provo, Utah 84606
 S: USA
 
-N: Paul Barton-Davis
-E: pbd@op.net
-D: Driver for WaveFront soundcards (Turtle Beach Maui, Tropez, Tropez+)
-D: Various bugfixes and changes to sound drivers
-S: USA 
-
 N: Krzysztof G. Baranowski
 E: kgb@manjak.knm.org.pl
 P: 1024/FA6F16D1 96 D1 1A CF 5F CA 69 EC  F9 4F 36 1F 6D 60 7B DA
@@ -174,6 +168,12 @@ S: ul. Koscielna 12a
 S: 62-300 Wrzesnia
 S: Poland
 
+N: Paul Barton-Davis
+E: pbd@op.net
+D: Driver for WaveFront soundcards (Turtle Beach Maui, Tropez, Tropez+)
+D: Various bugfixes and changes to sound drivers
+S: USA 
+
 N: Carlos Henrique Bauer
 E: chbauer@acm.org
 E: bauer@atlas.unisinos.br
@@ -482,11 +482,11 @@ S: Warrendale, Pennsylvania 15086
 S: USA
 
 N: Alex deVries
-E: puffin@redhat.com
-D: Various SGI parts, bits of HAL2 and Newport
-S: 18 Bernier Terrace
-S: Kanata, Ontario
-S: K2L 2V@
+E: adevries@thepuffingroup.com
+D: Various SGI parts, bits of HAL2 and Newport, PA-RISC Linux.
+S: 41.5 William Street
+S: Ottawa, Ontario
+S: K1N 6Z9
 S: CANADA
 
 N: Eddie C. Dost
@@ -794,6 +794,10 @@ S: 77 Clarence Mews
 S: London SE16 1GD
 S: United Kingdom
 
+N: Kai Harrekilde-Petersen
+E: khp@olicom.dk
+D: Original author of the ftape-HOWTO, i82078 fdc detection code.
+
 N: Bart Hartgers
 E: bart@etpmod.phys.tue.nl
 D: MTRR emulation with Centaur MCRs
@@ -801,10 +805,6 @@ S: Gen Stedmanstraat 212
 S: 5623 HZ Eindhoven
 S: The Netherlands
 
-N: Kai Harrekilde-Petersen
-E: khp@olicom.dk
-D: Original author of the ftape-HOWTO, i82078 fdc detection code.
-
 N: Andrew Haylett
 E: ajh@primag.co.uk
 D: Selection mechanism
@@ -858,6 +858,14 @@ S: Danckelmannstr. 48
 S: 14059 Berlin
 S: Germany
 
+N: David Hinds
+E: dhinds@zen.stanford.edu
+W: http://hyper.stanford.edu/~dhinds
+D: PCMCIA and CardBus stuff, PCMCIA-HOWTO, PCMCIA client drivers
+S: 2019 W. Middlefield Rd #1
+S: Mountain View, CA  94043
+S: USA
+
 N: Michael Hipp
 E: hippm@informatik.uni-tuebingen.de
 D: drivers for the racal ni5210 & ni6510 Ethernet-boards
@@ -1018,19 +1026,6 @@ 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
@@ -1154,6 +1149,10 @@ S: Markham, Ontario
 S: L3R 8B2
 S: Canada
 
+N: Andreas S. Krebs
+E: akrebs@altavista.net
+D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards
+
 N: Russell Kroll
 E: rkroll@exploits.org
 W: http://www.exploits.org/
@@ -1162,6 +1161,15 @@ S: Post Office Box 49458
 S: Colorado Springs, Colorado 80949-9458
 S: USA
 
+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: Gero Kuhlmann
 E: gero@gkminix.han.de
 D: mounting root via NFS
@@ -1253,10 +1261,14 @@ D: Busmaster driver for HP 10/100 Mbit Network Adapters
 S: University of Stuttgart, Germany and
 S: Ecole Nationale Superieure des Telecommunications, Paris
 
-N: Martin von Löwis
-E: loewis@informatik.hu-berlin.de
-D: script binary format
-D: NTFS driver
+N: Jamie Lokier
+E: jamie@imbolc.ucc.ie
+D: Reboot-through-BIOS for broken 486 motherboards
+S: 11 Goodson Walk
+S: Marston
+S: Oxford
+S: OX3 0HX
+S: United Kingdom
 
 N: Mark Lord
 E: mlord@pobox.com
@@ -1267,15 +1279,6 @@ S: 33 Ridgefield Cr
 S: Nepean, Ontario
 S: Canada K2H 6S3
 
-N: Jamie Lokier
-E: jamie@imbolc.ucc.ie
-D: Reboot-through-BIOS for broken 486 motherboards
-S: 11 Goodson Walk
-S: Marston
-S: Oxford
-S: OX3 0HX
-S: United Kingdom
-
 N: Warner Losh
 E: imp@village.org
 D: Linux/MIPS Deskstation support, Provided OI/OB for Linux
@@ -1283,6 +1286,11 @@ S: 8786 Niwot Road
 S: Niwot, Colorado 80503
 S: USA
 
+N: Martin von Löwis
+E: loewis@informatik.hu-berlin.de
+D: script binary format
+D: NTFS driver
+
 N: H.J. Lu
 E: hjl@gnu.ai.mit.edu
 D: GCC + libraries hacker
@@ -1295,10 +1303,6 @@ S: Puistokaari 1 E 18
 S: 00200 Helsinki
 S: Finland
 
-N: Kai Mäkisara
-E: Kai.Makisara@metla.fi
-D: SCSI Tape Driver
-
 N: Hamish Macdonald
 E: hamishm@lucent.com
 D: Linux/68k port
@@ -1343,6 +1347,10 @@ S: PO BOX 220, HFX. CENTRAL
 S: Halifax, Nova Scotia
 S: Canada B3J 3C8
 
+N: Kai Mäkisara
+E: Kai.Makisara@metla.fi
+D: SCSI Tape Driver
+
 N: Martin Mares
 E: mj@atrey.karlin.mff.cuni.cz
 W: http://atrey.karlin.mff.cuni.cz/~mj/
@@ -1399,11 +1407,13 @@ N: Arnaldo Carvalho de Melo
 E: acme@conectiva.com.br
 W: http://www.conectiva.com.br/~acme
 D: wanrouter hacking
+D: USB hacking
+D: miscellaneous Makefile & Config.in fixes
 D: Cyclom 2X synchronous card driver
 D: i18n for minicom, net-tools, util-linux, fetchmail, etc
-S: Conectiva Informatica LTDA
+S: Conectiva Informática LTDA
 S: R. Prof. Rubens Elke Braga, 558 - Parolin
-S: 80220-320 Curitiba - Parana
+S: 80220-320 Curitiba - Paraná
 S: Brazil
 
 N: Michael Meskes
@@ -1500,13 +1510,6 @@ S: 30 White Tail Lane
 S: Lafayette, Indiana 47905
 S: USA
 
-N: Johan Myreen
-E: jem@iki.fi
-D: PS/2 mouse driver writer etc.
-S: Dragonvagen 1 A 13
-S: FIN-00330 Helsingfors
-S: Finland
-
 N: Trond Myklebust
 E: trond.myklebust@fys.uio.no
 D: current NFS client hacker.
@@ -1514,6 +1517,13 @@ S: Dagaliveien 31e
 S: N-0391 Oslo
 S: Norway
 
+N: Johan Myreen
+E: jem@iki.fi
+D: PS/2 mouse driver writer etc.
+S: Dragonvagen 1 A 13
+S: FIN-00330 Helsingfors
+S: Finland
+
 N: Matija Nalis
 E: mnalis@jagor.srce.hr
 E: mnalis@voyager.hr
@@ -1628,6 +1638,13 @@ S: Demonstratsii 8-382
 S: Tula 300000
 S: Russia
 
+N: Johnnie Peters
+E: jpeters@phx.mcd.mot.com
+D: Motorola PowerPC changes for PReP
+S: 2900 S. Diable Way
+S: Tempe, Arizona 85282
+S: USA
+
 N: Kirk Petersen
 E: kirk@speakeasy.org
 W: http://www.speakeasy.org/~kirk/
@@ -1818,13 +1835,6 @@ S: Dag Hammerskjolds v. 3E
 S: S-226 64 LUND
 S: Sweden
 
-N: Peter De Schrijver
-E: stud11@cc4.kuleuven.ac.be
-D: Mitsumi CD-ROM driver patches March version
-S: Molenbaan 29
-S: B2240 Zandhoven
-S: Belgium
-
 N: Henning P. Schmiedehausen
 E: hps@tanstaafl.de
 D: added PCI support to the serial driver
@@ -1834,6 +1844,13 @@ N: Michael Schmitz
 E:
 D: Macintosh IDE Driver
 
+N: Peter De Schrijver
+E: stud11@cc4.kuleuven.ac.be
+D: Mitsumi CD-ROM driver patches March version
+S: Molenbaan 29
+S: B2240 Zandhoven
+S: Belgium
+
 N: Martin Schulze
 E: joey@linux.de
 W: http://home.pages.de/~joey/
@@ -1954,13 +1971,21 @@ S: Willowdale, Ontario
 S: Canada M2N 2Z1
 
 N: Adrian Sun
-E: asun@u.washington.edu
+E: asun@cobaltnet.com
 D: hfs support
 D: alpha rtc port, random appletalk fixes
 S: Department of Zoology, University of Washington
 S: Seattle, WA  98195-1800
 S: USA
 
+N: Corey Thomas
+E: corey@world.std.com
+W: http://world.std.com/~corey/index.html
+D: Raylink/WebGear wireless LAN device driver (ray_cs) author
+S: 145 Howard St.
+S: Northborough, MA 01532
+S: USA
+
 N: Tommy Thorn
 E: Tommy.Thorn@irisa.fr
 W: http://www.irisa.fr/prive/thorn/index.html
@@ -1997,9 +2022,9 @@ W: http://lie-br.conectiva.com.br/~marcelo/
 D: Miscellaneous kernel hacker
 D: Cyclom 2X driver hacker
 D: linuxconf apache & proftpd module maintainer
-S: Conectiva Informatica LTDA
+S: Conectiva Informática LTDA
 S: R. Prof. Rubens Elke Braga, 558 - Parolin
-S: 80220-320 Curitiba - Parana
+S: 80220-320 Curitiba - Paraná
 S: Brazil
 
 N: Stefan Traby
@@ -2036,6 +2061,17 @@ D: Linux-Workshop K
 S: Tacitusstr. 6
 S: D-50968 Köln
 
+N: Tsu-Sheng Tsao
+E: tsusheng@scf.usc.edu
+D: IGMP(Internet Group Management Protocol) version 2
+S: 2F 14 ALY 31 LN 166 SEC 1 SHIH-PEI RD
+S: Taipei 
+S: Taiwan 112
+S: Republic of China
+S: 24335 Delta Drive
+S: Diamond Bar, California 91765
+S: USA
+
 N: Theodore Ts'o
 E: tytso@mit.edu
 D: Random Linux hacker
@@ -2051,17 +2087,6 @@ S: 1 Amherst Street
 S: Cambridge, Massachusetts 02139
 S: USA
 
-N: Tsu-Sheng Tsao
-E: tsusheng@scf.usc.edu
-D: IGMP(Internet Group Management Protocol) version 2
-S: 2F 14 ALY 31 LN 166 SEC 1 SHIH-PEI RD
-S: Taipei 
-S: Taiwan 112
-S: Republic of China
-S: 24335 Delta Drive
-S: Diamond Bar, California 91765
-S: USA
-
 N: Simmule Turner
 E: sturner@tele-tv.com
 D: Added swapping to filesystem
@@ -2193,8 +2218,14 @@ D: The Linux Support Team Erlangen
 
 N: David Weinehall
 E: tao@acc.umu.se
-D: NE/2-driver maintainer
+W: http://www.acc.umu.se/~tao/
+W: http://www.acc.umu.se/~mcalinux/
+D: Fixes for the NE/2-driver
 D: Miscellaneous MCA-support
+D: Cleanup of the Config-files
+S: Axtorpsvagen 40:20
+S: S-903 37  UMEA
+S: Sweden
 
 N: Matt Welsh
 E: mdw@metalab.unc.edu
index edba246996be0b0c283baf70afa635140688ce7a..e0915bd2c350056e03aa3ee37bae5891d3c9fe7c 100644 (file)
@@ -210,3 +210,26 @@ options "-kr -i8" (stands for "K&R, 8 character indents").
 "indent" has a lot of options, and especially when it comes to comment
 re-formatting you may want to take a look at the manual page.  But
 remember: "indent" is not a fix for bad programming. 
+
+
+               Chapter 7: Configuration-files
+
+For configuration options (arch/xxx/config.in, and all the Config.in files),
+somewhat different indentation is used.
+
+An indention level of 3 is used in the code, while the text in the config-
+options should have an indention-level of 2 to indicate dependencies. The
+latter only applies to bool/tristate options. For other options, just use
+common sense. An example:
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   tristate 'Apply nitroglycerine inside the keyboard (DANGEROUS)' CONFIG_BOOM
+   if [ "$CONFIG_BOOM" != "n" ]; then
+      bool '  Output nice messages when you explode' CONFIG_CHEER
+   fi
+fi
+
+Generally, CONFIG_EXPERIMENTAL should surround all options not considered
+stable. All options that are known to trash data (experimental write-
+support for file-systems, for instance) should be denoted (DANGEROUS), other
+Experimental options should be denoted (EXPERIMENTAL).
index 025a245f242caf757e292984b91fdadbe15b721e..37c39a0c86f80d505152195c292410fee5a859d2 100644 (file)
-This is the new release of a module network device driver for General
-Instruments (also known as NextLevel) SB1000 cable modem board (also
-called internal SURFboard).
-I have tested and I am running this module on kernel 2.0.33.
-Steven N. Hirsch <shirsch@adelphia.net> gave me a diff patch
-(sb1000-1.1.2_127.patch to be applied with 'patch -p') that allows
-you to compile and run the driver with kernel versions 2.1.x.
-Thanks very much Steve!
-
-Here you'll the following files:
-
-- README
-- Makefile
-- sb1000.c      the actual device driver
-- cmconfig.c    an ifconfig-like program to correctly set the SB1000
-- cmping.c      a ping-like program to test your connection
-- ftptest.c     a small program to test your connection speed with FTP
-                (requires ftplib version >= 3.0)
-
-The directory ppp/ contains the files I am using to connect to MediaOne
-here in Jacksonville, to show how you can use the driver and the cmconfig
-program.
-
-Clemmitt Sigler wrote a very good and useful web page and installation
-script (for Adelphia PowerLink users but easy to port to other ISPs)
-about this SB1000 driver for Linux.
-You can find it here:
-     http://home.adelphia.net/~siglercm/sb1000.html
-Thanks very much Clemmitt!
-
-To install and run it:
-- cd sb1000-1.1.2
-- make
-- make install
-- configure the SB1000 card using the isapnp tools setting the correct
-  I/O's and IRQ. You can find more info about the isapnp tools at:
-     http://www.roestock.demon.co.uk/isapnptools/
-  (once you're happy with it, you may want to set the configuration
-   at boot time in one of the /etc/init.d/ scripts)
-  IMPORTANT NOTICE: after configuring isapnp, please look in the file
-  /etc/isapnp.conf for the line beginning with:
-     (READPORT
-  if it says: '(READPORT 0x0203)' (which should be the default), then
-  go to the next step. If instead it says something like:
-  '(READPORT 0x020b)' or '(READPORT 0x<another number>)', then please
-  follow the instructions at the end of this README file before going
-  to the next step.
-- install the PPP configuration files in the /etc/ppp directory; you
-  definitely have to change the file ppp@gi-on (the start up file),
-  setting the correct login name, the phone number for the PPP connection
-  and the frequency (k stands for kHz, M for MHz) for the cablemodem.
-  You'll also have to change the last line in the pap-secrets file
-  writing your login and password there (read the whole file for more
-  site specific configurations).
-  You may have to change the firewall file to suit your needs (IPs and
-  ports allowed to connect).
-- start the PPP connection with ppp@gi-on and see what happens; you may
-  want to set 'pppd' (the last command in the ppp@gi-on file) to debug
-  mode adding 'debug' at the end of the command ('pppd' prints its info in
-  the file /var/log/messages and/or /var/log/ppp.log). To make sure 'chat'
-  s not having problems you may want to add a '-v' (verbose) after the 'chat'
-  command in 'ppp-on-dialer' and check the results in /var/log/messages)
-- if everything is working fine you should see after a few seconds a message
-  likes this:
-            cm0: sb1000 at (0x120,0x310), csn 1, S/N 0x2a0d16d8, IRQ 9. 
-            sb1000.c:v1.1.2 6/01/98 (fventuri@mediaone.net) 
-  and ifconfig -a should show you two new interfaces: ppp0 and cm0.
-  Typing 'cmconfig cm0' will show you more info about the cablemodem interface.
-- please let me know if you see any other message coming from 'cm0' in
-  your '/var/log/messages' or '/var/log/debug' file, to help me debug the
-  code
-- also let me know if you have any problem; if everything works (hopefully),
-  let me know which speed you can reach downloading the 5Mb test file using
-  this driver.
-- if everything seems to work fine but your computer locks up after a while
-  (and typically during a lengthy download through the cablemodem), you may
-  need to add a short delay in the driver to 'slow down' the SURFboard
-  because your PC might not be able to keep up with the transfer rate of
-  the SB1000. To do this, edit the 'Makefile' and look for the 'SB1000_DELAY'
-  define: uncomment those 'CFLAGS' lines (and comment the default ones)
-  and try setting the delay to something like 60 microseconds with:
-  '-DSB1000_DELAY=60'; if it still doesn't work or you like playing with
-  the driver, you may try other numbers: remember though that the higher
-  the delay, the slower the driver (which slows down the rest of the PC
-  too when it is actively used). Thanks to Ed Daiga for this tip!
-
-This release has a few things fixed and a better handling of the frame errors.
-
-I also have slightly modified the 'cablemodem' script in the 'ppp' so
-you may interested in having a look at it: I basically have added filtering
-out broadcast messages (you shouldn't get them with a point-to-point
-interface and so far the ones I have received were from hosts trying to
-attack my system) and lower debug levels for the driver to avoid seeing
-the 'frame error' messages (so far noone has noticed any problem with the
-driver even with those messages).
-
-For questions, infos, etc, feel free to email me at:
-               fventuri@mediaone.net
-
-Good luck,
-Franco Venturi
-
-Thanks to Edge for his useful comments and to Steven N. Hirsch
-for his patch to run the driver with 2.1.x kernels.
-Thanks also to Ed Daiga for his help in finding that adding a delay
-in the driver fixes some lock up problems with some slow PCs.
-Many thanks to Clemmitt Sigler for his (much needed) web page about the
-SB1000 driver for Linux.
-An interesting URL for Linux + MediaOne (although with an external modem)
-is: http://rlz.ne.mediaone.net/linux/home.shtml
-Today, Sep 22 1998, I finished writing a short utility (ftptest.c) to
-'measure' your cablemodem speed connection in Linux, downloading to
-memory the same file several times. To compile it you need ftplib, version
-3 or above. To run it, type:
-  ftptest URL n
-where URL is in the form: ftp://ftp.site.local.isp/pub/testfile
-and n is the number of simultaneous FTP connections that you want to run
-
----------------------------------------------------------------------------
-IMPORTANT NOTICE: if in your file /etc/isapnp.conf, you found something
-like '(READPORT 0x020b)' or '(READPORT 0x<another number>)', (anything
-different from the default 0x0203), you have to change the READ_DATA_PORT
-parameter in the sb1000.c file as follows.
-  - edit the sb1000.c file, look for:
-       READ_DATA_PORT
-    (it should be around line 127 in version 1.1.2)
-  - change the value of READ_DATA_PORT to the same value found in
-    /etc/isapnp.conf; for instance, if you found a: '(READPORT 0x020b)',
-    then in sb1000.c you should have:
-          static const int READ_DATA_PORT = 0x20b; 
-  - save sb1000.c
-  - compile and install again the driver
-    (i.e. do a 'make' and a 'make install').
+sb1000 is a module network device driver for the General Instrument (also known
+as NextLevel) SURFboard1000 internal cable modem board.  This is an ISA card
+which is used by a number of cable TV companies to provide cable modem access.
+It's a one-way downstream-only cable modem, meaning that your upstream net link
+is provided by your regular phone modem.
+
+This driver was written by Franco Venturi <fventuri@mediaone.net>.  He deserves
+a great deal of thanks for this wonderful piece of code!
+
+-----------------------------------------------------------------------------
+
+Support for this device is now a part of the standard Linux kernel.  The
+driver source code file is drivers/net/sb1000.c.  In addition to this
+you will need:
+
+1.) The "cmconfig" program.  This is a utility which supplements "ifconfig"
+to configure the cable modem and network interface (usually called "cm0");
+and
+
+2.) Several PPP scripts which live in /etc/ppp to make connecting via your
+cable modem easy.
+
+   These utilities can be obtained from:
+
+      http://www.jacksonville.net/~fventuri/
+
+   in Franco's original source code distribution .tar.gz file.  Support for
+   the sb1000 driver can be found at:
+
+      http://home.adelphia.net/~siglercm/sb1000.html
+      http://linuxpower.cx/~cable/
+
+   along with these utilties.
+
+3.) The standard isapnp tools.  These are necessary to configure your SB1000
+card at boot time (or afterwards by hand) since it's a PnP card.
+
+   If you don't have these installed as a standard part of your Linux
+   distribution, you can find them at:
+
+      http://www.roestock.demon.co.uk/isapnptools/
+
+   or check your Linux distribution binary CD or their web site.  For help with
+   isapnp, pnpdump, or /etc/isapnp.conf, go to:
+
+      http://www.roestock.demon.co.uk/isapnptools/isapnpfaq.html
+
+-----------------------------------------------------------------------------
+
+To make the SB1000 card work, follow these steps:
+
+1.) Run `make config', or `make menuconfig', or `make xconfig', whichever
+you prefer, in the top kernel tree directory to set up your kernel
+configuration.  Make sure to say "Y" to "Prompt for development drivers"
+and to say "M" to the sb1000 driver.  Also say "Y" or "M" to all the standard
+networking questions to get TCP/IP and PPP networking support.
+
+2.) *BEFORE* you build the kernel, edit drivers/net/sb1000.c.  Make sure
+to redefine the value of READ_DATA_PORT to match the I/O address used
+by isapnp to access your PnP cards.  This is the value of READPORT in
+/etc/isapnp.conf or given by the output of pnpdump.
+
+3.) Build and install the kernel and modules as usual.
+
+4.) Boot your new kernel following the usual procedures.
+
+5.) Set up to configure the new SB1000 PnP card by capturing the output
+of "pnpdump" to a file and editing this file to set the correct I/O ports,
+IRQ, and DMA settings for all your PnP cards.  Make sure none of the settings
+conflict with one another.  Then test this configuration by running the
+"isapnp" command with your new config file as the input.  Check for
+errors and fix as necessary.  (As an aside, I use I/O ports 0x110 and
+0x310 and IRQ 11 for my SB1000 card and these work well for me.  YMMV.)
+Then save the finished config file as /etc/isapnp.conf for proper configuration
+on subsequent reboots.
+
+6.) Download the original file sb1000-1.1.2.tar.gz from Franco's site or one of
+the others referenced above.  As root, unpack it into a temporary directory and
+do a `make cmconfig' and then `install -c cmconfig /usr/local/sbin'.  Don't do
+`make install' because it expects to find all the utilities built and ready for
+installation, not just cmconfig.
+
+7.) As root, copy all the files under the ppp/ subdirectory in Franco's
+tar file into /etc/ppp, being careful not to overwrite any files that are
+already in there.  Then modify ppp@gi-on to set the correct login name,
+phone number, and frequency for the cable modem.  Also edit pap-secrets
+to specify your login name and password and any site-specific information
+you need.
+
+8.) Be sure to modify /etc/ppp/firewall to use ipchains instead of
+the older ipfwadm commands from the 2.0.x kernels.  There's a neat utility to
+convert ipfwadm commands to ipchains commands:
+
+   http://users.dhp.com/~whisper/ipfwadm2ipchains/
+
+You may also wish to modify the firewall script to implement a different
+firewalling scheme.
+
+9.) Start the PPP connection via the script /etc/ppp/ppp@gi-on.  You must be
+root to do this.  It's better to use a utility like sudo to execute
+frequently used commands like this with root permissions if possible.  If you
+connect successfully the cable modem interface will come up and you'll see a
+driver message like this at the console:
+
+         cm0: sb1000 at (0x110,0x310), csn 1, S/N 0x2a0d16d8, IRQ 11.
+         sb1000.c:v1.1.2 6/01/98 (fventuri@mediaone.net)
+
+The "ifconfig" command should show two new interfaces, ppp0 and cm0.
+The command "cmconfig cm0" will give you information about the cable modem
+interface.
+
+10.) Try pinging a site via `ping -c 5 www.yahoo.com', for example.  You should
+see packets received.
+
+11.) If you can't get site names (like www.yahoo.com) to resolve into
+IP addresses (like 204.71.200.67), be sure your /etc/resolv.conf file
+has no syntax errors and has the right nameserver IP addresses in it.
+If this doesn't help, try something like `ping -c 5 204.71.200.67' to
+see if the networking is running but the DNS resolution is where the
+problem lies.
+
+12.) If you still have problems, go to the support web sites mentioned above
+and read the information and documentation there.
+
+-----------------------------------------------------------------------------
+
+Common problems:
+
+1.) Packets go out on the ppp0 interface but don't come back on the cm0
+interface.  It looks like I'm connected but I can't even ping any
+numerical IP addresses.  (This happens predominantly on Debian systems due
+to a default boot-time configuration script.)
+
+Solution -- As root `echo 0 > /proc/sys/net/ipv4/conf/cm0/rp_filter' so it
+can share the same IP address as the ppp0 interface.  Note that this
+command should probably be added to the /etc/ppp/cablemodem script
+*right*between* the "/sbin/ifconfig" and "/sbin/cmconfig" commands.
+You may need to do this to /proc/sys/net/ipv4/conf/ppp0/rp_filter as well.
+If you do this to /proc/sys/net/ipv4/conf/default/rp_filter on each reboot
+(in rc.local or some such) then any interfaces can share the same IP
+addresses.
+
+2.) I get "unresolved symbol" error messages on executing `insmod sb1000.o'.
+
+Solution -- You probably have a non-matching kernel source tree and
+/usr/include/linux and /usr/include/asm header files.  Make sure you
+install the correct versions of the header files in these two directories.
+Then rebuild and reinstall the kernel.
+
+3.) When isapnp runs it reports an error, and my SB1000 card isn't working.
+
+Solution -- There's a problem with later versions of isapnp using the "(CHECK)"
+option in the lines that allocate the two I/O addresses for the SB1000 card.
+This first popped up on RH 6.0.  Delete "(CHECK)" for the SB1000 I/O addresses.
+Make sure they don't conflict with any other pieces of hardware first!  Then
+rerun isapnp and go from there.
+
+4.) I can't execute the /etc/ppp/ppp@gi-on file.
+
+Solution -- As root do `chmod ug+x /etc/ppp/ppp@gi-on'.
+
+5.) The firewall script isn't working (with 2.2.x and higher kernels).
+
+Solution -- Use the ipfwadm2ipchains script referenced above to convert the
+/etc/ppp/firewall script from the deprecated ipfwadm commands to ipchains.
+
+6.) I'm getting *tons* of firewall deny messages in the /var/kern.log,
+/var/messages, and/or /var/syslog files, and they're filling up my /var
+partition!!!
+
+Solution -- First, tell your ISP that you're receiving DoS (Denial of Service)
+and/or portscanning (UDP connection attempts) attacks!  Look over the deny
+messages to figure out what the attack is and where it's coming from.  Next,
+edit /etc/ppp/cablemodem and make sure the ",nobroadcast" option is turned on
+to the "cmconfig" command (uncomment that line).  If you're not receiving these
+denied packets on your broadcast interface (IP address xxx.yyy.zzz.255
+typically), then someone is attacking your machine in particular.  Be careful
+out there....
+
+7.) Everything seems to work fine but my computer locks up after a while
+(and typically during a lengthy download through the cable modem)!
+
+Solution -- You may need to add a short delay in the driver to 'slow down' the
+SURFboard because your PC might not be able to keep up with the transfer rate
+of the SB1000. To do this, it's probably best to download Franco's
+sb1000-1.1.2.tar.gz archive and build and install sb1000.o manually.  You'll
+want to edit the 'Makefile' and look for the 'SB1000_DELAY'
+define.  Uncomment those 'CFLAGS' lines (and comment out the default ones)
+and try setting the delay to something like 60 microseconds with:
+'-DSB1000_DELAY=60'.  Then do `make' and as root `make install' and try
+it out.  If it still doesn't work or you like playing with the driver, you may
+try other numbers.  Remember though that the higher the delay, the slower the
+driver (which slows down the rest of the PC too when it is actively
+used). Thanks to Ed Daiga for this tip!
+
+-----------------------------------------------------------------------------
+
+Credits:  This README came from Franco Venturi's original README file which is
+still supplied with his driver .tar.gz archive.  I and all other sb1000 users
+owe Franco a tremendous "Thank you!"  Additional thanks goes to Carl Patten
+and Ralph Bonnell who are now managing the Linux SB1000 web site, and to
+the SB1000 users who reported and helped debug the common problems listed
+above.
+
+
+                                       Clemmitt Sigler
+                                       csigler@vt.edu
index 4321f92cb7b6237cbdec8a09227ac77aa208235e..6532b058ed92cdf305d3a97172230fd0d8d9d5b5 100644 (file)
@@ -29,7 +29,7 @@ trivial patch so apply some common sense.
        job the maintainers (and especially Linus) do is to keep things
        looking the same. Sometimes this means that the clever hack in
        your driver to get around a problem actually needs to become a
-       generalized kernel feature ready for next time. See 
+       generalized kernel feature ready for next time. See
        Documentation/CodingStyle for guidance here.
 
        PLEASE try to include any credit lines you want added with the
@@ -63,7 +63,7 @@ S: Status, one of the following:
        Maintained:     Someone actually looks after it.
        Odd Fixes:      It has a maintainer but they don't have time to do
                        much other than throw the odd patch in. See below..
-       Orphan:         No current maintainer [but maybe you could take the 
+       Orphan:         No current maintainer [but maybe you could take the
                        role as you write your new code].
        Obsolete:       Old code. Something tagged obsolete generally means
                        it has been replaced by a better system and you
@@ -131,12 +131,6 @@ M: Jay.Schulist@spacs.k12.wi.us
 L:     linux-atalk@netspace.org
 S:     Maintained
 
-ARPD SUPPORT
-P:     Jonathan Layes
-M:     layes@loran.com
-L:     linux-net@vger.rutgers.edu
-S:     Maintained
-
 ARM MFM AND FLOPPY DRIVERS
 P:     Dave Gilbert
 M:     linux@treblig.org
@@ -150,6 +144,12 @@ L: arm-linux@tardis.ed.ac.uk
 W:     http://www.arm.uk.linux.org/~rmk/armlinux.html
 S:     Maintained
 
+ARPD SUPPORT
+P:     Jonathan Layes
+M:     layes@loran.com
+L:     linux-net@vger.rutgers.edu
+S:     Maintained
+
 AX.25 NETWORK LAYER
 P:     Matthias Welwarsky
 M:     dg2fef@afthd.tu-darmstadt.de
@@ -182,6 +182,12 @@ M: jgarzik@pobox.com
 L:     linux-fbdev@vuser.vu.union.edu
 S:     Maintained
 
+COMPAQ SMART2 RAID DRIVER
+P:     Charles White   
+M:     Charles White <arrays@compaq.com>
+L:     compaqandlinux@yps.org  
+S:     Maintained
+
 COMPUTONE INTELLIPORT MULTIPORT CARD
 P:     Doug McNash
 P:     Michael H. Warfield
@@ -287,12 +293,6 @@ M: mike@i-Connect.Net
 L:     linux-eata@i-connect.net, linux-scsi@vger.rutgers.edu
 S:     Maintained
 
-COMPAQ SMART2 RAID DRIVER
-P:     Charles White   
-M:     Charles White <arrays@compaq.com>
-L:     compaqandlinux@yps.org  
-S:     Maintained
-
 EATA ISA/EISA/PCI SCSI DRIVER
 P:     Dario Ballabio
 M:     dario@milano.europe.dg.com
@@ -369,7 +369,7 @@ S:  Maintained
 
 HFS FILESYSTEM
 P:      Adrian Sun
-M:      asun@u.washington.edu
+M:      asun@cobaltnet.com
 L:      linux-kernel@vger.rutgers.edu
 S:      Maintained
 
@@ -390,17 +390,23 @@ P:        Jaroslav Kysela
 M:     perex@suse.cz
 S:     Maintained
 
+HPFS FILESYSTEM
+P:     Mikulas Patocka
+M:     mikulas@artax.karlin.mff.cuni.cz
+W:     http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
+S:     Maintained
+
 IBM MCA SCSI SUBSYSTEM DRIVER
 P:     Michael Lang
 M:     langa2@kph.uni-mainz.de
 W:     http://www.uni-mainz.de/~langm000/linux.html
 S:     Maintained
 
-HPFS FILESYSTEM
-P:     Mikulas Patocka
-M:     mikulas@artax.karlin.mff.cuni.cz
-W:     http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
-S:     Maintained
+IBM ServeRAID RAID DRIVER
+P:      Keith Mitchell
+M:      ipslinux@us.ibm.com
+W:      http://www.developer.ibm.com/welcome/netfinity/serveraid_beta.html
+S:      Supported
 
 IBM ServeRAID RAID DRIVER
 P:      Keith Mitchell
@@ -415,7 +421,7 @@ L:  linux-kernel@vger.rutgers.edu
 W:     http://linux.kernel.org/pub/linux/kernel/people/hedrick/
 S:     Supported
 
-IDE/ATAPI CDROM DRIVER 
+IDE/ATAPI CDROM DRIVER
 P:     Jens Axboe
 M:     axboe@image.dk
 L:     linux-kernel@vger.rutgers.edu
@@ -524,8 +530,9 @@ S:  Maintained
 
 MISCELLANEOUS MCA-SUPPORT
 P:     David Weinehall
-M:     mcalinux@acc.umu.se (project MCA-team)
 M:     tao@acc.umu.se (personal)
+W:     http://www.acc.umu.se/~tao/
+W:     http://www.acc.umu.se/~mcalinux/
 L:     linux-kernel@vger.rutgers.edu
 S:     Maintained
 
@@ -571,7 +578,7 @@ L:  netfilter@lists.samba.org
 S:     Supported
 
 NETROM NETWORK LAYER
-P:     Tomi Manninen 
+P:     Tomi Manninen
 M:     Tomi.Manninen@hut.fi
 L:     linux-hams@vger.rutgers.edu
 S:     Maintained
@@ -627,16 +634,6 @@ L: linux-tr@emissary.aus-etc.com
 W:     http://www.linuxtr.net
 S:     Maintained
 
-OLYMPIC NETWORK DRIVER
-P:     Peter De Shrijver
-M:     p2@ace.ulyssis.sutdent.kuleuven.ac.be   
-P:     Mike Phillips
-M:     phillim@amtrak.com
-L:     linux-net@vger.rutgers.edu
-L:     linux-tr@emissary.aus-etc.com
-W:     http://www.linuxtr.net
-S:     Maintained
-
 OPL3-SA2, SA3, and SAx DRIVER
 P:     Scott Murray
 M:     scottm@interlog.com
@@ -668,17 +665,23 @@ P:        Jens Maurer
 M:     jmaurer@cck.uni-kl.de
 S:     Maintained
 
+PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES)
+P:     Thomas Sailer
+M:     sailer@ife.ee.ethz.ch
+L:     linux-sound@vger.rutgers.edu
+W:     http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html
+S:     Maintained
+
 PCI SUBSYSTEM
 P:     Martin Mares
 M:     mj@atrey.karlin.mff.cuni.cz
 L:     linux-kernel@vger.rutgers.edu
 S:     Maintained
 
-PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES)
-P:     Thomas Sailer
-M:     sailer@ife.ee.ethz.ch
-L:     linux-sound@vger.rutgers.edu
-W:     http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html
+PCMCIA SUBSYSTEM
+P:     David Hinds
+M:     dhinds@zen.stanford.edu
+L:     linux-kernel@vger.rutgers.edu
 S:     Maintained
 
 PCNET32 NETWORK DRIVER
@@ -701,6 +704,12 @@ M: longyear@pobox.com
 L:     linux-ppp@vger.rutgers.edu
 S:     Maintained
 
+RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER
+P:     Corey Thomas
+M:     corey@world.std.com
+L:     linux-kernel@vger.rutgers.edu
+S:     Maintained
+
 REAL TIME CLOCK DRIVER
 P:     Paul Gortmaker
 M:     p_gortmaker@yahoo.com
@@ -725,7 +734,7 @@ M:  emoenke@gwdg.de
 L:     linux-kernel@vger.rutgers.edu
 S:     Maintained
 
-SCSI CDROM DRIVER 
+SCSI CDROM DRIVER
 P:     Jens Axboe
 M:     axboe@image.dk
 L:     linux-kernel@vger.rutgers.edu
@@ -776,7 +785,7 @@ L:  linux-net@vger.rutgers.edu
 S:     Maintained
 
 SOUND
-P:     Alan Cox 
+P:     Alan Cox
 M:     alan@redhat.com
 S:     Supported
 
@@ -860,7 +869,7 @@ M:  mnalis@jagor.srce.hr
 L:     linux-kernel@vger.rutgers.edu
 S:     Maintained
 
-UNIFORM CDROM DRIVER 
+UNIFORM CDROM DRIVER
 P:     Jens Axboe
 M:     axboe@image.dk
 L:     linux-kernel@vger.rutgers.edu
@@ -888,6 +897,11 @@ L: linux-kernel@vger.rutgers.edu
 W:     http://bmrc.berkeley.edu/people/chaffee
 S:     Maintained
 
+VIA 82Cxxx AUDIO DRIVER
+P:     Jeff Garzik
+M:     jgarzik@pobox.com
+S:     Maintained
+
 VIDEO FOR LINUX
 P:     Alan Cox
 M:     Alan.Cox@linux.org
index 58e116ce9861b1d8c94ccb49d0e014fc0fab5e18..9d9f99b55ecf488cf168004e9a959d4965f22187 100644 (file)
@@ -285,6 +285,7 @@ CONFIG_EEXPRESS_PRO100=y
 # PCMCIA network devices
 #
 # CONFIG_PCMCIA_PCNET is not set
+# CONFIG_PCMCIA_3C589 is not set
 CONFIG_PCMCIA_RAYCS=y
 
 #
index efd8e8bc04120808897bd7674e037eb6b356db29..ce408284840af9c5083ab2aac952757e39760399 100644 (file)
@@ -385,7 +385,7 @@ void __init init_IRQ(void)
 #endif 
 
        /*
-        * Set the clock to 100 Hz, we already have a valid
+        * Set the clock to HZ Hz, we already have a valid
         * vector now:
         */
        outb_p(0x34,0x43);              /* binary, mode 2, LSB/MSB, ch 0 */
index 7a4c37236877bd6ff7ca22d1b0b0cb562c15097e..f76c68f594d2f7fa59012d358d0691d55d1e4927 100644 (file)
     19990512   Richard Gooch <rgooch@atnf.csiro.au>
               Minor cleanups.
   v1.35
+    19990707   Zoltan Boszormenyi <zboszor@mol.hu>
+               Check whether ARR3 is protected in cyrix_get_free_region()
+               and mtrr_del(). The code won't attempt to delete or change it
+               from now on if the BIOS protected ARR3. It silently skips ARR3
+               in cyrix_get_free_region() or returns with an error code from
+               mtrr_del().
+    19990711   Zoltan Boszormenyi <zboszor@mol.hu>
+               Reset some bits in the CCRs in cyrix_arr_init() to disable SMM
+               if ARR3 isn't protected. This is needed because if SMM is active
+               and ARR3 isn't protected then deleting and setting ARR3 again
+               may lock up the processor. With SMM entirely disabled, it does
+               not happen.
+    19990812   Zoltan Boszormenyi <zboszor@mol.hu>
+               Rearrange switch() statements so the driver accomodates to
+               the fact that the AMD Athlon handles its MTRRs the same way
+               as Intel does.
+    19990814   Zoltan Boszormenyi <zboszor@mol.hu>
+              Double check for Intel in mtrr_add()'s big switch() because
+              that revision check is only valid for Intel CPUs.
+    19990819   Alan Cox <alan@redhat.com>
+               Tested Zoltan's changes on a pre production Athlon - 100%
+               success.
 */
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -309,6 +331,7 @@ struct set_mtrr_context
     unsigned long ccr3;
 };
 
+static int arr3_protected;
 
 /*  Put the processor into a state where MTRRs can be safely set  */
 static void set_mtrr_prepare (struct set_mtrr_context *ctxt)
@@ -321,6 +344,8 @@ static void set_mtrr_prepare (struct set_mtrr_context *ctxt)
     switch (boot_cpu_data.x86_vendor)
     {
       case X86_VENDOR_AMD:
+       if (boot_cpu_data.x86 >= 6) break; /* Athlon and post-Athlon CPUs */
+       /* else fall through */
       case X86_VENDOR_CENTAUR:
        return;
        /*break;*/
@@ -344,6 +369,7 @@ static void set_mtrr_prepare (struct set_mtrr_context *ctxt)
 
     switch (boot_cpu_data.x86_vendor)
     {
+      case X86_VENDOR_AMD:
       case X86_VENDOR_INTEL:
        /*  Disable MTRRs, and set the default type to uncached  */
        rdmsr (MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi);
@@ -365,6 +391,8 @@ static void set_mtrr_done (struct set_mtrr_context *ctxt)
     switch (boot_cpu_data.x86_vendor)
     {
       case X86_VENDOR_AMD:
+       if (boot_cpu_data.x86 >= 6) break; /* Athlon and post-Athlon CPUs */
+       /* else fall through */
       case X86_VENDOR_CENTAUR:
        __restore_flags (ctxt->flags);
        return;
@@ -376,6 +404,7 @@ static void set_mtrr_done (struct set_mtrr_context *ctxt)
     /*  Restore MTRRdefType  */
     switch (boot_cpu_data.x86_vendor)
     {
+      case X86_VENDOR_AMD:
       case X86_VENDOR_INTEL:
        wrmsr (MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi);
        break;
@@ -406,6 +435,9 @@ static unsigned int get_num_var_ranges (void)
 
     switch (boot_cpu_data.x86_vendor)
     {
+      case X86_VENDOR_AMD:
+       if (boot_cpu_data.x86 < 6) return 2; /* pre-Athlon CPUs */
+       /* else fall through */
       case X86_VENDOR_INTEL:
        rdmsr (MTRRcap_MSR, config, dummy);
        return (config & 0xff);
@@ -416,9 +448,6 @@ static unsigned int get_num_var_ranges (void)
         /*  and Centaur has 8 MCR's  */
        return 8;
        /*break;*/
-      case X86_VENDOR_AMD:
-       return 2;
-       /*break;*/
     }
     return 0;
 }   /*  End Function get_num_var_ranges  */
@@ -430,12 +459,14 @@ static int have_wrcomb (void)
 
     switch (boot_cpu_data.x86_vendor)
     {
+      case X86_VENDOR_AMD:
+       if (boot_cpu_data.x86 < 6) return 1; /* pre-Athlon CPUs */
+       /* else fall through */
       case X86_VENDOR_INTEL:
        rdmsr (MTRRcap_MSR, config, dummy);
        return (config & (1<<10));
        /*break;*/
       case X86_VENDOR_CYRIX:
-      case X86_VENDOR_AMD:
       case X86_VENDOR_CENTAUR:
        return 1;
        /*break;*/
@@ -1030,6 +1061,7 @@ static int cyrix_get_free_region (unsigned long base, unsigned long size)
        for (i = 0; i < 7; i++)
        {
            cyrix_get_arr (i, &lbase, &lsize, &ltype);
+           if ((i == 3) && arr3_protected) continue;
            if (lsize < 1) return i;
        }
        /* ARR0-ARR6 isn't free, try ARR7 but its size must be at least 256K */
@@ -1062,13 +1094,30 @@ int mtrr_add (unsigned long base, unsigned long size, unsigned int type,
     if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return -ENODEV;
     switch (boot_cpu_data.x86_vendor)
     {
+      case X86_VENDOR_AMD:
+       if (boot_cpu_data.x86 < 6) { /* pre-Athlon CPUs */
+         /* Apply the K6 block alignment and size rules
+            In order
+               o Uncached or gathering only
+               o 128K or bigger block
+               o Power of 2 block
+               o base suitably aligned to the power
+           */
+         if (type > MTRR_TYPE_WRCOMB || size < (1 << 17) ||
+             (size & ~(size-1))-size || (base & (size-1)))
+             return -EINVAL;
+         break;
+       } /* else fall through */
       case X86_VENDOR_INTEL:
-       /*  For Intel PPro stepping <= 7, must be 4 MiB aligned  */
-       if ( (boot_cpu_data.x86 == 6) && (boot_cpu_data.x86_model == 1) &&
-            (boot_cpu_data.x86_mask <= 7) && ( base & ( (1 << 22) - 1 ) ) )
-       {
-           printk ("mtrr: base(0x%lx) is not 4 MiB aligned\n", base);
-           return -EINVAL;
+       /*  Double check for Intel, we may run on Athlon. */
+       if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
+         /*  For Intel PPro stepping <= 7, must be 4 MiB aligned  */
+         if ( (boot_cpu_data.x86 == 6) && (boot_cpu_data.x86_model == 1) &&
+              (boot_cpu_data.x86_mask <= 7) && ( base & ( (1 << 22) - 1 ) ) )
+         {
+             printk ("mtrr: base(0x%lx) is not 4 MiB aligned\n", base);
+             return -EINVAL;
+         }
        }
        /*  Fall through  */
       case X86_VENDOR_CYRIX:
@@ -1105,18 +1154,6 @@ int mtrr_add (unsigned long base, unsigned long size, unsigned int type,
            return -EINVAL;
        }
        break;
-      case X86_VENDOR_AMD:
-       /* Apply the K6 block alignment and size rules
-          In order
-             o Uncached or gathering only
-             o 128K or bigger block
-             o Power of 2 block
-             o base suitably aligned to the power
-         */
-       if (type > MTRR_TYPE_WRCOMB || size < (1 << 17) ||
-           (size & ~(size-1))-size || (base & (size-1)))
-           return -EINVAL;
-       break;
       default:
        return -EINVAL;
        /*break;*/
@@ -1221,6 +1258,15 @@ int mtrr_del (int reg, unsigned long base, unsigned long size)
        printk ("mtrr: register: %d too big\n", reg);
        return -EINVAL;
     }
+    if (boot_cpu_data.x86_vendor == X86_VENDOR_CYRIX)
+    {
+       if ((reg == 3) && arr3_protected)
+       {
+           spin_unlock (&main_lock);
+           printk ("mtrr: ARR3 cannot be changed\n");
+           return -EINVAL;
+       }
+    }
     (*get_mtrr) (reg, &lbase, &lsize, &ltype);
     if (lsize < 1)
     {
@@ -1585,22 +1631,22 @@ static void __init cyrix_arr_init(void)
     ccr[5] = getCx86 (CX86_CCR5);
     ccr[6] = getCx86 (CX86_CCR6);
 
-    if (ccr[3] & 1)
+    if (ccr[3] & 1) {
       ccrc[3] = 1;
-    else {
+      arr3_protected = 1;
+    } else {
       /* Disable SMM mode (bit 1), access to SMM memory (bit 2) and
        * access to SMM memory through ARR3 (bit 7).
        */
-/*
       if (ccr[1] & 0x80) { ccr[1] &= 0x7f; ccrc[1] |= 0x80; }
       if (ccr[1] & 0x04) { ccr[1] &= 0xfb; ccrc[1] |= 0x04; }
       if (ccr[1] & 0x02) { ccr[1] &= 0xfd; ccrc[1] |= 0x02; }
-*/
+      arr3_protected = 0;
       if (ccr[6] & 0x02) {
         ccr[6] &= 0xfd; ccrc[6] = 1; /* Disable write protection of ARR3. */
         setCx86 (CX86_CCR6, ccr[6]);
       }
-      /* Disable ARR3. */
+      /* Disable ARR3. This is safe now that we disabled SMM. */
       /* cyrix_set_arr_up (3, 0, 0, 0, FALSE); */
     }
     /* If we changed CCR1 in memory, change it in the processor, too. */
@@ -1660,6 +1706,12 @@ 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)
     {
+      case X86_VENDOR_AMD:
+       if (boot_cpu_data.x86 < 6) { /* pre-Athlon CPUs */
+         get_mtrr = amd_get_mtrr;
+         set_mtrr_up = amd_set_mtrr_up;
+         break;
+       } /* else fall through */
       case X86_VENDOR_INTEL:
        get_mtrr = intel_get_mtrr;
        set_mtrr_up = intel_set_mtrr_up;
@@ -1669,10 +1721,6 @@ static void __init mtrr_setup(void)
        set_mtrr_up = cyrix_set_arr_up;
        get_free_region = cyrix_get_free_region;
        break;
-      case X86_VENDOR_AMD:
-       get_mtrr = amd_get_mtrr;
-       set_mtrr_up = amd_set_mtrr_up;
-       break;
      case X86_VENDOR_CENTAUR:
         get_mtrr = centaur_get_mcr;
         set_mtrr_up = centaur_set_mcr_up;
@@ -1691,6 +1739,8 @@ void __init mtrr_init_boot_cpu(void)
     mtrr_setup ();
     switch (boot_cpu_data.x86_vendor)
     {
+      case X86_VENDOR_AMD:
+       if (boot_cpu_data.x86 < 6) break; /* pre-Athlon CPUs */
       case X86_VENDOR_INTEL:
        get_mtrr_state (&smp_mtrr_state);
        break;
@@ -1727,6 +1777,9 @@ void __init mtrr_init_secondary_cpu(void)
     if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return;
     switch (boot_cpu_data.x86_vendor)
     {
+      case X86_VENDOR_AMD:
+       /* Just for robustness: pre-Athlon CPUs cannot do SMP. */
+       if (boot_cpu_data.x86 < 6) break;
       case X86_VENDOR_INTEL:
        intel_mtrr_init_secondary_cpu ();
        break;
@@ -1752,6 +1805,8 @@ int __init mtrr_init(void)
 #  ifdef __SMP__
     switch (boot_cpu_data.x86_vendor)
     {
+      case X86_VENDOR_AMD:
+       if (boot_cpu_data.x86 < 6) break; /* pre-Athlon CPUs */
       case X86_VENDOR_INTEL:
        finalize_mtrr_state (&smp_mtrr_state);
        mtrr_state_warn (smp_changes_mask);
index 31a9c847faad51b854ab1f456115142241de61ab..88ba3feeb9a2163c81c6d0f7bc77a2ed6cb00fce 100644 (file)
@@ -61,6 +61,7 @@
 #include <asm/msr.h>
 #include <asm/desc.h>
 #include <asm/e820.h>
+#include <asm/dma.h>
 
 /*
  * Machine setup..
@@ -401,18 +402,49 @@ void __init add_memory_region(unsigned long start,
 
 void __init setup_memory_region(void)
 {
+#define E820_DEBUG     0
+#ifdef E820_DEBUG
+       int i;
+#endif
+
        /*
         * If we're lucky and live on a modern system, the setup code
         * will have given us a memory map that we can use to properly
         * set up memory.  If we aren't, we'll fake a memory map.
+        *
+        * We check to see that the memory map contains at least 2 elements
+        * before we'll use it, because the detection code in setup.S may
+        * not be perfect and most every PC known to man has two memory
+        * regions: one from 0 to 640k, and one from 1mb up.  (The IBM
+        * thinkpad 560x, for example, does not cooperate with the memory
+        * detection code.)
         */
-       if (E820_MAP_NR) {
+       if (E820_MAP_NR > 1) {
                /* got a memory map; copy it into a safe place.
                 */
                e820.nr_map = E820_MAP_NR;
                if (e820.nr_map > E820MAX)
                        e820.nr_map = E820MAX;
                memcpy(e820.map, E820_MAP, e820.nr_map * sizeof e820.map[0]);
+#ifdef E820_DEBUG
+               for (i=0; i < e820.nr_map; i++) {
+                       printk("e820: %ld @ %08lx ",
+                               (unsigned long)(e820.map[i].size),
+                               (unsigned long)(e820.map[i].addr));
+                       switch (e820.map[i].type) {
+                       case E820_RAM:  printk("(usable)\n");
+                                       break;
+                       case E820_RESERVED:
+                                       printk("(reserved)\n");
+                                       break;
+                       case E820_ACPI:
+                                       printk("(ACPI data)\n");
+                                       break;
+                       default:        printk("type %lu\n", e820.map[i].type);
+                                       break;
+                       }
+               }
+#endif
        }
        else {
                /* otherwise fake a memory map; one section from 0k->640k,
@@ -422,8 +454,8 @@ void __init setup_memory_region(void)
 
                mem_size = (ALT_MEM_K < EXT_MEM_K) ? EXT_MEM_K : ALT_MEM_K;
 
-               add_memory_region(0, LOWMEMSIZE(), 1);
-               add_memory_region(HIGH_MEMORY, mem_size << 10, 1);
+               add_memory_region(0, LOWMEMSIZE(), E820_RAM);
+               add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
        }
 } /* setup_memory_region */
 
@@ -503,7 +535,7 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigne
                                         */
                                        e820.nr_map = 0;
                                        usermem = 1;
-                                       add_memory_region(0, LOWMEMSIZE(), 1);
+                                       add_memory_region(0, LOWMEMSIZE(), E820_RAM);
                                }
                                mem_size = memparse(from+4, &from);
                                if (*from == '@')
@@ -512,7 +544,7 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigne
                                        start_at = HIGH_MEMORY;
                                        mem_size -= HIGH_MEMORY;
                                }
-                               add_memory_region(start_at, mem_size, 1);
+                               add_memory_region(start_at, mem_size, E820_RAM);
                        }
                }
                c = *(from++);
@@ -531,7 +563,7 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigne
        memory_end = 0;
        for (i=0; i < e820.nr_map; i++) {
                /* RAM? */
-               if (e820.map[i].type == 1) {
+               if (e820.map[i].type == E820_RAM) {
                        unsigned long end = e820.map[i].addr + e820.map[i].size;
 
                        if (end > memory_end)
@@ -856,6 +888,15 @@ static void __init cyrix_model(struct cpuinfo_x86 *c)
                        c->x86_model = (dir1 & 0x20) ? 1 : 2;
                        c->x86_capability&=~X86_FEATURE_TSC;
                }
+#ifdef CONFIG_PCI
+               /* It isnt really a PCI quirk directly, but the cure is the
+                  same. The MediaGX has deep magic SMM stuff that handles the
+                  SB emulation. It thows away the fifo on disable_dma() which
+                  is wrong and ruins the audio. */
+               
+               printk(KERN_INFO "Working around Cyrix MediaGX virtual DMA bug.\n");
+               isa_dma_bridge_buggy = 1;
+#endif         
                break;
 
         case 5: /* 6x86MX/M II */
@@ -881,8 +922,8 @@ static void __init cyrix_model(struct cpuinfo_x86 *c)
                        dir0_msn = 0;
                        p = Cx486S_name[0];
                        break;
-               break;
                }
+               break;
 
        default:  /* unknown (shouldn't happen, we know everyone ;-) */
                dir0_msn = 7;
index 4f55a89f89696827fb158b80b2f26ab452353116..05684997fa9278a38abab78ef268e9e1a96ca38c 100644 (file)
@@ -414,25 +414,23 @@ void __init mem_init(unsigned long start_mem, unsigned long end_mem)
        for (avail = i = 0; i < e820.nr_map; i++) {
                unsigned long addr, end, size;
 
-               if (e820.map[i].type != 1)      /* not usable memory */
+               if (e820.map[i].type != E820_RAM)       /* not usable memory */
                        continue;
                addr = e820.map[i].addr;
                size = e820.map[i].size;
 
-               /* Overflow large memory reasonably gracefully */
+               /* Silently ignore memory regions starting above 4gb */
                if (addr != e820.map[i].addr)
                        continue;
 
                printk("memory region: %luk @ %08lx\n", size >> 10, addr );
 
                /* Make sure we don't get fractional pages */
-               end = (addr + size) & PAGE_MASK;
-               addr = PAGE_ALIGN(addr);
-               if (end <= addr)
-                       continue;
+               end = PAGE_OFFSET + ((addr + size) & PAGE_MASK);
+               addr= PAGE_OFFSET + PAGE_ALIGN(addr);
+
+               for ( ; addr < end; addr += PAGE_SIZE) {
 
-               size = end - addr;
-               for (addr = addr + PAGE_OFFSET ; size ; addr += PAGE_SIZE, size -= PAGE_SIZE) {
                        /* this little bit of grossness is for dealing
                         * with memory borrowing for system bookkeeping
                         * (smp stacks, zero page, kernel code, etc)
@@ -446,14 +444,11 @@ void __init mem_init(unsigned long start_mem, unsigned long end_mem)
                         * in any case, we don't want to hack mem_map
                         * entries above end_mem.
                         */
-                       if ( addr < start_low_mem )
-                               continue;
-                       if ( addr > end_mem )
-                               continue;
-                       if ( addr >= HIGH_MEMORY && addr <= start_mem )
+                       if ( (addr < start_low_mem)
+                         || (addr >= (HIGH_MEMORY + PAGE_OFFSET)&& addr <= start_mem)
+                         || (addr > end_mem) )
                                continue;
 
-                       avail++;
                        clear_bit(PG_reserved, &mem_map[MAP_NR(addr)].flags);
                }
        }
index 5664f0ea21ee2737af47a719b9537738a6278ebb..7c434938fc963daaab1dd54e03c969b75a8367f8 100644 (file)
@@ -674,7 +674,7 @@ static inline int tx_take (amb_dev * dev) {
     return 0;
   } else {
     
-    spin_unlock_irqrestore (&dev->lock, flags);
+    spin_unlock_irqrestore (&txq->lock, flags);
     return -1;
   }
 }
index e1d776efda14cffe97934238eda658e3fe0833ea..a177e7de6217c07210c637d4e05417a78c1122cd 100644 (file)
@@ -29,9 +29,7 @@
 #include <linux/major.h>
 #include <linux/malloc.h>
 #include <linux/mm.h>
-#if LINUX_VERSION_CODE >= 0x020100
 #include <linux/poll.h>
-#endif
 #include <linux/pci.h>
 #include <linux/signal.h>
 #include <asm/io.h>
 #include <linux/wrapper.h>
 #include <linux/interrupt.h>
 
-#if LINUX_VERSION_CODE >= 0x020100
 #include <asm/uaccess.h>
 #include <linux/vmalloc.h>
-#else
-#include <linux/bios32.h>
-#define mdelay(x) udelay((x)*1000)
-#define signal_pending(current)  (current->signal & ~current->blocked)
-#define sigfillset(set)
-
-static inline int time_before(unsigned long a, unsigned long b)
-{
-       return((long)((a) - (b)) < 0L);
-}
-
-static inline unsigned long
-copy_to_user(void *to, const void *from, unsigned long n)
-{
-        memcpy_tofs(to,from,n);
-       return 0;
-}
-
-static inline unsigned long
-copy_from_user(void *to, const void *from, unsigned long n)
-{
-        memcpy_fromfs(to,from,n);
-       return 0;
-}
-#define ioremap vremap 
-#define iounmap vfree
-#endif
 
 #include <linux/videodev.h>
 #include <linux/i2c.h>
@@ -83,19 +53,10 @@ copy_from_user(void *to, const void *from, unsigned long n)
 #define DEBUG(x)               /* Debug driver */      
 #define IDEBUG(x)              /* Debug interrupt handler */
 
-#if LINUX_VERSION_CODE >= 0x020117
-MODULE_PARM(vidmem,"i");
-MODULE_PARM(triton1,"i");
-MODULE_PARM(remap,"1-4i");
-MODULE_PARM(radio,"1-4i");
-MODULE_PARM(card,"1-4i");
-MODULE_PARM(pll,"1-4i");
-#endif
 
 /* Anybody who uses more than four? */
 #define BTTV_MAX 4
 
-static int find_vga(void);
 static void bt848_set_risc_jmps(struct bttv *btv);
 
 static unsigned int vidmem=0;   /* manually set video mem address */
@@ -243,6 +204,12 @@ static void rvfree(void * mem, unsigned long size)
        }
 }
 
+MODULE_PARM(vidmem,"i");
+MODULE_PARM(triton1,"i");
+MODULE_PARM(remap,"1-4i");
+MODULE_PARM(radio,"1-4i");
+MODULE_PARM(card,"1-4i");
+MODULE_PARM(pll,"1-4i");
 
 
 /*
@@ -403,7 +370,7 @@ static void writeee(struct i2c_bus *bus, unsigned char *eedata)
        }
 }
 
-void attach_inform(struct i2c_bus *bus, int id)
+static void attach_inform(struct i2c_bus *bus, int id)
 {
         struct bttv *btv = (struct bttv*)bus->data;
         
@@ -422,7 +389,7 @@ void attach_inform(struct i2c_bus *bus, int id)
        }
 }
 
-void detach_inform(struct i2c_bus *bus, int id)
+static void detach_inform(struct i2c_bus *bus, int id)
 {
         struct bttv *btv = (struct bttv*)bus->data;
 
@@ -563,7 +530,7 @@ static struct tvcard tvcards[] =
         /* MIRO PCTV pro */
         { 3, 1, 0, 2, 65551, { 2, 3, 1, 1}, {1,65537, 0, 0,10}},
        /* ADS Technologies Channel Surfer TV (and maybe TV+FM) */
-       { 3, 4, 2, 2, 15, { 2, 3, 1, 1}, { 13, 14, 11, 7, 0, 0}, 0},
+       { 3, 4, 0, 2, 15, { 2, 3, 1, 1}, { 13, 14, 11, 7, 0, 0}, 0},
         /* AVerMedia TVCapture 98 */
        { 3, 4, 0, 2, 15, { 2, 3, 1, 1}, { 13, 14, 11, 7, 0, 0}, 0},
         /* Aimslab VHX */
@@ -1591,20 +1558,18 @@ static long bttv_read(struct video_device *v, char *buf, unsigned long count, in
 static int bttv_open(struct video_device *dev, int flags)
 {
        struct bttv *btv = (struct bttv *)dev;
-       int users, i;
-
+       int i, ret;
+       
+       ret = -EBUSY;
+       down(&btv->lock);
         if (btv->user)
-                return -EBUSY;
-        audio(btv, AUDIO_UNMUTE);
-        for (i=users=0; i<bttv_num; i++)
-                users+=bttvs[i].user;
-        if (users==1)
-                find_vga();
-        btv->fbuffer=NULL;
-        if (!btv->fbuffer)
-                btv->fbuffer=(unsigned char *) rvmalloc(2*BTTV_MAX_FBUF);
+               goto out_unlock;
+
+       btv->fbuffer= (unsigned char *) rvmalloc(2*BTTV_MAX_FBUF);
+       ret = -ENOMEM;
         if (!btv->fbuffer)
-                return -EINVAL;
+               goto out_unlock;
+       audio(btv, AUDIO_UNMUTE);
         btv->grabbing = 0;
         btv->grab = 0;
         btv->lastgrab = 0;
@@ -1612,14 +1577,20 @@ static int bttv_open(struct video_device *dev, int flags)
                 btv->frame_stat[i] = GBUFFER_UNUSED;
 
         btv->user++;
+        up(&btv->lock);
         MOD_INC_USE_COUNT;
         return 0;   
+
+ out_unlock:
+       up(&btv->lock);
+       return ret;
 }
 
 static void bttv_close(struct video_device *dev)
 {
        struct bttv *btv=(struct bttv *)dev;
-       
+
+       down(&btv->lock);       
        btv->user--;
        audio(btv, AUDIO_INTERN);
        btv->cap&=~3;
@@ -1649,6 +1620,7 @@ static void bttv_close(struct video_device *dev)
        if(btv->fbuffer)
                rvfree((void *) btv->fbuffer, 2*BTTV_MAX_FBUF);
        btv->fbuffer=0;
+       up(&btv->lock);
        MOD_DEC_USE_COUNT;  
 }
 
@@ -1769,14 +1741,16 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                         
                         if (v.channel>tvcards[btv->type].video_inputs)
                                 return -EINVAL;
-                       bt848_muxsel(btv, v.channel);
                        if(v.norm!=VIDEO_MODE_PAL&&v.norm!=VIDEO_MODE_NTSC
                           &&v.norm!=VIDEO_MODE_SECAM)
                                return -EOPNOTSUPP;
+                       down(&btv->lock);
+                       bt848_muxsel(btv, v.channel);
                        btv->win.norm = v.norm;
                         make_vbitab(btv);
                        bt848_set_winsize(btv);
                        btv->channel=v.channel;
+                       up(&btv->lock);
                        return 0;
                }
                case VIDIOCGTUNER:
@@ -1821,7 +1795,9 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                           &&v.mode!=VIDEO_MODE_SECAM)
                                return -EOPNOTSUPP;
                        btv->win.norm = v.mode;
+                       down(&btv->lock);
                        bt848_set_winsize(btv);
+                       up(&btv->lock);
                        return 0;
                }
                case VIDIOCGPICT:
@@ -1848,6 +1824,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        int format;
                        if(copy_from_user(&p, arg,sizeof(p)))
                                return -EFAULT;
+                       down(&btv->lock);
                        /* We want -128 to 127 we get 0-65535 */
                        bt848_bright(btv, (p.brightness>>8)-128);
                        /* 0-511 for the colour */
@@ -1865,6 +1842,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                 if (fmtbppx2[format&0x0f]/2 == btv->win.bpp)
                                         btv->win.color_fmt = format;
                         }
+                       up(&btv->lock);
                        return 0;
                }
                case VIDIOCSWIN:
@@ -1878,7 +1856,9 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                
                        if(vw.flags || vw.width < 16 || vw.height < 16) 
                         {
+                               down(&btv->lock);
                                bt848_cap(btv,0);
+                               up(&btv->lock);
                                return -EINVAL;
                         }              
                        if (btv->win.bpp < 4) 
@@ -1888,6 +1868,8 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                i = vw.x - i;
                                vw.width -= i;
                        }
+                       
+                       down(&btv->lock);
                        btv->win.x=vw.x;
                        btv->win.y=vw.y;
                        btv->win.width=vw.width;
@@ -1902,6 +1884,8 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        
                        bt848_cap(btv,0);
                        bt848_set_winsize(btv);
+                       
+                       up(&btv->lock);
 
                        /*
                         *      Do any clips.
@@ -1925,11 +1909,13 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                        return -EFAULT;
                                }
                        }
+                       down(&btv->lock);
                        make_clip_tab(btv, vcp, vw.clipcount);
                        if (vw.clipcount != 0)
                                vfree(vcp);
                        if(on && btv->win.vidadr!=0)
                                bt848_cap(btv,1);
+                       up(&btv->lock);
                        return 0;
                }
                case VIDIOCGWIN:
@@ -1953,17 +1939,17 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        int v;
                        if(copy_from_user(&v, arg,sizeof(v)))
                                return -EFAULT;
+                       if(v!=0 && (btv->win.vidadr==0 || btv->win.width==0
+                                  || btv->win.height==0))
+                                  return -EINVAL;
+
+                       down(&btv->lock);                                  
                        if(v==0)
-                       {
                                bt848_cap(btv,0);
-                       }
                        else
-                       {
-                               if(btv->win.vidadr==0 || btv->win.width==0
-                                  || btv->win.height==0)
-                                 return -EINVAL;
                                bt848_cap(btv,1);
-                       }
+                       up(&btv->lock);
+
                        return 0;
                }
                case VIDIOCGFBUF:
@@ -1995,6 +1981,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                v.depth!=24 && v.depth!=32 && v.width > 16 &&
                                v.height > 16 && v.bytesperline > 16)
                                return -EINVAL;
+                       down(&btv->lock);
                         if (v.base)
                                btv->win.vidadr=(unsigned long)v.base;
                        btv->win.sheight=v.height;
@@ -2006,6 +1993,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        DEBUG(printk("Display at %p is %d by %d, bytedepth %d, bpl %d\n",
                                v.base, v.width,v.height, btv->win.bpp, btv->win.bpl));
                        bt848_set_winsize(btv);
+                       up(&btv->lock);
                        return 0;               
                }
                case VIDIOCKEY:
@@ -2072,13 +2060,17 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        struct video_audio v;
                        if(copy_from_user(&v,arg, sizeof(v)))
                                return -EFAULT;
+                       down(&btv->lock);
                        if(v.flags&VIDEO_AUDIO_MUTE)
                                audio(btv, AUDIO_MUTE);
                        /* One audio source per tuner */
                        /* if(v.audio!=0) */
                        /* ADSTech TV card has more than one */
                        if(v.audio<0 || v.audio >= tvcards[btv->type].audio_inputs)
+                       {
+                               up(&btv->lock);
                                return -EINVAL;
+                       }
                        bt848_muxsel(btv,v.audio);
                        if(!(v.flags&VIDEO_AUDIO_MUTE))
                                audio(btv, AUDIO_UNMUTE);
@@ -2142,6 +2134,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                                MSP_SET_STEREO,&(v.mode));
                        }
                        btv->audio_dev=v;
+                       up(&btv->lock);
                        return 0;
                }
 
@@ -2168,26 +2161,21 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                         return 0;
 
                case BTTV_WRITEE:
-#if LINUX_VERSION_CODE >= 0x020100
-                       if(!capable(CAP_SYS_ADMIN)
-                       || !capable(CAP_SYS_RAWIO))
-#else
-                       if(!suser())
-#endif
+                       if(!capable(CAP_SYS_ADMIN))
                                return -EPERM;
                        if(copy_from_user((void *) eedata, (void *) arg, 256))
                                return -EFAULT;
+                       down(&btv->lock);
                        writeee(&(btv->i2c), eedata);
+                       up(&btv->lock);
                        return 0;
 
                case BTTV_READEE:
-#if LINUX_VERSION_CODE >= 0x020100
                        if(!capable(CAP_SYS_ADMIN))
-#else
-                       if(!suser())
-#endif
                                return -EPERM;
+                       down(&btv->lock);
                        readee(&(btv->i2c), eedata);
+                       up(&btv->lock);
                        if(copy_to_user((void *) arg, (void *) eedata, 256))
                                return -EFAULT;
                        break;
@@ -2200,28 +2188,29 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
       
                 case BTTV_PLLSET: {
                         struct bttv_pll_info p;
-#if LINUX_VERSION_CODE >= 0x020100
                        if(!capable(CAP_SYS_ADMIN))
-#else
-                       if(!suser())
-#endif
                                 return -EPERM;
                         if(copy_from_user(&p , (void *) arg, sizeof(btv->pll)))
                                return -EFAULT;
+                       down(&btv->lock);
                         btv->pll.pll_ifreq = p.pll_ifreq;
                         btv->pll.pll_ofreq = p.pll_ofreq;
                         btv->pll.pll_crystal = p.pll_crystal;
-
+                       up(&btv->lock);
                        break;
                 }                                              
                case VIDIOCMCAPTURE:
                {
                         struct video_mmap vm;
+                        int v;
                        if(copy_from_user((void *) &vm, (void *) arg, sizeof(vm)))
                                return -EFAULT;
                         if (btv->frame_stat[vm.frame] == GBUFFER_GRABBING)
                                 return -EBUSY;
-                       return vgrab(btv, &vm);
+                        down(&btv->lock);
+                       v=vgrab(btv, &vm);
+                       up(&btv->lock);
+                               return v;
                }
                
                case VIDIOCGMBUF:
@@ -2303,9 +2292,8 @@ static int bttv_init_done(struct video_device *dev)
  *    But e.g. pte_alloc() does not work in modules ... :-(
  */
  
-static int bttv_mmap(struct video_device *dev, const char *adr, unsigned long size)
+static int do_bttv_mmap(struct bttv *btv, const char *adr, unsigned long size)
 {
-       struct bttv *btv=(struct bttv *)dev;
         unsigned long start=(unsigned long) adr;
        unsigned long page,pos;
 
@@ -2329,6 +2317,17 @@ static int bttv_mmap(struct video_device *dev, const char *adr, unsigned long si
        return 0;
 }
 
+static int bttv_mmap(struct video_device *dev, const char *adr, unsigned long size)
+{
+       struct bttv *btv=(struct bttv *)dev;
+       int r;
+       
+       down(&btv->lock);
+       r=do_bttv_mmap(btv, adr, size);
+       up(&btv->lock);
+       return r;
+}
+
 static struct video_device bttv_template=
 {
        "UNSET",
@@ -2394,7 +2393,6 @@ static long vbi_read(struct video_device *v, char *buf, unsigned long count,
        return count;
 }
 
-#if LINUX_VERSION_CODE >= 0x020100
 static unsigned int vbi_poll(struct video_device *dev, struct file *file,
        poll_table *wait)
 {
@@ -2408,15 +2406,16 @@ static unsigned int vbi_poll(struct video_device *dev, struct file *file,
 
        return mask;
 }
-#endif
 
 static int vbi_open(struct video_device *dev, int flags)
 {
        struct bttv *btv=(struct bttv *)(dev-2);
 
+       down(&btv->lock);
        btv->vbip=VBIBUF_SIZE;
        btv->cap|=0x0c;
        bt848_set_risc_jmps(btv);
+       up(&btv->lock);
 
        MOD_INC_USE_COUNT;
        return 0;   
@@ -2425,9 +2424,11 @@ static int vbi_open(struct video_device *dev, int flags)
 static void vbi_close(struct video_device *dev)
 {
        struct bttv *btv=(struct bttv *)(dev-2);
-  
+
+       down(&btv->lock);  
        btv->cap&=~0x0c;
        bt848_set_risc_jmps(btv);
+       up(&btv->lock);
 
        MOD_DEC_USE_COUNT;  
 }
@@ -2463,25 +2464,34 @@ static int radio_open(struct video_device *dev, int flags)
 {
        struct bttv *btv = (struct bttv *)(dev-1);
 
+       down(&btv->lock);
        if (btv->user)
-               return -EBUSY;
+               goto busy_unlock;
        btv->user++;
+       
        set_freq(btv,400*16);
        btv->radio = 1;
        bt848_muxsel(btv,0);
        audio(btv, AUDIO_UNMUTE);
+       up(&btv->lock);
        
        MOD_INC_USE_COUNT;
        return 0;   
+
+ busy_unlock:
+       up(&btv->lock);
+       return -EBUSY;
 }
 
 static void radio_close(struct video_device *dev)
 {
        struct bttv *btv=(struct bttv *)(dev-1);
   
+       down(&btv->lock);
        btv->user--;
        btv->radio = 0;
        /*audio(btv, AUDIO_MUTE);*/
+       up(&btv->lock);
        MOD_DEC_USE_COUNT;  
 }
 
@@ -2571,233 +2581,6 @@ static struct video_device radio_template=
 };
 
 
-struct vidbases 
-{
-       unsigned short vendor, device;
-       char *name;
-       uint badr;
-};
-
-static struct vidbases vbs[] = {
-        { PCI_VENDOR_ID_ALLIANCE, PCI_DEVICE_ID_ALLIANCE_AT3D,
-                "Alliance AT3D", PCI_BASE_ADDRESS_0},
-       { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_215CT222,
-                "ATI MACH64 CT", PCI_BASE_ADDRESS_0},
-       { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_210888GX,
-               "ATI MACH64 Winturbo", PCI_BASE_ADDRESS_0},
-       { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_215GT,
-                "ATI MACH64 GT", PCI_BASE_ADDRESS_0},
-       { PCI_VENDOR_ID_CIRRUS, 0, "Cirrus Logic", PCI_BASE_ADDRESS_0},
-       { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA,
-               "DEC DC21030", PCI_BASE_ADDRESS_0},
-       { PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL,
-               "Matrox Millennium", PCI_BASE_ADDRESS_1},
-       { PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2,
-               "Matrox Millennium II", PCI_BASE_ADDRESS_0},
-       { PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2_AGP,
-               "Matrox Millennium II AGP", PCI_BASE_ADDRESS_0},
-       { PCI_VENDOR_ID_MATROX, 0x051a, "Matrox Mystique", PCI_BASE_ADDRESS_1},
-       { PCI_VENDOR_ID_MATROX, 0x0521, "Matrox G200", PCI_BASE_ADDRESS_0},
-       { PCI_VENDOR_ID_N9, PCI_DEVICE_ID_N9_I128, 
-               "Number Nine Imagine 128", PCI_BASE_ADDRESS_0},
-       { PCI_VENDOR_ID_N9, PCI_DEVICE_ID_N9_I128_2, 
-               "Number Nine Imagine 128 Series 2", PCI_BASE_ADDRESS_0},
-       { PCI_VENDOR_ID_S3, 0, "S3", PCI_BASE_ADDRESS_0},
-       { PCI_VENDOR_ID_TSENG, 0, "TSENG", PCI_BASE_ADDRESS_0},
-       { PCI_VENDOR_ID_NVIDIA_SGS, PCI_DEVICE_ID_NVIDIA_SGS_RIVA128,
-                "Riva128", PCI_BASE_ADDRESS_1},
-};
-
-
-/* DEC TGA offsets stolen from XFree-3.2 */
-
-static uint dec_offsets[4] = {
-       0x200000,
-       0x804000,
-       0,
-       0x1004000
-};
-
-#define NR_CARDS (sizeof(vbs)/sizeof(struct vidbases))
-
-/* Scan for PCI display adapter
-   if more than one card is present the last one is used for now */
-
-#if LINUX_VERSION_CODE >= 0x020100
-
-static int find_vga(void)
-{
-       unsigned short badr;
-       int found = 0, i, tga_type;
-       unsigned int vidadr=0;
-       struct pci_dev *dev;
-
-
-       for (dev = pci_devices; dev != NULL; dev = dev->next) 
-       {
-               if (dev->class != PCI_CLASS_NOT_DEFINED_VGA &&
-                       ((dev->class) >> 16 != PCI_BASE_CLASS_DISPLAY))
-               {
-                       continue;
-               }
-               if (PCI_FUNC(dev->devfn) != 0)
-                       continue;
-
-               badr=0;
-               printk(KERN_INFO "bttv: PCI display adapter: ");
-               for (i=0; i<NR_CARDS; i++) 
-               {
-                       if (dev->vendor == vbs[i].vendor) 
-                       {
-                               if (vbs[i].device) 
-                                       if (vbs[i].device!=dev->device)
-                                               continue;
-                               printk("%s.\n", vbs[i].name);
-                               badr=vbs[i].badr;
-                               break;
-                       }
-               }
-               if (!badr) 
-               {
-                       printk(KERN_ERR "bttv: Unknown video memory base address.\n");
-                       continue;
-               }
-               pci_read_config_dword(dev, badr, &vidadr);
-               if (vidadr & PCI_BASE_ADDRESS_SPACE_IO) 
-               {
-                       printk(KERN_ERR "bttv: Memory seems to be I/O memory.\n");
-                       printk(KERN_ERR "bttv: Check entry for your card type in bttv.c vidbases struct.\n");
-                       continue;
-               }
-               vidadr &= PCI_BASE_ADDRESS_MEM_MASK;
-               if (!vidadr) 
-               {
-                       printk(KERN_ERR "bttv: Memory @ 0, must be something wrong!");
-                       continue;
-               }
-     
-               if (dev->vendor == PCI_VENDOR_ID_DEC &&
-                       dev->device == PCI_DEVICE_ID_DEC_TGA) 
-               {
-                       tga_type = (readl((unsigned long)vidadr) >> 12) & 0x0f;
-                       if (tga_type != 0 && tga_type != 1 && tga_type != 3) 
-                       {
-                               printk(KERN_ERR "bttv: TGA type (0x%x) unrecognized!\n", tga_type);
-                               found--;
-                       }
-                       vidadr+=dec_offsets[tga_type];
-               }
-               DEBUG(printk(KERN_DEBUG "bttv: memory @ 0x%08x, ", vidadr));
-               DEBUG(printk(KERN_DEBUG "devfn: 0x%04x.\n", dev->devfn));
-               found++;
-       }
-  
-       if (vidmem)
-       {
-               vidadr=vidmem<<20;
-               printk(KERN_INFO "bttv: Video memory override: 0x%08x\n", vidadr);
-               found=1;
-       }
-       for (i=0; i<BTTV_MAX; i++)
-               bttvs[i].win.vidadr=vidadr;
-
-       return found;
-}
-
-#else
-static int find_vga(void)
-{
-       unsigned int devfn, class, vendev;
-       unsigned short vendor, device, badr;
-       int found=0, bus=0, i, tga_type;
-       unsigned int vidadr=0;
-
-
-       for (devfn = 0; devfn < 0xff; devfn++) 
-       {
-               if (PCI_FUNC(devfn) != 0)
-                       continue;
-               pcibios_read_config_dword(bus, devfn, PCI_VENDOR_ID, &vendev);
-               if (vendev == 0xffffffff || vendev == 0x00000000) 
-                       continue;
-               pcibios_read_config_word(bus, devfn, PCI_VENDOR_ID, &vendor);
-               pcibios_read_config_word(bus, devfn, PCI_DEVICE_ID, &device);
-               pcibios_read_config_dword(bus, devfn, PCI_CLASS_REVISION, &class);
-               class = class >> 16;
-/*             if (class == PCI_CLASS_DISPLAY_VGA) {*/
-               if ((class>>8) == PCI_BASE_CLASS_DISPLAY ||
-                       /* Number 9 GXE64Pro needs this */
-                       class == PCI_CLASS_NOT_DEFINED_VGA) 
-               {
-                       badr=0;
-                       printk(KERN_INFO "bttv: PCI display adapter: ");
-                       for (i=0; i<NR_CARDS; i++) 
-                       {
-                               if (vendor==vbs[i].vendor) 
-                               {
-                                       if (vbs[i].device) 
-                                               if (vbs[i].device!=device)
-                                                       continue;
-                                       printk("%s.\n", vbs[i].name);
-                                       badr=vbs[i].badr;
-                                       break;
-                               }
-                       }
-                        if (NR_CARDS == i)
-                            printk("UNKNOWN.\n");
-                       if (!badr) 
-                       {
-                               printk(KERN_ERR "bttv: Unknown video memory base address.\n");
-                               continue;
-                       }
-                       pcibios_read_config_dword(bus, devfn, badr, &vidadr);
-                       if (vidadr & PCI_BASE_ADDRESS_SPACE_IO) 
-                       {
-                               printk(KERN_ERR "bttv: Memory seems to be I/O memory.\n");
-                               printk(KERN_ERR "bttv: Check entry for your card type in bttv.c vidbases struct.\n");
-                               continue;
-                       }
-                       vidadr &= PCI_BASE_ADDRESS_MEM_MASK;
-                       if (!vidadr) 
-                       {
-                               printk(KERN_ERR "bttv: Memory @ 0, must be something wrong!\n");
-                               continue;
-                       }
-      
-                       if (vendor==PCI_VENDOR_ID_DEC)
-                               if (device==PCI_DEVICE_ID_DEC_TGA) 
-                       {
-                               tga_type = (readl((unsigned long)vidadr) >> 12) & 0x0f;
-                               if (tga_type != 0 && tga_type != 1 && tga_type != 3) 
-                               {
-                                       printk(KERN_ERR "bttv: TGA type (0x%x) unrecognized!\n", tga_type);
-                                       found--;
-                               }
-                               vidadr+=dec_offsets[tga_type];
-                       }
-
-                       DEBUG(printk(KERN_DEBUG "bttv: memory @ 0x%08x, ", vidadr));
-                       DEBUG(printk(KERN_DEBUG "devfn: 0x%04x.\n", devfn));
-                       found++;
-               }
-       }
-  
-       if (vidmem)
-       {
-                if (vidmem < 0x1000)
-                        vidadr=vidmem<<20;
-                else
-                        vidadr=vidmem;
-               printk(KERN_INFO "bttv: Video memory override: 0x%08x\n", vidadr);
-               found=1;
-       }
-       for (i=0; i<BTTV_MAX; i++)
-               bttvs[i].win.vidadr=vidadr;
-
-       return found;
-}
-#endif
-
 
 #define  TRITON_PCON              0x50 
 #define  TRITON_BUS_CONCURRENCY   (1<<0)
@@ -2806,8 +2589,6 @@ static int find_vga(void)
 #define  TRITON_PEER_CONCURRENCY  (1<<3)
   
 
-#if LINUX_VERSION_CODE >= 0x020100
-
 static void handle_chipset(void)
 {
        struct pci_dev *dev = NULL;
@@ -2839,110 +2620,8 @@ static void handle_chipset(void)
 
                printk(KERN_INFO "bttv: Host bridge 82437FX Triton PIIX\n");
                triton1=BT848_INT_ETBF;
-                       
-#if 0                  
-               /* The ETBF bit SHOULD make all this unnecessary */
-               /* 430FX (Triton I) freezes with bus concurrency on -> switch it off */
-
-               pci_read_config_byte(dev, TRITON_PCON, &b);
-               bo=b;
-               DEBUG(printk(KERN_DEBUG "bttv: 82437FX: PCON: 0x%x\n",b));
-               if(!(b & TRITON_BUS_CONCURRENCY)) 
-               {
-                       printk(KERN_WARNING "bttv: 82437FX: disabling bus concurrency\n");
-                       b |= TRITON_BUS_CONCURRENCY;
-               }
-               if(b & TRITON_PEER_CONCURRENCY) 
-               {
-                       printk(KERN_WARNING "bttv: 82437FX: disabling peer concurrency\n");
-                       b &= ~TRITON_PEER_CONCURRENCY;
-               }
-               if(!(b & TRITON_STREAMING)) 
-               {
-                       printk(KERN_WARNING "bttv: 82437FX: disabling streaming\n");
-                       b |=  TRITON_STREAMING;
-               }
-
-               if (b!=bo) 
-               {
-                       pci_write_config_byte(dev, TRITON_PCON, b); 
-                       printk(KERN_DEBUG "bttv: 82437FX: PCON changed to: 0x%x\n",b);
-               }
-#endif
-       }
-}
-#else
-static void handle_chipset(void)
-{
-       int index;
-  
-       for (index = 0; index < 8; index++)
-       {
-               unsigned char bus, devfn;
-               unsigned char b;
-    
-               /* Beware the SiS 85C496 my friend - rev 49 don't work with a bttv */
-               
-               if (!pcibios_find_device(PCI_VENDOR_ID_SI, 
-                                        PCI_DEVICE_ID_SI_496, 
-                                        index, &bus, &devfn))
-               {
-                       printk(KERN_WARNING "BT848 and SIS 85C496 chipset don't always work together.\n");
-               }                       
-
-               if (!pcibios_find_device(PCI_VENDOR_ID_INTEL, 
-                                        PCI_DEVICE_ID_INTEL_82441,
-                                        index, &bus, &devfn)) 
-               {
-                       pcibios_read_config_byte(bus, devfn, 0x53, &b);
-                       DEBUG(printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, "));
-                       DEBUG(printk("bufcon=0x%02x\n",b));
-               }
-
-               if (!pcibios_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437,
-                           index, &bus, &devfn)) 
-               {
-                       printk(KERN_INFO "bttv: Host bridge 82437FX Triton PIIX\n");
-                       triton1=BT848_INT_ETBF;
-                       
-#if 0                  
-                       /* The ETBF bit SHOULD make all this unnecessary */
-                       /* 430FX (Triton I) freezes with bus concurrency on -> switch it off */
-                       {   
-                               unsigned char bo;
-
-                               pcibios_read_config_byte(bus, devfn, TRITON_PCON, &b);
-                               bo=b;
-                               DEBUG(printk(KERN_DEBUG "bttv: 82437FX: PCON: 0x%x\n",b));
-
-                               if(!(b & TRITON_BUS_CONCURRENCY)) 
-                               {
-                                       printk(KERN_WARNING "bttv: 82437FX: disabling bus concurrency\n");
-                                       b |= TRITON_BUS_CONCURRENCY;
-                               }
-
-                               if(b & TRITON_PEER_CONCURRENCY) 
-                               {
-                                       printk(KERN_WARNING "bttv: 82437FX: disabling peer concurrency\n");
-                                       b &= ~TRITON_PEER_CONCURRENCY;
-                               }
-                               if(!(b & TRITON_STREAMING)) 
-                               {
-                                       printk(KERN_WARNING "bttv: 82437FX: disabling streaming\n");
-                                       b |=  TRITON_STREAMING;
-                               }
-
-                               if (b!=bo) 
-                               {
-                                       pcibios_write_config_byte(bus, devfn, TRITON_PCON, b); 
-                                       printk(KERN_DEBUG "bttv: 82437FX: PCON changed to: 0x%x\n",b);
-                               }
-                       }
-#endif
-               }
        }
 }
-#endif
 
 static void init_tea6300(struct i2c_bus *bus) 
 {
@@ -2956,14 +2635,14 @@ static void init_tea6300(struct i2c_bus *bus)
 
 static void init_tea6320(struct i2c_bus *bus)
 {
-  I2CWrite(bus, I2C_TEA6300, TEA6320_V, 0x28, 1); /* master volume */
-  I2CWrite(bus, I2C_TEA6300, TEA6320_FFL, 0x28, 1); /* volume left 0dB  */
-  I2CWrite(bus, I2C_TEA6300, TEA6320_FFR, 0x28, 1); /* volume right 0dB */
-  I2CWrite(bus, I2C_TEA6300, TEA6320_FRL, 0x28, 1); /* volume rear left 0dB  */
-  I2CWrite(bus, I2C_TEA6300, TEA6320_FRR, 0x28, 1); /* volume rear right 0dB */
-  I2CWrite(bus, I2C_TEA6300, TEA6320_BA, 0x11, 1); /* bass 0dB         */
-  I2CWrite(bus, I2C_TEA6300, TEA6320_TR, 0x11, 1); /* treble 0dB       */
-  I2CWrite(bus, I2C_TEA6300, TEA6320_S, TEA6320_S_GMU, 1); /* mute off input A */
+       I2CWrite(bus, I2C_TEA6300, TEA6320_V, 0x28, 1); /* master volume */
+       I2CWrite(bus, I2C_TEA6300, TEA6320_FFL, 0x28, 1); /* volume left 0dB  */
+       I2CWrite(bus, I2C_TEA6300, TEA6320_FFR, 0x28, 1); /* volume right 0dB */
+       I2CWrite(bus, I2C_TEA6300, TEA6320_FRL, 0x28, 1); /* volume rear left 0dB  */
+       I2CWrite(bus, I2C_TEA6300, TEA6320_FRR, 0x28, 1); /* volume rear right 0dB */
+       I2CWrite(bus, I2C_TEA6300, TEA6320_BA, 0x11, 1); /* bass 0dB         */
+       I2CWrite(bus, I2C_TEA6300, TEA6320_TR, 0x11, 1); /* treble 0dB       */
+       I2CWrite(bus, I2C_TEA6300, TEA6320_S, TEA6320_S_GMU, 1); /* mute off input A */
 }
 
 static void init_tda8425(struct i2c_bus *bus) 
@@ -3093,16 +2772,16 @@ static void idcard(int i)
         
         if (I2CRead(&(btv->i2c), I2C_TEA6300) >=0)
         {
-          if(btv->type==BTTV_AVEC_INTERCAP)
-            {
-                printk(KERN_INFO "bttv%d: fader chip: TEA6320\n",btv->nr);
-                btv->audio_chip = TEA6320;
-                init_tea6320(&(btv->i2c));
-            } else {
-               printk(KERN_INFO "bttv%d: fader chip: TEA6300\n",btv->nr);
-               btv->audio_chip = TEA6300;
-               init_tea6300(&(btv->i2c));
-            }
+               if(btv->type==BTTV_AVEC_INTERCAP)
+               {
+                       printk(KERN_INFO "bttv%d: fader chip: TEA6320\n",btv->nr);
+                       btv->audio_chip = TEA6320;
+                       init_tea6320(&(btv->i2c));
+               } else {
+                       printk(KERN_INFO "bttv%d: fader chip: TEA6300\n",btv->nr);
+                       btv->audio_chip = TEA6300;
+                       init_tea6300(&(btv->i2c));
+               }
         } else
                printk(KERN_INFO "bttv%d: NO fader chip: TEA6300\n",btv->nr);
 
@@ -3213,6 +2892,8 @@ static int init_bt848(int i)
         struct bttv *btv = &bttvs[i];
 
        btv->user=0; 
+       
+       init_MUTEX(&btv->lock);
 
        /* reset the bt848 */
        btwrite(0, BT848_SRESET);
@@ -3521,7 +3202,6 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
  *     Scan for a Bt848 card, request the irq and map the io memory 
  */
 
-#if LINUX_VERSION_CODE >= 0x020100
 int configure_bt848(struct pci_dev *dev, int bttv_num)
 {
        int result;
@@ -3550,22 +3230,6 @@ int configure_bt848(struct pci_dev *dev, int bttv_num)
         else
                 btv->i2c_command=(I2C_TIMING | BT848_I2C_SCL | BT848_I2C_SDA);
 
-#if 0
-        if (remap[bttv_num])
-        {
-                unsigned int dw = btv->bt848_adr;
-
-                if (remap[bttv_num] < 0x1000)
-                        remap[bttv_num]<<=20;
-                remap[bttv_num]&=PCI_BASE_ADDRESS_MEM_MASK;
-                printk(KERN_INFO "bttv%d: remapping to : 0x%lx.\n",
-                       bttv_num,remap[bttv_num]);
-                remap[bttv_num]|=btv->bt848_adr&(~PCI_BASE_ADDRESS_MEM_MASK);
-                pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, remap[bttv_num]);
-                pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &dw);
-                btv->dev->base_address[0] = btv->bt848_adr;
-        }                                      
-#endif        
         pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
         printk(KERN_INFO "bttv%d: Brooktree Bt%d (rev %d) ",
                bttv_num,btv->id, btv->revision);
@@ -3660,170 +3324,6 @@ static int find_bt848(void)
                printk(KERN_INFO "bttv: %d Bt8xx card(s) found.\n", bttv_num);
        return bttv_num;
 }
-#else
-static int find_bt848(void)
-{
-       short pci_index;    
-       unsigned char command, latency;
-       int result;
-       unsigned char bus, devfn;
-       struct bttv *btv;
-
-       bttv_num=0;
-
-       if (!pcibios_present()) 
-       {
-               DEBUG(printk(KERN_DEBUG "bttv%d: PCI-BIOS not present or not accessable!\n",bttv_num));
-               return 0;
-       }
-
-       for (pci_index = 0;
-                !pcibios_find_device(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
-                                     pci_index, &bus, &devfn)
-             ||!pcibios_find_device(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
-                                    pci_index, &bus, &devfn)
-             ||!pcibios_find_device(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878,
-                                    pci_index, &bus, &devfn)
-             ||!pcibios_find_device(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879,
-                                    pci_index, &bus, &devfn);
-             ++pci_index) 
-       {
-               btv=&bttvs[bttv_num];
-                btv->nr = bttv_num;
-               btv->bus=bus;
-               btv->devfn=devfn;
-               btv->bt848_mem=NULL;
-               btv->vbibuf=NULL;
-               btv->risc_jmp=NULL;
-               btv->vbi_odd=NULL;
-               btv->vbi_even=NULL;
-               btv->vbiq=NULL;
-               btv->capq=NULL;
-               btv->capqo=NULL;
-               btv->capqe=NULL;
-
-               btv->vbip=VBIBUF_SIZE;
-
-               pcibios_read_config_word(btv->bus, btv->devfn, PCI_DEVICE_ID,
-                                        &btv->id);
-               pcibios_read_config_byte(btv->bus, btv->devfn,
-                       PCI_INTERRUPT_LINE, &btv->irq);
-               pcibios_read_config_dword(btv->bus, btv->devfn, PCI_BASE_ADDRESS_0,
-                       &btv->bt848_adr);
-                if (btv->id >= 878)
-                        btv->i2c_command = 0x83;                   
-                else
-                        btv->i2c_command=
-                                (I2C_TIMING | BT848_I2C_SCL | BT848_I2C_SDA);
-
-               if (remap[bttv_num])
-               {
-                        if (remap[bttv_num] < 0x1000)
-                                remap[bttv_num]<<=20;
-                       remap[bttv_num]&=PCI_BASE_ADDRESS_MEM_MASK;
-                       printk(KERN_INFO "bttv%d: remapping to : 0x%08x.\n",
-                               bttv_num,remap[bttv_num]);
-                       remap[bttv_num]|=btv->bt848_adr&(~PCI_BASE_ADDRESS_MEM_MASK);
-                       pcibios_write_config_dword(btv->bus, btv->devfn, PCI_BASE_ADDRESS_0,
-                                remap[bttv_num]);
-                       pcibios_read_config_dword(btv->bus, btv->devfn, PCI_BASE_ADDRESS_0,
-                               &btv->bt848_adr);
-               }                                       
-                
-               btv->bt848_adr&=PCI_BASE_ADDRESS_MEM_MASK;
-               pcibios_read_config_byte(btv->bus, btv->devfn, PCI_CLASS_REVISION,
-                            &btv->revision);
-               printk(KERN_INFO "bttv%d: Brooktree Bt%d (rev %d) ",
-                       bttv_num,btv->id, btv->revision);
-                printk("bus: %d, devfn: %d, ",
-                       btv->bus, btv->devfn);
-               printk("irq: %d, ",btv->irq);
-               printk("memory: 0x%08x.\n", btv->bt848_adr);
-    
-                btv->pll.pll_crystal = 0;
-                btv->pll.pll_ifreq   = 0;
-                btv->pll.pll_ofreq   = 0;
-                btv->pll.pll_current = 0;
-                if (!(btv->id==848 && btv->revision==0x11)) {
-                        switch (pll[btv->nr]) {
-                        case 0:
-                                /* off */
-                                break;
-                        case 1:
-                                /* 28 MHz crystal installed */
-                                btv->pll.pll_ifreq=28636363;
-                                btv->pll.pll_crystal=BT848_IFORM_XT0;
-                                break;
-                        case 2:
-                                /* 35 MHz crystal installed */
-                                btv->pll.pll_ifreq=35468950;
-                                btv->pll.pll_crystal=BT848_IFORM_XT1;
-                                break;
-                        }
-                }
-                
-               btv->bt848_mem=ioremap(btv->bt848_adr, 0x1000);
-                
-               result = request_irq(btv->irq, bttv_irq,
-                       SA_SHIRQ | SA_INTERRUPT,"bttv",(void *)btv);
-               if (result==-EINVAL) 
-               {
-                       printk(KERN_ERR "bttv%d: Bad irq number or handler\n",
-                               bttv_num);
-                       return -EINVAL;
-               }
-               if (result==-EBUSY)
-               {
-                       printk(KERN_ERR "bttv%d: IRQ %d busy, change your PnP config in BIOS\n",bttv_num,btv->irq);
-                       return result;
-               }
-               if (result < 0) 
-                       return result;
-
-               /* Enable bus-mastering */
-               pcibios_read_config_byte(btv->bus, btv->devfn, PCI_COMMAND, &command);
-               command|=PCI_COMMAND_MASTER;
-               pcibios_write_config_byte(btv->bus, btv->devfn, PCI_COMMAND, command);
-               pcibios_read_config_byte(btv->bus, btv->devfn, PCI_COMMAND, &command);
-               if (!(command&PCI_COMMAND_MASTER)) 
-               {
-                       printk(KERN_ERR "bttv%d: PCI bus-mastering could not be enabled\n",bttv_num);
-                       return -1;
-               }
-               pcibios_read_config_byte(btv->bus, btv->devfn, PCI_LATENCY_TIMER,
-                       &latency);
-               if (!latency) 
-               {
-                       latency=32;
-                       pcibios_write_config_byte(btv->bus, btv->devfn,
-                                                 PCI_LATENCY_TIMER, latency);
-               }
-               DEBUG(printk(KERN_DEBUG "bttv%d: latency: %02x\n",
-                             bttv_num, latency));
-
-                btv->triton1=triton1 ? BT848_INT_ETBF : 0;
-               if (triton1 && btv->id >= 878) 
-               {
-                       triton1 = 0;
-                       printk("bttv: Enabling 430FX compatibilty for bt878\n");
-                       pcibios_read_config_byte(btv->bus, btv->devfn, BT878_DEVCTRL, &command);
-                       command|=BT878_EN_TBFX;
-                       pcibios_write_config_byte(btv->bus, btv->devfn, BT878_DEVCTRL, command);
-                       pcibios_read_config_byte(btv->bus, btv->devfn, BT878_DEVCTRL, &command);
-                       if (!(command&BT878_EN_TBFX)) 
-                       {
-                               printk("bttv: 430FX compatibility could not be enabled\n");
-                               return -1;
-                       }
-               }
-
-               bttv_num++;
-       }
-       if(bttv_num)
-               printk(KERN_INFO "bttv: %d Bt8xx card(s) found.\n", bttv_num);
-       return bttv_num;
-}
-#endif
 
 static void release_bttv(void)
 {
@@ -3848,17 +3348,11 @@ static void release_bttv(void)
                i2c_unregister_bus((&btv->i2c));
 
                /* disable PCI bus-mastering */
-#if LINUX_VERSION_CODE >= 0x020100
+
                pci_read_config_byte(btv->dev, PCI_COMMAND, &command);
                /* Should this be &=~ ?? */
                command&=~PCI_COMMAND_MASTER;
                pci_write_config_byte(btv->dev, PCI_COMMAND, command);
-#else
-               pcibios_read_config_byte(btv->bus, btv->devfn, PCI_COMMAND, &command);
-               command&=~PCI_COMMAND_MASTER;
-               pcibios_write_config_byte(btv->bus, btv->devfn, PCI_COMMAND, command);
-
-#endif
     
                /* unmap and free memory */
                if (btv->grisc)
index 847336116cb90cdb0e269c490ba5d11c21c24a2d..83c9f1e8feaea05142bda5977ac39595b18dbd2e 100644 (file)
@@ -84,6 +84,7 @@ struct bttv
        struct video_picture picture;           /* Current picture params */
        struct video_audio audio_dev;           /* Current audio params */
 
+       struct semaphore lock;
        int user;
        int capuser;
        struct device_open open_data[MAX_OPENS];
index 509f18b134b6059a9978f94b8d05f958cd6960ae..b535ac05e1816c889b3836a7ce7ba32c2cb3668e 100644 (file)
@@ -374,13 +374,13 @@ static int i2c_getdataline(struct i2c_bus *bus)
        return (btread(ZR36057_I2CBR) >> 1) & 1;
 }
 
-void attach_inform(struct i2c_bus *bus, int id)
+static void attach_inform(struct i2c_bus *bus, int id)
 {
        DEBUG(struct zoran *zr = (struct zoran *) bus->data);
        DEBUG(printk(BUZ_DEBUG "-%u: i2c attach %02x\n", zr->id, id));
 }
 
-void detach_inform(struct i2c_bus *bus, int id)
+static void detach_inform(struct i2c_bus *bus, int id)
 {
        DEBUG(struct zoran *zr = (struct zoran *) bus->data);
        DEBUG(printk(BUZ_DEBUG "-%u: i2c detach %02x\n", zr->id, id));
index 94e7e262805846e0dd7ba0a531fd8e9af553c9ac..d0bcd2a07ba452a7df72571d32273d9dfbd36a07 100644 (file)
@@ -1,7 +1,7 @@
 #define BLOCKMOVE
 #define        Z_WAKE
 static char rcsid[] =
-"$Revision: 2.3.1.1 $$Date: 1999/07/15 16:45:53 $";
+"$Revision: 2.3.2.1 $$Date: 1999/09/27 11:01:22 $";
 
 /*
  *  linux/drivers/char/cyclades.c
@@ -9,9 +9,8 @@ static char rcsid[] =
  * This file contains the driver for the Cyclades Cyclom-Y multiport
  * serial boards.
  *
- * Maintained by Ivan Passos (ivan@cyclades.com),
- * Marcio Saito (marcio@cyclades.com) and 
- * Randolph Bentson (bentson@grieg.seaslug.org).
+ * Initially written by Randolph Bentson (bentson@grieg.seaslug.org).
+ * Maintained by Ivan Passos (ivan@cyclades.com).
  *
  * For Technical support and installation problems, please send e-mail
  * to support@cyclades.com.
@@ -31,6 +30,16 @@ static char rcsid[] =
  *   void cleanup_module(void);
  *
  * $Log: cyclades.c,v $
+ * Revision 2.3.2.1   1999/09/27 11:01:22 ivan
+ * Revisited CONFIG_PCI conditional compilation for PCI board support;
+ * Implemented TIOCGICOUNT and TIOCMIWAIT ioctl support;
+ * _Major_ cleanup on the Cyclades-Z interrupt support code / logic;
+ * Removed CTS handling from the driver -- this is now completely handled
+ * by the firmware (Cyclades-Z only);
+ * Flush RX on-board buffers as well on close (Cyclades-Z only);
+ * Fixed handling of ASYNC_SPD_* TTY flags;
+ * Module unload now unmaps all memory area allocated by ioremap;
+ *
  * Revision 2.3.1.1   1999/07/15 16:45:53 ivan
  * Removed CY_PROC conditional compilation;
  * Implemented SMP-awareness for the driver;
@@ -655,7 +664,8 @@ static char rcsid[] =
 
 #define cy_put_user    put_user
 
-static unsigned long cy_get_user(unsigned long *addr)
+static unsigned long 
+cy_get_user(unsigned long *addr)
 {
        unsigned long result = 0;
        int error = get_user (result, addr);
@@ -829,6 +839,7 @@ static int cy_chip_offset [] =
 static unsigned short  cy_pci_nboard = 0;
 static unsigned short  cy_isa_nboard = 0;
 static unsigned short  cy_nboard = 0;
+#ifdef CONFIG_PCI
 static unsigned short  cy_pci_dev_id[] = {
                            PCI_DEVICE_ID_CYCLOM_Y_Lo,  /* PCI < 1Mb */
                            PCI_DEVICE_ID_CYCLOM_Y_Hi,  /* PCI > 1Mb */
@@ -840,7 +851,7 @@ static unsigned short       cy_pci_dev_id[] = {
                            PCI_DEVICE_ID_CYCLOM_Z_Hi,  /* Z PCI > 1Mb */
                            0                           /* end of table */
                        };
-
+#endif
 
 static void cy_start(struct tty_struct *);
 static void set_line_char(struct cyclades_port *);
@@ -968,6 +979,9 @@ do_softint(void *private_)
     if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
         wake_up_interruptible(&info->open_wait);
     }
+    if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) {
+       wake_up_interruptible(&info->delta_msr_wait);
+    }
     if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
         if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP))
         && tty->ldisc.write_wakeup){
@@ -1016,7 +1030,8 @@ cyy_issue_cmd(volatile ucchar *base_addr, u_char cmd, int index)
 } /* cyy_issue_cmd */
 
 #ifndef CONFIG_COBALT_27       /* ISA interrupt detection code */
-static unsigned detect_isa_irq (volatile ucchar *address)
+static unsigned 
+detect_isa_irq (volatile ucchar *address)
 {
   int irq;
   unsigned long irqs, flags;
@@ -1151,7 +1166,19 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                         j = (cy_readb(base_addr+(CyRIVR<<index)) & CyIVRMask);
                         if ( j == CyIVRRxEx ) { /* exception */
                             data = cy_readb(base_addr+(CyRDSR<<index));
+
+                           /* For statistics only */
+                           if (data & CyBREAK)
+                               info->icount.brk++;
+                           else if(data & CyFRAME)
+                               info->icount.frame++;
+                           else if(data & CyPARITY)
+                               info->icount.parity++;
+                           else if(data & CyOVERRUN)
+                               info->icount.overrun++;
+
                             if(data & info->ignore_status_mask){
+                               info->icount.rx++;
                                 continue;
                             }
                             if (tty->flip.count < TTY_FLIPBUF_SIZE){
@@ -1159,9 +1186,10 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                 if (data & info->read_status_mask){
                                     if(data & CyBREAK){
                                         *tty->flip.flag_buf_ptr++ =
-                                                           TTY_BREAK;
+                                                           TTY_BREAK;
                                         *tty->flip.char_buf_ptr++ =
                                          cy_readb(base_addr+(CyRDSR<<index));
+                                       info->icount.rx++;
                                         if (info->flags & ASYNC_SAK){
                                             do_SAK(tty);
                                         }
@@ -1170,17 +1198,20 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                                            TTY_FRAME;
                                         *tty->flip.char_buf_ptr++ =
                                          cy_readb(base_addr+(CyRDSR<<index));
+                                       info->icount.rx++;
                                        info->idle_stats.frame_errs++;
                                     }else if(data & CyPARITY){
                                         *tty->flip.flag_buf_ptr++ =
                                                            TTY_PARITY;
                                         *tty->flip.char_buf_ptr++ =
                                          cy_readb(base_addr+(CyRDSR<<index));
+                                       info->icount.rx++;
                                        info->idle_stats.parity_errs++;
                                     }else if(data & CyOVERRUN){
                                         *tty->flip.flag_buf_ptr++ =
                                                            TTY_OVERRUN;
                                         *tty->flip.char_buf_ptr++ = 0;
+                                       info->icount.rx++;
                                         /* If the flip buffer itself is
                                            overflowing, we still lose
                                            the next incoming character.
@@ -1192,6 +1223,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                                             TTY_NORMAL;
                                            *tty->flip.char_buf_ptr++ =
                                            cy_readb(base_addr+(CyRDSR<<index));
+                                           info->icount.rx++;
                                         }
                                        info->idle_stats.overruns++;
                                     /* These two conditions may imply */
@@ -1201,15 +1233,18 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                     }else{
                                         *tty->flip.flag_buf_ptr++ = 0;
                                         *tty->flip.char_buf_ptr++ = 0;
+                                       info->icount.rx++;
                                     }
                                 }else{
                                     *tty->flip.flag_buf_ptr++ = 0;
                                     *tty->flip.char_buf_ptr++ = 0;
+                                   info->icount.rx++;
                                 }
                             }else{
                                 /* there was a software buffer
                                   overrun and nothing could be
                                   done about it!!! */
+                               info->icount.buf_overrun++;
                                info->idle_stats.overruns++;
                             }
                         } else { /* normal character reception */
@@ -1233,6 +1268,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                 data = cy_readb(base_addr+(CyRDSR<<index));
                                 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
                                 *tty->flip.char_buf_ptr++ = data;
+                               info->icount.rx++;
 #ifdef CY_16Y_HACK
                                 udelay(10L);
 #endif
@@ -1286,11 +1322,11 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                     /* load the on-chip space for outbound data */
                     char_count = info->xmit_fifo_size;
 
-
                     if(info->x_char) { /* send special char */
                         outch = info->x_char;
                         cy_writeb((u_long)base_addr+(CyTDR<<index), outch);
                         char_count--;
+                       info->icount.tx++;
                         info->x_char = 0;
                     }
 
@@ -1351,6 +1387,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                             info->xmit_tail = (info->xmit_tail + 1)
                                                       & (SERIAL_XMIT_SIZE - 1);
                             cy_writeb((u_long)base_addr+(CyTDR<<index), outch);
+                           info->icount.tx++;
                         }else{
                             if(char_count > 1){
                                 info->xmit_cnt--;
@@ -1359,6 +1396,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                 cy_writeb((u_long)base_addr+(CyTDR<<index), 
                                          outch);
                                 cy_writeb((u_long)base_addr+(CyTDR<<index), 0);
+                               info->icount.tx++;
                                 char_count--;
                             }else{
                             }
@@ -1397,6 +1435,16 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                     if(info->tty == 0){/* no place for data, ignore it*/
                         ;
                     }else{
+                       if (mdm_change & CyANY_DELTA) {
+                           /* For statistics only */
+                           if (mdm_change & CyDCD)     info->icount.dcd++;
+                           if (mdm_change & CyCTS)     info->icount.cts++;
+                           if (mdm_change & CyDSR)     info->icount.dsr++;
+                           if (mdm_change & CyRI)      info->icount.rng++;
+
+                           cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
+                       }
+
                         if((mdm_change & CyDCD)
                         && (info->flags & ASYNC_CHECK_CD)){
                             if(mdm_status & CyDCD){
@@ -1438,9 +1486,9 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                 }
                             }
                         }
-                        if(mdm_status & CyDSR){
+                        if(mdm_change & CyDSR){
                         }
-                        if(mdm_status & CyRI){
+                        if(mdm_change & CyRI){
                         }
                     }
                     /* end of service */
@@ -1497,7 +1545,6 @@ cyz_fetch_msg( struct cyclades_card *cinfo,
     return 0;
 } /* cyz_fetch_msg */
 
-
 static int
 cyz_issue_cmd( struct cyclades_card *cinfo,
            uclong channel, ucchar cmd, uclong param)
@@ -1532,12 +1579,181 @@ cyz_issue_cmd( struct cyclades_card *cinfo,
     return(0);
 } /* cyz_issue_cmd */
 
-#ifdef CONFIG_CYZ_INTR
 static void
-cyz_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+cyz_handle_rx(struct cyclades_port *info, volatile struct BUF_CTRL *buf_ctrl)
+{
+  struct cyclades_card *cinfo = &cy_card[info->card];
+  struct tty_struct *tty = info->tty;
+  volatile int char_count;
+#ifdef BLOCKMOVE
+  int small_count;
+#else
+  char data;
+#endif
+  volatile uclong rx_put, rx_get, rx_bufsize;
+
+/* Removed due to compilation problems in Alpha systems */
+//    if ((char_count = CHARS_IN_BUF(buf_ctrl))){
+
+    rx_get = cy_readl(&buf_ctrl->rx_get);
+    rx_put = cy_readl(&buf_ctrl->rx_put);
+    rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize);
+    if (rx_put >= rx_get)
+       char_count = rx_put - rx_get;
+    else
+       char_count = rx_put - rx_get + rx_bufsize;
+
+    if ( char_count ) {
+       info->last_active = jiffies;
+       info->jiffies[1] = jiffies;
+
+#ifdef CY_ENABLE_MONITORING
+       info->mon.int_count++;
+       info->mon.char_count += char_count;
+       if (char_count > info->mon.char_max)
+           info->mon.char_max = char_count;
+       info->mon.char_last = char_count;
+#endif
+       if(tty == 0){
+           /* flush received characters */
+           rx_get = (rx_get + char_count) & (rx_bufsize - 1);
+           info->rflush_count++;
+       }else{
+#ifdef BLOCKMOVE
+           /* we'd like to use memcpy(t, f, n) and memset(s, c, count)
+              for performance, but because of buffer boundaries, there
+              may be several steps to the operation */
+           while(0 < (small_count = 
+                      cy_min((rx_bufsize - rx_get),
+                      cy_min((TTY_FLIPBUF_SIZE - tty->flip.count), char_count))
+                )) {
+               memcpy_fromio(tty->flip.char_buf_ptr,
+                             (char *)(cinfo->base_addr
+                                      + cy_readl(&buf_ctrl->rx_bufaddr)
+                                      + rx_get),
+                             small_count);
+
+               tty->flip.char_buf_ptr += small_count;
+               memset(tty->flip.flag_buf_ptr, TTY_NORMAL, small_count);
+               tty->flip.flag_buf_ptr += small_count;
+               rx_get = (rx_get + small_count) & (rx_bufsize - 1);
+               char_count -= small_count;
+               info->icount.rx += small_count;
+               info->idle_stats.recv_bytes += small_count;
+               tty->flip.count += small_count;
+           }
+#else
+           while(char_count--){
+               if (tty->flip.count >= TTY_FLIPBUF_SIZE){
+                   break;
+               }
+               data = cy_readb(cinfo->base_addr +
+                       cy_readl(&buf_ctrl->rx_bufaddr) + rx_get);
+               rx_get = (rx_get + 1) & (rx_bufsize - 1);
+               tty->flip.count++;
+               *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
+               *tty->flip.char_buf_ptr++ = data;
+               info->idle_stats.recv_bytes += small_count;
+               info->icount.rx++;
+           }
+#endif
+           info->idle_stats.recv_idle = jiffies;
+           queue_task(&tty->flip.tqueue, &tq_timer);
+       }
+       /* Update rx_get */
+       cy_writel(&buf_ctrl->rx_get, rx_get);
+    }
+}
+
+static void
+cyz_handle_tx(struct cyclades_port *info, volatile struct BUF_CTRL *buf_ctrl)
+{
+  struct cyclades_card *cinfo = &cy_card[info->card];
+  struct tty_struct *tty = info->tty;
+  char data;
+  volatile int char_count;
+#ifdef BLOCKMOVE
+  int small_count;
+#endif
+  volatile uclong tx_put, tx_get, tx_bufsize;
+
+/* Removed due to compilation problems in Alpha systems */
+//    if ((char_count = SPACE_IN_BUF(buf_ctrl))){
+
+    tx_get = cy_readl(&buf_ctrl->tx_get);
+    tx_put = cy_readl(&buf_ctrl->tx_put);
+    tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
+    if (tx_put >= tx_get)
+       char_count = tx_get - tx_put - 1 + tx_bufsize;
+    else
+       char_count = tx_get - tx_put - 1;
+
+    if ( char_count ) {
+
+       if( tty == 0 ){
+           goto ztxdone;
+       }
+
+       if(info->x_char) { /* send special char */
+           data = info->x_char;
+
+           cy_writeb((cinfo->base_addr + 
+               cy_readl(&buf_ctrl->tx_bufaddr) + tx_put), data);
+           tx_put = (tx_put + 1) & (tx_bufsize - 1);
+           info->x_char = 0;
+           char_count--;
+           info->icount.tx++;
+           info->last_active = jiffies;
+           info->jiffies[2] = jiffies;
+       }
+#ifdef BLOCKMOVE
+       while(0 < (small_count = 
+                  cy_min((tx_bufsize - tx_put),
+                  cy_min ((SERIAL_XMIT_SIZE - info->xmit_tail),
+                       cy_min(info->xmit_cnt, char_count))))){
+
+           memcpy_toio((char *)(cinfo->base_addr
+                                + cy_readl(&buf_ctrl->tx_bufaddr) + tx_put),
+                       &info->xmit_buf[info->xmit_tail],
+                       small_count);
+
+           tx_put = (tx_put + small_count) & (tx_bufsize - 1);
+           char_count -= small_count;
+           info->icount.tx += small_count;
+           info->xmit_cnt -= small_count;
+           info->xmit_tail = 
+               (info->xmit_tail + small_count) & (SERIAL_XMIT_SIZE - 1);
+           info->last_active = jiffies;
+           info->jiffies[2] = jiffies;
+       }
+#else
+       while (info->xmit_cnt && char_count){
+           data = info->xmit_buf[info->xmit_tail];
+           info->xmit_cnt--;
+           info->xmit_tail = (info->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
+
+           cy_writeb(cinfo->base_addr + 
+               cy_readl(&buf_ctrl->tx_bufaddr) + tx_put, data);
+           tx_put = (tx_put + 1) & (tx_bufsize - 1);
+           char_count--;
+           info->icount.tx++;
+           info->last_active = jiffies;
+           info->jiffies[2] = jiffies;
+       }
+#endif
+    ztxdone:
+       if (info->xmit_cnt < WAKEUP_CHARS) {
+           cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
+       }
+       /* Update tx_put */
+       cy_writel(&buf_ctrl->tx_put, tx_put);
+    }
+}
+
+static void
+cyz_handle_cmd(struct cyclades_card *cinfo)
 {
   struct tty_struct *tty;
-  struct cyclades_card *cinfo;
   struct cyclades_port *info;
   static volatile struct FIRM_ID *firm_id;
   static volatile struct ZFW_CTRL *zfw_ctrl;
@@ -1548,264 +1764,135 @@ cyz_interrupt(int irq, void *dev_id, struct pt_regs *regs)
   ucchar cmd;
   uclong param;
   uclong hw_ver, fw_ver;
-  char data;
-  volatile int char_count, special_count;
-#ifdef BLOCKMOVE
-  int small_count;
-#endif
-  volatile uclong tx_put, tx_get, tx_bufsize;
-  volatile uclong rx_put, rx_get, rx_bufsize;
-
-    if((cinfo = (struct cyclades_card *)dev_id) == 0){
-#ifdef CY_DEBUG_INTERRUPTS
-       printk("cyz_interrupt: spurious interrupt %d\n\r", irq);
-#endif
-        return; /* spurious interrupt */
-    }
+  int special_count;
+  int delta_count;
 
-       firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
-        if (!ISZLOADED(*cinfo)) {
-#ifdef CY_DEBUG_INTERRUPTS
-           printk("cyz_interrupt: board not yet loaded (INT %d).\n\r", irq);
-#endif
-           return;
+    firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
+    zfw_ctrl = (struct ZFW_CTRL *)
+              (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
+    board_ctrl = &(zfw_ctrl->board_ctrl);
+    fw_ver = cy_readl(&board_ctrl->fw_version);
+    hw_ver = cy_readl(&((struct RUNTIME_9060 *)(cinfo->ctl_addr))->mail_box_0);
+
+    while(cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) {
+       special_count = 0;
+       delta_count = 0;
+       info = &cy_port[channel + cinfo->first_line];
+       if((tty = info->tty) == 0) {
+           continue;
        }
+       ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
+       buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
 
-       zfw_ctrl = (struct ZFW_CTRL *)
-                  (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
-       board_ctrl = &(zfw_ctrl->board_ctrl);
-       fw_ver = cy_readl(&board_ctrl->fw_version);
-       hw_ver = cy_readl(&((struct RUNTIME_9060 *)
-                            (cinfo->ctl_addr))->mail_box_0);
-
-       while(cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) {
-           special_count = 0;
-           info = &cy_port[channel + cinfo->first_line];
-            if((tty = info->tty) == 0) continue;
-           ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
-           buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
-
-           switch(cmd){
+       switch(cmd) {
            case C_CM_PR_ERROR:
                tty->flip.count++;
                *tty->flip.flag_buf_ptr++ = TTY_PARITY;
                *tty->flip.char_buf_ptr++ = 0;
+               info->icount.rx++;
                special_count++;
-               break;
+               break;
            case C_CM_FR_ERROR:
                tty->flip.count++;
                *tty->flip.flag_buf_ptr++ = TTY_FRAME;
                *tty->flip.char_buf_ptr++ = 0;
+               info->icount.rx++;
                special_count++;
-               break;
+               break;
            case C_CM_RXBRK:
                tty->flip.count++;
                *tty->flip.flag_buf_ptr++ = TTY_BREAK;
                *tty->flip.char_buf_ptr++ = 0;
+               info->icount.rx++;
                special_count++;
-               break;
+               break;
            case C_CM_MDCD:
+               info->icount.dcd++;
+               delta_count++;
                if (info->flags & ASYNC_CHECK_CD){
                    if ((fw_ver > 241 ? 
-                          ((u_long)param) : 
-                          cy_readl(&ch_ctrl[channel].rs_status)) & C_RS_DCD) {
-                       /* SP("Open Wakeup\n"); */
-                       cy_sched_event(info,
-                           Cy_EVENT_OPEN_WAKEUP);
-                   }else if(!((info->flags
-                               & ASYNC_CALLOUT_ACTIVE)
-                        &&(info->flags
-                           & ASYNC_CALLOUT_NOHUP))){
-                       /* SP("Hangup\n"); */
-                       cy_sched_event(info,
-                           Cy_EVENT_HANGUP);
+                         ((u_long)param) : 
+                         cy_readl(&ch_ctrl[channel].rs_status)) & C_RS_DCD) {
+                       cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP);
+                   }else if(!((info->flags & ASYNC_CALLOUT_ACTIVE)
+                            &&(info->flags & ASYNC_CALLOUT_NOHUP))){
+                       cy_sched_event(info, Cy_EVENT_HANGUP);
                    }
                }
-               break;
+               break;
            case C_CM_MCTS:
-               if (info->flags & ASYNC_CTS_FLOW) {
-                   if(info->tty->hw_stopped){
-                       if( cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD){
-                           /* cy_start isn't used because... 
-                              HW flow is handled by the board */
-                           /* SP("Write Wakeup\n"); */
-                           cy_sched_event(info,
-                               Cy_EVENT_WRITE_WAKEUP);
-                       }
-                   }else{
-                       if(!(cy_readl(&ch_ctrl[channel].rs_status) & C_RS_CTS)){
-                           /* cy_stop isn't used because 
-                              HW flow is handled by the board */
-                           /* SP("Write stop\n"); */
-                       }
-                   }
-               }
-               break;
+               info->icount.cts++;
+               delta_count++;
+               break;
            case C_CM_MRI:
-               break;
+               info->icount.rng++;
+               delta_count++;
+               break;
            case C_CM_MDSR:
-               break;
+               info->icount.dsr++;
+               delta_count++;
+               break;
 #ifdef Z_WAKE
            case C_CM_IOCTLW:
                cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP);
-               break;
+               break;
 #endif
+#ifdef CONFIG_CYZ_INTR
            case C_CM_RXHIWM:
            case C_CM_RXNNDT:
                /* Reception Interrupt */
 #ifdef CY_DEBUG_INTERRUPTS
-           printk("cyz_interrupt: rcvd intr, card %d, port %ld\n\r", 
-               info->card, channel);
-#endif
-
-           rx_get = cy_readl(&buf_ctrl->rx_get);
-           rx_put = cy_readl(&buf_ctrl->rx_put);
-           rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize);
-           if (rx_put >= rx_get)
-               char_count = rx_put - rx_get;
-           else
-               char_count = rx_put - rx_get + rx_bufsize;
-
-           if ( char_count ){
-
-#ifdef CY_ENABLE_MONITORING
-               info->mon.int_count++;
-               info->mon.char_count += char_count;
-               if (char_count > info->mon.char_max)
-                  info->mon.char_max = char_count;
-               info->mon.char_last = char_count;
+               printk("cyz_interrupt: rcvd intr, card %d, port %ld\n\r", 
+                       info->card, channel);
 #endif
-               info->idle_stats.recv_bytes += char_count;
-               info->idle_stats.recv_idle   = jiffies;
-               if( tty == 0){
-                   /* flush received characters */
-                   rx_get = (rx_get + char_count) & (rx_bufsize - 1);
-                   /* SP("-"); */
-                   info->rflush_count++;
-               }else{
-#ifdef BLOCKMOVE
-               /* we'd like to use memcpy(t, f, n) and memset(s, c, count)
-                  for performance, but because of buffer boundaries, there
-                  may be several steps to the operation */
-                   while(0 < (small_count
-                       = cy_min((rx_bufsize - rx_get),
-                                cy_min((TTY_FLIPBUF_SIZE - tty->flip.count),
-                                       char_count)))){
-
-                       memcpy_fromio(tty->flip.char_buf_ptr,
-                                     (char *)(cinfo->base_addr
-                                      + cy_readl(&buf_ctrl->rx_bufaddr)
-                                      + rx_get),
-                                     small_count);
-
-                       tty->flip.char_buf_ptr += small_count;
-                       memset(tty->flip.flag_buf_ptr,
-                              TTY_NORMAL,
-                              small_count);
-                       tty->flip.flag_buf_ptr += small_count;
-                       rx_get = (rx_get + small_count) & (rx_bufsize - 1);
-                       char_count -= small_count;
-                       tty->flip.count += small_count;
-                   }
-#else
-                   while(char_count--){
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE){
-                               break;
-                       }
-                       data = cy_readb(cinfo->base_addr +
-                                  cy_readl(&buf_ctrl->rx_bufaddr) + rx_get);
-                       rx_get = (rx_get + 1) & (rx_bufsize - 1);
-                       tty->flip.count++;
-                       *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
-                       *tty->flip.char_buf_ptr++ = data;
-                   }
-#endif
-                   queue_task(&tty->flip.tqueue, &tq_timer);
-               }
-               /* Update rx_get */
-               cy_writel(&buf_ctrl->rx_get, rx_get);
-           }
+               cyz_handle_rx(info, buf_ctrl);
                break;
            case C_CM_TXBEMPTY:
            case C_CM_TXLOWWM:
            case C_CM_INTBACK:
                /* Transmission Interrupt */
 #ifdef CY_DEBUG_INTERRUPTS
-           printk("cyz_interrupt: xmit intr, card %d, port %ld\n\r", 
-               info->card, channel);
-#endif
-
-           tx_get = cy_readl(&buf_ctrl->tx_get);
-           tx_put = cy_readl(&buf_ctrl->tx_put);
-           tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
-           if (tx_put >= tx_get)
-               char_count = tx_get - tx_put - 1 + tx_bufsize;
-           else
-               char_count = tx_get - tx_put - 1;
-
-           if ( char_count ){
-
-               if( tty == 0 ){
-                   goto ztxdone;
-               }
-
-               if(info->x_char) { /* send special char */
-                   data = info->x_char;
-
-                   cy_writeb((cinfo->base_addr +
-                             cy_readl(&buf_ctrl->tx_bufaddr) + tx_put), data);
-                   tx_put = (tx_put + 1) & (tx_bufsize - 1);
-                   info->x_char = 0;
-                   char_count--;
-               }
-#ifdef BLOCKMOVE
-               while(0 < (small_count
-                   = cy_min((tx_bufsize - tx_put),
-                            cy_min ((SERIAL_XMIT_SIZE - info->xmit_tail),
-                                    cy_min(info->xmit_cnt, char_count))))){
-
-                   memcpy_toio((char *)(cinfo->base_addr
-                                + cy_readl(&buf_ctrl->tx_bufaddr) + tx_put),
-                               &info->xmit_buf[info->xmit_tail],
-                               small_count);
-
-                   tx_put = (tx_put + small_count) & (tx_bufsize - 1);
-                   char_count -= small_count;
-                   info->xmit_cnt -= small_count;
-                   info->xmit_tail =
-                      (info->xmit_tail + small_count) & (SERIAL_XMIT_SIZE - 1);
-               }
-#else
-               while (info->xmit_cnt && char_count){
-                   data = info->xmit_buf[info->xmit_tail];
-                   info->xmit_cnt--;
-                   info->xmit_tail =
-                       (info->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
-
-                   cy_writeb(cinfo->base_addr +
-                             cy_readl(&buf_ctrl->tx_bufaddr) + tx_put, 
-                             data);
-                   tx_put = (tx_put + 1) & (tx_bufsize - 1);
-                   char_count--;
-               }
-
+               printk("cyz_interrupt: xmit intr, card %d, port %ld\n\r", 
+                       info->card, channel);
 #endif
-           ztxdone:
-               if (info->xmit_cnt < WAKEUP_CHARS) {
-                   cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
-               }
-               /* Update tx_put */
-               cy_writel(&buf_ctrl->tx_put, tx_put);
-           }
+               cyz_handle_tx(info, buf_ctrl);
                break;
+#endif /* CONFIG_CYZ_INTR */
            case C_CM_FATAL:
                /* should do something with this !!! */
-               break;
-           }
-           if(special_count){
-               queue_task(&tty->flip.tqueue, &tq_timer);
-           }
+               break;
+           default:
+               break;
        }
+       if(delta_count)
+           cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
+       if(special_count)
+           queue_task(&tty->flip.tqueue, &tq_timer);
+    }
+}
+
+#ifdef CONFIG_CYZ_INTR
+static void
+cyz_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+  struct cyclades_card *cinfo;
+
+    if((cinfo = (struct cyclades_card *)dev_id) == 0){
+#ifdef CY_DEBUG_INTERRUPTS
+       printk("cyz_interrupt: spurious interrupt %d\n\r", irq);
+#endif
+        return; /* spurious interrupt */
+    }
+
+    if (!ISZLOADED(*cinfo)) {
+#ifdef CY_DEBUG_INTERRUPTS
+       printk("cyz_interrupt: board not yet loaded (IRQ%d).\n\r", irq);
+#endif
+       return;
+    }
+
+    /* Handle the interrupts */
+    cyz_handle_cmd(cinfo);
 
     return;
 } /* cyz_interrupt */
@@ -1815,272 +1902,43 @@ cyz_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 static void
 cyz_poll(unsigned long arg)
 {
+  struct cyclades_card *cinfo;
+  struct cyclades_port *info;
+  struct tty_struct *tty;
   static volatile struct FIRM_ID *firm_id;
   static volatile struct ZFW_CTRL *zfw_ctrl;
   static volatile struct BOARD_CTRL *board_ctrl;
   static volatile struct CH_CTRL *ch_ctrl;
   static volatile struct BUF_CTRL *buf_ctrl;
-  struct cyclades_card *cinfo;
-  struct cyclades_port *info;
-  struct tty_struct *tty;
   int card, port;
-  int char_count;
-#ifdef BLOCKMOVE
-  int small_count;
-#endif
-  char data;
-  uclong channel;
-  ucchar cmd;
-  uclong param;
-  uclong hw_ver, fw_ver;
-  volatile uclong tx_put, tx_get, tx_bufsize;
-  volatile uclong rx_put, rx_get, rx_bufsize;
 
     cyz_timerlist.expires = jiffies + (HZ);
     for (card = 0 ; card < NR_CARDS ; card++){
        cinfo = &cy_card[card];
-       if (!IS_CYC_Z(*cinfo)) continue;
 
+       if (!IS_CYC_Z(*cinfo)) continue;
+       if (!ISZLOADED(*cinfo)) continue;
 
-       firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
-        if (!ISZLOADED(*cinfo)) {
+       /* Skip first polling cycle to avoid racing conditions with the FW */
+       if (!cinfo->intr_enabled) {
+           cinfo->intr_enabled = 1;
            continue;
        }
 
+       firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
        zfw_ctrl = (struct ZFW_CTRL *)
-                  (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
-       board_ctrl = &(zfw_ctrl->board_ctrl);
-       fw_ver = cy_readl(&board_ctrl->fw_version);
-       hw_ver = cy_readl(&((struct RUNTIME_9060 *)
-                            (cinfo->ctl_addr))->mail_box_0);
-
-       while(cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1){
-           char_count = 0;
-           info = &cy_port[ channel + cinfo->first_line ];
-            if((tty = info->tty) == 0) continue;
-           ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
-           buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
-           info->jiffies[0] = jiffies;
-
-           switch(cmd){
-           case C_CM_PR_ERROR:
-               tty->flip.count++;
-               *tty->flip.flag_buf_ptr++ = TTY_PARITY;
-               *tty->flip.char_buf_ptr++ = 0;
-               char_count++;
-               break;
-           case C_CM_FR_ERROR:
-               tty->flip.count++;
-               *tty->flip.flag_buf_ptr++ = TTY_FRAME;
-               *tty->flip.char_buf_ptr++ = 0;
-               char_count++;
-               break;
-           case C_CM_RXBRK:
-               tty->flip.count++;
-               *tty->flip.flag_buf_ptr++ = TTY_BREAK;
-               *tty->flip.char_buf_ptr++ = 0;
-               char_count++;
-               break;
-           case C_CM_MDCD:
-               if (info->flags & ASYNC_CHECK_CD){
-                   if ((fw_ver > 241 ? 
-                          ((u_long)param) : 
-                          cy_readl(&ch_ctrl[channel].rs_status)) & C_RS_DCD) {
-                       cy_sched_event(info,
-                           Cy_EVENT_OPEN_WAKEUP);
-                   }else if(!((info->flags
-                               & ASYNC_CALLOUT_ACTIVE)
-                        &&(info->flags
-                           & ASYNC_CALLOUT_NOHUP))){
-                       cy_sched_event(info,
-                           Cy_EVENT_HANGUP);
-                   }
-               }
-               break;
-           case C_CM_MCTS:
-               if (info->flags & ASYNC_CTS_FLOW) {
-                   if(info->tty->hw_stopped){
-                       if( cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD){
-                           /* cy_start isn't used because... 
-                              HW flow is handled by the board */
-                           cy_sched_event(info,
-                               Cy_EVENT_WRITE_WAKEUP);
-                       }
-                   }else{
-                       if(!(cy_readl(&ch_ctrl[channel].rs_status) & C_RS_CTS)){
-                           /* cy_stop isn't used because 
-                              HW flow is handled by the board */
-                       }
-                   }
-               }
-               break;
-           case C_CM_MRI:
-               break;
-           case C_CM_MDSR:
-               break;
-#ifdef Z_WAKE
-           case C_CM_IOCTLW:
-               cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP);
-               break;
-#endif
-           case C_CM_FATAL:
-               /* should do something with this !!! */
-               break;
-           }
-           if(char_count){
-               queue_task(&tty->flip.tqueue, &tq_timer);
-           }
-       }
+                  (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
+
+       cyz_handle_cmd(cinfo);
+
        for (port = 0; port < cy_readl(&board_ctrl->n_channel); port++){
            info = &cy_port[ port + cinfo->first_line ];
             tty = info->tty;
            ch_ctrl = &(zfw_ctrl->ch_ctrl[port]);
            buf_ctrl = &(zfw_ctrl->buf_ctrl[port]);
 
-/* Removed due to compilation problems in Alpha systems */
-//         if ((char_count = CHARS_IN_BUF(buf_ctrl))){
-
-           rx_get = cy_readl(&buf_ctrl->rx_get);
-           rx_put = cy_readl(&buf_ctrl->rx_put);
-           rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize);
-           if (rx_put >= rx_get)
-               char_count = rx_put - rx_get;
-           else
-               char_count = rx_put - rx_get + rx_bufsize;
-
-           if ( char_count ){
-
-               info->last_active = jiffies;
-               info->jiffies[1] = jiffies;
-
-#ifdef CY_ENABLE_MONITORING
-               info->mon.int_count++;
-               info->mon.char_count += char_count;
-               if (char_count > info->mon.char_max)
-                  info->mon.char_max = char_count;
-               info->mon.char_last = char_count;
-#endif
-               info->idle_stats.recv_bytes += char_count;
-               info->idle_stats.recv_idle   = jiffies;
-               if( tty == 0){
-                   /* flush received characters */
-                   rx_get = (rx_get + char_count) & (rx_bufsize - 1);
-                   info->rflush_count++;
-               }else{
-#ifdef BLOCKMOVE
-               /* we'd like to use memcpy(t, f, n) and memset(s, c, count)
-                  for performance, but because of buffer boundaries, there
-                  may be several steps to the operation */
-                   while(0 < (small_count
-                       = cy_min((rx_bufsize - rx_get),
-                                cy_min((TTY_FLIPBUF_SIZE - tty->flip.count),
-                                       char_count)))){
-
-                       memcpy_fromio(tty->flip.char_buf_ptr,
-                                     (char *)(cinfo->base_addr
-                                      + cy_readl(&buf_ctrl->rx_bufaddr)
-                                      + rx_get),
-                                     small_count);
-
-                       tty->flip.char_buf_ptr += small_count;
-                       memset(tty->flip.flag_buf_ptr,
-                              TTY_NORMAL,
-                              small_count);
-                       tty->flip.flag_buf_ptr += small_count;
-                       rx_get = (rx_get + small_count) & (rx_bufsize - 1);
-                       char_count -= small_count;
-                       tty->flip.count += small_count;
-                   }
-#else
-                   while(char_count--){
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE){
-                               break;
-                       }
-                       data = cy_readb(cinfo->base_addr +
-                                  cy_readl(&buf_ctrl->rx_bufaddr) + rx_get);
-                       rx_get = (rx_get + 1) & (rx_bufsize - 1);
-                       tty->flip.count++;
-                       *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
-                       *tty->flip.char_buf_ptr++ = data;
-                   }
-#endif
-                   queue_task(&tty->flip.tqueue, &tq_timer);
-               }
-               /* Update rx_get */
-               cy_writel(&buf_ctrl->rx_get, rx_get);
-           }
-
-/* Removed due to compilation problems in Alpha systems */
-//         if ((char_count = SPACE_IN_BUF(buf_ctrl))){
-
-           tx_get = cy_readl(&buf_ctrl->tx_get);
-           tx_put = cy_readl(&buf_ctrl->tx_put);
-           tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
-           if (tx_put >= tx_get)
-               char_count = tx_get - tx_put - 1 + tx_bufsize;
-           else
-               char_count = tx_get - tx_put - 1;
-
-           if ( char_count ){
-
-               if( tty == 0 ){
-                   goto ztxdone;
-               }
-
-               if(info->x_char) { /* send special char */
-                   data = info->x_char;
-
-                   cy_writeb((cinfo->base_addr +
-                             cy_readl(&buf_ctrl->tx_bufaddr) + tx_put), data);
-                   tx_put = (tx_put + 1) & (tx_bufsize - 1);
-                   info->x_char = 0;
-                   char_count--;
-                   info->last_active = jiffies;
-                   info->jiffies[2] = jiffies;
-               }
-#ifdef BLOCKMOVE
-               while(0 < (small_count
-                   = cy_min((tx_bufsize - tx_put),
-                            cy_min ((SERIAL_XMIT_SIZE - info->xmit_tail),
-                                    cy_min(info->xmit_cnt, char_count))))){
-
-                   memcpy_toio((char *)(cinfo->base_addr
-                                + cy_readl(&buf_ctrl->tx_bufaddr) + tx_put),
-                               &info->xmit_buf[info->xmit_tail],
-                               small_count);
-
-                   tx_put = (tx_put + small_count) & (tx_bufsize - 1);
-                   char_count -= small_count;
-                   info->xmit_cnt -= small_count;
-                   info->xmit_tail =
-                      (info->xmit_tail + small_count) & (SERIAL_XMIT_SIZE - 1);
-                   info->last_active = jiffies;
-                   info->jiffies[2] = jiffies;
-               }
-#else
-               while (info->xmit_cnt && char_count){
-                   data = info->xmit_buf[info->xmit_tail];
-                   info->xmit_cnt--;
-                   info->xmit_tail =
-                       (info->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
-
-                   cy_writeb(cinfo->base_addr +
-                             cy_readl(&buf_ctrl->tx_bufaddr) + tx_put, 
-                             data);
-                   tx_put = (tx_put + 1) & (tx_bufsize - 1);
-                   char_count--;
-                   info->last_active = jiffies;
-                   info->jiffies[2] = jiffies;
-               }
-
-#endif
-           ztxdone:
-               if (info->xmit_cnt < WAKEUP_CHARS) {
-                   cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
-               }
-               /* Update tx_put */
-               cy_writel(&buf_ctrl->tx_put, tx_put);
-           }
+           cyz_handle_rx(info, buf_ctrl);
+           cyz_handle_tx(info, buf_ctrl);
        }
        /* poll every 40 ms */
        cyz_timerlist.expires = jiffies + cyz_polling_cycle;
@@ -2220,20 +2078,20 @@ startup(struct cyclades_port * info)
        cy_writel(&ch_ctrl[channel].intr_enable, 
                  C_IN_TXBEMPTY|C_IN_TXLOWWM|C_IN_RXHIWM|C_IN_RXNNDT|
                  C_IN_IOCTLW|
-                 C_IN_MDCD|C_IN_MCTS);
+                 C_IN_MDCD);
 #else
        cy_writel(&ch_ctrl[channel].intr_enable, 
                  C_IN_IOCTLW|
-                 C_IN_MDCD|C_IN_MCTS);
+                 C_IN_MDCD);
 #endif /* CONFIG_CYZ_INTR */
 #else
 #ifdef CONFIG_CYZ_INTR
        cy_writel(&ch_ctrl[channel].intr_enable, 
                  C_IN_TXBEMPTY|C_IN_TXLOWWM|C_IN_RXHIWM|C_IN_RXNNDT|
-                 C_IN_MDCD|C_IN_MCTS);
+                 C_IN_MDCD);
 #else
        cy_writel(&ch_ctrl[channel].intr_enable, 
-                 C_IN_MDCD|C_IN_MCTS);
+                 C_IN_MDCD);
 #endif /* CONFIG_CYZ_INTR */
 #endif /* Z_WAKE */
 
@@ -2353,6 +2211,9 @@ shutdown(struct cyclades_port * info)
 
        CY_LOCK(info, flags);
 
+           /* Clear delta_msr_wait queue to avoid mem leaks. */
+           wake_up_interruptible(&info->delta_msr_wait);
+
            if (info->xmit_buf){
                unsigned char * temp;
                temp = info->xmit_buf;
@@ -2419,7 +2280,7 @@ shutdown(struct cyclades_port * info)
                retval = cyz_issue_cmd(&cy_card[info->card],
                        channel, C_CM_IOCTLM, 0L);
                if (retval != 0){
-                   printk("cyc:shutdown retval (2) was %x\n", retval);
+                   printk("cyc:shutdown retval was %x\n", retval);
                }
 #ifdef CY_DEBUG_DTR
                printk("cyc:shutdown dropping Z DTR\n");
@@ -2707,6 +2568,10 @@ cy_open(struct tty_struct *tty, struct file * filp)
               interrupts should be enabled as soon as the first open happens 
               to one of its ports. */
            if (!cy_card[info->card].intr_enabled) {
+               /* Enable interrupts on the PLX chip */
+               cy_writew(cy_card[info->card].ctl_addr+0x68,
+                       cy_readw(cy_card[info->card].ctl_addr+0x68)|0x0900);
+               /* Enable interrupts on the FW */
                retval = cyz_issue_cmd(&cy_card[info->card], 
                                        0, C_CM_IRQ_ENBL, 0L);
                if (retval != 0){
@@ -2791,7 +2656,8 @@ cy_open(struct tty_struct *tty, struct file * filp)
 /*
  * cy_wait_until_sent() --- wait until the transmitter is empty
  */
-static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
+static void 
+cy_wait_until_sent(struct tty_struct *tty, int timeout)
 {
   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
   unsigned char *base_addr;
@@ -2873,9 +2739,9 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
  * This routine is called when a particular tty device is closed.
  */
 static void
-cy_close(struct tty_struct * tty, struct file * filp)
+cy_close(struct tty_struct *tty, struct file *filp)
 {
-  struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
+  struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
   unsigned long flags;
 
 #ifdef CY_DEBUG_OTHER
@@ -2979,7 +2845,7 @@ cy_close(struct tty_struct * tty, struct file * filp)
            retval = cyz_issue_cmd(&cy_card[info->card], channel, 
                                   C_CM_IOCTLW, 0L);
            if (retval != 0){
-               printk("cyc:shutdown retval (1) was %x\n", retval);
+               printk("cyc:cy_close retval (1) was %x\n", retval);
            }
            CY_UNLOCK(info, flags);
            interruptible_sleep_on(&info->shutdown_wait);
@@ -2994,6 +2860,17 @@ cy_close(struct tty_struct * tty, struct file * filp)
         tty->driver.flush_buffer(tty);
     if (tty->ldisc.flush_buffer)
         tty->ldisc.flush_buffer(tty);
+    if (IS_CYC_Z(cy_card[info->card])) { /* If it is a Z card, flush the
+                                           on-board RX buffers as well */
+       int retval;
+       int channel = info->line - cy_card[info->card].first_line;
+
+       retval = cyz_issue_cmd(&cy_card[info->card], channel,
+                               C_CM_FLUSH_RX, 0L);
+       if (retval != 0) {
+           printk("cyc: cy_close retval (2) was %x\n", retval);
+       }
+    }
     CY_LOCK(info, flags);
 
     tty->closing = 0;
@@ -3273,6 +3150,20 @@ set_line_char(struct cyclades_port * info)
     cflag = info->tty->termios->c_cflag;
     iflag = info->tty->termios->c_iflag;
 
+    /*
+     * Set up the tty->alt_speed kludge
+     */
+    if (info->tty) {
+       if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+           info->tty->alt_speed = 57600;
+       if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+           info->tty->alt_speed = 115200;
+       if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+           info->tty->alt_speed = 230400;
+       if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+           info->tty->alt_speed = 460800;
+    }
+
     card = info->card;
     channel = (info->line) - (cy_card[card].first_line);
     chip_number = channel / 4;
@@ -3282,7 +3173,11 @@ set_line_char(struct cyclades_port * info)
        index = cy_card[card].bus_index;
 
        /* baud rate */
-       baud = tty_get_baud_rate(info->tty);
+       if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) {
+           baud = info->baud;
+       } else {
+           baud = tty_get_baud_rate(info->tty);
+       }
        if (baud > CD1400_MAX_SPEED) {
            baud = CD1400_MAX_SPEED;
        }
@@ -3483,6 +3378,7 @@ set_line_char(struct cyclades_port * info)
       struct BOARD_CTRL *board_ctrl;
       struct CH_CTRL *ch_ctrl;
       struct BUF_CTRL *buf_ctrl;
+      uclong sw_flow;
       int retval;
 
         firm_id = (struct FIRM_ID *)
@@ -3498,7 +3394,11 @@ set_line_char(struct cyclades_port * info)
        buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
 
        /* baud rate */
-       baud = tty_get_baud_rate(info->tty);
+       if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) {
+           baud = info->baud;
+       } else {
+           baud = tty_get_baud_rate(info->tty);
+       }
        if (baud > CYZ_MAX_SPEED) {
            baud = CYZ_MAX_SPEED;
        }
@@ -3540,14 +3440,24 @@ set_line_char(struct cyclades_port * info)
 
        /* CTS flow control flag */
        if (cflag & CRTSCTS){
-           info->flags |= ASYNC_CTS_FLOW;
            cy_writel(&ch_ctrl->hw_flow,
                cy_readl(&ch_ctrl->hw_flow) | C_RS_CTS | C_RS_RTS);
        }else{
-           info->flags &= ~ASYNC_CTS_FLOW;
            cy_writel(&ch_ctrl->hw_flow,
                cy_readl(&ch_ctrl->hw_flow) & ~(C_RS_CTS | C_RS_RTS));
        }
+       /* As the HW flow control is done in firmware, the driver doesn't
+          need to care about it */
+       info->flags &= ~ASYNC_CTS_FLOW;
+
+       /* XON/XOFF/XANY flow control flags */
+       sw_flow = 0;
+       if (iflag & IXON){
+           sw_flow |= C_FL_OXX;
+           if (iflag & IXANY)
+               sw_flow |= C_FL_OIXANY;
+       }
+       cy_writel(&ch_ctrl->sw_flow, sw_flow);
 
        retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L);
        if (retval != 0){
@@ -3562,14 +3472,6 @@ set_line_char(struct cyclades_port * info)
            info->flags |= ASYNC_CHECK_CD;
        }
 
-       if (iflag & IXON){
-           cy_writel(&ch_ctrl->sw_flow, 
-               cy_readl(&ch_ctrl->sw_flow) | C_FL_OXX);
-       } else {
-           cy_writel(&ch_ctrl->sw_flow, 
-               cy_readl(&ch_ctrl->sw_flow) & ~C_FL_OXX);
-       }
-
        if(baud == 0){ /* baud rate is zero, turn off line */
            cy_writel(&ch_ctrl->rs_control,
                cy_readl(&ch_ctrl->rs_control) & ~C_RS_DTR);
@@ -3595,20 +3497,6 @@ set_line_char(struct cyclades_port * info)
        }
     }
 
-    /*
-     * Set up the tty->alt_speed kludge
-     */
-    if (info->tty) {
-       if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-           info->tty->alt_speed = 57600;
-       if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-           info->tty->alt_speed = 115200;
-       if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
-           info->tty->alt_speed = 230400;
-       if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
-           info->tty->alt_speed = 460800;
-    }
-
 
 } /* set_line_char */
 
@@ -3749,7 +3637,7 @@ get_modem_info(struct cyclades_port * info, unsigned int *value)
        }
 
     }
-    return cy_put_user(result,(unsigned int *) value);
+    return cy_put_user(result, value);
 } /* get_modem_info */
 
 
@@ -4208,7 +4096,10 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
             unsigned int cmd, unsigned long arg)
 {
   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
+  struct cyclades_icount cprev, cnow;          /* kernel counter temps */
+  struct serial_icounter_struct *p_cuser;      /* user space */
   int ret_val = 0;
+  unsigned long flags;
 
     if (serial_paranoia_check(info, tty->device, "cy_ioctl"))
        return -ENODEV;
@@ -4264,6 +4155,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
             if (copy_to_user((void *)arg, (void *)&cy_card[info->card], 
                        sizeof (struct cyclades_card))) {
                ret_val = -EFAULT;
+               break;
            }
            ret_val = 0;
             break;
@@ -4300,6 +4192,77 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
         case TIOCSSERIAL:
             ret_val = set_serial_info(info, (struct serial_struct *) arg);
             break;
+       /*
+        * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change 
+        * - mask passed in arg for lines of interest
+        *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+        * Caller should use TIOCGICOUNT to see which one it was
+        */
+       case TIOCMIWAIT:
+           CY_LOCK(info, flags);
+           /* note the counters on entry */
+           cprev = info->icount;
+           CY_UNLOCK(info, flags);
+           while (1) {
+               interruptible_sleep_on(&info->delta_msr_wait);
+               /* see if a signal did it */
+               if (signal_pending(current)) {
+                   return -ERESTARTSYS;
+               }
+
+               CY_LOCK(info, flags);
+               cnow = info->icount; /* atomic copy */
+               CY_UNLOCK(info, flags);
+
+               if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
+                   cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
+                   return -EIO; /* no change => error */
+               }
+               if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || 
+                    ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || 
+                    ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) || 
+                    ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
+                   return 0;
+               }
+               cprev = cnow;
+           }
+           /* NOTREACHED */
+
+       /*
+        * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+        * Return: write counters to the user passed counter struct
+        * NB: both 1->0 and 0->1 transitions are counted except for
+        *     RI where only 0->1 is counted.
+        */
+       case TIOCGICOUNT:
+           CY_LOCK(info, flags);
+           cnow = info->icount;
+           CY_UNLOCK(info, flags);
+           p_cuser = (struct serial_icounter_struct *) arg;
+           ret_val = put_user(cnow.cts, &p_cuser->cts);
+           if (ret_val) return ret_val;
+           ret_val = put_user(cnow.dsr, &p_cuser->dsr);
+           if (ret_val) return ret_val;
+           ret_val = put_user(cnow.rng, &p_cuser->rng);
+           if (ret_val) return ret_val;
+           ret_val = put_user(cnow.dcd, &p_cuser->dcd);
+           if (ret_val) return ret_val;
+           ret_val = put_user(cnow.rx, &p_cuser->rx);
+           if (ret_val) return ret_val;
+           ret_val = put_user(cnow.tx, &p_cuser->tx);
+           if (ret_val) return ret_val;
+           ret_val = put_user(cnow.frame, &p_cuser->frame);
+           if (ret_val) return ret_val;
+           ret_val = put_user(cnow.overrun, &p_cuser->overrun);
+           if (ret_val) return ret_val;
+           ret_val = put_user(cnow.parity, &p_cuser->parity);
+           if (ret_val) return ret_val;
+           ret_val = put_user(cnow.brk, &p_cuser->brk);
+           if (ret_val) return ret_val;
+           ret_val = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
+           if (ret_val) return ret_val;
+           ret_val = 0;
+           break;
         default:
             ret_val = -ENOIOCTLCMD;
     }
@@ -4328,7 +4291,8 @@ cy_set_termios(struct tty_struct *tty, struct termios * old_termios)
 #endif
 
     if ((tty->termios->c_cflag == old_termios->c_cflag) &&
-       ((tty->termios->c_iflag & IXON) == (old_termios->c_iflag & IXON)))
+       ((tty->termios->c_iflag & (IXON|IXANY)) == 
+        (old_termios->c_iflag & (IXON|IXANY))))
         return;
     set_line_char(info);
 
@@ -4819,7 +4783,8 @@ cy_detect_isa(void)
 } /* cy_detect_isa */
 #endif /* CONFIG_COBALT_27 */
 
-static void plx_init(uclong addr, uclong initctl)
+static void 
+plx_init(uclong addr, uclong initctl)
 {
     /* Reset PLX */
     cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x40000000);
@@ -4851,6 +4816,7 @@ cy_detect_pci(void)
   unsigned short        device_id,dev_index = 0;
   uclong               mailbox;
   uclong               Ze_addr0[NR_CARDS], Ze_addr2[NR_CARDS], ZeIndex = 0;
+  unsigned char         Ze_irq[NR_CARDS];
 
         if(pci_present() == 0) {    /* PCI bus not present */
                 return(0);
@@ -4872,8 +4838,8 @@ cy_detect_pci(void)
                 /* read PCI configuration area */
                cy_pci_irq = pdev->irq;
                cy_pci_addr0 = pdev->resource[0].start;
-               cy_pci_addr1 = pdev->resource[1].start; 
-               cy_pci_addr2 = pdev->resource[2].start; 
+               cy_pci_addr1 = pdev->resource[1].start;
+               cy_pci_addr2 = pdev->resource[2].start;
                 pci_read_config_byte(pdev, PCI_REVISION_ID, &cyy_rev_id);
 
                device_id &= ~PCI_DEVICE_ID_MASK;
@@ -4892,7 +4858,7 @@ cy_detect_pci(void)
                if (pdev->resource[2].flags & ~PCI_BASE_ADDRESS_IO_MASK) {
                    printk("  Warning: PCI I/O bit incorrectly set. "
                           "Ignoring it...\n");
-                   cy_pci_addr2 &= PCI_BASE_ADDRESS_IO_MASK;
+                   pdev->resource[2].flags &= PCI_BASE_ADDRESS_IO_MASK;
                }
 
 #if defined(__alpha__)
@@ -5020,11 +4986,14 @@ cy_detect_pci(void)
             printk("Cyclades-Z/PCI: found winaddr=0x%lx ctladdr=0x%lx\n",
                 (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
 #endif
-                cy_pci_addr0 &= PCI_BASE_ADDRESS_MEM_MASK;
 #if !defined(__alpha__)
                 cy_pci_addr0 = (ulong)ioremap(cy_pci_addr0, CyPCI_Zctl);
 #endif
 
+               /* Disable interrupts on the PLX before resetting it */
+               cy_writew(cy_pci_addr0+0x68,
+                       cy_readw(cy_pci_addr0+0x68) & ~0x0900);
+
                plx_init(cy_pci_addr0, 0x6c);
                /* For some yet unknown reason, once the PLX9060 reloads
                   the EEPROM, the IRQ is lost and, thus, we have to
@@ -5034,12 +5003,11 @@ cy_detect_pci(void)
 
                mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 *) 
                           cy_pci_addr0)->mail_box_0);
-                cy_pci_addr2 &= PCI_BASE_ADDRESS_MEM_MASK;
 
-               if (cy_pci_addr2 & ~PCI_BASE_ADDRESS_IO_MASK) {
+               if (pdev->resource[2].flags & ~PCI_BASE_ADDRESS_IO_MASK) {
                    printk("  Warning: PCI I/O bit incorrectly set. "
                           "Ignoring it...\n");
-                   cy_pci_addr2 &= PCI_BASE_ADDRESS_IO_MASK;
+                   pdev->resource[2].flags &= PCI_BASE_ADDRESS_IO_MASK;
                }
                if (mailbox == ZE_V1) {
 #if !defined(__alpha__)
@@ -5053,6 +5021,7 @@ cy_detect_pci(void)
                    } else {
                        Ze_addr0[ZeIndex] = cy_pci_addr0;
                        Ze_addr2[ZeIndex] = cy_pci_addr2;
+                       Ze_irq[ZeIndex] = cy_pci_irq;
                        ZeIndex++;
                    }
                    i--;
@@ -5154,11 +5123,6 @@ cy_detect_pci(void)
 
                 printk("%d channels starting from port %d.\n",
                    cy_pci_nchan,cy_next_channel);
-#ifdef CONFIG_CYZ_INTR
-               /* Enable interrupts on the PLX chip */
-               cy_writew(cy_pci_addr0+0x68,
-                       cy_readw(cy_pci_addr0+0x68)|0x0900);
-#endif /* CONFIG_CYZ_INTR */
                 cy_next_channel += cy_pci_nchan;
     }
         }
@@ -5166,9 +5130,11 @@ cy_detect_pci(void)
         for (; ZeIndex != 0 && i < NR_CARDS; i++) {
            cy_pci_addr0 = Ze_addr0[0];
            cy_pci_addr2 = Ze_addr2[0];
+           cy_pci_irq = Ze_irq[0];
            for (j = 0 ; j < ZeIndex-1 ; j++) {
                Ze_addr0[j] = Ze_addr0[j+1];
                Ze_addr2[j] = Ze_addr2[j+1];
+               Ze_irq[j] = Ze_irq[j+1];
            }
            ZeIndex--;
                mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 *) 
@@ -5241,11 +5207,6 @@ cy_detect_pci(void)
 
                 printk("%d channels starting from port %d.\n",
                    cy_pci_nchan,cy_next_channel);
-#ifdef CONFIG_CYZ_INTR
-               /* Enable interrupts on the PLX chip */
-               cy_writew(cy_pci_addr0+0x68,
-                       cy_readw(cy_pci_addr0+0x68)|0x0900);
-#endif /* CONFIG_CYZ_INTR */
                 cy_next_channel += cy_pci_nchan;
         }
        if (ZeIndex != 0) {
@@ -5501,6 +5462,11 @@ cy_init(void)
                     info->rco = 0;
                     info->close_delay = 5*HZ/10;
                    info->closing_wait = CLOSING_WAIT_DELAY;
+                   info->icount.cts = info->icount.dsr = 
+                       info->icount.rng = info->icount.dcd = 0;
+                   info->icount.rx = info->icount.tx = 0;
+                   info->icount.frame = info->icount.parity = 0;
+                   info->icount.overrun = info->icount.brk = 0;
                     info->x_char = 0;
                     info->event = 0;
                     info->count = 0;
@@ -5519,6 +5485,7 @@ cy_init(void)
                    init_waitqueue_head(&info->open_wait);
                    init_waitqueue_head(&info->close_wait);
                    init_waitqueue_head(&info->shutdown_wait);
+                   init_waitqueue_head(&info->delta_msr_wait);
                     /* info->session */
                     /* info->pgrp */
                     info->read_status_mask = 0;
@@ -5552,6 +5519,11 @@ cy_init(void)
                     info->cor5 = 0;
                     info->close_delay = 5*HZ/10;
                    info->closing_wait = CLOSING_WAIT_DELAY;
+                   info->icount.cts = info->icount.dsr = 
+                       info->icount.rng = info->icount.dcd = 0;
+                   info->icount.rx = info->icount.tx = 0;
+                   info->icount.frame = info->icount.parity = 0;
+                   info->icount.overrun = info->icount.brk = 0;
                    chip_number = (port - cinfo->first_line) / 4;
                     if ((info->chip_rev = cy_readb(cinfo->base_addr +
                                 (cy_chip_offset[chip_number]<<index) +
@@ -5589,6 +5561,7 @@ cy_init(void)
                    init_waitqueue_head(&info->open_wait);
                    init_waitqueue_head(&info->close_wait);
                    init_waitqueue_head(&info->shutdown_wait);
+                   init_waitqueue_head(&info->delta_msr_wait);
                     /* info->session */
                     /* info->pgrp */
                     info->read_status_mask =
@@ -5650,13 +5623,16 @@ cleanup_module(void)
     restore_flags(flags);
 
     for (i = 0; i < NR_CARDS; i++) {
-        if (cy_card[i].base_addr != 0
+        if (cy_card[i].base_addr != 0) {
+           iounmap((void *)cy_card[i].base_addr);
+           if (cy_card[i].ctl_addr != 0)
+               iounmap((void *)cy_card[i].ctl_addr);
+           if (cy_card[i].irq
 #ifndef CONFIG_CYZ_INTR
-           && cy_card[i].num_chips != -1 /* not a Z card */
+               && cy_card[i].num_chips != -1 /* not a Z card */
 #endif /* CONFIG_CYZ_INTR */
-           && cy_card[i].irq)
-        {
-            free_irq(cy_card[i].irq, &cy_card[i]);
+           )
+               free_irq(cy_card[i].irq, &cy_card[i]);
         }
     }
     if (tmp_buf) {
index ad5a4270ebf122a46a52aaa8fd0d65fe17830f62..36db3299d5a306a90ae7d02b7820cb389bc2b873 100644 (file)
@@ -79,6 +79,7 @@
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
+#include <asm/semaphore.h>
 
 #define VERSION        "1.6.1"
 
@@ -1588,8 +1589,8 @@ load_fep:
                        ch->blocked_open = 0;
                        ch->callout_termios = pcxe_callout.init_termios;
                        ch->normal_termios = pcxe_driver.init_termios;
-                       ch->open_wait = 0;
-                       ch->close_wait = 0;
+                       init_waitqueue_head(ch->open_wait);
+                       init_waitqueue_head(ch->close_wait);
                        ch->asyncflags = 0;
                }
 
index fc3101f347307b20ed48ab8b4dfde50ca93db001..ee986b3353c4d716a69ab0aa6a575f497a7fb34e 100644 (file)
@@ -35,6 +35,7 @@
 #include <asm/uaccess.h>       /* copy to/from user            */
 #include <linux/videodev.h>    /* kernel radio structs         */
 #include <linux/config.h>      /* CONFIG_RADIO_RTRACK_PORT     */
+#include <asm/semaphore.h>     /* Lock for the I/O             */
 
 #ifndef CONFIG_RADIO_RTRACK_PORT
 #define CONFIG_RADIO_RTRACK_PORT -1
@@ -42,6 +43,7 @@
 
 static int io = CONFIG_RADIO_RTRACK_PORT; 
 static int users = 0;
+static struct semaphore lock;
 
 struct rt_device
 {
@@ -86,19 +88,23 @@ static void rt_incvol(void)
 static void rt_mute(struct rt_device *dev)
 {
        dev->muted = 1;
+       down(&lock);
        outb(0xd0, io);                 /* volume steady, off           */
+       up(&lock);
 }
 
 static int rt_setvol(struct rt_device *dev, int vol)
 {
        int i;
 
+       down(&lock);
+       
        if(vol == dev->curvol) {        /* requested volume = current */
                if (dev->muted) {       /* user is unmuting the card  */
                        dev->muted = 0;
                        outb (0xd8, io);        /* enable card */
                }       
-       
+               up(&lock);
                return 0;
        }
 
@@ -107,6 +113,7 @@ static int rt_setvol(struct rt_device *dev, int vol)
                sleep_delay(2000000);   /* make sure it's totally down  */
                outb(0xd0, io);         /* volume steady, off           */
                dev->curvol = 0;        /* track the volume state!      */
+               up(&lock);
                return 0;
        }
 
@@ -119,7 +126,7 @@ static int rt_setvol(struct rt_device *dev, int vol)
                        rt_decvol();
 
        dev->curvol = vol;
-
+       up(&lock);
        return 0;
 }
 
@@ -165,6 +172,8 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq)
 
        freq += 171200;                 /* Add 10.7 MHz IF              */
        freq /= 800;                    /* Convert to 50 kHz units      */
+       
+       down(&lock);                    /* Stop other ops interfering */
         
        send_0_byte (io, dev);          /*  0: LSB of frequency         */
 
@@ -191,11 +200,13 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq)
                outb (0xd0, io);        /* volume steady + sigstr */
        else
                outb (0xd8, io);        /* volume steady + sigstr + on */
+               
+       up(&lock);
 
        return 0;
 }
 
-int rt_getsigstr(struct rt_device *dev)
+static int rt_getsigstr(struct rt_device *dev)
 {
        if (inb(io) & 2)        /* bit set = no signal present  */
                return 0;
@@ -324,8 +335,14 @@ static struct video_device rtrack_radio=
        NULL
 };
 
-int __init rtrack_init(struct video_init *v)
+static int __init rtrack_init(void)
 {
+       if(io==-1)
+       {
+               printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+               return -EINVAL;
+       }
+
        if (check_region(io, 2)) 
        {
                printk(KERN_ERR "rtrack: port 0x%x already in use\n", io);
@@ -340,6 +357,10 @@ int __init rtrack_init(struct video_init *v)
        request_region(io, 2, "rtrack");
        printk(KERN_INFO "AIMSlab Radiotrack/radioreveal card driver.\n");
 
+       /* Set up the I/O locking */
+       
+       init_MUTEX(&lock);
+       
        /* mute card - prevents noisy bootups */
 
        /* this ensures that the volume is all the way down  */
@@ -351,8 +372,6 @@ int __init rtrack_init(struct video_init *v)
        return 0;
 }
 
-#ifdef MODULE
-
 MODULE_AUTHOR("M.Kirkwood");
 MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card.");
 MODULE_PARM(io, "i");
@@ -360,20 +379,12 @@ MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)");
 
 EXPORT_NO_SYMBOLS;
 
-int init_module(void)
-{
-       if(io==-1)
-       {
-               printk(KERN_ERR "You must set an I/O address with io=0x???\n");
-               return -EINVAL;
-       }
-       return rtrack_init(NULL);
-}
-
-void cleanup_module(void)
+static void __exit cleanup_rtrack_module(void)
 {
        video_unregister_device(&rtrack_radio);
        release_region(io,2);
 }
 
-#endif
+module_init(rtrack_init);
+module_exit(cleanup_rtrack_module);
+
index 1c26bba933d186aa10266b963f96ed3f45999a27..2fb8714adf2face8f4c721f33bdb804daa097d90 100644 (file)
@@ -42,6 +42,7 @@
 static int io = CONFIG_RADIO_AZTECH_PORT; 
 static int radio_wait_time = 1000;
 static int users = 0;
+static struct semaphore lock;
 
 struct az_device
 {
@@ -86,7 +87,9 @@ static void send_1_byte (struct az_device *dev)
 
 static int az_setvol(struct az_device *dev, int vol)
 {
+       down(&lock);
        outb (volconvert(vol), io);
+       up(&lock);
        return 0;
 }
 
@@ -119,6 +122,8 @@ static int az_setfreq(struct az_device *dev, unsigned long frequency)
        frequency += 171200;            /* Add 10.7 MHz IF              */
        frequency /= 800;               /* Convert to 50 kHz units      */
                                        
+       down(&lock);
+       
        send_0_byte (dev);              /*  0: LSB of frequency       */
 
        for (i = 0; i < 13; i++)        /*   : frequency bits (1-13)  */
@@ -146,6 +151,8 @@ static int az_setfreq(struct az_device *dev, unsigned long frequency)
 
        udelay (radio_wait_time);
        outb_p(128+64+volconvert(dev->curvol), io);
+       
+       up(&lock);
 
        return 0;
 }
@@ -279,14 +286,21 @@ static struct video_device aztech_radio=
        NULL
 };
 
-int __init aztech_init(struct video_init *v)
+static int __init aztech_init(void)
 {
+       if(io==-1)
+       {
+               printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+               return -EINVAL;
+       }
+
        if (check_region(io, 2)) 
        {
                printk(KERN_ERR "aztech: port 0x%x already in use\n", io);
                return -EBUSY;
        }
 
+       init_MUTEX(&lock);
        aztech_radio.priv=&aztech_unit;
        
        if(video_register_device(&aztech_radio, VFL_TYPE_RADIO)==-1)
@@ -299,8 +313,6 @@ int __init aztech_init(struct video_init *v)
        return 0;
 }
 
-#ifdef MODULE
-
 MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
 MODULE_DESCRIPTION("A driver for the Aztech radio card.");
 MODULE_PARM(io, "i");
@@ -308,20 +320,11 @@ MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)");
 
 EXPORT_NO_SYMBOLS;
 
-int init_module(void)
-{
-       if(io==-1)
-       {
-               printk(KERN_ERR "You must set an I/O address with io=0x???\n");
-               return -EINVAL;
-       }
-       return aztech_init(NULL);
-}
-
-void cleanup_module(void)
+static void __exit aztech_cleanup(void)
 {
        video_unregister_device(&aztech_radio);
        release_region(io,2);
 }
 
-#endif
+module_init(aztech_init);
+module_exit(aztech_cleanup);
index 9cee2342e3fd8568474947f8cb971a37b1720651..523ac09558c5e87b55a837351d5f58a684542437 100644 (file)
@@ -23,6 +23,7 @@
 #include <asm/uaccess.h>       /* copy to/from user            */
 #include <linux/videodev.h>    /* kernel radio structs         */
 #include <linux/config.h>      /* CONFIG_RADIO_GEMTEK_PORT     */
+#include <linux/spinlock.h>
 
 #ifndef CONFIG_RADIO_GEMTEK_PORT
 #define CONFIG_RADIO_GEMTEK_PORT -1
@@ -30,6 +31,7 @@
 
 static int io = CONFIG_RADIO_GEMTEK_PORT; 
 static int users = 0;
+static spinlock_t lock;
 
 struct gemtek_device
 {
@@ -48,7 +50,9 @@ static void gemtek_mute(struct gemtek_device *dev)
 {
         if(dev->muted)
                return;
+       spin_lock(&lock);
        outb(0x10, io);
+       spin_unlock(&lock);
        dev->muted = 1;
 }
 
@@ -56,7 +60,9 @@ static void gemtek_unmute(struct gemtek_device *dev)
 {
        if(dev->muted == 0)
                return;
+       spin_lock(&lock);
        outb(0x20, io);
+       spin_unlock(&lock);
        dev->muted = 0;
 }
 
@@ -87,6 +93,8 @@ static int gemtek_setfreq(struct gemtek_device *dev, unsigned long freq)
        freq *= 7825;
        freq /= 100000;
 
+       spin_lock(&lock);
+       
        /* 2 start bits */
        outb_p(0x03, io);
        udelay(5);
@@ -114,13 +122,17 @@ static int gemtek_setfreq(struct gemtek_device *dev, unsigned long freq)
        outb_p(0x07, io);
        udelay(5);
 
+       spin_unlock(&lock);
+       
        return 0;
 }
 
 int gemtek_getsigstr(struct gemtek_device *dev)
 {
+       spin_lock(&lock);
        inb(io);
        udelay(5);
+       spin_unlock(&lock);
        if (inb(io) & 8)                /* bit set = no signal present */
                return 0;
        return 1;               /* signal present */
@@ -250,8 +262,14 @@ static struct video_device gemtek_radio=
        NULL
 };
 
-int __init gemtek_init(struct video_init *v)
+static int __init gemtek_init(void)
 {
+       if(io==-1)
+       {
+               printk(KERN_ERR "You must set an I/O address with io=0x20c, io=0x30c, io=0x24c or io=0x34c (or io=0x248 for the combined sound/radiocard)\n");
+               return -EINVAL;
+       }
+
        if (check_region(io, 4)) 
        {
                printk(KERN_ERR "gemtek: port 0x%x already in use\n", io);
@@ -266,6 +284,7 @@ int __init gemtek_init(struct video_init *v)
        request_region(io, 4, "gemtek");
        printk(KERN_INFO "GemTek Radio Card driver.\n");
 
+       spin_lock_init(&lock);
        /* mute card - prevents noisy bootups */
        outb(0x10, io);
        udelay(5);
@@ -277,8 +296,6 @@ int __init gemtek_init(struct video_init *v)
        return 0;
 }
 
-#ifdef MODULE
-
 MODULE_AUTHOR("Jonas Munsin");
 MODULE_DESCRIPTION("A driver for the GemTek Radio Card");
 MODULE_PARM(io, "i");
@@ -286,23 +303,14 @@ MODULE_PARM_DESC(io, "I/O address of the GemTek card (0x20c, 0x30c, 0x24c or 0x3
 
 EXPORT_NO_SYMBOLS;
 
-int init_module(void)
-{
-       if(io==-1)
-       {
-               printk(KERN_ERR "You must set an I/O address with io=0x20c, io=0x30c, io=0x24c or io=0x34c (or io=0x248 for the combined sound/radiocard)\n");
-               return -EINVAL;
-       }
-       return gemtek_init(NULL);
-}
-
-void cleanup_module(void)
+static void __exit gemtek_cleanup(void)
 {
        video_unregister_device(&gemtek_radio);
        release_region(io,4);
 }
 
-#endif
+module_init(gemtek_init);
+module_exit(gemtek_cleanup);
 
 /*
   Local variables:
index 66314f72faa1e747d990d63bdf017f75ebda6a5d..04beea2d540e8461ea59f782319764f85f38ec86 100644 (file)
@@ -205,7 +205,7 @@ static struct video_device pcm20_radio=
        NULL
 };
 
-int __init pcm20_init(struct video_init *v)
+static int __init pcm20_init(void)
 {
 
        pcm20_radio.priv=&pcm20_unit;
@@ -224,22 +224,16 @@ int __init pcm20_init(struct video_init *v)
        return 0;
 }
 
-#ifdef MODULE
-
 MODULE_AUTHOR("Ruurd Reitsma");
 MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
 
 EXPORT_NO_SYMBOLS;
 
-int init_module(void)
-{
-
-       return pcm20_init(NULL); 
-}
-
-void cleanup_module(void)
+static void __exit pcm20_cleanup(void)
 {
        video_unregister_device(&pcm20_radio);
 }
 
-#endif
+module_init(pcm20_init);
+module_exit(pcm20_cleanup);
+
index 7370f3a616006e7d4e8b7eb635bd9b63d73cbbc5..8876d789d7be478927150c7002a5e84261d36652 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/uaccess.h>       /* copy to/from user            */
 #include <linux/videodev.h>    /* kernel radio structs         */
 #include <linux/config.h>      /* CONFIG_RADIO_RTRACK2_PORT    */
+#include <linux/spinlock.h>
 
 #ifndef CONFIG_RADIO_RTRACK2_PORT
 #define CONFIG_RADIO_RTRACK2_PORT -1
@@ -23,6 +24,7 @@
 
 static int io = CONFIG_RADIO_RTRACK2_PORT; 
 static int users = 0;
+static spinlock_t lock;
 
 struct rt_device
 {
@@ -38,7 +40,9 @@ static void rt_mute(struct rt_device *dev)
 {
         if(dev->muted)
                return;
+       spin_lock(&lock);
        outb(1, io);
+       spin_unlock(&lock);
        dev->muted = 1;
 }
 
@@ -46,7 +50,9 @@ static void rt_unmute(struct rt_device *dev)
 {
        if(dev->muted == 0)
                return;
+       spin_lock(&lock);
        outb(0, io);
+       spin_unlock(&lock);
        dev->muted = 0;
 }
 
@@ -69,6 +75,8 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq)
        int i;
 
        freq = freq / 200 + 856;
+       
+       spin_lock(&lock);
 
        outb_p(0xc8, io);
        outb_p(0xc9, io);
@@ -85,11 +93,13 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq)
 
        outb_p(0xc8, io);
        if (!dev->muted)
-         outb_p(0, io);
+               outb_p(0, io);
+               
+       spin_unlock(&lock);
        return 0;
 }
 
-int rt_getsigstr(struct rt_device *dev)
+static int rt_getsigstr(struct rt_device *dev)
 {
        if (inb(io) & 2)        /* bit set = no signal present  */
                return 0;
@@ -227,7 +237,8 @@ int __init rtrack2_init(struct video_init *v)
        }
 
        rtrack2_radio.priv=&rtrack2_unit;
-       
+
+       spin_lock_init(&lock);  
        if(video_register_device(&rtrack2_radio, VFL_TYPE_RADIO)==-1)
                return -EINVAL;
                
index c659cc7ba29ebff8dcb81933758a0eeb3240b541..ef73f2d77c97b5662c0a952d5e2c9e74337bd2dc 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/uaccess.h>       /* copy to/from user            */
 #include <linux/videodev.h>    /* kernel radio structs         */
 #include <linux/config.h>      /* CONFIG_RADIO_SF16MI_PORT     */
+#include <asm/semaphore.h>
 
 struct fmi_device
 {
@@ -37,6 +38,7 @@ struct fmi_device
 
 static int io = CONFIG_RADIO_SF16FMI_PORT; 
 static int users = 0;
+static struct semaphore lock;
 
 /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
 /* It is only usefull to give freq in intervall of 800 (=0.05Mhz),
@@ -67,12 +69,16 @@ static void outbits(int bits, unsigned int data, int port)
 
 static inline void fmi_mute(int port)
 {
+       down(&lock);
        outb(0x00, port);
+       up(&lock);
 }
 
 static inline void fmi_unmute(int port)
 {
+       down(&lock);
        outb(0x08, port);
+       up(&lock);
 }
 
 static inline int fmi_setfreq(struct fmi_device *dev)
@@ -81,6 +87,8 @@ static inline int fmi_setfreq(struct fmi_device *dev)
        unsigned long freq = dev->curfreq;
        int i;
        
+       down(&lock);
+       
        outbits(16, RSF16_ENCODE(freq), myport);
        outbits(8, 0xC0, myport);
        for(i=0; i< 100; i++)
@@ -93,6 +101,8 @@ static inline int fmi_setfreq(struct fmi_device *dev)
        current->state = TASK_UNINTERRUPTIBLE;
        schedule_timeout(HZ/7);
 */     
+
+       up(&lock);
        if (dev->curvol) fmi_unmute(myport);
        return 0;
 }
@@ -104,6 +114,7 @@ static inline int fmi_getsigstr(struct fmi_device *dev)
        int myport = dev->port;
        int i;
        
+       down(&lock);
        val = dev->curvol ? 0x08 : 0x00;        /* unmute/mute */
        outb(val, myport);
        outb(val | 0x10, myport);
@@ -119,6 +130,8 @@ static inline int fmi_getsigstr(struct fmi_device *dev)
 */     
        res = (int)inb(myport+1);
        outb(val, myport);
+       
+       up(&lock);
        return (res & 2) ? 0 : 0xFFFF;
 }
 
@@ -290,6 +303,8 @@ int __init fmi_init(struct video_init *v)
        fmi_unit.flags = VIDEO_TUNER_LOW;
        fmi_radio.priv = &fmi_unit;
        
+       init_MUTEX(&lock);
+       
        if(video_register_device(&fmi_radio, VFL_TYPE_RADIO)==-1)
                return -EINVAL;
                
index 34638c5d5def89b9c7fc6711bd3a8347906d4135..9fb119c306421dcb7a68cf8090e5663d5b6b0dec 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/uaccess.h>       /* copy to/from user            */
 #include <linux/videodev.h>    /* kernel radio structs         */
 #include <linux/config.h>      /* CONFIG_RADIO_TERRATEC_PORT   */
+#include <linux/spinlock.h>
 
 #ifndef CONFIG_RADIO_TERRATEC_PORT
 #define CONFIG_RADIO_TERRATEC_PORT 0x590
@@ -50,6 +51,7 @@
 
 static int io = CONFIG_RADIO_TERRATEC_PORT; 
 static int users = 0;
+static spinlock_t lock;
 
 struct tt_device
 {
@@ -66,12 +68,14 @@ static void cardWriteVol(int volume)
 {
        int i;
        volume = volume+(volume * 32); // change both channels
+       spin_lock(&lock);
        for (i=0;i<8;i++)
        {
                if (volume & (0x80>>i))
                        outb(0x80, VOLPORT);
                else outb(0x00, VOLPORT);
        }
+       spin_unlock(&lock);
 }
 
 
@@ -148,6 +152,8 @@ static int tt_setfreq(struct tt_device *dev, unsigned long freq1)
                temp = temp/2;
        }
 
+       spin_lock(&lock);
+       
        for (i=24;i>-1;i--)                     /* bit shift the values to the radiocard */
        {
                if (buffer[i]==1) 
@@ -163,6 +169,8 @@ static int tt_setfreq(struct tt_device *dev, unsigned long freq1)
                }
        }
        outb(0x00, BASEPORT);     
+       
+       spin_unlock(&lock);
   
        return 0;
 }
@@ -309,6 +317,8 @@ int __init terratec_init(struct video_init *v)
 
        terratec_radio.priv=&terratec_unit;
        
+       spin_lock_init(&lock);
+       
        if(video_register_device(&terratec_radio, VFL_TYPE_RADIO)==-1)
                return -EINVAL;
                
diff --git a/drivers/char/radio-trust.c b/drivers/char/radio-trust.c
new file mode 100644 (file)
index 0000000..15dee60
--- /dev/null
@@ -0,0 +1,354 @@
+/* radio-trust.c - Trust FM Radio card driver for Linux 2.2 
+ * by Eric Lammerts <eric@scintilla.utwente.nl>
+ *
+ * Based on radio-aztech.c. Original notes:
+ *
+ * Adapted to support the Video for Linux API by 
+ * Russell Kroll <rkroll@exploits.org>.  Based on original tuner code by:
+ *
+ * Quay Ly
+ * Donald Song
+ * Jason Lewis      (jlewis@twilight.vtc.vsc.edu) 
+ * Scott McGrath    (smcgrath@twilight.vtc.vsc.edu)
+ * William McGrath  (wmcgrath@twilight.vtc.vsc.edu)
+ *
+ * The basis for this code may be found at http://bigbang.vtc.vsc.edu/fmradio/
+ */
+
+#include <stdarg.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/videodev.h>
+#include <linux/config.h>      /* CONFIG_RADIO_TRUST_PORT      */
+
+/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
+
+#ifndef CONFIG_RADIO_TRUST_PORT
+#define CONFIG_RADIO_TRUST_PORT -1
+#endif
+
+static int io = CONFIG_RADIO_TRUST_PORT; 
+static int ioval = 0xf;
+static int users = 0;
+static __u16 curvol;
+static __u16 curbass;
+static __u16 curtreble;
+static unsigned long curfreq;
+static int curstereo;
+static int curmute;
+
+/* i2c addresses */
+#define TDA7318_ADDR 0x88
+#define TSA6060T_ADDR 0xc4
+
+#define TR_DELAY do { inb(io); inb(io); inb(io); } while(0)
+#define TR_SET_SCL outb(ioval |= 2, io)
+#define TR_CLR_SCL outb(ioval &= 0xfd, io)
+#define TR_SET_SDA outb(ioval |= 1, io)
+#define TR_CLR_SDA outb(ioval &= 0xfe, io)
+
+static void write_i2c(int n, ...)
+{
+       unsigned char val, mask;
+       va_list args;
+
+       va_start(args, n);
+
+       /* start condition */
+       TR_SET_SDA;
+       TR_SET_SCL;
+       TR_DELAY;
+       TR_CLR_SDA;
+       TR_CLR_SCL;
+       TR_DELAY;
+
+       for(; n; n--) {
+               val = va_arg(args, unsigned);
+               for(mask = 0x80; mask; mask >>= 1) {
+                       if(val & mask)
+                               TR_SET_SDA;
+                       else
+                               TR_CLR_SDA;
+                       TR_SET_SCL;
+                       TR_DELAY;
+                       TR_CLR_SCL;
+                       TR_DELAY;
+               }
+               /* acknowledge bit */
+               TR_SET_SDA;
+               TR_SET_SCL;
+               TR_DELAY;
+               TR_CLR_SCL;
+               TR_DELAY;
+       }
+
+       /* stop condition */
+       TR_CLR_SDA;
+       TR_DELAY;
+       TR_SET_SCL;
+       TR_DELAY;
+       TR_SET_SDA;
+       TR_DELAY;
+
+       va_end(args);
+}
+
+static void tr_setvol(__u16 vol)
+{
+       curvol = vol / 2048;
+       write_i2c(2, TDA7318_ADDR, curvol ^ 0x1f);
+}
+
+static int basstreble2chip[15] = {
+       0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8
+};
+
+static void tr_setbass(__u16 bass)
+{
+       curbass = bass / 4370;
+       write_i2c(2, TDA7318_ADDR, 0x60 | basstreble2chip[curbass]);
+}
+
+static void tr_settreble(__u16 treble)
+{
+       curtreble = treble / 4370;
+       write_i2c(2, TDA7318_ADDR, 0x70 | basstreble2chip[curtreble]);
+}
+
+static void tr_setstereo(int stereo)
+{
+       curstereo = !!stereo;
+       ioval = (ioval & 0xfb) | (!curstereo << 2);
+       outb(ioval, io);
+}
+
+static void tr_setmute(int mute)
+{
+       curmute = !!mute;
+       ioval = (ioval & 0xf7) | (curmute << 3);
+       outb(ioval, io);
+}
+
+static int tr_getsigstr(void)
+{
+       int i, v;
+       
+       for(i = 0, v = 0; i < 100; i++) v |= inb(io);
+       return (v & 1)? 0 : 0xffff;
+}
+
+static int tr_getstereo(void)
+{
+       /* don't know how to determine it, just return the setting */
+       return curstereo;
+}
+
+static void tr_setfreq(unsigned long f)
+{
+       f /= 160;       /* Convert to 10 kHz units      */
+       f += 1070;      /* Add 10.7 MHz IF                      */
+
+       write_i2c(5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0);
+}
+
+static int tr_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+{
+       switch(cmd)
+       {
+               case VIDIOCGCAP:
+               {
+                       struct video_capability v;
+
+                       v.type=VID_TYPE_TUNER;
+                       v.channels=1;
+                       v.audios=1;
+
+                       /* No we don't do pictures */
+                       v.maxwidth=0;
+                       v.maxheight=0;
+                       v.minwidth=0;
+                       v.minheight=0;
+
+                       strcpy(v.name, "Trust FM Radio");
+
+                       if(copy_to_user(arg,&v,sizeof(v)))
+                               return -EFAULT;
+
+                       return 0;
+               }
+               case VIDIOCGTUNER:
+               {
+                       struct video_tuner v;
+
+                       if(copy_from_user(&v, arg,sizeof(v))!=0) 
+                               return -EFAULT;
+
+                       if(v.tuner)     /* Only 1 tuner */ 
+                               return -EINVAL;
+
+                       v.rangelow = 87500 * 16;
+                       v.rangehigh = 108000 * 16;
+                       v.flags = VIDEO_TUNER_LOW;
+                       v.mode = VIDEO_MODE_AUTO;
+
+                       v.signal = tr_getsigstr();
+                       if(tr_getstereo())
+                               v.flags |= VIDEO_TUNER_STEREO_ON;
+
+                       strcpy(v.name, "FM");
+
+                       if(copy_to_user(arg,&v, sizeof(v)))
+                               return -EFAULT;
+
+                       return 0;
+               }
+               case VIDIOCSTUNER:
+               {
+                       struct video_tuner v;
+
+                       if(copy_from_user(&v, arg, sizeof(v)))
+                               return -EFAULT;
+                       if(v.tuner != 0)
+                               return -EINVAL;
+
+                       return 0;
+               }
+               case VIDIOCGFREQ:
+                       if(copy_to_user(arg, &curfreq, sizeof(curfreq)))
+                               return -EFAULT;
+                       return 0;
+
+               case VIDIOCSFREQ:
+               {
+                       unsigned long f;
+
+                       if(copy_from_user(&f, arg, sizeof(curfreq)))
+                               return -EFAULT;
+                       tr_setfreq(f);
+                       return 0;
+               }
+               case VIDIOCGAUDIO:
+               {       
+                       struct video_audio v;
+
+                       memset(&v,0, sizeof(v));
+                       v.flags = VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME |
+                                 VIDEO_AUDIO_BASS | VIDEO_AUDIO_TREBLE;
+                       v.mode = curstereo? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
+                       v.volume = curvol * 2048;
+                       v.step = 2048;
+                       v.bass = curbass * 4370;
+                       v.treble = curtreble * 4370;
+                       
+                       strcpy(v.name, "Trust FM Radio");
+                       if(copy_to_user(arg,&v, sizeof(v)))
+                               return -EFAULT;
+                       return 0;                       
+               }
+               case VIDIOCSAUDIO:
+               {
+                       struct video_audio v;
+
+                       if(copy_from_user(&v, arg, sizeof(v))) 
+                               return -EFAULT; 
+                       if(v.audio) 
+                               return -EINVAL;
+
+                       tr_setvol(v.volume);                                    
+                       tr_setbass(v.bass);
+                       tr_settreble(v.treble);
+                       tr_setstereo(v.mode & VIDEO_SOUND_STEREO);
+                       tr_setmute(v.flags & VIDEO_AUDIO_MUTE);
+                       return 0;
+               }
+               default:
+                       return -ENOIOCTLCMD;
+       }
+}
+
+static int tr_open(struct video_device *dev, int flags)
+{
+       if(users)
+               return -EBUSY;
+       users++;
+       MOD_INC_USE_COUNT;
+       return 0;
+}
+
+static void tr_close(struct video_device *dev)
+{
+       users--;
+       MOD_DEC_USE_COUNT;
+}
+
+static struct video_device trust_radio=
+{
+       "Trust FM Radio",
+       VID_TYPE_TUNER,
+       VID_HARDWARE_TRUST,
+       tr_open,
+       tr_close,
+       NULL,   /* Can't read  (no capture ability) */
+       NULL,   /* Can't write */
+       NULL,   /* No poll */
+       tr_ioctl,
+       NULL,
+       NULL
+};
+
+static int __init trust_init(void)
+{
+       if(io == -1) {
+               printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+               return -EINVAL;
+       }
+       if(check_region(io, 2)) {
+               printk(KERN_ERR "trust: port 0x%x already in use\n", io);
+               return -EBUSY;
+       }
+       if(video_register_device(&trust_radio, VFL_TYPE_RADIO)==-1)
+               return -EINVAL;
+               
+       request_region(io, 2, "Trust FM Radio");
+
+       printk(KERN_INFO "Trust FM Radio card driver v1.0.\n");
+
+       write_i2c(2, TDA7318_ADDR, 0x80);       /* speaker att. LF = 0 dB */
+       write_i2c(2, TDA7318_ADDR, 0xa0);       /* speaker att. RF = 0 dB */
+       write_i2c(2, TDA7318_ADDR, 0xc0);       /* speaker att. LR = 0 dB */
+       write_i2c(2, TDA7318_ADDR, 0xe0);       /* speaker att. RR = 0 dB */
+       write_i2c(2, TDA7318_ADDR, 0x40);       /* stereo 1 input, gain = 18.75 dB */
+
+       tr_setvol(0x8000);                                      
+       tr_setbass(0x8000);
+       tr_settreble(0x8000);
+       tr_setstereo(1);
+
+       /* mute card - prevents noisy bootups */
+       tr_setmute(1);
+
+       return 0;
+}
+
+#ifdef MODULE
+
+MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
+MODULE_DESCRIPTION("A driver for the Trust FM Radio card.");
+MODULE_PARM(io, "i");
+MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)");
+
+EXPORT_NO_SYMBOLS;
+
+#endif /* MODULE */
+
+static void __exit cleanup_trust_module(void)
+{
+       video_unregister_device(&trust_radio);
+       release_region(io, 2);
+}
+
+module_init(trust_init);
+module_exit(cleanup_trust_module);
index f0d8e37c7a951c279fe02a2dd9c910d18f6e9616..a11de7ba8951b56591769b592709b27047452988 100644 (file)
@@ -47,6 +47,7 @@ struct zol_device {
        unsigned long curfreq;
        int muted;
        unsigned int stereo;
+       struct semaphore lock;
 };
 
 
@@ -64,26 +65,30 @@ static int zol_setvol(struct zol_device *dev, int vol)
        if (dev->muted)
                return 0;
 
+       down(&dev->lock);
        if (vol == 0) {
                outb(0, io);
                outb(0, io);
                inb(io + 3);    /* Zoltrix needs to be read to confirm */
+               up(&dev->lock);
                return 0;
        }
 
        outb(dev->curvol-1, io);
        sleep_delay();
        inb(io + 2);
-
+       up(&dev->lock);
        return 0;
 }
 
 static void zol_mute(struct zol_device *dev)
 {
        dev->muted = 1;
+       down(&dev->lock);
        outb(0, io);
        outb(0, io);
        inb(io + 3);            /* Zoltrix needs to be read to confirm */
+       up(&dev->lock);
 }
 
 static void zol_unmute(struct zol_device *dev)
@@ -107,6 +112,8 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq)
        bitmask = 0xc480402c10080000ull;
        i = 45;
 
+       down(&dev->lock);
+       
        outb(0, io);
        outb(0, io);
        inb(io + 3);            /* Zoltrix needs to be read to confirm */
@@ -141,14 +148,21 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq)
        inb(io+2);
 
         udelay(1000);
+        
        if (dev->muted)
        {
                outb(0, io);
                outb(0, io);
                inb(io + 3);
                udelay(1000);
-       } else
-        zol_setvol(dev, dev->curvol);
+       }
+       
+       up(&dev->lock);
+       
+       if(!dev->muted)
+       {
+               zol_setvol(dev, dev->curvol);
+       }
        return 0;
 }
 
@@ -158,6 +172,7 @@ int zol_getsigstr(struct zol_device *dev)
 {
        int a, b;
 
+       down(&dev->lock);
        outb(0x00, io);         /* This stuff I found to do nothing */
        outb(dev->curvol, io);
        sleep_delay();
@@ -167,6 +182,8 @@ int zol_getsigstr(struct zol_device *dev)
        sleep_delay();
        b = inb(io);
 
+       up(&dev->lock);
+       
        if (a != b)
                return (0);
 
@@ -180,6 +197,8 @@ int zol_is_stereo (struct zol_device *dev)
 {
        int x1, x2;
 
+       down(&dev->lock);
+       
        outb(0x00, io);
        outb(dev->curvol, io);
        sleep_delay();
@@ -189,6 +208,8 @@ int zol_is_stereo (struct zol_device *dev)
        sleep_delay();
        x2 = inb(io);
 
+       up(&dev->lock);
+       
        if ((x1 == x2) && (x1 == 0xcf))
                return 1;
        return 0;
@@ -351,6 +372,8 @@ int __init zoltrix_init(struct video_init *v)
        request_region(io, 2, "zoltrix");
        printk(KERN_INFO "Zoltrix Radio Plus card driver.\n");
 
+       init_MUTEX(&zoltrix_unit.lock);
+       
        /* mute card - prevents noisy bootups */
 
        /* this ensures that the volume is all the way down  */
index b0e3c2357fce0cedda1c38a0d917a80e482b5e62..d97304a1369c5cfd5d96564c845ee5660b3be8a3 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * random.c -- A strong random number generator
  *
- * Version 1.88, last modified 30-Aug-99
+ * Version 1.89, last modified 19-Sep-99
  * 
  * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.  All
  * rights reserved.
@@ -1329,8 +1329,14 @@ static ssize_t extract_entropy(struct entropy_store *r, void * buf,
  */
 void get_random_bytes(void *buf, int nbytes)
 {
-       extract_entropy(sec_random_state, (char *) buf, nbytes, 
-                       EXTRACT_ENTROPY_SECONDARY);
+       if (sec_random_state)  
+               extract_entropy(sec_random_state, (char *) buf, nbytes, 
+                               EXTRACT_ENTROPY_SECONDARY);
+       else if (random_state)
+               extract_entropy(random_state, (char *) buf, nbytes, 0);
+       else
+               printk(KERN_NOTICE "get_random_bytes called before "
+                                  "random driver initialization\n");
 }
 
 /*********************************************************************
@@ -2012,7 +2018,7 @@ __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
        if (!rekey_time || (tv.tv_sec - rekey_time) > REKEY_INTERVAL) {
                rekey_time = tv.tv_sec;
                /* First three words are overwritten below. */
-               get_random_bytes(&secret+3, sizeof(secret)-12);
+               get_random_bytes(&secret[3], sizeof(secret)-12);
                count = (tv.tv_sec/REKEY_INTERVAL) << HASH_BITS;
        }
 
index 2e93553c55af3012095e9cae6b292862b7a83006..5ab107a0f23cee8642efce54bb50dce0db97a0c5 100644 (file)
@@ -79,9 +79,9 @@ static const int disp_modes[8][3] =
 
 
 
-#define PAGE_WAIT 30                           /* Time in jiffies between requesting page and */
+#define PAGE_WAIT (300*HZ/1000)                        /* Time between requesting page and */
                                                /* checking status bits */
-#define PGBUF_EXPIRE 1500                      /* Time in jiffies to wait before retransmitting */
+#define PGBUF_EXPIRE (15*HZ)                   /* Time to wait before retransmitting */
                                                /* page regardless of infobits */
 typedef struct {
        u8 pgbuf[VTX_VIRTUALSIZE];              /* Page-buffer */
@@ -107,9 +107,9 @@ struct saa5249_device
 #define CCTWR 34               /* I²C write/read-address of vtx-chip */
 #define CCTRD 35
 #define NOACK_REPEAT 10                /* Retry access this many times on failure */
-#define CLEAR_DELAY 5          /* Time in jiffies required to clear a page */
-#define I2C_TIMEOUT 300                /* open/close/SDA-check timeout in jiffies */
-#define READY_TIMEOUT 3                /* Time in jiffies to wait for ready signal of I²C-bus interface */
+#define CLEAR_DELAY (HZ/20)    /* Time required to clear a page */
+#define I2C_TIMEOUT (3*HZ)     /* open/close/SDA-check timeout */
+#define READY_TIMEOUT (30*HZ/1000)     /* Time to wait for ready signal of I²C-bus interface */
 #define INIT_DELAY 500         /* Time in usec to wait at initialization of CEA interface */
 #define START_DELAY 10         /* Time in usec to wait before starting write-cycle (CEA) */
 
index 5881bc5fbfb1b500573b3829bb44f9dde8ee3922..ddb6d8bf8c02f7d098faec41df958579390d3a91 100644 (file)
@@ -1,3 +1,4 @@
+
 /* 3c527.c: 3Com Etherlink/MC32 driver for Linux
  *
  *     (c) Copyright 1998 Red Hat Software Inc
@@ -15,7 +16,7 @@
  */
 
 static const char *version =
-       "3c527.c:v0.04 1999/03/16 Alan Cox (alan@redhat.com)\n";
+       "3c527.c:v0.05 1999/09/06 Alan Cox (alan@redhat.com)\n";
 
 /*
  *     Things you need
@@ -108,6 +109,7 @@ struct mc32_local
        u16 tx_skb_end;
        struct sk_buff *rx_skb[RX_RING_MAX];    /* Receive ring */
        void *rx_ptr[RX_RING_MAX];              /* Data pointers */
+       u32 mc_list_valid;                      /* True when the mclist is set */
 };
 
 /* The station (ethernet) address prefix, used for a sanity check. */
@@ -138,6 +140,8 @@ static void mc32_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 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);
+static void    mc32_reset_multicast_list(struct net_device *dev);
+
 
 /*
  * Check for a network adaptor of this type, and return '0' iff one exists.
@@ -445,16 +449,56 @@ static void mc32_ring_poll(struct net_device *dev)
 /*
  *     Send exec commands
  */
+
+
+/*
+ *     Send command from interrupt state
+ */
+
+static int mc32_command_nowait(struct net_device *dev, u16 cmd, void *data, int len)
+{
+       struct mc32_local *lp = (struct mc32_local *)dev->priv;
+       int ioaddr = dev->base_addr;
+       
+       if(lp->exec_pending)
+               return -1;
+               
+       lp->exec_pending=1;
+       lp->exec_box->mbox=0;
+       lp->exec_box->mbox=cmd;
+       memcpy((void *)lp->exec_box->data, data, len);
+       barrier();      /* the memcpy forgot the volatile so be sure */
+
+       /* Send the command */
+       while(!(inb(ioaddr+HOST_STATUS)&HOST_STATUS_CRR));
+       outb(1<<6, ioaddr+HOST_CMD);    
+       return 0;
+}
+
+
+/*
+ *     Send command and block for results. On completion spot and reissue
+ *     multicasts
+ */
+  
 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;
        unsigned long flags;
+       int ret = 0;
        
+       /*
+        *      Wait for a command
+        */
+        
        while(lp->exec_pending)
                sleep_on(&lp->event);
                
+       /*
+        *      Issue mine
+        */
+
        lp->exec_pending=1;
        lp->exec_box->mbox=0;
        lp->exec_box->mbox=cmd;
@@ -472,18 +516,20 @@ static int mc32_command(struct net_device *dev, u16 cmd, void *data, int len)
        lp->exec_pending=0;
        restore_flags(flags);
        
+        
+       if(lp->exec_box->data[0]&(1<<13))
+               ret = -1;
        /*
         *      A multicast set got blocked - do it now
         */
-        
+               
        if(lp->mc_reload_wait)
-               mc32_set_multicast_list(dev);
+               mc32_reset_multicast_list(dev);
 
-       if(lp->exec_box->data[0]&(1<<13))
-               return -1;
-       return 0;
+       return ret;
 }
 
+
 /*
  *     RX abort
  */
@@ -1063,20 +1109,18 @@ static struct net_device_stats *mc32_get_stats(struct net_device *dev)
  * num_addrs > 0       Multicast mode, receive normal and MC packets,
  *                     and do best-effort filtering.
  */
-static void mc32_set_multicast_list(struct net_device *dev)
+static void do_mc32_set_multicast_list(struct net_device *dev, int retry)
 {
+       struct mc32_local *lp = (struct mc32_local *)dev->priv;
        u16 filt;
+
        if (dev->flags&IFF_PROMISC)
-       {
                /* Enable promiscuous mode */
                filt = 1;
-               mc32_command(dev, 0, &filt, 2);
-       }
        else if((dev->flags&IFF_ALLMULTI) || dev->mc_count > 10)
        {
                dev->flags|=IFF_PROMISC;
                filt = 1;
-               mc32_command(dev, 0, &filt, 2);
        }
        else if(dev->mc_count)
        {
@@ -1087,24 +1131,47 @@ static void mc32_set_multicast_list(struct net_device *dev)
                int i;
                
                filt = 0;
-               block[1]=0;
-               block[0]=dev->mc_count;
-               bp=block+2;
                
-               for(i=0;i<dev->mc_count;i++)
+               if(retry==0)
+                       lp->mc_list_valid = 0;
+               if(!lp->mc_list_valid)
                {
-                       memcpy(bp, dmc->dmi_addr, 6);
-                       bp+=6;
-                       dmc=dmc->next;
+                       block[1]=0;
+                       block[0]=dev->mc_count;
+                       bp=block+2;
+               
+                       for(i=0;i<dev->mc_count;i++)
+                       {
+                               memcpy(bp, dmc->dmi_addr, 6);
+                               bp+=6;
+                               dmc=dmc->next;
+                       }
+                       if(mc32_command_nowait(dev, 2, block, 2+6*dev->mc_count)==-1)
+                       {
+                               lp->mc_reload_wait = 1;
+                               return;
+                       }
+                       lp->mc_list_valid=1;
                }
-               mc32_command(dev, 2, block, 2+6*dev->mc_count);
-               mc32_command(dev, 0, &filt, 2);
        }
        else 
        {
                filt = 0;
-               mc32_command(dev, 0, &filt, 2);
        }
+       if(mc32_command_nowait(dev, 0, &filt, 2)==-1)
+       {
+               lp->mc_reload_wait = 1;
+       }
+}
+
+static void mc32_set_multicast_list(struct net_device *dev)
+{
+       do_mc32_set_multicast_list(dev,0);
+}
+
+static void mc32_reset_multicast_list(struct net_device *dev)
+{
+       do_mc32_set_multicast_list(dev,1);
 }
 
 #ifdef MODULE
index fbfd71d93369180555e075c4daba8c9890fc6db1..be62ef741d807448bee688176f6e13e42c3f76df 100644 (file)
@@ -3295,7 +3295,7 @@ int dfx_xmt_queue_pkt(
         *                      wide.
         */
 
-       p_xmt_descr->long_0     = (u32) (PI_XMT_DESCR_M_SOP | PI_XMT_DESCR_M_EOP | ((skb->len + 3) << PI_XMT_DESCR_V_SEG_LEN));
+       p_xmt_descr->long_0     = (u32) (PI_XMT_DESCR_M_SOP | PI_XMT_DESCR_M_EOP | ((skb->len) << PI_XMT_DESCR_V_SEG_LEN));
        p_xmt_descr->long_1 = (u32) virt_to_bus(skb->data);
 
        /*
index ca0a2144fbdfae7dbad62261b1cf1481f8e271e6..4ea0e6b71b496af348426af6a5c66d4821df602e 100644 (file)
@@ -75,7 +75,7 @@ extern inline void mem_on(short port, volatile char *mem_base,
 {
        /* This is a little weird: set the shared memory window by doing a
           read.  The low address bits specify the starting page. */
-       mem_base[start_page];
+       readb(mem_base+start_page);
        inb(port + E21_MEM_ENABLE);
        outb(E21_MEM_ON, port + E21_MEM_ENABLE + E21_MEM_ON);
 }
index 8a6f50a36fdf4246b05f2b031f3324ac065d0564..5be68c382353557fc234da86aeba7a87c93c967c 100644 (file)
@@ -15,12 +15,12 @@ dep_tristate 'SMC IrCC' CONFIG_SMC_IRCC_FIR $CONFIG_IRDA
 comment 'Dongle support' 
 bool 'Serial dongle support' CONFIG_DONGLE
 if [ "$CONFIG_DONGLE" != "n" ]; then
-  dep_tristate '   ESI JetEye PC dongle' CONFIG_ESI_DONGLE $CONFIG_IRDA
-  dep_tristate '   ACTiSYS IR-220L and IR220L+ dongle' CONFIG_ACTISYS_DONGLE $CONFIG_IRDA
-  dep_tristate '   Tekram IrMate 210B dongle' CONFIG_TEKRAM_DONGLE $CONFIG_IRDA
-  dep_tristate '   Greenwich GIrBIL dongle' CONFIG_GIRBIL_DONGLE $CONFIG_IRDA
-  dep_tristate '   Parallax LiteLink dongle' CONFIG_LITELINK_DONGLE $CONFIG_IRDA
-  dep_tristate '   Adaptec Airport 1000/2000 dongle' CONFIG_AIRPORT_DONGLE $CONFIG_IRDA
+   dep_tristate '  ESI JetEye PC dongle' CONFIG_ESI_DONGLE $CONFIG_IRDA
+   dep_tristate '  ACTiSYS IR-220L and IR220L+ dongle' CONFIG_ACTISYS_DONGLE $CONFIG_IRDA
+   dep_tristate '  Tekram IrMate 210B dongle' CONFIG_TEKRAM_DONGLE $CONFIG_IRDA
+   dep_tristate '  Greenwich GIrBIL dongle' CONFIG_GIRBIL_DONGLE $CONFIG_IRDA
+   dep_tristate '  Parallax LiteLink dongle' CONFIG_LITELINK_DONGLE $CONFIG_IRDA
+   dep_tristate '  Adaptec Airport 1000/2000 dongle' CONFIG_AIRPORT_DONGLE $CONFIG_IRDA
 fi
 
 endmenu
index 6bab577f51952cadafdaf23c3c1f7134cda65c3d..f83fce38c5f42f8f140c7396f8574617cab7d746 100644 (file)
@@ -135,14 +135,14 @@ static void actisys_change_speed(struct irda_device *idev, __u32 speed)
                
                /* Wait at a few ms */
                current->state = TASK_INTERRUPTIBLE;
-               schedule_timeout(2);
+               schedule_timeout(MSECS_TO_JIFFIES(20));
 
                /* Set DTR, Set RTS */
                irda_device_set_dtr_rts(idev, TRUE, TRUE);
                
                /* Wait at a few ms again */
                current->state = TASK_INTERRUPTIBLE;
-               schedule_timeout(2);
+               schedule_timeout(MSECS_TO_JIFFIES(20));
 
                 /* Go to next baudrate */
                if (idev->io.dongle_id == ACTISYS_DONGLE)
@@ -174,7 +174,7 @@ static void actisys_reset(struct irda_device *idev)
 
        /* Sleep 10-20 ms*/
        current->state = TASK_INTERRUPTIBLE;
-       schedule_timeout(2);
+       schedule_timeout(MSECS_TO_JIFFIES(20));
        
        /* Go back to normal mode */
        irda_device_set_dtr_rts(idev, TRUE, TRUE);
index 615592776696a86c7e37475330faf2f4a9b91f56..b60241a40b61b215853fae777ad369dedcbe99e2 100644 (file)
@@ -6,7 +6,7 @@
  * Status:       Experimental.
  * Author:       Dag Brattli <dagb@cs.uit.no>
  * Created at:   Sun Aug  3 13:49:59 1997
- * Modified at:   Wed Aug 11 09:24:46 1999
+ * Modified at:   Tue Aug 31 13:54:27 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:      serial.c by Linus Torvalds 
  * 
@@ -280,7 +280,7 @@ void irport_change_speed(struct irda_device *idev, __u32 speed)
        int lcr;    /* Line control reg */
        int divisor;
 
-       DEBUG(0, __FUNCTION__ "(), Setting speed to: %d\n", speed);
+       DEBUG(2, __FUNCTION__ "(), Setting speed to: %d\n", speed);
 
        ASSERT(idev != NULL, return;);
        ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
@@ -472,8 +472,8 @@ int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev)
  */
 static void irport_receive(struct irda_device *idev) 
 {
-       int iobase;
        int boguscount = 0;
+       int iobase;
 
        ASSERT(idev != NULL, return;);
 
@@ -488,7 +488,7 @@ static void irport_receive(struct irda_device *idev)
 
                /* Make sure we don't stay here to long */
                if (boguscount++ > 32) {
-                       DEBUG(0,__FUNCTION__ "(), breaking!\n");
+                       DEBUG(2,__FUNCTION__ "(), breaking!\n");
                        break;
                }
        } while (inb(iobase+UART_LSR) & UART_LSR_DR);   
@@ -530,9 +530,8 @@ void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                        DEBUG(2, __FUNCTION__ "(), RLSI\n");
                        break;
                case UART_IIR_RDI:
-                       //if (lsr & UART_LSR_DR)
-                               /* Receive interrupt */
-                               irport_receive(idev);
+                       /* Receive interrupt */
+                       irport_receive(idev);
                        break;
                case UART_IIR_THRI:
                        if (lsr & UART_LSR_THRE)
index 3d3e24f8a9aba61758d78f700a3a5fa93620241f..6a439a1a865ae1c831164897925fc73f75151876 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Dec  9 21:18:38 1997
- * Modified at:   Tue Aug 24 13:32:24 1999
+ * Modified at:   Tue Sep 28 08:39:29 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       slip.c by Laurence Culhane,   <loz@holmes.demon.co.uk>
  *                          Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
  ********************************************************************/    
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
 #include <linux/kernel.h>
 #include <linux/tty.h>
-#include <asm/segment.h>
 #include <linux/init.h>
+#include <linux/skbuff.h>
+
+#include <asm/segment.h>
+#include <asm/uaccess.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irtty.h>
@@ -411,7 +413,7 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
                 */
                if (fp && *fp++) { 
                        DEBUG( 0, "Framing or parity error!\n");
-                       irda_device_set_media_busy(&self->idev, TRUE);
+                       irda_device_set_media_busy(&self->idev.netdev, TRUE);
 
                        cp++;
                        continue;
@@ -726,8 +728,13 @@ static int irtty_net_init(struct net_device *dev)
 
 static int irtty_net_open(struct net_device *dev)
 {
+       struct irda_device *idev = dev->priv;
+
        irda_device_net_open(dev);
 
+       /* Make sure we can receive more data */
+       irtty_stop_receiver(idev, FALSE);
+
        MOD_INC_USE_COUNT;
 
        return 0;
@@ -735,6 +742,11 @@ static int irtty_net_open(struct net_device *dev)
 
 static int irtty_net_close(struct net_device *dev)
 {
+       struct irda_device *idev = dev->priv;
+
+       /* Make sure we don't receive more data */
+       irtty_stop_receiver(idev, TRUE);
+
        irda_device_net_close(dev);
 
        MOD_DEC_USE_COUNT;
index 162350c1bae7db24f632fab2059b2de8692f7974..3b575d01ea3f40f88bd160a880a1d097e4988f1e 100644 (file)
@@ -1303,7 +1303,7 @@ static void pc87108_wait_until_sent( struct irda_device *idev)
 {
        /* Just delay 60 ms */
        current->state = TASK_INTERRUPTIBLE;
-       schedule_timeout(6);
+       schedule_timeout(MSECS_TO_JIFFIES(60));
 }
 
 /*
index 94df892ede34d67bdaf0dcdc7dc9465ac18c45c8..00ab408d6af7ebc520a6ae31e512df803fca2382 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Thomas Davis (tadavis@jps.net)
  * Created at:    
- * Modified at:   Tue Aug 24 13:33:22 1999
+ * Modified at:   Wed Sep 22 07:47:19 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Thomas Davis, All Rights Reserved.
@@ -52,14 +52,16 @@ static char *driver_name = "smc-ircc";
 
 #define CHIP_IO_EXTENT 8
 
-static unsigned int io[]  = { 0x2e8, 0x140, ~0, ~0 };
-static unsigned int io2[] = { 0x2f8, 0x3e8, 0, 0};
+static unsigned int io[]  = { 0x2e8, 0x140, 0x118, ~0 }; 
+static unsigned int io2[] = { 0x2f8, 0x3e8, 0x2e8, 0};
 
 static struct ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL};
 
 /* Some prototypes */
 static int  ircc_open( int i, unsigned int iobase, unsigned int board_addr);
+#ifdef MODULE
 static int  ircc_close( struct irda_device *idev);
+#endif /* MODULE */
 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);
@@ -264,6 +266,7 @@ static int ircc_open( int i, unsigned int iobase, unsigned int iobase2)
  *    Close driver instance
  *
  */
+#ifdef MODULE
 static int ircc_close( struct irda_device *idev)
 {
        int iobase;
@@ -304,6 +307,7 @@ static int ircc_close( struct irda_device *idev)
        DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
        return 0;
 }
+#endif /* MODULE */
 
 /*
  * Function ircc_probe (iobase, board_addr, irq, dma)
@@ -311,7 +315,7 @@ static int ircc_close( struct irda_device *idev)
  *    Returns non-negative on success.
  *
  */
-static int ircc_probe( int iobase, int iobase2) 
+static int ircc_probe(int iobase, int iobase2) 
 {
        int version = 1;
        int low, high, chip, config, dma, irq;
@@ -327,17 +331,17 @@ static int ircc_probe( int iobase, int iobase2)
        irq = config >> 4 & 0x0f;
        dma = config & 0x0f;
 
-       if (high == 0x10 && low == 0xb8 && chip == 0xf1) {
-               DEBUG(0, "SMC IrDA Controller found; version = %d, "
+        if (high == 0x10 && low == 0xb8 && (chip == 0xf1 || chip == 0xf2)) { 
+                DEBUG(0, "SMC IrDA Controller found; IrCC version %d.%d, "
                      "port 0x%04x, dma %d, interrupt %d\n",
-                     version, iobase, dma, irq);
+                      chip & 0x0f, version, iobase, dma, irq);
        } else {
                return -1;
        }
 
        serial_out(iobase, UART_MASTER, 0);
 
-       DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+       DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 
        return config;
 }
@@ -798,7 +802,7 @@ static void ircc_wait_until_sent( struct irda_device *idev)
 
        /* Just delay 60 ms */
        current->state = TASK_INTERRUPTIBLE;
-       schedule_timeout(6);
+       schedule_timeout(MSECS_TO_JIFFIES(60));
 
        DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
 }
index 201b10b8365f3ff9631d092eefb7bf68f33f168e..d0dbaa4f726b6665ef2ffeaa2db5f52e795c72d9 100644 (file)
@@ -542,7 +542,7 @@ toshoboe_wait_until_sent (struct irda_device *idev)
       while (self->taskfile->xmit[i].control)
         {
           current->state = TASK_INTERRUPTIBLE;
-          schedule_timeout (6);
+          schedule_timeout (MSECS_TO_JIFFIES(60));
         }
     }
 
index 978fc62d7c2930a73829b226d8e945be92165f93..869ccd5d6094a920a7a4aa9ebce1e1a0a0c23197 100644 (file)
@@ -767,7 +767,7 @@ static void uircc_wait_until_sent( struct irda_device *idev)
 {
        /* Just delay 60 ms */
        current->state = TASK_INTERRUPTIBLE;
-       schedule_timeout(6);
+       schedule_timeout(MSECS_TO_JIFFIES(60));
 }
 
 /*
index 055610824f5221ff4ceac7fb4b4f6ccfe9a0255e..b061559b8deb8865940a7f0dfb7b32842a8b9c77 100644 (file)
@@ -40,7 +40,7 @@
 #include <asm/system.h>
 
 #include <linux/netdevice.h>
-#include "../../drivers/net/8390.h"
+#include "../8390.h"
 
 #include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
index 9bca412c8c8e50e60eda73065efbba643bb0e99f..570fbbc0df1475ca068fb4151f7742f8a5ca956f 100644 (file)
  *     This driver is for PCnet32 and PCnetPCI based ethercards
  */
 
-static const char *version = "pcnet32.c:v1.23 6.7.1999 tsbogend@alpha.franken.de\n";
+static const char *version = "pcnet32.c:v1.23ac 21.9.1999 tsbogend@alpha.franken.de\n";
 
 #include <linux/config.h>
 #include <linux/module.h>
-#ifdef MODVERSIONS
-#include <linux/modversions.h>
-#endif
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -39,6 +36,7 @@ static const char *version = "pcnet32.c:v1.23 6.7.1999 tsbogend@alpha.franken.de
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/spinlock.h>
 
 static unsigned int pcnet32_portlist[] __initdata = {0x300, 0x320, 0x340, 0x360, 0};
 
@@ -156,6 +154,7 @@ static int full_duplex[MAX_UNITS] = {0, };
  *        Michael Richard <mcr@solidum.com>)
  *         added chip id for 79c973/975 (thanks to Zach Brown <zab@zabbo.net>)
  * v1.23   fixed small bug, when manual selecting MII speed/duplex
+ * v1.23ac Added SMP spinlocking - Alan Cox <alan@redhat.com>
  */
 
 
@@ -255,14 +254,15 @@ struct pcnet32_private {
     struct sk_buff *rx_skbuff[RX_RING_SIZE];
     struct pcnet32_access a;
     void *origmem;
-    int cur_rx, cur_tx;                        /* The next free ring entry */
-    int dirty_rx, dirty_tx;                    /* The ring entries to be free()ed. */
+    spinlock_t lock;                           /* Guard lock */
+    int cur_rx, cur_tx;                                /* The next free ring entry */
+    int dirty_rx, dirty_tx;                    /* The ring entries to be free()ed. */
     struct net_device_stats stats;
     char tx_full;
     int  options;
-    int  shared_irq:1,                      /* shared irq possible */
-         full_duplex:1,                     /* full duplex possible */
-         mii:1;                             /* mii port available */
+    int  shared_irq:1,                         /* shared irq possible */
+         full_duplex:1,                        /* full duplex possible */
+         mii:1;                                /* mii port available */
 #ifdef MODULE
     struct net_device *next;
 #endif    
@@ -510,7 +510,7 @@ static int __init
 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;
+    int i,media,fdx = 0, mii = 0, fset = 0;
     int chip_version;
     char *chipname;
     char *priv;
@@ -551,11 +551,11 @@ pcnet32_probe1(struct net_device *dev, unsigned long ioaddr, unsigned char irq_l
        break;
      case 0x2623:
        chipname = "PCnet/FAST 79C971";
-       fdx = 1; mii = 1;
+       fdx = 1; mii = 1; fset = 1;
        break;
      case 0x2624:
        chipname = "PCnet/FAST+ 79C972";
-       fdx = 1; mii = 1;
+       fdx = 1; mii = 1; fset = 1;
        break;
      case 0x2625:
        chipname = "PCnet/FAST III 79C973";
@@ -588,6 +588,19 @@ pcnet32_probe1(struct net_device *dev, unsigned long ioaddr, unsigned char irq_l
        printk("pcnet32: PCnet version %#x, no PCnet32 chip.\n",chip_version);
        return ENODEV;
     }
+
+    /*
+     * On selected chips turn on the BCR18:NOUFLO bit. This stops transmit
+     *  starting until the packet is loaded. Strike one for reliability, lose
+     *  one for latency - although on PCI this isnt a big loss. Older chips 
+     *  have FIFO's smaller than a packet, so you can't do this.
+     */
+         
+    if(fset)
+    {
+       a->write_bcr(ioaddr, 18, (a->read_bcr(ioaddr, 18) | 0x0800));
+       a->write_csr(ioaddr, 80, a->read_csr(ioaddr, 80) | 0x0c00);
+    }
     
     dev = init_etherdev(dev, 0);
 
@@ -611,6 +624,9 @@ pcnet32_probe1(struct net_device *dev, unsigned long ioaddr, unsigned char irq_l
     lp = (struct pcnet32_private *)(((unsigned long)priv+15) & ~15);
       
     memset(lp, 0, sizeof(*lp));
+    
+    spin_lock_init(&lp->lock);
+    
     dev->priv = lp;
     lp->name = chipname;
     lp->shared_irq = shared;
@@ -933,9 +949,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
        return 1;
     }
 
-    save_flags (flags);
-    cli ();
-
+    spin_lock_irqsave(&lp->lock, flags);
     /* Fill in a Tx ring entry */
 
     /* Mask to ring buffer boundary. */
@@ -964,7 +978,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
        clear_bit (0, (void *)&dev->tbusy);
     else
        lp->tx_full = 1;
-    restore_flags(flags);
+    spin_unlock_irqrestore(&lp->lock, flags);
     return 0;
 }
 
@@ -986,6 +1000,9 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 
     ioaddr = dev->base_addr;
     lp = (struct pcnet32_private *)dev->priv;
+    
+    spin_lock(&lp->lock);
+    
     if (dev->interrupt)
        printk("%s: Re-entering the interrupt handler.\n", dev->name);
 
@@ -1094,12 +1111,14 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
     /* Clear any other interrupt, and set interrupt enable. */
     lp->a.write_csr (ioaddr, 0, 0x7940);
     lp->a.write_rap(ioaddr,rap);
-
+    
     if (pcnet32_debug > 4)
        printk("%s: exiting interrupt, csr0=%#4.4x.\n",
               dev->name, lp->a.read_csr (ioaddr, 0));
 
     dev->interrupt = 0;
+    
+    spin_unlock(&lp->lock);
     return;
 }
 
@@ -1248,12 +1267,11 @@ pcnet32_get_stats(struct net_device *dev)
     u16 saved_addr;
     unsigned long flags;
 
-    save_flags(flags);
-    cli();
+    spin_lock_irqsave(&lp->lock, flags);
     saved_addr = lp->a.read_rap(ioaddr);
     lp->stats.rx_missed_errors = lp->a.read_csr (ioaddr, 112);
     lp->a.write_rap(ioaddr, saved_addr);
-    restore_flags(flags);
+    spin_unlock_irqrestore(&lp->lock, flags);
 
     return &lp->stats;
 }
index 346830ec65414dc34ac392698f146f1a7af02615..b0d8a9ad4d778ea37c679e798aceed2f0e28aa0f 100644 (file)
@@ -912,6 +912,7 @@ printk("cm0: IP identification: %02x%02x  fragment offset: %02x%02x\n", buffer[3
        /* datagram completed: send to upper level */
        skb_trim(skb, dlen);
        netif_rx(skb);
+       stats->rx_bytes+=dlen;
        stats->rx_packets++;
        lp->rx_bytes += dlen;
        lp->rx_skb[ns] = 0;
@@ -1257,7 +1258,7 @@ init_module(void)
        int i;
        for (i = 0; i < 100; i++) {
                sprintf(devname, "cm%d", i);
-               if (dev_get(devname) == NULL) break;
+               if (dev_get(devname) == 0) break;
        }
        if (i == 100) {
                printk(KERN_ERR "sb1000: can't register any device cm<n>\n");
index c0bc40ff15ba86ebc798f2e1e6726cf98d576d79..4fa976736c5e5d93ae7191c1691b720772aaeeaf 100644 (file)
@@ -831,6 +831,9 @@ slip_open(struct tty_struct *tty)
        struct slip *sl;
        int err;
 
+       if(!capable(CAP_NET_ADMIN))
+               return -EPERM;
+               
        MOD_INC_USE_COUNT;
 
        /* RTnetlink lock is misused here to serialize concurrent
index 4bad54ac9e392ca23a92c65f03cb4fa5cbeba590..cbbee85327edf8bb2af41a62e5b99b65bf429b7a 100644 (file)
@@ -59,6 +59,13 @@ static       int             sa_int = 0;
 static int             duplex = 0;
 static int             speed = 0;
 
+MODULE_PARM(aui, "i");
+MODULE_PARM(sa_int, "i");
+MODULE_PARM(duplex, "i");
+MODULE_PARM(speed, "i");
+MODULE_PARM(debug, "i");
+EXPORT_NO_SYMBOLS;
+
 #endif
 
 
@@ -352,7 +359,7 @@ extern int init_module(void)
        
        /* printk( "TLAN:  Found %d device(s).\n", TLanDevicesInstalled ); */
 
-    return ( ( TLanDevicesInstalled >= 0 ) ? 0 : -ENODEV );
+       return ( ( TLanDevicesInstalled > 0 ) ? 0 : -ENODEV );
 
 } /* init_module */
 
@@ -2528,13 +2535,13 @@ void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits )
 
        for ( i = ( 0x1 << ( num_bits - 1 ) ); i; i >>= 1 ) {
                TLan_ClearBit( TLAN_NET_SIO_MCLK, sio );
-               TLan_GetBit( TLAN_NET_SIO_MCLK, sio );
+               (void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio );
                if ( data & i )
                        TLan_SetBit( TLAN_NET_SIO_MDATA, sio );
                else
                        TLan_ClearBit( TLAN_NET_SIO_MDATA, sio );
                TLan_SetBit( TLAN_NET_SIO_MCLK, sio );
-               TLan_GetBit( TLAN_NET_SIO_MCLK, sio );
+               (void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio );
        }
 
 } /* TLan_MiiSendData */
index 5b1c8e82972850b87bec674102cb457a1e08510c..ec8fcb7a8bb31e9ca2666816f5b973d9c530fa33 100644 (file)
@@ -81,10 +81,11 @@ static struct pci_fixup pci_fixups[] __initdata = {
        { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82441,      quirk_passive_release },
        /*
         * Its not totally clear which chipsets are the problematic ones
-        * This is the 82C586 variants. At the moment the 596 is an unknown
-        * quantity.
+        * We know 82C586 and 82C596 variants are affected.
+        *
         */
        { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_82C586_0,     quirk_isa_dma_hangs },
+       { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_82C596,       quirk_isa_dma_hangs },
        { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_S3,       PCI_DEVICE_ID_S3_868,           quirk_s3_64M },
        { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_S3,       PCI_DEVICE_ID_S3_968,           quirk_s3_64M },
        { 0 }
index 49ace00b2bac47b4361a5bc4924d0e707a9db528..95b07bdad9e0a6e1a1db93517260a66d61c1b751 100644 (file)
@@ -218,7 +218,7 @@ int __init a2091_detect(Scsi_Host_Template *tpnt)
        if (num_a2091++ == 0) {
            first_instance = instance;
            a2091_template = instance->hostt;
-           request_irq(IRQ_AMIGA_PORTS, a2091_intr, SA_SHORQ, "A2091 SCSI",
+           request_irq(IRQ_AMIGA_PORTS, a2091_intr, SA_SHIRQ, "A2091 SCSI",
                        a2091_intr);
        }
        DMA(instance)->CNTR = CNTR_PDMD | CNTR_INTEN;
index 985453a0c5e5a45149360972f9d1b1b4f703cc6c..bce089b6ad2f1dac5a2d00248a5d2c7917712b9d 100644 (file)
@@ -1,6 +1,21 @@
 /*
  *      eata.c - Low-level driver for EATA/DMA SCSI host adapters.
  *
+ *      16 Sep 1999 Rev. 5.11 for linux 2.2.12 and 2.3.18
+ *        + Updated to the new __setup interface for boot command line options.
+ *        + When loaded as a module, accepts the new parameter boot_options
+ *          which value is a string with the same format of the kernel boot
+ *          command line options. A valid example is:
+ *          modprobe eata 'boot_options=\"0x7410,0x230,lc:y,tc:n,mq:4\"'
+ *
+ *       9 Sep 1999 Rev. 5.10 for linux 2.2.12 and 2.3.17
+ *        + 64bit cleanup for Linux/Alpha platform support
+ *          (contribution from H.J. Lu).
+ *
+ *      22 Jul 1999 Rev. 5.00 for linux 2.2.10 and 2.3.11
+ *        + Removed pre-2.2 source code compatibility.
+ *        + Added call to pci_set_master.
+ *
  *      26 Jul 1998 Rev. 4.33 for linux 2.0.35 and 2.1.111
  *        + Added command line option (rs:[y|n]) to reverse the scan order
  *          of PCI boards. The default is rs:y, which reverses the BIOS order
  *          This driver is based on the CAM (Common Access Method Committee)
  *          EATA (Enhanced AT Bus Attachment) rev. 2.0A, using DMA protocol.
  *
- *  Copyright (C) 1994-1998 Dario Ballabio (dario@milano.europe.dg.com)
+ *  Copyright (C) 1994-1999 Dario Ballabio (dario@milano.europe.dg.com)
  *
  *  Redistribution and use in source and binary forms, with or without
  *  modification, are permitted provided that redistributions of source
  *  PM3021     -  SmartRAID Adapter for ISA
  *  PM3222     -  SmartRAID Adapter for EISA (PM3222W is 16-bit wide SCSI)
  *  PM3224     -  SmartRAID Adapter for PCI  (PM3224W is 16-bit wide SCSI)
+ *  PM33340UW  -  SmartRAID Adapter for PCI  ultra wide multichannel
  *
  *  The above list is just an indication: as a matter of fact all DPT
  *  boards using the EATA/DMA protocol are supported by this driver,
  *  After the optional list of detection probes, other possible command line
  *  options are:
  *
- *  eh:y  use new scsi code (linux 2.2 only);
+ *  eh:y  use new scsi code;
  *  eh:n  use old scsi code;
  *  et:y  force use of extended translation (255 heads, 63 sectors);
  *  et:n  use disk geometry detected by scsicam_bios_param;
 #if defined(MODULE)
 #include <linux/module.h>
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,26)
+MODULE_PARM(boot_options, "s");
 MODULE_PARM(io_port, "1-" __MODULE_STRING(MAX_INT_PARAM) "i");
 MODULE_PARM(linked_comm, "i");
 MODULE_PARM(tagged_comm, "i");
@@ -370,7 +386,6 @@ MODULE_PARM(use_new_eh_code, "i");
 MODULE_PARM(ext_tran, "i");
 MODULE_PARM(rev_scan, "i");
 MODULE_AUTHOR("Dario Ballabio");
-#endif
 
 #endif
 
@@ -393,46 +408,21 @@ MODULE_AUTHOR("Dario Ballabio");
 #include <linux/stat.h>
 #include <linux/config.h>
 #include <linux/pci.h>
-
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,1,93)
-#include <linux/bios32.h>
-#endif
-
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,36)
 #include <linux/init.h>
+#include <linux/ctype.h>
+
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18)
+#include <asm/spinlock.h>
 #else
-#define __initfunc(A) A
-#define __initdata
-#define __init
+#include <linux/spinlock.h>
 #endif
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,101)
-#include <linux/spinlock.h>
-#define IRQ_FLAGS
-#define IRQ_LOCK
-#define IRQ_LOCK_SAVE
-#define IRQ_UNLOCK
-#define IRQ_UNLOCK_RESTORE
 #define SPIN_FLAGS unsigned long spin_flags;
 #define SPIN_LOCK spin_lock_irq(&io_request_lock);
 #define SPIN_LOCK_SAVE spin_lock_irqsave(&io_request_lock, spin_flags);
 #define SPIN_UNLOCK spin_unlock_irq(&io_request_lock);
 #define SPIN_UNLOCK_RESTORE \
                   spin_unlock_irqrestore(&io_request_lock, spin_flags);
-static int use_new_eh_code = TRUE;
-#else
-#define IRQ_FLAGS unsigned long irq_flags;
-#define IRQ_LOCK cli();
-#define IRQ_LOCK_SAVE do {save_flags(irq_flags); cli();} while (0);
-#define IRQ_UNLOCK sti();
-#define IRQ_UNLOCK_RESTORE do {restore_flags(irq_flags);} while (0);
-#define SPIN_FLAGS
-#define SPIN_LOCK
-#define SPIN_LOCK_SAVE
-#define SPIN_UNLOCK
-#define SPIN_UNLOCK_RESTORE
-static int use_new_eh_code = FALSE;
-#endif
 
 struct proc_dir_entry proc_scsi_eata2x = {
     PROC_SCSI_EATA2X, 6, "eata2x",
@@ -516,6 +506,10 @@ struct proc_dir_entry proc_scsi_eata2x = {
 #define ASOK              0x00
 #define ASST              0x01
 
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18)
+#define ARRAY_SIZE(x) (sizeof (x) / sizeof((x)[0]))
+#endif
+
 #define YESNO(a) ((a) ? 'y' : 'n')
 #define TLDEV(type) ((type) == TYPE_DISK || (type) == TYPE_ROM)
 
@@ -529,8 +523,8 @@ struct proc_dir_entry proc_scsi_eata2x = {
 
 /* Board info structure */
 struct eata_info {
-   ulong  data_len;     /* Number of valid bytes after this field */
-   ulong  sign;         /* ASCII "EATA" signature */
+   u_int32_t data_len;  /* Number of valid bytes after this field */
+   u_int32_t sign;      /* ASCII "EATA" signature */
    unchar        :4,    /* unused low nibble */
           version:4;    /* EATA version, should be 0x1 */
    unchar  ocsena:1,    /* Overlap Command Support Enabled */
@@ -543,8 +537,8 @@ struct eata_info {
            haaval:1;    /* Host Adapter Address Valid */
    ushort cp_pad_len;   /* Number of pad bytes after cp_len */
    unchar host_addr[4]; /* Host Adapter SCSI ID for channels 3, 2, 1, 0 */
-   ulong  cp_len;       /* Number of valid bytes in cp */
-   ulong  sp_len;       /* Number of valid bytes in sp */
+   u_int32_t cp_len;    /* Number of valid bytes in cp */
+   u_int32_t sp_len;    /* Number of valid bytes in sp */
    ushort queue_size;   /* Max number of cp that can be queued */
    ushort unused;
    ushort scatt_size;   /* Max number of entries in scatter/gather table */
@@ -593,8 +587,8 @@ struct mssp {
                      eoc:1;    /* End Of Command (1 = command completed) */
    unchar target_status;       /* SCSI status received after data transfer */
    unchar unused[2];
-   ulong inv_res_len;          /* Number of bytes not transferred */
-   struct mscp *cpp;           /* Address set in cp */
+   u_int32_t inv_res_len;      /* Number of bytes not transferred */
+   u_int32_t cpp_index;        /* Index of address set in cp */
    char mess[12];
    };
 
@@ -629,13 +623,13 @@ struct mscp {
               one:1;     /* 1 */
    unchar mess[3];       /* Massage to/from Target */
    unchar cdb[12];       /* Command Descriptor Block */
-   ulong  data_len;      /* If sg=0 Data Length, if sg=1 sglist length */
-   struct mscp *cpp;     /* Address to be returned in sp */
-   ulong  data_address;  /* If sg=0 Data Address, if sg=1 sglist address */
-   ulong  sp_addr;       /* Address where sp is DMA'ed when cp completes */
-   ulong  sense_addr;    /* Address where Sense Data is DMA'ed on error */
+   u_int32_t data_len;   /* If sg=0 Data Length, if sg=1 sglist length */
+   u_int32_t cpp_index;  /* Index of address to be returned in sp */
+   u_int32_t data_address; /* If sg=0 Data Address, if sg=1 sglist address */
+   u_int32_t sp_addr;    /* Address where sp is DMA'ed when cp completes */
+   u_int32_t sense_addr; /* Address where Sense Data is DMA'ed on error */
+   /* Additional fields begin here. */
    Scsi_Cmnd *SCpnt;
-   unsigned int index;   /* cp index */
    struct sg_list *sglist;
    };
 
@@ -664,7 +658,7 @@ static char sha[MAX_BOARDS];
 /* Initialize num_boards so that ihdlr can work while detect is in progress */
 static unsigned int num_boards = MAX_BOARDS;
 
-static unsigned long io_port[] __initdata = {
+static unsigned long io_port[] = {
 
    /* Space for MAX_INT_PARAM ports usable while loading as a module */
    SKIP,    SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,
@@ -704,6 +698,8 @@ static int link_statistics = 0;
 static int tag_mode = TAG_MIXED;
 static int ext_tran = FALSE;
 static int rev_scan = TRUE;
+static int use_new_eh_code = TRUE;
+static char *boot_options = NULL;
 
 #if defined(CONFIG_SCSI_EATA_TAGGED_QUEUE)
 static int tagged_comm = TRUE;
@@ -726,9 +722,7 @@ static int max_queue_depth = MAX_CMD_PER_LUN;
 static void select_queue_depths(struct Scsi_Host *host, Scsi_Device *devlist) {
    Scsi_Device *dev;
    int j, ntag = 0, nuntag = 0, tqd, utqd;
-   IRQ_FLAGS
 
-   IRQ_LOCK_SAVE
    j = ((struct hostdata *) host->hostdata)->board_number;
 
    for(dev = devlist; dev; dev = dev->next) {
@@ -781,7 +775,6 @@ static void select_queue_depths(struct Scsi_Host *host, Scsi_Device *devlist) {
              dev->queue_depth, link_suffix, tag_suffix);
       }
 
-   IRQ_UNLOCK_RESTORE
    return;
 }
 
@@ -795,7 +788,7 @@ static inline int wait_on_busy(unsigned long iobase, unsigned int loop) {
    return FALSE;
 }
 
-static inline int do_dma(unsigned long iobase, unsigned int addr, unchar cmd) {
+static inline int do_dma(unsigned long iobase, unsigned long addr, unchar cmd) {
 
    if (wait_on_busy(iobase, (addr ? MAXLOOP * 100 : MAXLOOP))) return TRUE;
 
@@ -828,12 +821,42 @@ static inline int read_pio(unsigned long iobase, ushort *start, ushort *end) {
    return FALSE;
 }
 
-static inline int __init 
-get_pci_irq(unsigned long port_base, unsigned char *apic_irq){
+static inline void tune_pci_port(unsigned long port_base) {
 
 #if defined(CONFIG_PCI)
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,93)
+   unsigned int addr, k;
+   struct pci_dev *dev = NULL;
+
+   if (!pci_present()) return;
+
+   for (k = 0; k < MAX_PCI; k++) {
+
+      if (!(dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) break;
+
+      if (pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &addr)) continue;
+
+#if defined(DEBUG_PCI_DETECT)
+      printk("%s: tune_pci_port, bus %d, devfn 0x%x, addr 0x%x.\n",
+             driver_name, dev->bus->number, dev->devfn, addr);
+#endif
+
+      if ((addr & PCI_BASE_ADDRESS_IO_MASK) + PCI_BASE_ADDRESS_0 == port_base) {
+         pci_set_master(dev);
+         return;
+         }
+
+      }
+
+#endif /* end CONFIG_PCI */
+
+   return;
+}
+
+static inline int
+            get_pci_irq(unsigned long port_base, unsigned char *apic_irq) {
+
+#if defined(CONFIG_PCI)
 
    unsigned int addr;
    struct pci_dev *dev = NULL;
@@ -849,9 +872,6 @@ get_pci_irq(unsigned long port_base, unsigned char *apic_irq){
              driver_name, dev->bus->number, dev->devfn, addr, dev->irq);
 #endif
 
-      if ((addr & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO)
-             continue;
-
       if ((addr & PCI_BASE_ADDRESS_IO_MASK) + PCI_BASE_ADDRESS_0 == port_base) {
          *apic_irq = dev->irq;
          return TRUE;
@@ -859,15 +879,13 @@ get_pci_irq(unsigned long port_base, unsigned char *apic_irq){
 
       }
 
-#endif /* end new style PCI code */
-
 #endif /* end CONFIG_PCI */
 
    return FALSE;
 }
 
-static inline int __init port_detect \
-      (unsigned long port_base, unsigned int j, Scsi_Host_Template *tpnt){
+static inline int port_detect \
+      (unsigned long port_base, unsigned int j, Scsi_Host_Template *tpnt) {
    unsigned char irq, dma_channel, subversion, i;
    unsigned char protocol_rev, apic_irq;
    struct eata_info info;
@@ -881,7 +899,9 @@ static inline int __init port_detect \
    sprintf(name, "%s%d", driver_name, j);
 
    if(check_region(port_base, REGION_SIZE)) {
+#if defined(DEBUG_DETECT)
       printk("%s: address 0x%03lx in use, skipping probe.\n", name, port_base);
+#endif
       return FALSE;
       }
 
@@ -992,7 +1012,7 @@ static inline int __init port_detect \
    config.len = (ushort) htons((ushort)510);
    config.ocena = TRUE;
 
-   if (do_dma(port_base, (unsigned int)&config, SET_CONFIG_DMA)) {
+   if (do_dma(port_base, (unsigned long)&config, SET_CONFIG_DMA)) {
       printk("%s: busy timeout sending configuration, detaching.\n", name);
       return FALSE;
       }
@@ -1105,14 +1125,10 @@ static inline int __init port_detect \
       }
    else                                 tag_type = 'n';
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,101)
    sh[j]->hostt->use_new_eh_code = use_new_eh_code;
-#else
-   use_new_eh_code = FALSE;
-#endif
 
    if (j == 0) {
-      printk("EATA/DMA 2.0x: Copyright (C) 1994-1998 Dario Ballabio.\n");
+      printk("EATA/DMA 2.0x: Copyright (C) 1994-1999 Dario Ballabio.\n");
       printk("%s config options -> tc:%c, lc:%c, mq:%d, eh:%c, rs:%c, et:%c.\n",
              driver_name, tag_type, YESNO(linked_comm), max_queue_depth,
              YESNO(use_new_eh_code), YESNO(rev_scan), YESNO(ext_tran));
@@ -1148,10 +1164,11 @@ static inline int __init port_detect \
              info.pci, info.eisa, info.raidnum);
 #endif
 
+   tune_pci_port(sh[j]->io_port);
    return TRUE;
 }
 
-void  __init eata2x_setup(char *str, int *ints){
+static void internal_setup(char *str, int *ints) {
    int i, argc = ints[0];
    char *cur = str, *pc;
 
@@ -1187,14 +1204,28 @@ void  __init eata2x_setup(char *str, int *ints){
    return;
 }
 
-static void __init add_pci_ports(void){
+static int option_setup(char *str) {
+   int ints[MAX_INT_PARAM];
+   char *cur = str;
+   int i = 1;
+
+   while (cur && isdigit(*cur) && i <= MAX_INT_PARAM) {
+      ints[i++] = simple_strtoul(cur, NULL, 0);
+
+      if ((cur = strchr(cur, ',')) != NULL) cur++;
+   }
+
+   ints[0] = i - 1;
+   internal_setup(cur, ints);
+   return 0;
+}
+
+static void add_pci_ports(void) {
 
 #if defined(CONFIG_PCI)
 
    unsigned int addr, k;
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,93)
-
    struct pci_dev *dev = NULL;
 
    if (!pci_present()) return;
@@ -1218,48 +1249,18 @@ static void __init add_pci_ports(void){
              (addr & PCI_BASE_ADDRESS_IO_MASK) + PCI_BASE_ADDRESS_0;
       }
 
-#else  /* else old style PCI code */
-
-   unsigned short i = 0;
-   unsigned char bus, devfn;
-
-   if (!pcibios_present()) return;
-
-   for (k = 0; k < MAX_PCI; k++) {
-
-      if (pcibios_find_class(PCI_CLASS_STORAGE_SCSI << 8, i++, &bus, &devfn)
-             != PCIBIOS_SUCCESSFUL) break;
-
-      if (pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &addr)
-             != PCIBIOS_SUCCESSFUL) continue;
-
-#if defined(DEBUG_PCI_DETECT)
-      printk("%s: detect, seq. %d, bus %d, devfn 0x%x, addr 0x%x.\n",
-             driver_name, k, bus, devfn, addr);
-#endif
-
-      if ((addr & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO)
-             continue;
-
-      /* Order addresses according to rev_scan value */
-      io_port[MAX_INT_PARAM + (rev_scan ? (MAX_PCI - k) : (1 + k))] =
-             (addr & PCI_BASE_ADDRESS_IO_MASK) + PCI_BASE_ADDRESS_0;
-      }
-
-#endif /* end old style PCI code */
-
 #endif /* end CONFIG_PCI */
 
    return;
 }
 
-int __init eata2x_detect(Scsi_Host_Template *tpnt){
+int eata2x_detect(Scsi_Host_Template *tpnt) {
    unsigned int j = 0, k;
-   IRQ_FLAGS
 
-   IRQ_LOCK_SAVE
    tpnt->proc_dir = &proc_scsi_eata2x;
 
+   if(boot_options) option_setup(boot_options);
+
 #if defined(MODULE)
    /* io_port could have been modified when loading as a module */
    if(io_port[0] != SKIP) {
@@ -1280,7 +1281,6 @@ int __init eata2x_detect(Scsi_Host_Template *tpnt){
       }
 
    num_boards = j;
-   IRQ_UNLOCK_RESTORE
    return j;
 }
 
@@ -1353,10 +1353,9 @@ static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
    /* The EATA protocol uses Big Endian format */
    cpp->sp_addr = V2DEV(spp);
 
-   cpp->cpp = cpp;
    SCpnt->scsi_done = done;
-   cpp->index = i;
-   SCpnt->host_scribble = (unsigned char *) &cpp->index;
+   cpp->cpp_index = i;
+   SCpnt->host_scribble = (unsigned char *) &cpp->cpp_index;
 
    if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",
                         BN(j), i, SCpnt->channel, SCpnt->target,
@@ -1425,7 +1424,7 @@ static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
       }
 
    /* Send control packet to the board */
-   if (do_dma(sh[j]->io_port, (unsigned int) cpp, SEND_CP_DMA)) {
+   if (do_dma(sh[j]->io_port, (unsigned long) cpp, SEND_CP_DMA)) {
       SCpnt->host_scribble = NULL;
       printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n",
              BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid);
@@ -1438,11 +1437,8 @@ static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
 
 int eata2x_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
    int rtn;
-   IRQ_FLAGS
 
-   IRQ_LOCK_SAVE
    rtn = do_qcomm(SCpnt, done);
-   IRQ_UNLOCK_RESTORE
    return rtn;
 }
 
@@ -1514,16 +1510,11 @@ static inline int do_old_abort(Scsi_Cmnd *SCarg) {
 
 int eata2x_old_abort(Scsi_Cmnd *SCarg) {
    int rtn;
-   IRQ_FLAGS
 
-   IRQ_LOCK_SAVE
    rtn = do_old_abort(SCarg);
-   IRQ_UNLOCK_RESTORE
    return rtn;
 }
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,101)
-
 static inline int do_abort(Scsi_Cmnd *SCarg) {
    unsigned int i, j;
 
@@ -1601,8 +1592,6 @@ int eata2x_abort(Scsi_Cmnd *SCarg) {
    return do_abort(SCarg);
 }
 
-#endif /* new_eh_code */
-
 static inline int do_old_reset(Scsi_Cmnd *SCarg) {
    unsigned int i, j, time, k, c, limit = 0;
    int arg_done = FALSE;
@@ -1689,10 +1678,8 @@ static inline int do_old_reset(Scsi_Cmnd *SCarg) {
 
    HD(j)->in_reset = TRUE;
    SPIN_UNLOCK
-   IRQ_UNLOCK
    time = jiffies;
    while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L);
-   IRQ_LOCK
    SPIN_LOCK
    printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit);
 
@@ -1728,7 +1715,6 @@ static inline int do_old_reset(Scsi_Cmnd *SCarg) {
          continue;
 
       SCpnt->scsi_done(SCpnt);
-      IRQ_LOCK
       }
 
    HD(j)->in_reset = FALSE;
@@ -1746,16 +1732,11 @@ static inline int do_old_reset(Scsi_Cmnd *SCarg) {
 
 int eata2x_old_reset(Scsi_Cmnd *SCarg, unsigned int reset_flags) {
    int rtn;
-   IRQ_FLAGS
 
-   IRQ_LOCK_SAVE
    rtn = do_old_reset(SCarg);
-   IRQ_UNLOCK_RESTORE
    return rtn;
 }
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,101)
-
 static inline int do_reset(Scsi_Cmnd *SCarg) {
    unsigned int i, j, time, k, c, limit = 0;
    int arg_done = FALSE;
@@ -1836,10 +1817,8 @@ static inline int do_reset(Scsi_Cmnd *SCarg) {
 
    HD(j)->in_reset = TRUE;
    SPIN_UNLOCK
-   IRQ_UNLOCK
    time = jiffies;
    while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L);
-   IRQ_LOCK
    SPIN_LOCK
    printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit);
 
@@ -1875,7 +1854,6 @@ static inline int do_reset(Scsi_Cmnd *SCarg) {
          continue;
 
       SCpnt->scsi_done(SCpnt);
-      IRQ_LOCK
       }
 
    HD(j)->in_reset = FALSE;
@@ -1892,8 +1870,6 @@ int eata2x_reset(Scsi_Cmnd *SCarg) {
    return do_reset(SCarg);
 }
 
-#endif /* new_eh_code */
-
 int eata2x_biosparam(Disk *disk, kdev_t dev, int *dkinfo) {
    int size = disk->capacity;
 
@@ -2058,7 +2034,7 @@ static void flush_dev(Scsi_Device *dev, unsigned long cursec, unsigned int j,
    for (n = 0; n < n_ready; n++) {
       k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
 
-      if (do_dma(sh[j]->io_port, (unsigned int) cpp, SEND_CP_DMA)) {
+      if (do_dma(sh[j]->io_port, (unsigned long) cpp, SEND_CP_DMA)) {
          printk("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter"\
                 " busy, will abort.\n", BN(j), (ihdlr ? "ihdlr" : "qcomm"),
                 SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid, k);
@@ -2112,25 +2088,21 @@ static inline void ihdlr(int irq, unsigned int j) {
    if (spp->eoc == FALSE)
       printk("%s: ihdlr, spp->eoc == FALSE, irq %d, reg 0x%x, count %d.\n",
              BN(j), irq, reg, HD(j)->iocount);
-   if (spp->cpp == NULL)
-      printk("%s: ihdlr, spp->cpp == NULL,  irq %d, reg 0x%x, count %d.\n",
-             BN(j), irq, reg, HD(j)->iocount);
-   if (spp->eoc == FALSE || spp->cpp == NULL) return;
+   if (spp->cpp_index < 0 || spp->cpp_index >= sh[j]->can_queue)
+      printk("%s: ihdlr, bad spp->cpp_index %d, irq %d, reg 0x%x, count %d.\n",
+             BN(j), spp->cpp_index, irq, reg, HD(j)->iocount);
+   if (spp->eoc == FALSE || spp->cpp_index < 0
+                         || spp->cpp_index >= sh[j]->can_queue) return;
 
-   cpp = spp->cpp;
+   /* Find the mailbox to be serviced on this board */
+   i = spp->cpp_index;
+
+   cpp = &(HD(j)->cp[i]);
 
 #if defined(DEBUG_GENERATE_ABORTS)
    if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 500) < 3)) return;
 #endif
 
-   /* Find the mailbox to be serviced on this board */
-   i = cpp - HD(j)->cp;
-
-   if (cpp < HD(j)->cp || cpp >= HD(j)->cp + sh[j]->can_queue
-                                     || i >= sh[j]->can_queue)
-      panic("%s: ihdlr, invalid mscp bus address %p, cp0 %p.\n", BN(j),
-            cpp, HD(j)->cp);
-
    if (HD(j)->cp_stat[i] == IGNORE) {
       HD(j)->cp_stat[i] = FREE;
       return;
@@ -2289,24 +2261,18 @@ static inline void ihdlr(int irq, unsigned int j) {
 
 static void do_interrupt_handler(int irq, void *shap, struct pt_regs *regs) {
    unsigned int j;
-   IRQ_FLAGS
    SPIN_FLAGS
 
    /* Check if the interrupt must be processed by this handler */
    if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) return;
 
    SPIN_LOCK_SAVE
-   IRQ_LOCK_SAVE
    ihdlr(irq, j);
-   IRQ_UNLOCK_RESTORE
    SPIN_UNLOCK_RESTORE
 }
 
 int eata2x_release(struct Scsi_Host *shpnt) {
    unsigned int i, j;
-   IRQ_FLAGS
-
-   IRQ_LOCK_SAVE
 
    for (j = 0; sh[j] != NULL && sh[j] != shpnt; j++);
 
@@ -2322,7 +2288,6 @@ int eata2x_release(struct Scsi_Host *shpnt) {
 
    release_region(sh[j]->io_port, sh[j]->n_io_port);
    scsi_unregister(sh[j]);
-   IRQ_UNLOCK_RESTORE
    return FALSE;
 }
 
@@ -2330,4 +2295,15 @@ int eata2x_release(struct Scsi_Host *shpnt) {
 Scsi_Host_Template driver_template = EATA;
 
 #include "scsi_module.c"
+
+#else
+
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18)
+void eata2x_setup(char *str, int *ints) {
+   internal_setup(str, ints);
+}
+#else
+__setup("eata=", option_setup);
 #endif
+
+#endif /* end MODULE */
index f1641f42d469269b0143b74f07ac26f13f1de1b8..6c00ca0a2b4d2efe2a9a5e01e57e8737c2d9c5fe 100644 (file)
@@ -16,12 +16,10 @@ int eata2x_reset(Scsi_Cmnd *);
 int eata2x_old_reset(Scsi_Cmnd *, unsigned int);
 int eata2x_biosparam(Disk *, kdev_t, int *);
 
-#define EATA_VERSION "4.33.00"
+#define EATA_VERSION "5.11.00"
 
 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,101)
-
 #define EATA {                                                               \
                 name:              "EATA/DMA 2.0x rev. " EATA_VERSION " ",   \
                 detect:                  eata2x_detect,                      \
@@ -40,21 +38,4 @@ int eata2x_biosparam(Disk *, kdev_t, int *);
                 use_new_eh_code:         1    /* Enable new error code */    \
              }
 
-#else /* Use old scsi code */
-
-#define EATA {                                                               \
-                name:              "EATA/DMA 2.0x rev. " EATA_VERSION " ",   \
-                detect:                  eata2x_detect,                      \
-                release:                 eata2x_release,                     \
-                queuecommand:            eata2x_queuecommand,                \
-                abort:                   eata2x_old_abort,                   \
-                reset:                   eata2x_old_reset,                   \
-                bios_param:              eata2x_biosparam,                   \
-                this_id:                 7,                                  \
-                unchecked_isa_dma:       1,                                  \
-                use_clustering:          ENABLE_CLUSTERING                   \
-             }
-
-#endif
-
 #endif
index e3d2ea4b971b958b28e93a7e2489bb245dc6a84b..450fc370e4aa5292848f219a190eac940c801640 100644 (file)
@@ -2531,9 +2531,9 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) {
                scb->scsi_cmd->result = DID_OK << 16;
 
             if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
-               INQUIRYDATA inq;
+               IPS_INQUIRYDATA inq;
 
-               memset(&inq, 0, sizeof(INQUIRYDATA));
+               memset(&inq, 0, sizeof(IPS_INQUIRYDATA));
 
                inq.DeviceType = TYPE_PROCESSOR;
                inq.DeviceTypeQualifier = 0;
@@ -2925,11 +2925,11 @@ ips_online(ips_ha_t *ha, ips_scb_t *scb) {
 /****************************************************************************/
 static int
 ips_inquiry(ips_ha_t *ha, ips_scb_t *scb) {
-   INQUIRYDATA inq;
+   IPS_INQUIRYDATA inq;
 
    DBG("ips_inquiry");
 
-   memset(&inq, 0, sizeof(INQUIRYDATA));
+   memset(&inq, 0, sizeof(IPS_INQUIRYDATA));
 
    inq.DeviceType = TYPE_DISK;
    inq.DeviceTypeQualifier = 0;
index 3f80b3c9154666c7f58e1df431073b86d74796e5..a4244234afb01d560acdd7c286ca1d16333d4ed9 100644 (file)
@@ -613,7 +613,7 @@ typedef struct {
    u8        ProductRevisionLevel[4];
    u8        VendorSpecific[20];
    u8        Reserved3[40];
-} INQUIRYDATA, *PINQUIRYDATA;
+} IPS_INQUIRYDATA, *IPS_PINQUIRYDATA;
 
 /*
  * Read Capacity Data Format
index c67d5a129cf7a405f8bfcb5a45dcfb57ee086b0c..c54f5e351b83783c21c6ba3cfa8d7c49225998b2 100644 (file)
 typedef struct {
    volatile unsigned char   SASR;
    char                     pad;
+#ifdef CONFIG_SGI
+   char                     pad2,pad3;
+#endif
    volatile unsigned char   SCMD;
 } wd33c93_regs;
 
index 3414387488423fd4445d1715dd6df9ebc751192d..9e5fd5a6bd29cc09661c32435df87181d729e46c 100644 (file)
@@ -187,7 +187,7 @@ int probe_opl3sa_mpu(struct address_info *hw_config)
 {
 #if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
        unsigned char conf;
-       static char irq_bits[] = {
+       static signed char irq_bits[] = {
                -1, -1, -1, -1, -1, 1, -1, 2, -1, 3, 4
        };
 
index baca53992a34b4947df9adc82b4c10e7feb811b7..f91d3dcdfd39a73399c32aee58efd81c26139d4b 100644 (file)
@@ -742,6 +742,14 @@ static void sb16_audio_output_block(int dev, unsigned long buf, int count,
        restore_flags(flags);
 }
 
+
+/*
+ *     This fails on the Cyrix MediaGX. If you don't have the DMA enabled
+ *     before the first sample arrives it locks up. However even if you
+ *     do enable the DMA in time you just get DMA timeouts and missing
+ *     interrupts and stuff, so for now I've not bothered fixing this either.
+ */
 static void sb16_audio_start_input(int dev, unsigned long buf, int count, int intrflag)
 {
        unsigned long   flags, cnt;
index 44b40e7364760ce176e65451c2122e58bab4320b..a21da2d695281576aeb625259bb6b602f49f33ae 100644 (file)
@@ -179,7 +179,7 @@ int init_module(void)
                        return -ENODEV;
 #ifdef CONFIG_MIDI
                config_mpu.io_base = mpu_io;
-               if (mpu_io && probe_sbmpu(&config_mpu))
+               if (probe_sbmpu(&config_mpu))
                        sbmpu = 1;
                if (sbmpu)
                        attach_sbmpu(&config_mpu);
index f51083d186a7f9e94cf01285054222c93279430f..37dd03f4f364ee2bdfbd900d66e7246422ec9677 100644 (file)
@@ -1216,7 +1216,17 @@ int probe_sbmpu(struct address_info *hw_config)
        last_devc = 0;
 
        if (hw_config->io_base <= 0)
+       {
+               /* The real vibra16 is fine about this, but we have to go
+                  wipe up after Cyrix again */
+                          
+               if(devc->model == MDL_SB16 && devc->minor >= 12)
+               {
+                       unsigned char   bits = sb_getmixer(devc, 0x84) & ~0x06;
+                       sb_setmixer(devc, 0x84, bits | 0x02);           /* Disable MPU */
+               }
                return 0;
+       }
 
 #if defined(CONFIG_SOUND_MPU401)
        if (devc->model == MDL_ESS)
index 4e53fde1dc2d56a69ac7517d778bc4eb9c90fbf0..d9a423f16cb5ba26763aeb122001662fa77dd150 100644 (file)
@@ -320,7 +320,7 @@ int __init root_nfs_init(void)
  *  Parse NFS server and directory information passed on the kernel
  *  command line.
  */
-void __init nfs_root_setup(char *line, int *ints)
+void __init nfs_root_setup(char *line)
 {
        ROOT_DEV = MKDEV(UNNAMED_MAJOR, 255);
        if (line[0] == '/' || line[0] == ',' || (line[0] >= '0' && line[0] <= '9')) {
@@ -335,6 +335,7 @@ void __init nfs_root_setup(char *line, int *ints)
        root_nfs_parse_addr(nfs_root_name);
 }
 
+__setup("nfsroot=", nfs_root_setup);
 
 /***************************************************************************
 
index 33cef410925cf4d0c6914a8842a698b2233f0711..bce1d34aad70f655a596304537f7e22aff8d72b8 100644 (file)
@@ -69,6 +69,9 @@ static int riscix_partition(struct gendisk *hd, kdev_t dev, unsigned long first_
        struct buffer_head *bh;
        struct riscix_record *rr;
        unsigned int riscix_minor;
+       
+       if(get_ptable_blocksize(dev)!=1024)
+               return 0;
 
        printk(" [RISCiX]");
 
@@ -113,6 +116,9 @@ static int linux_partition(struct gendisk *hd, kdev_t dev, unsigned long first_s
        struct linux_part *linuxp;
        unsigned int linux_minor, mask = (1 << hd->minor_shift) - 1;
 
+       if(get_ptable_blocksize(dev)!=1024)
+               return 0;
+               
        printk(" [Linux]");
 
        add_gd_partition(hd, linux_minor = minor++, first_sect, nr_sects);
@@ -151,6 +157,9 @@ static int adfspart_check_CUMANA(struct gendisk *hd, kdev_t dev, unsigned long f
        char *name = "CUMANA/ADFS";
        int first = 1;
 
+       if(get_ptable_blocksize(dev)!=1024)
+               return 0;
+
        /*
         * Try Cumana style partitions - sector 3 contains ADFS boot block with pointer
         * to next 'drive'.
@@ -236,6 +245,9 @@ static int adfspart_check_ADFS(struct gendisk *hd, kdev_t dev, unsigned long fir
        struct buffer_head *bh;
        struct disc_record *dr;
 
+       if(get_ptable_blocksize(dev)!=1024)
+               return 0;
+
        if (!(bh = bread(dev, 3, 1024)))
                return -1;
 
@@ -287,6 +299,9 @@ static int adfspart_check_ICSLinux(kdev_t dev, unsigned long block)
        unsigned int offset = block & 1 ? 512 : 0;
        int result = 0;
 
+       if(get_ptable_blocksize(dev)!=1024)
+               return 0;
+
        bh = bread(dev, block >> 1, 1024);
 
        if (bh != NULL) {
@@ -319,6 +334,9 @@ static int adfspart_check_ICS(struct gendisk *hd, kdev_t dev, unsigned long firs
        unsigned int i, mask = (1 << hd->minor_shift) - 1;
        struct ics_part { unsigned long start; signed long size; } *p;
 
+       if(get_ptable_blocksize(dev)!=1024)
+               return 0;
+               
        /*
         * Try ICS style partitions - sector 0 contains partition info.
         */
index 6991a4b6dc52eae7d95349c3551fb92c14b887e2..a4ba9253be2ab5648dba335d2cb474499663e216 100644 (file)
@@ -77,6 +77,8 @@ static void extended_partition(struct gendisk *hd, kdev_t dev)
        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 loopct = 0;         /* number of links followed
+                                  without finding a data partition */
        int i;
 
        first_sector = hd->part[MINOR(dev)].start_sect;
@@ -84,6 +86,8 @@ static void extended_partition(struct gendisk *hd, kdev_t dev)
        this_sector = first_sector;
 
        while (1) {
+               if (++loopct > 100)
+                       return;
                if ((current_minor & mask) == 0)
                        return;
                if (!(bh = bread(dev,0,get_ptable_blocksize(dev))))
@@ -121,8 +125,11 @@ static void extended_partition(struct gendisk *hd, kdev_t dev)
                                     first_sector + first_size))
                                continue;
 
-                       add_gd_partition(hd, current_minor, this_sector+START_SECT(p)*sector_size, NR_SECTS(p)*sector_size);
+                       add_gd_partition(hd, current_minor,
+                                        this_sector+START_SECT(p)*sector_size,
+                                        NR_SECTS(p)*sector_size);
                        current_minor++;
+                       loopct = 0;
                        if ((current_minor & mask) == 0)
                                goto done;
                }
@@ -349,18 +356,30 @@ check_table:
                /*
                 * Look for various forms of IDE disk geometry translation
                 */
-               extern int ide_xlate_1024(kdev_t, int, const char *);
+               extern int ide_xlate_1024(kdev_t, int, int, const char *);
                unsigned int sig = le16_to_cpu(*(unsigned short *)(data + 2));
+               int heads = 0;
+               /*
+                * The i386 partition handling programs very often
+                * make partitions end on cylinder boundaries.
+                * There is no need to do so, and Linux fdisk doesnt always
+                * do this, and Windows NT on Alpha doesnt do this either,
+                * but still, this helps to guess #heads.
+                */
+               for (i = 0; i < 4; i++) {
+                       struct partition *q = &p[i];
+                       if (NR_SECTS(q)) {
+                               if ((q->sector & 63) == 1 &&
+                                   (q->end_sector & 63) == 63)
+                                       heads = q->end_head + 1;
+                               break;
+                       }
+               }
                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.
+                        * Accesses to sector 0 must go to sector 1 instead.
                         */
-                       if (ide_xlate_1024(dev, -1, " [EZD]")) {
+                       if (ide_xlate_1024(dev, -1, heads, " [EZD]")) {
                                data += 512;
                                goto check_table;
                        }
@@ -368,48 +387,25 @@ check_table:
 
                        /*
                         * 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.
+                        * including a "new" MBR with its own partition table.
                         */
-                       if (ide_xlate_1024(dev, 1, " [DM6:DDO]")) {
+                       if (ide_xlate_1024(dev, 1, heads, " [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))) {
+                          data[sig] == 0xAA && data[sig+1] == 0x55 &&
+                          (data[sig+2] & 1)) {
                        /* 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) {
+                       (void) ide_xlate_1024 (dev, 0, heads, " [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]");
+                       (void) ide_xlate_1024(dev, 0, heads, " [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;
-                                       }
-                               }
-                       }
+                       (void) ide_xlate_1024(dev, 2, heads, " [PTBL]");
                }
        }
 #endif /* CONFIG_BLK_DEV_IDE */
index 4ea8d33cffc685a013f4ad756999da107602a424..1862f6f5fd1f6c512d5536d30a2f0bf13907f35b 100644 (file)
@@ -90,6 +90,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
        fd = 0;
        len = dentry->d_name.len;
        name = dentry->d_name.name;
+       if (len > 1 && *name == '0') goto out;
        while (len-- > 0) {
                c = *name - '0';
                name++;
index 618ed0aa56d69a311b1e3525a674890f5e13f8a3..50b708d91af0974f2e30477751822fe139b8c8ca 100644 (file)
 #define E820MAX        32              /* number of entries in E820MAP */
 #define E820NR 0x1e8           /* # entries in E820MAP */
 
+#define E820_RAM       1
+#define E820_RESERVED  2
+#define E820_ACPI      3
+
 #define HIGH_MEMORY    (1024*1024)
 
 #ifndef __ASSEMBLY__
index 044433b2039a1955db03457631e84478e6f566a4..53e3ea81bce9675b36605488c373f0061912a288 100644 (file)
@@ -1,9 +1,9 @@
 /* $Revision: 2.6 $$Date: 1998/08/10 16:57:01 $
  * linux/include/linux/cyclades.h
  *
- * This file is maintained by Ivan Passos <ivan@cyclades.com>, 
- * Marcio Saito <marcio@cyclades.com> and
- * Randolph Bentson <bentson@grieg.seaslug.org>.
+ * This file was initially written by
+ * Randolph Bentson <bentson@grieg.seaslug.org> and is maintained by
+ * Ivan Passos <ivan@cyclades.com>.
  *
  * This file contains the general definitions for the cyclades.c driver
  *$Log: cyclades.h,v $
@@ -317,6 +317,7 @@ struct      FIRM_ID {
 #define C_IN_RXOFL     0x00010000      /* RX buffer overflow */
 #define C_IN_IOCTLW    0x00020000      /* I/O control w/ wait */
 #define C_IN_MRTS      0x00040000      /* modem RTS drop */
+#define C_IN_ICHAR     0x00080000
  
 /* flow control */
 
@@ -373,6 +374,8 @@ struct      FIRM_ID {
 #define        C_CM_TXLOWWM    0x61            /* Tx buffer low water mark */
 #define        C_CM_RXHIWM     0x62            /* Rx buffer high water mark */
 #define        C_CM_RXNNDT     0x63            /* rx no new data timeout */
+#define        C_CM_TXFEMPTY   0x64
+#define        C_CM_ICHAR      0x65
 #define        C_CM_MDCD       0x70            /* modem DCD change */
 #define        C_CM_MDSR       0x71            /* modem DSR change */
 #define        C_CM_MRI        0x72            /* modem RI change */
@@ -410,6 +413,8 @@ struct CH_CTRL {
        uclong  hw_overflow;    /* hw overflow counter */
        uclong  sw_overflow;    /* sw overflow counter */
        uclong  comm_error;     /* frame/parity error counter */
+       uclong ichar;
+       uclong filler[7];
 };
 
 
@@ -504,7 +509,6 @@ struct cyclades_card {
 #else
     uclong filler;
 #endif
-
 };
 
 struct cyclades_chip {
@@ -527,6 +531,15 @@ struct cyclades_chip {
 #define cy_readw(port)  readw(port)
 #define cy_readl(port)  readl(port)
 
+/*
+ * Statistics counters
+ */
+struct cyclades_icount {
+       __u32   cts, dsr, rng, dcd, tx, rx;
+       __u32   frame, parity, overrun, brk;
+       __u32   buf_overrun;
+};
+
 /*
  * This is our internal structure for each serial port's state.
  * 
@@ -575,12 +588,14 @@ struct cyclades_port {
        unsigned long           rflush_count;
        struct termios          normal_termios;
        struct termios          callout_termios;
-        struct cyclades_monitor mon;
-       struct cyclades_idle_stats   idle_stats;
+       struct cyclades_monitor mon;
+       struct cyclades_idle_stats      idle_stats;
+       struct cyclades_icount  icount;
        struct tq_struct        tqueue;
        wait_queue_head_t       open_wait;
        wait_queue_head_t       close_wait;
        wait_queue_head_t       shutdown_wait;
+       wait_queue_head_t       delta_msr_wait;
 };
 
 /*
@@ -593,6 +608,7 @@ struct cyclades_port {
 #define Cy_EVENT_BREAK                 3
 #define Cy_EVENT_OPEN_WAKEUP           4
 #define Cy_EVENT_SHUTDOWN_WAKEUP       5
+#define        Cy_EVENT_DELTA_WAKEUP           6
 
 #define        CLOSING_WAIT_DELAY      30*HZ
 #define CY_CLOSING_WAIT_NONE   65535
@@ -771,6 +787,7 @@ struct cyclades_port {
 #define CyRTPR         (0x21*2)
 #define CyMSVR1                (0x6C*2)
 #define CyMSVR2                (0x6D*2)
+#define      CyANY_DELTA       (0xF0)
 #define      CyDSR             (0x80)
 #define      CyCTS             (0x40)
 #define      CyRI              (0x20)
index 275d82fc9a360d2283a764e584f0b585ce30961e..5d547a99f1caf9be276b98225f81fef1b224501e 100644 (file)
@@ -1,12 +1,12 @@
 /*********************************************************************
  *                
  * Filename:      irda.h
- * Version:       
- * Description:   
+ * Version:       1.0
+ * Description:   Exported IrDA sockets interface
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Mar  8 14:06:12 1999
- * Modified at:   Mon Mar 22 14:14:54 1999
+ * Modified at:   Mon Sep 27 12:11:49 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -83,8 +83,8 @@ struct sockaddr_irda {
 };
 
 struct irda_device_info {
-       unsigned int  saddr;       /* Address of remote device */
-       unsigned int  daddr;       /* Link where it was discovered */
+       unsigned int  saddr;        /* Address of remote device */
+       unsigned int  daddr;        /* Link where it was discovered */
        char          info[22];     /* Description */
        unsigned char charset;      /* Charset used for description */
        unsigned char hints[2];     /* Hint bits */
@@ -92,7 +92,7 @@ struct irda_device_info {
 
 struct irda_device_list {
        unsigned int len;
-       struct irda_device_info dev[0];
+       struct irda_device_info dev[1];
 };
 
 struct irda_ias_set {
index 590d4b10f8780f29b47bad944ff062d402beb2c0..bff574aac740721cab80d2ca8385fca88e5e40bb 100644 (file)
@@ -278,8 +278,9 @@ struct video_unit
 #define VID_HARDWARE_TYPHOON   19
 #define VID_HARDWARE_VINO      20      /* Reserved for SGI Indy Vino */
 #define VID_HARDWARE_CADET     21      /* Cadet radio */
-#define VID_HARDWARE_CPIA      22
+#define VID_HARDWARE_TRUST     22      /* Trust FM Radio */
 #define VID_HARDWARE_TERRATEC  23      /* TerraTec ActiveRadio */
+#define VID_HARDWARE_CPIA      24
 
 /*
  *     Initialiser list
index 6b45e54bb4e026e78a4ee5508b27e97d9f0df66c..500baba378e9e17ca985bd6232aec7e930b72e2a 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Jun  6 23:24:22 1999
- * Modified at:   Fri Aug 13 07:31:35 1999
+ * Modified at:   Tue Aug 31 10:22:02 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -83,9 +83,13 @@ struct ircomm_tty_cb {
        struct termios    callout_termios;
 
        wait_queue_head_t open_wait;
+       wait_queue_head_t close_wait;
        struct timer_list watchdog_timer;
        struct tq_struct  tqueue;
 
+        unsigned short    close_delay;
+        unsigned short    closing_wait; /* time to wait before closing */
+
        long pgrp;              /* pgrp of opening process */
        int  open_count;
        int  blocked_open;      /* # of blocked opens */
index 8556dd741b6ea0d1d1581a4db5def70801adf69d..545bf20a60b33b82c27e025d8344123ff6b9455b 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Wed Jun  9 15:55:18 1999
- * Modified at:   Mon Jul  5 12:56:56 1999
+ * Modified at:   Thu Sep  2 10:29:30 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -52,6 +52,8 @@ typedef enum {
        IRCOMM_TTY_DISCOVERY_INDICATION,
        IRCOMM_TTY_CONNECT_CONFIRM,
        IRCOMM_TTY_CONNECT_INDICATION,
+       IRCOMM_TTY_DISCONNECT_REQUEST,
+       IRCOMM_TTY_DISCONNECT_INDICATION,
        IRCOMM_TTY_WD_TIMER_EXPIRED,
        IRCOMM_TTY_GOT_PARAMETERS,
        IRCOMM_TTY_GOT_LSAPSEL,
@@ -66,6 +68,7 @@ struct ircomm_tty_info {
 
 extern char *ircomm_state[];
 extern char *ircomm_event[];
+extern char *ircomm_tty_state[];
 
 int ircomm_tty_do_event(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event,
                        struct sk_buff *skb, struct ircomm_tty_info *info);
@@ -79,6 +82,9 @@ void ircomm_tty_connect_confirm(void *instance, void *sap,
                                __u32 max_sdu_size, 
                                __u8 max_header_size, 
                                struct sk_buff *skb);
+void ircomm_tty_disconnect_indication(void *instance, void *sap, 
+                                     LM_REASON reason,
+                                     struct sk_buff *skb);
 void ircomm_tty_connect_indication(void *instance, void *sap, 
                                   struct qos_info *qos, 
                                   __u32 max_sdu_size,
index fb8874fef85b0b1cb574781428182e54b3c88bb6..5e00eec7ac359ebcb587d7a3dd35811183667558 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Dec  9 21:13:12 1997
- * Modified at:   Thu Jul  8 12:53:35 1999
+ * Modified at:   Mon Sep 27 11:13:18 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
@@ -73,7 +73,7 @@ if(!(expr)) { \
 #define MSECS_TO_JIFFIES(ms) (((ms)*HZ+999)/1000)
 
 /*
- *  Magic numbers used by Linux/IR. Random numbers which must be unique to 
+ *  Magic numbers used by Linux-IrDA. Random numbers which must be unique to 
  *  give the best protection
  */
 typedef __u32 magic_t;
@@ -245,7 +245,7 @@ typedef struct {
                                struct qos_info *qos, __u32 max_sdu_size,
                                __u8 max_header_size, struct sk_buff *skb);
        void (*connect_indication)(void *instance, void *sap, 
-                                  struct qos_info *qos, __u32 max_sdu_size,
+                                  struct qos_info *qos, __u32 max_sdu_size, 
                                   __u8 max_header_size, struct sk_buff *skb);
        void (*disconnect_indication)(void *instance, void *sap, 
                                      LM_REASON reason, struct sk_buff *);
index 7652b1512f73bfaf5a1eff92bf3970ede2d6a86a..5c5d2280e56ebed50cf255c29d15dea876cda24e 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Apr 14 12:41:42 1998
- * Modified at:   Tue Aug 24 13:58:23 1999
+ * Modified at:   Mon Sep 20 11:21:31 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
 #include <net/irda/irqueue.h>
 #include <net/irda/irlap_frame.h>
 
+/* Some private IOCTL's */
+#define SIOCSDONGLE    (SIOCDEVPRIVATE + 0)
+#define SIOCSBANDWIDTH (SIOCDEVPRIVATE + 1)
+#define SIOCSMEDIABUSY (SIOCDEVPRIVATE + 2)
+
 /* Some non-standard interface flags (should not conflict with any in if.h) */
 #define IFF_SIR        0x0001 /* Supports SIR speeds */
 #define IFF_MIR        0x0002 /* Supports MIR speeds */
@@ -153,12 +158,13 @@ int  irda_device_open(struct irda_device *, char *name, void *priv);
 void irda_device_close(struct irda_device *);
 
 /* Interface to be uses by IrLAP */
-inline void irda_device_set_media_busy(struct irda_device *, int status);
-inline int  irda_device_is_media_busy(struct irda_device *);
-inline int  irda_device_is_receiving(struct irda_device *);
-inline void irda_device_change_speed(struct irda_device *, int);
+void irda_device_set_media_busy(struct net_device *dev, int status);
+int  irda_device_is_media_busy(struct net_device *dev);
+int  irda_device_is_receiving(struct net_device *dev);
+struct qos_info *irda_device_get_qos(struct net_device *dev);
 
-inline struct qos_info *irda_device_get_qos(struct irda_device *self);
+/* Interface for internal use */
+void irda_device_change_speed(struct irda_device *, int);
 int  irda_device_txqueue_empty(struct irda_device *self);
 void irda_device_init_dongle(struct irda_device *self, int type);
 void irda_device_unregister_dongle(struct dongle *dongle);
index 11241374076dadd3c104d62ad7fe0129c33078c2..f21365188ba0a1efb46a64bf1a0d3ae0dbb6fb51 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Thu Jul  8 21:22:50 1999
+ * Modified at:   Mon Sep 20 10:14:47 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -90,8 +90,7 @@ struct irlap_cb {
        QUEUE   q;     /* Must be first */
        magic_t magic;
 
-       struct irda_device *irdev;
-       struct net_device      *netdev;
+       struct net_device  *netdev;
 
        /* Connection state */
        volatile IRLAP_STATE state;       /* Current state */
@@ -183,7 +182,7 @@ extern hashbin_t *irlap;
 int irlap_init(void);
 void irlap_cleanup(void);
 
-struct irlap_cb *irlap_open(struct irda_device *dev);
+struct irlap_cb *irlap_open(struct net_device *dev);
 void irlap_close(struct irlap_cb *self);
 
 void irlap_connect_request(struct irlap_cb *self, __u32 daddr, 
diff --git a/include/net/irda/irlpt_cli.h b/include/net/irda/irlpt_cli.h
deleted file mode 100644 (file)
index 7525a29..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      irlpt_cli.h
- * Version:       0.1
- * Description:   
- * Status:        Experimental.
- * Author:        Dag Brattli <dagb@cs.uit.no>
- * Created at:    Sat Feb 21 18:54:38 1998
- * Modified at:   Wed Apr 21 16:46:26 1999
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1998, Thomas Davis, <ratbert@radiks.net>
- *     Copyright (c) 1998, Dag Brattli, 
- *     All Rights Reserved
- *      
- *     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.
- *  
- *     I, Thomas Davis, provide no warranty for any of this software. This
- *     material is provided "AS-IS" and at no charge.
- *     
- ********************************************************************/
-
-#ifndef IRLPT_CLIENT_H
-#define IRLPT_CLIENT_H
-
-/* Debug function */
-
-/* int  client_init( struct net_device *dev); */
-
-/*
- * if it's static, it doesn't go in here.
- */
-
-void irlpt_client_get_value_confirm(int result, __u16 obj_id, 
-                                   struct ias_value *value, 
-                                   void *priv);
-void irlpt_client_connect_indication( void *instance, 
-                                     void *sap, 
-                                     struct qos_info *qos, 
-                                     int max_seg_size,
-                                     struct sk_buff *skb);
-void irlpt_client_connect_request( struct irlpt_cb *self);
-
-extern hashbin_t *irlpt_clients;
-
-#endif
diff --git a/include/net/irda/irlpt_cli_fsm.h b/include/net/irda/irlpt_cli_fsm.h
deleted file mode 100644 (file)
index b6fd153..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      irlpt_cli_fsm.h
- * Version:       0.1
- * Sources:       irlan_event.h
- * 
- *     Copyright (c) 1997 Dag Brattli <dagb@cs.uit.no>, 
- *             All Rights Reserved.
- *     Copyright (c) 1998, Thomas Davis, <ratbert@radiks.net>, 
- *             All Rights Reserved.
- *     
- *     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.
- *
- *     I, Thomas Davis, provide no warranty for any of this software. 
- *     This material is provided "AS-IS" and at no charge.
- *
- ********************************************************************/
-
-#ifndef IRLPT_EVENT_H
-#define IRLPT_EVENT_H
-
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-
-extern void irlpt_client_do_event( struct irlpt_cb *self,  
-                                  IRLPT_EVENT event, 
-                                  struct sk_buff *skb, 
-                                  struct irlpt_info *info);
-extern void irlpt_client_next_state( struct irlpt_cb *self, 
-                                    IRLPT_CLIENT_STATE state);
-
-#endif
-
diff --git a/include/net/irda/irlpt_common.h b/include/net/irda/irlpt_common.h
deleted file mode 100644 (file)
index 25ad8ef..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*********************************************************************
- *
- * Filename:      irlpt_common.h
- * Version:       
- * Description:   
- * Status:        Experimental.
- * Author:        Thomas Davis, <ratbert@radiks.net>
- * Created at:    Sat Feb 21 18:54:38 1998
- * Modified at:   Sun Mar  8 23:44:19 1998
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * Sources:      irlan.c
- *
- *     Copyright (c) 1998, Thomas Davis, <ratbert@radiks.net>,
- *                        Dag Brattli,  <dagb@cs.uit.no>
- *     All Rights Reserved.
- *
- *     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.
- *
- *     I, Thomas Davis, provide no warranty for any of this software.
- *     This material is provided "AS-IS" and at no charge.
- *
- ********************************************************************/
-
-#ifndef IRLPT_COMMON_H
-#define IRLPT_COMMON_H
-
-#include <net/irda/qos.h>
-#include <net/irda/irmod.h>
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/miscdevice.h>
-
-#include <linux/poll.h>
-
-extern char *irlpt_service_type[];
-extern char *irlpt_port_type[];
-extern char *irlpt_connected[];
-extern char *irlpt_reasons[];
-extern char *irlpt_client_fsm_state[];
-extern char *irlpt_server_fsm_state[];
-extern char *irlpt_fsm_event[];
-
-extern wait_queue_head_t lpt_wait;
-
-extern struct irlpt_cb *irlpt_find_handle(unsigned int minor);
-extern void irlpt_flow_control(struct sk_buff *skb);
-
-extern ssize_t irlpt_read( struct file *file, char *buffer, 
-                          size_t count, loff_t *noidea);
-extern ssize_t irlpt_write(struct file *file, const char *buffer, 
-                          size_t count, loff_t *noidea);
-extern loff_t irlpt_seek(struct file *, loff_t, int);
-extern int irlpt_open(struct inode * inode, struct file *file);
-extern int irlpt_close(struct inode *inode, struct file *file);
-extern u_int irlpt_poll(struct file *file, poll_table *wait);
-
-/* FSM definitions */
-
-typedef enum {
-        IRLPT_CLIENT_IDLE,
-       IRLPT_CLIENT_QUERY,
-       IRLPT_CLIENT_READY,
-       IRLPT_CLIENT_WAITI,
-       IRLPT_CLIENT_CONN,
-} IRLPT_CLIENT_STATE;
-
-typedef enum {
-       IRLPT_SERVER_IDLE,
-       IRLPT_SERVER_CONN,
-} IRLPT_SERVER_STATE;
-    
-/* IrLPT Events */
-
-typedef enum {
-       QUERY_REMOTE_IAS,
-       IAS_PROVIDER_AVAIL,
-       IAS_PROVIDER_NOT_AVAIL,
-       LAP_DISCONNECT,
-       LMP_CONNECT,
-       LMP_DISCONNECT,
-       LMP_CONNECT_INDICATION,
-       LMP_DISCONNECT_INDICATION,
-        IRLPT_DISCOVERY_INDICATION,
-       IRLPT_CONNECT_REQUEST,
-       IRLPT_DISCONNECT_REQUEST,
-       CLIENT_DATA_INDICATION,
-} IRLPT_EVENT;
-
-struct irlpt_info {
-       struct lsap_cb *lsap;
-       __u8 dlsap_sel;
-       __u32 daddr;
-       __u32 saddr;
-};
-
-/* Command packet types */
-
-#define IRLPT_MAX_PACKET 1024
-#define IRLPT_MAX_HEADER LMP_MAX_HEADER
-#define IRLPT_MAX_DEVICES 3
-#define IRLPT_MAGIC 0x0755
-
-typedef enum {
-       IRLPT_DISCONNECTED,
-       IRLPT_WAITING,
-       IRLPT_CONNECTED,
-       IRLPT_FLUSHED,
-} IRLPT_SERVER_STATUS;
-
-#define IRLPT_LSAP      0x09
-
-#define PI_SERVICE_TYPE        0x00
-
-#define IRLPT_UNKNOWN         0x00            /* not defined yet. */
-#define IRLPT_THREE_WIRE_RAW  0x01             /* bit 0 */
-#define IRLPT_THREE_WIRE      0x02             /* bit 1 */
-#define IRLPT_NINE_WIRE              0x04              /* bit 2 */
-#define IRLPT_CENTRONICS      0x08             /* bit 3 */
-#define IRLPT_SERVER_MODE     0xFF            /* our own flag */
-
-#define PI_PORT_TYPE   0x01
-
-#define IRLPT_SERIAL   0x01            /* bit 0 */
-#define IRLPT_PARALLEL 0x02            /* bit 1 */
-
-#define PI_PORT_NAME   0x02
-
-#define PI_CRITICAL    0x80
-
-struct irlpt_cb {
-       QUEUE queue;            /* must be first. */
-
-       int magic;              /* magic used to detect corruption of 
-                                  the struct */
-       __u32 daddr;            /* address of remote printer */
-       __u32 saddr;            /* my local address. */
-
-       struct timer_list retry_timer;
-       
-       int volatile state;     /* Current state of IrCOMM layer */
-       int open_retries;
-        int in_use;            /* flag to prevent re-use */
-        char ifname[16];               /* name of the allocated instance, 
-                                  and registered device. */
-       struct lsap_cb *lsap;   /* lmp handle */
-
-       __u8 dlsap_sel;         /* remote LSAP selector address */
-       __u8 slsap_sel;         /* local LSAP selectoraddress */
-       __u8 servicetype;       /* Type of remote service, ie THREE_WIRE_RAW */
-       __u8 porttype;          /* type of remote port. */
-
-       struct miscdevice ir_dev; /* used to register the misc device. */
-
-       int count;                /* open count */
-       int max_data_size;      /* max frame size we can send */
-       int max_header_size;    /* how much header space is needed */
-       int pkt_count;          /* how many packets are queued up */
-
-       wait_queue_head_t read_wait;    /* wait queues */
-       wait_queue_head_t write_wait;
-       wait_queue_head_t ex_wait;
-
-       /* this is used to remove the printer when it's gone */
-       struct timer_list lpt_timer;
-       void (*timeout) (unsigned long data);
-
-       void (*do_event) (struct irlpt_cb *self, IRLPT_EVENT event, 
-                         struct sk_buff *skb,
-                         struct irlpt_info *info);
-
-       /* this is used by the server side of the system */
-
-        IRLPT_SERVER_STATE connected;
-
-       int eof;
-       int service_LSAP;
-
-       struct sk_buff_head rx_queue; /* read buffer queue */
-};
-
-/* Debug function */
-void irlpt_dump_buffer(struct sk_buff *);
-
-#endif
diff --git a/include/net/irda/irlpt_server.h b/include/net/irda/irlpt_server.h
deleted file mode 100644 (file)
index f5713cc..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      irlpt_server.h
- * Version:       0.1
- * Description:   
- * Status:        Experimental.
- * Author:        Dag Brattli <dagb@cs.uit.no>
- * Created at:    Sat Feb 21 18:54:38 1998
- * Modified at:   Tue Sep 22 11:41:42 1998
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1998, Thomas Davis, <ratbert@radiks.net>
- *     Copyright (c) 1998, Dag Brattli, 
- *     All Rights Reserved
- *      
- *     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.
- *  
- *     I, Thomas Davis, provide no warranty for any of this software. This
- *     material is provided "AS-IS" and at no charge.
- *     
- ********************************************************************/
-
-#ifndef IRLPT_SERVER_H
-#define IRLPT_SERVER_H
-
-#include "qos.h"
-#include "irmod.h"
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/miscdevice.h>
-
-/* int  server_init( struct net_device *dev); */
-
-extern struct irlpt_cb *irlpt_server;
-
-#endif
diff --git a/include/net/irda/irlpt_server_fsm.h b/include/net/irda/irlpt_server_fsm.h
deleted file mode 100644 (file)
index c7ee3f8..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      server_server_fsm.h
- * Version:       0.1
- * Sources:       irlan_event.h
- * 
- *     Copyright (c) 1997 Dag Brattli <dagb@cs.uit.no>, 
- *             All Rights Reserved.
- *     Copyright (c) 1998, Thomas Davis, <ratbert@radiks.net>, 
- *             All Rights Reserved.
- *     
- *     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.
- *
- *     I, Thomas Davis, provide no warranty for any of this software. 
- *     This material is provided "AS-IS" and at no charge.
- *
- ********************************************************************/
-
-#ifndef IRLPT_EVENT_H
-#define IRLPT_EVENT_H
-
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-
-void irlpt_server_do_event( struct irlpt_cb *self, 
-                           IRLPT_EVENT event, 
-                           struct sk_buff *skb, 
-                           struct irlpt_info *info);
-void irlpt_server_next_state( struct irlpt_cb *self, 
-                             IRLPT_SERVER_STATE state);
-
-#endif
index 48ac3ee8e0e533472f470347cc5c29412747406c..a44ab2b9f7056993d35894bffbc90ed022504efd 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:31 1997
- * Modified at:   Tue Aug 24 09:27:05 1999
+ * Modified at:   Mon Sep 27 11:38:01 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -141,6 +141,11 @@ static __inline __u32 irttp_get_daddr(struct tsap_cb *self)
        return irlmp_get_daddr(self->lsap);
 }
 
+static __inline __u32 irttp_get_max_seq_size(struct tsap_cb *self)
+{
+       return self->max_seg_size;
+}
+
 extern struct irttp_cb *irttp;
 
 #endif /* IRTTP_H */
diff --git a/include/net/irda/irvtd.h b/include/net/irda/irvtd.h
deleted file mode 100644 (file)
index 6834008..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      irvtd.h
- * Version:       0.1
- * Sources:       irlpt.h
- * 
- *     Copyright (c) 1998, Takahide Higuchi <thiguchi@pluto.dti.ne.jp>,
- *     All Rights Reserved.
- *     
- *     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.
- *
- *     I, Takahide Higuchi, provide no warranty for any of this software.
- *     This material is provided "AS-IS" and at no charge.
- *
- ********************************************************************/
-
-#ifndef IRVTD_H
-#define IRVTD_H
-
-#include <linux/types.h>
-#include <linux/ioctl.h>
-#include <linux/tqueue.h>
-#include <linux/serial.h>
-
-#include <net/irda/irmod.h>
-#include <net/irda/qos.h>
-#include <net/irda/ircomm_common.h>
-
-
-#define IRVTD_MAGIC 0xff545943  /* random */
-#define COMM_MAX_TTY 1
-#define IRVTD_RX_QUEUE_HIGH 10
-#define IRVTD_RX_QUEUE_LOW  2
-
-#define IRCOMM_MAJOR  60;  /* Zero means automatic allocation
-                              60,61,62,and 63 is reserved for experiment */
-#define IRVTD_MINOR 64
-
-
-
-struct irvtd_cb {
-
-        int magic;          /* magic used to detect corruption of the struct */
-
-       /* if daddr is NULL, remote device have not been discovered yet */
-
-       int tx_disable;
-       int rx_disable;
-       struct sk_buff *txbuff;     
-       struct sk_buff_head rxbuff; 
-       struct ircomm_cb *comm;     /* ircomm instance */
-
-       __u32 tx_max_sdu_size;
-       __u32 max_header_size;
-       /* 
-        * These members are used for compatibility with usual serial device.
-        * See linux/serial.h
-        */
-
-       int flags;
-       struct tty_struct *tty;
-
-       int line;
-       int count;                /* open count */
-       int blocked_open;
-       wait_queue_head_t       open_wait;
-       wait_queue_head_t       close_wait;
-       wait_queue_head_t       delta_msr_wait;
-       wait_queue_head_t       tx_wait;
-
-       struct timer_list       tx_timer;
-       struct timer_list       rx_timer;
-
-       long pgrp;
-       long session;  
-       unsigned short  closing_wait;     /* time to wait before closing */
-       unsigned short  close_delay;
-       
-       int custom_divisor;
-       int mcr;
-       int msr;
-       int cts_stoptx;
-       int ttp_stoptx;
-       int ttp_stoprx;
-       int disconnect_pend;
-       struct serial_icounter_struct icount;
-       int read_status_mask;
-       int ignore_status_mask;
-};
-
-
-#endif
index b2f5b953ba87ed64abeee02ec553bf345068c221..dc2ea126956287ca9882578bc675c73173611058 100644 (file)
 
 /*
  * $Log: toshoboe.h,v $
+ * Revision 1.4  1999/06/29 13:46:42  root
+ * ls
+ *
+ * Revision 1.3  1999/06/29 12:31:03  root
+ * *** empty log message ***
+ *
  * Revision 1.2  1999/05/09 01:43:08  root
  * *** empty log message ***
  *
@@ -157,6 +163,8 @@ struct toshoboe_cb
     struct OboeTaskFile *taskfile;  /*The taskfile   */
     void *xmit_bufs[TX_SLOTS];  /*The buffers   */
     void *recv_bufs[RX_SLOTS];
+    int open;
+    int stopped;               /*Stopped by some or other APM stuff*/
   };
 
 
index bf12552bf991ff726bd1f2e2a3e95f050cec430f..942182e353b29756d3e0c2caf4e34c22ab6269b6 100644 (file)
@@ -2,30 +2,30 @@
 # IrDA protocol configuration
 #
 
-if [ "$CONFIG_NET" != "n" ] ; then
+if [ "$CONFIG_NET" != "n" ]; then
 
-  mainmenu_option next_comment
-  comment 'IrDA (infrared) support'
-  dep_tristate 'IrDA subsystem support' CONFIG_IRDA $CONFIG_NET
+   mainmenu_option next_comment
+   comment 'IrDA (infrared) support'
+   dep_tristate 'IrDA subsystem support' CONFIG_IRDA $CONFIG_NET
 
-  if [ "$CONFIG_IRDA" != "n" ] ; then
-    comment 'IrDA protocols'
-    source net/irda/irlan/Config.in
-    source net/irda/ircomm/Config.in
+   if [ "$CONFIG_IRDA" != "n" ]; then
+      comment 'IrDA protocols'
+      source net/irda/irlan/Config.in
+      source net/irda/ircomm/Config.in
 
-    bool 'IrDA protocol options' CONFIG_IRDA_OPTIONS
-    if [ "$CONFIG_IRDA_OPTIONS" != "n" ] ; then
-      comment '   IrDA options'
-      bool '   Cache last LSAP' CONFIG_IRDA_CACHE_LAST_LSAP
-      bool '   Fast RRs' CONFIG_IRDA_FAST_RR
-      bool '   Debug information' CONFIG_IRDA_DEBUG
-    fi
-  fi
+      bool '  IrDA protocol options' CONFIG_IRDA_OPTIONS
+      if [ "$CONFIG_IRDA_OPTIONS" != "n" ]; then
+        comment '  IrDA options'
+        bool '    Cache last LSAP' CONFIG_IRDA_CACHE_LAST_LSAP
+        bool '    Fast RRs' CONFIG_IRDA_FAST_RR
+        bool '    Debug information' CONFIG_IRDA_DEBUG
+      fi
+   fi
 
-  if [ "$CONFIG_IRDA" != "n" ] ; then
-    source net/irda/compressors/Config.in
-    source drivers/net/irda/Config.in
-  fi
-  endmenu
+   if [ "$CONFIG_IRDA" != "n" ]; then
+      source net/irda/compressors/Config.in
+      source drivers/net/irda/Config.in
+   fi
+   endmenu
 fi
 
index 9cdc295256286f0631aa11c49566f805ca1cb1e2..96060aa884f3b25f094e8064a87a505dae619fb3 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun May 31 10:12:43 1998
- * Modified at:   Mon Aug 23 09:44:37 1999
+ * Modified at:   Mon Sep 27 20:11:52 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       af_netroom.c, af_ax25.c, af_rose.c, af_x25.c etc.
  * 
@@ -47,6 +47,8 @@ extern void irda_cleanup(void);
 extern int  irlap_driver_rcv(struct sk_buff *, struct net_device *, 
                             struct packet_type *);
 
+static int irda_create(struct socket *sock, int protocol);
+
 static struct proto_ops irda_stream_ops;
 static struct proto_ops irda_dgram_ops;
 static hashbin_t *cachelog = NULL;
@@ -66,8 +68,6 @@ static int irda_data_indication(void *instance, void *sap, struct sk_buff *skb)
        struct sock *sk;
        int err;
 
-       DEBUG(1, __FUNCTION__ "()\n");
-
        self = (struct irda_sock *) instance;
        ASSERT(self != NULL, return -1;);
 
@@ -98,7 +98,7 @@ static void irda_disconnect_indication(void *instance, void *sap,
        struct irda_sock *self;
        struct sock *sk;
 
-       DEBUG(1, __FUNCTION__ "()\n");
+       DEBUG(2, __FUNCTION__ "()\n");
 
        self = (struct irda_sock *) instance;
 
@@ -129,7 +129,7 @@ static void irda_connect_confirm(void *instance, void *sap,
        struct irda_sock *self;
        struct sock *sk;
 
-       DEBUG(1, __FUNCTION__ "()\n");
+       DEBUG(2, __FUNCTION__ "()\n");
 
        self = (struct irda_sock *) instance;
 
@@ -141,7 +141,7 @@ static void irda_connect_confirm(void *instance, void *sap,
 
        /* Find out what the largest chunk of data that we can transmit is */
        if (max_sdu_size == SAR_DISABLE)
-               self->max_data_size = qos->data_size.value - max_header_size;
+               self->max_data_size = irttp_get_max_seq_size(self->tsap);
        else
                self->max_data_size = max_sdu_size;
 
@@ -173,7 +173,7 @@ static void irda_connect_indication(void *instance, void *sap,
        struct irda_sock *self;
        struct sock *sk;
 
-       DEBUG(1, __FUNCTION__ "()\n");
+       DEBUG(2, __FUNCTION__ "()\n");
 
        self = (struct irda_sock *) instance;
 
@@ -185,7 +185,7 @@ static void irda_connect_indication(void *instance, void *sap,
 
        /* Find out what the largest chunk of data that we can transmit is */
        if (max_sdu_size == SAR_DISABLE)
-               self->max_data_size = qos->data_size.value - max_header_size;
+               self->max_data_size = irttp_get_max_seq_size(self->tsap);
        else
                self->max_data_size = max_sdu_size;
 
@@ -428,8 +428,6 @@ static int irda_listen( struct socket *sock, int backlog)
 {
        struct sock *sk = sock->sk;
 
-       DEBUG(1, __FUNCTION__ "()\n");
-
        if (sk->type == SOCK_STREAM && sk->state != TCP_LISTEN) {
                sk->max_ack_backlog = backlog;
                sk->state           = TCP_LISTEN;
@@ -495,6 +493,8 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
        struct sk_buff *skb;
        int err;
 
+       DEBUG(0, __FUNCTION__ "()\n");
+
        self = sk->protinfo.irda;
        ASSERT(self != NULL, return -1;);
 
@@ -1171,8 +1171,7 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        case SIOCSIFNETMASK:
        case SIOCGIFMETRIC:
        case SIOCSIFMETRIC:
-               return -EINVAL;
-               
+               return -EINVAL;         
        default:
                DEBUG(1, __FUNCTION__ "(), doing device ioctl!\n");
                return dev_ioctl(cmd, (void *) arg);
@@ -1212,7 +1211,7 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
                DEBUG(0, __FUNCTION__ "(), sorry not impl. yet!\n");
                return 0;
        case IRTTP_MAX_SDU_SIZE:
-               DEBUG(0, __FUNCTION__ "(), setting max_sdu_size = %d\n", opt);
+               DEBUG(2, __FUNCTION__ "(), setting max_sdu_size = %d\n", opt);
                self->max_sdu_size_rx = opt;
                break;
        default:
@@ -1232,13 +1231,12 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
 {
        struct sock *sk = sock->sk;
        struct irda_sock *self;
-       struct irda_device_list *list;
-       __u8 optbuf[sizeof(struct irda_device_list) +
-                  sizeof(struct irda_device_info)*10];
+       struct irda_device_list list;
+       struct irda_device_info *info;
        discovery_t *discovery;
        int val = 0;
        int len = 0;
-       int i = 0;
+       int offset, total;
 
        self = sk->protinfo.irda;
 
@@ -1261,7 +1259,15 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
                if (!cachelog)
                        return -EAGAIN;
 
-               list = (struct irda_device_list *) optbuf;
+               info = &list.dev[0];
+
+               /* Offset to first device entry */
+               offset = sizeof(struct irda_device_list) - 
+                       sizeof(struct irda_device_info);
+
+               total = offset;    /* Initialized to size of the device list */
+               list.len = 0;     /* Initialize lenght of list */
+
                /* 
                 * Now, check all discovered devices (if any), and notify
                 * client only about the services that the client is
@@ -1271,36 +1277,43 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
                while (discovery != NULL) {
                        /* Mask out the ones we don't want */
                        if (discovery->hints.word & self->mask) {
+                               
+                               /* Check if room for this device entry */
+                               if (len - total >= sizeof(struct irda_device_info))
+                                       break;
+
                                /* Copy discovery information */
-                               list->dev[i].saddr = discovery->saddr;
-                               list->dev[i].daddr = discovery->daddr;
-                               list->dev[i].charset = discovery->charset;
-                               list->dev[i].hints[0] = discovery->hints.byte[0];
-                               list->dev[i].hints[1] = discovery->hints.byte[1];
-                               strncpy(list->dev[i].info, discovery->nickname,
+                               info->saddr = discovery->saddr;
+                               info->daddr = discovery->daddr;
+                               info->charset = discovery->charset;
+                               info->hints[0] = discovery->hints.byte[0];
+                               info->hints[1] = discovery->hints.byte[1];
+                               strncpy(info->info, discovery->nickname,
                                        NICKNAME_MAX_LEN);
-                               if (++i >= 10)
-                                       break;
+
+                               if (copy_to_user(optval+offset, &info, 
+                                                sizeof(struct irda_device_info)))
+                                       return -EFAULT;
+                               list.len++;
+                               total += sizeof(struct irda_device_info);
                        }
                        discovery = (discovery_t *) hashbin_get_next(cachelog);
                }
                cachelog = NULL;
 
-               list->len = i;
-               len = sizeof(struct irda_device_list) +
-                       sizeof(struct irda_device_info) * i;
-
-               DEBUG(1, __FUNCTION__ "(), len=%d, i=%d\n", len, i);
-
-               if (put_user(len, optlen))
+               /* Write total number of bytes used back to client */
+               if (put_user(total, optlen))
                        return -EFAULT;
-               
-               if (copy_to_user(optval, &optbuf, len))
+
+               /* Write total list length back to client */
+               if (copy_to_user(optval, &list, 
+                                sizeof(struct irda_device_list) -
+                                sizeof(struct irda_device_info)))
                        return -EFAULT;
                break;
        case IRTTP_MAX_SDU_SIZE:
                val = self->max_data_size;
-               DEBUG(0, __FUNCTION__ "(), getting max_sdu_size = %d\n", val);
+               DEBUG(2, __FUNCTION__ "(), getting max_sdu_size = %d\n", val);
                len = sizeof(int);
                if (put_user(len, optlen))
                        return -EFAULT;
@@ -1370,7 +1383,7 @@ SOCKOPS_WRAP(irda_stream, PF_IRDA);
 /*
  * Function irda_device_event (this, event, ptr)
  *
- *    
+ *    Called when a device is taken up or down
  *
  */
 static int irda_device_event(struct notifier_block *this, unsigned long event,
@@ -1378,8 +1391,6 @@ static int irda_device_event(struct notifier_block *this, unsigned long event,
 {
        struct net_device *dev = (struct net_device *) ptr;
        
-       DEBUG(3, __FUNCTION__ "()\n");
-       
         /* Reject non IrDA devices */
        if (dev->type != ARPHRD_IRDA) 
                return NOTIFY_DONE;
index 61500751b23ecf1674e6ff7493b7e2f2eb7051b0..1a4306dea02a8cd37b3fed6119d4f4776294c099 100644 (file)
@@ -1,9 +1,11 @@
 
-bool 'IrLAP compression' CONFIG_IRDA_COMPRESSION
+bool '  IrLAP compression' CONFIG_IRDA_COMPRESSION
 
-if [ "$CONFIG_IRDA_COMPRESSION" != "n" ] ; then
-        comment '   IrDA compressors'
-        dep_tristate '   Deflate compression (experimental)' CONFIG_IRDA_DEFLATE $CONFIG_IRDA
-#      tristate '   BZIP2 compression' CONFIG_IRDA_BZIP2
-#      tristate '   BSD compression' CONFIG_IRDA_BSD
+if [ "$CONFIG_IRDA_COMPRESSION" != "n" ]; then
+   comment '    IrDA compressors'
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      dep_tristate '    Deflate compression (EXPERIMENTAL)' CONFIG_IRDA_DEFLATE $CONFIG_IRDA
+   fi
+#   tristate '    BZIP2 compression' CONFIG_IRDA_BZIP2
+#   tristate '    BSD compression' CONFIG_IRDA_BSD
 fi
index f384eb8d76dfe6c21e3610d382f912a591368e8d..67f967c5a8756f22b9b37e5f5842fcf7fbeef50b 100644 (file)
@@ -1,3 +1,3 @@
 
-dep_tristate 'IrCOMM protocol' CONFIG_IRCOMM $CONFIG_IRDA
+dep_tristate '  IrCOMM protocol' CONFIG_IRCOMM $CONFIG_IRDA
 
index c439ffdabb6bb78837660c49777eed84d026ed3b..89e3294fded58d55553e8726f6b4e8957a0ec6f0 100644 (file)
@@ -8,7 +8,7 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := ircomm_and_tty.o
-O_OBJS  := ircomm_param.o ircomm_core.o ircomm_event.o ircomm_lmp.o ircomm_ttp.o ircomm_tty.o ircomm_tty_attach.o ircomm_tty_ioctl.c
+O_OBJS  := ircomm_param.o ircomm_core.o ircomm_event.o ircomm_lmp.o ircomm_ttp.o ircomm_tty.o ircomm_tty_attach.o ircomm_tty_ioctl.o
 M_OBJS   := ircomm.o ircomm-tty.o
 MI_OBJS  := ircomm_param.o ircomm_core.o ircomm_event.o ircomm_lmp.o ircomm_ttp.o ircomm_tty.o ircomm_tty_attach.o ircomm_tty_ioctl.o
 
index f2e8b2d4654893adc704932ceec7dc1815935f33..18f0b24db4baac63db0bda914c7cd49744efe37d 100644 (file)
@@ -1,12 +1,12 @@
 /*********************************************************************
  *                
  * Filename:      ircomm_event.c
- * Version:       
- * Description:   
+ * Version:       1.0
+ * Description:   IrCOMM layer state machine
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Jun  6 20:33:11 1999
- * Modified at:   Wed Aug 25 12:58:27 1999
+ * Modified at:   Thu Sep  2 10:09:25 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -161,18 +161,15 @@ static int ircomm_state_waitr(struct ircomm_cb *self, IRCOMM_EVENT event,
                ircomm_next_state(self, IRCOMM_CONN);
                ret = self->issue.connect_response(self, skb);
                break;
-
        case IRCOMM_DISCONNECT_REQUEST:
                ircomm_next_state(self, IRCOMM_IDLE);
                ret = self->issue.disconnect_request(self, skb, info);
                break;
-
        case IRCOMM_TTP_DISCONNECT_INDICATION:
        case IRCOMM_LMP_DISCONNECT_INDICATION:
                ircomm_next_state(self, IRCOMM_IDLE);
                ircomm_disconnect_indication(self, skb, info);
                break;
-
        default:
                DEBUG(0, __FUNCTION__ "(), unknown event = %s\n",
                      ircomm_event[event]);
index 943dbd724ef035cc89f8c734b87cb87b4346572f..4294dbdb2027d153d8b2ccc07c557dce7f725710 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Jun  7 10:25:11 1999
- * Modified at:   Wed Aug 25 13:48:14 1999
+ * Modified at:   Fri Sep  3 09:28:20 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -102,6 +102,7 @@ int ircomm_param_flush(struct ircomm_tty_cb *self)
  */
 int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush)
 {
+       unsigned long flags;
        struct sk_buff *skb;
        int count;
 
@@ -119,12 +120,16 @@ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush)
        if (self->service_type == IRCOMM_3_WIRE_RAW)
                return 0;
 
-       skb = self->ctrl_skb;
-       
+       save_flags(flags);
+       cli();
+
+       skb = self->ctrl_skb;   
        if (!skb) {
                skb = dev_alloc_skb(256);
-               if (!skb)
-                       return -1;
+               if (!skb) {
+                       restore_flags(flags);
+                       return -ENOMEM;
+               }
                
                skb_reserve(skb, self->max_header_size);
 
@@ -136,8 +141,13 @@ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush)
         */
        count = irda_param_insert(self, pi, skb->tail, skb_tailroom(skb),
                                  &ircomm_param_info);
-       if (count > 0)
-               skb_put(skb, count);
+       if (count < 0) {
+               DEBUG(0, __FUNCTION__ "(), no room for parameter!\n");
+               restore_flags(flags);
+               return -1;
+       }
+       skb_put(skb, count);
+       restore_flags(flags);
 
        if (flush) {
                ircomm_control_request(self->ircomm, skb);
@@ -201,13 +211,25 @@ static int ircomm_param_service_type(void *instance, param_t *param, int get)
 /*
  * Function ircomm_param_port_type (self, param)
  *
- *    
- *
+ *    The port type parameter tells if the devices are serial or parallel.
+ *    Since we only advertise serial service, this parameter should only
+ *    be equal to IRCOMM_SERIAL.
  */
 static int ircomm_param_port_type(void *instance, param_t *param, int get)
 {
-       DEBUG(0, __FUNCTION__ "(), not impl.\n");
+       struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
+
+       ASSERT(self != NULL, return -1;);
+       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
+       
+       if (get)
+               param->pv.b = IRCOMM_SERIAL;
+       else {
+               self->session.port_type = param->pv.b;
 
+               DEBUG(0, __FUNCTION__ "(), port type=%d\n", 
+                     self->session.port_type);
+       }
        return 0;
 }
 
@@ -223,11 +245,13 @@ static int ircomm_param_port_name(void *instance, param_t *param, int get)
        
        ASSERT(self != NULL, return -1;);
        ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
-       
-       if (get)
+
+       if (get) {
                DEBUG(0, __FUNCTION__ "(), not imp!\n");
-       else
+       } else {
                DEBUG(0, __FUNCTION__ "(), port-name=%s\n", param->pv.c);
+               strncpy(self->session.port_name, param->pv.c, 32);
+       }
 
        return 0;
 }
@@ -273,8 +297,6 @@ static int ircomm_param_data_format(void *instance, param_t *param, int get)
        else
                self->session.data_format = param->pv.b;
        
-       DEBUG(1, __FUNCTION__ "(), data format = 0x%02x\n", param->pv.b);
-
        return 0;
 }
 
@@ -359,9 +381,6 @@ static int ircomm_param_dte(void *instance, param_t *param, int get)
        else {
                dte = param->pv.b;
                
-               /* Null modem cable emulator */
-               self->session.null_modem = TRUE;
-
                if (dte & IRCOMM_DELTA_DTR)
                        self->session.dce |= (IRCOMM_DELTA_DSR|
                                              IRCOMM_DELTA_RI |
@@ -379,14 +398,9 @@ static int ircomm_param_dte(void *instance, param_t *param, int get)
                /* Take appropriate actions */
                ircomm_tty_check_modem_status(self);
 
-               /* 
-                * Send reply, and remember not to set delta values for the
-                * initial parameters 
-                */
-               self->session.dte = (IRCOMM_DTR| IRCOMM_RTS);
-               ircomm_param_request(self, IRCOMM_DTE, TRUE);
+               /* Null modem cable emulator */
+               self->session.null_modem = TRUE;
        }
-       DEBUG(1, __FUNCTION__ "(), dte = 0x%02x\n", param->pv.b);
 
        return 0;
 }
@@ -426,18 +440,24 @@ static int ircomm_param_dce(void *instance, param_t *param, int get)
 /*
  * Function ircomm_param_poll (instance, param)
  *
- *    
+ *    Called when the peer device is polling for the line settings
  *
  */
 static int ircomm_param_poll(void *instance, param_t *param, int get)
 {
-       DEBUG(0, __FUNCTION__ "(), not impl.\n");
-
-       return 0;
-}
+       struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
 
+       ASSERT(self != NULL, return -1;);
+       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
+       /* Poll parameters are always of lenght 0 (just a signal) */
+       if (!get) {
+               /* Respond with DTE line settings */
+               ircomm_param_request(self, IRCOMM_DTE, TRUE);
+       }
 
+       return 0;
+}
 
 
 
index b3bd3744bc085eab1bb03ab01bcf8cc96151c797..9c188aa495e5779907978546a8b1b30e41468f8c 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Jun  6 20:48:27 1999
- * Modified at:   Tue Aug 17 10:28:26 1999
+ * Modified at:   Mon Sep 27 11:17:23 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -196,7 +196,7 @@ void ircomm_ttp_connect_confirm(void *instance, void *sap,
                return;
        }
 
-       info.max_data_size = qos->data_size.value - max_header_size
+       info.max_data_size = irttp_get_max_seq_size(self->tsap)
                - IRCOMM_HEADER_SIZE;
        info.max_header_size = max_header_size + IRCOMM_HEADER_SIZE;
        info.qos = qos;
@@ -206,7 +206,7 @@ void ircomm_ttp_connect_confirm(void *instance, void *sap,
 
 /*
  * Function ircomm_ttp_connect_indication (instance, sap, qos, max_sdu_size,
- *                                            max_header_size, skb)
+ *                                         max_header_size, skb)
  *
  *    
  *
@@ -232,7 +232,7 @@ void ircomm_ttp_connect_indication(void *instance, void *sap,
                return;
        }
 
-       info.max_data_size = qos->data_size.value - max_header_size
+       info.max_data_size = irttp_get_max_seq_size(self->tsap)
                - IRCOMM_HEADER_SIZE;
        info.max_header_size = max_header_size + IRCOMM_HEADER_SIZE;
        info.qos = qos;
index f3642841a5d480502ce059a96b761b4bb199850e..8df8d876e962c5f9dee2a2666a43b2aa08b9719f 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Jun  6 21:00:56 1999
- * Modified at:   Wed Aug 25 15:12:18 1999
+ * Modified at:   Tue Sep 21 11:46:59 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       serial.c and previous IrCOMM work by Takahide Higuchi
  * 
@@ -60,11 +60,8 @@ static void ircomm_tty_flush_buffer(struct tty_struct *tty);
 static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch);
 static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout);
 static void ircomm_tty_hangup(struct tty_struct *tty);
-static void ircomm_tty_break(struct tty_struct *tty, int break_state);
 static void ircomm_tty_do_softint(void *private_);
-static void ircomm_tty_disconnect_indication(void *instance, void *sap, 
-                                            LM_REASON reason,
-                                            struct sk_buff *skb);
+
 static int ircomm_tty_data_indication(void *instance, void *sap,
                                      struct sk_buff *skb);
 static int ircomm_tty_control_indication(void *instance, void *sap,
@@ -127,7 +124,6 @@ int __init ircomm_tty_init(void)
        driver.stop            = ircomm_tty_stop;
        driver.start           = ircomm_tty_start;
        driver.hangup          = ircomm_tty_hangup;
-       driver.break_ctl       = ircomm_tty_break;
        driver.wait_until_sent = ircomm_tty_wait_until_sent;
        driver.read_proc       = ircomm_tty_read_proc;
 
@@ -170,9 +166,12 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self)
        notify_t notify;
        int ret;
 
+       ASSERT(self != NULL, return -1;);
+       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
+
        /* Already open */
        if (self->flags & ASYNC_INITIALIZED) {
-               DEBUG(0, __FUNCTION__ "(), already open so break out!\n");
+               DEBUG(2, __FUNCTION__ "(), already open so break out!\n");
                return 0;
        }
 
@@ -181,10 +180,10 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self)
        /* These callbacks we must handle ourselves */
        notify.data_indication       = ircomm_tty_data_indication;
        notify.udata_indication      = ircomm_tty_control_indication;
-       notify.disconnect_indication = ircomm_tty_disconnect_indication;
        notify.flow_indication       = ircomm_tty_flow_indication;
 
        /* Use the ircomm_tty interface for these ones */
+       notify.disconnect_indication = ircomm_tty_disconnect_indication;
        notify.connect_confirm       = ircomm_tty_connect_confirm;
        notify.connect_indication    = ircomm_tty_connect_indication;
        strncpy(notify.name, "ircomm_tty", NOTIFY_MAX_NAME);
@@ -201,7 +200,7 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self)
        /* Connect IrCOMM link with remote device */
        ret = ircomm_tty_attach_cable(self);
        if (ret < 0) {
-               DEBUG(0, __FUNCTION__ "(), error attaching cable!\n");
+               ERROR(__FUNCTION__ "(), error attaching cable!\n");
                return ret;
        }
 
@@ -227,7 +226,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
        
        tty = self->tty;
 
-       DEBUG(1, __FUNCTION__ "()\n");
+       DEBUG(2, __FUNCTION__ "()\n");
 
        if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
                /* this is a callout device */
@@ -283,7 +282,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
        retval = 0;
        add_wait_queue(&self->open_wait, &wait);
        
-       DEBUG(1, "%s(%d):block_til_ready before block on %s open_count=%d\n",
+       DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n",
              __FILE__,__LINE__, tty->driver.name, self->open_count );
 
        save_flags(flags); cli();
@@ -391,16 +390,25 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
                self->tqueue.routine = ircomm_tty_do_softint;
                self->tqueue.data = self;
                self->max_header_size = 5;
-               self->max_data_size = 2048-self->max_header_size;
+               self->max_data_size = 64-self->max_header_size;
+               self->close_delay = 5*HZ/10;
+               self->closing_wait = 30*HZ;
 
                /* Init some important stuff */
                init_timer(&self->watchdog_timer);
                init_waitqueue_head(&self->open_wait);
-               skb_queue_head_init(&self->tx_queue);
+               init_waitqueue_head(&self->close_wait);
+
+               /* 
+                * Force TTY into raw mode by default which is usually what
+                * we want for IrCOMM and IrLPT. This way applications will
+                * not have to twiddle with printcap etc.  
+                */
+               tty->termios->c_iflag = 0;
+               tty->termios->c_oflag = 0;
 
                /* Insert into hash */
                hashbin_insert(ircomm_tty, (QUEUE *) self, line, NULL);
-
        }
        self->open_count++;
 
@@ -413,12 +421,28 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
        /* Not really used by us, but lets do it anyway */
        self->tty->low_latency = (self->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
 
+       /*
+        * If the port is the middle of closing, bail out now
+        */
+       if (tty_hung_up_p(filp) ||
+           (self->flags & ASYNC_CLOSING)) {
+               if (self->flags & ASYNC_CLOSING)
+                       interruptible_sleep_on(&self->close_wait);
+               /* MOD_DEC_USE_COUNT; "info->tty" will cause this? */
+#ifdef SERIAL_DO_RESTART
+               return ((self->flags & ASYNC_HUP_NOTIFY) ?
+                       -EAGAIN : -ERESTARTSYS);
+#else
+               return -EAGAIN;
+#endif
+       }
+
        /* Check if this is a "normal" ircomm device, or an irlpt device */
        if (line < 0x10) {
                self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE;
-               DEBUG(0, __FUNCTION__ "(), IrCOMM device\n");
+               DEBUG(2, __FUNCTION__ "(), IrCOMM device\n");
        } else {
-               DEBUG(0, __FUNCTION__ "(), IrLPT device\n");
+               DEBUG(2, __FUNCTION__ "(), IrLPT device\n");
                self->service_type = IRCOMM_3_WIRE_RAW;
        }
 
@@ -452,7 +476,6 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
 static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
-       struct sk_buff *skb;
        unsigned long flags;
 
        DEBUG(2, __FUNCTION__ "()\n");
@@ -484,7 +507,7 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
                MOD_DEC_USE_COUNT;
                restore_flags(flags);
 
-               DEBUG(2, __FUNCTION__ "(), returning 2\n");
+               DEBUG(2, __FUNCTION__ "(), open count > 0\n");
                return;
        }
        self->flags |= ASYNC_CLOSING;
@@ -494,6 +517,10 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
         * the line discipline to only process XON/XOFF characters.
         */
        tty->closing = 1;
+       if (self->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+               tty_wait_until_sent(tty, self->closing_wait);
+
+       self->flags &= ~ASYNC_INITIALIZED;
 
        if (tty->driver.flush_buffer)
                tty->driver.flush_buffer(tty);
@@ -503,35 +530,47 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
        tty->closing = 0;
        self->tty = 0;
 
-       wake_up_interruptible(&self->open_wait);
-       
+       if (self->blocked_open) {
+               if (self->close_delay) {
+                       current->state = TASK_INTERRUPTIBLE;
+                       schedule_timeout(self->close_delay);
+               }
+               wake_up_interruptible(&self->open_wait);
+       }
+
        self->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
                         ASYNC_CLOSING);
+       wake_up_interruptible(&self->close_wait);
 
        MOD_DEC_USE_COUNT;
-       restore_flags(flags);
 
        del_timer(&self->watchdog_timer);
        
-       /* Free frames queued for transmission */
-       while ((skb = skb_dequeue(&self->tx_queue)) != NULL)
-               dev_kfree_skb(skb);
-
        /* Free parameter buffer */
        if (self->ctrl_skb) {
                dev_kfree_skb(self->ctrl_skb);
                self->ctrl_skb = NULL;
        }
 
+       /* Free transmit buffer */
+       if (self->tx_skb) {
+               dev_kfree_skb(self->tx_skb);
+               self->tx_skb = NULL;
+       }
+
+       restore_flags(flags);
+
        ircomm_tty_detach_cable(self);
        ircomm_close(self->ircomm);
-
        self->ircomm = NULL;
+
+#if IRCOMM_TTY_CLOSE_WILL_DEALLOC
        self->magic = 0;
 
        hashbin_remove(ircomm_tty, self->line, NULL);
 
        kfree(self);
+#endif
 }
 
 /*
@@ -544,18 +583,15 @@ static void ircomm_tty_flush_buffer(struct tty_struct *tty)
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 
-       DEBUG(2, __FUNCTION__ "()\n");
-
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
-       /* Flush transmit buffer if any */
-       if ((self->tx_skb) && (!tty->hw_stopped)) {
-               DEBUG(0, __FUNCTION__ "(), flushing!\n");
-               ircomm_tty_do_event(self, IRCOMM_TTY_DATA_REQUEST, 
-                                   self->tx_skb, NULL);
-               self->tx_skb = NULL;
-       }
+       /* 
+        * Let do_softint() do this to avoid race condition with 
+        * do_softint() ;-) 
+        */
+       queue_task(&self->tqueue, &tq_immediate);
+       mark_bh(IMMEDIATE_BH);
 }
 
 /*
@@ -569,28 +605,31 @@ static void ircomm_tty_do_softint(void *private_)
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) private_;
        struct tty_struct *tty;
+       unsigned long flags;
+       struct sk_buff *skb;
 
-       DEBUG(2, __FUNCTION__ "()\n");
-       
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+       if (!self || self->magic != IRCOMM_TTY_MAGIC)
+               return;
 
        tty = self->tty;
        if (!tty)
                return;
 
-       if (tty->hw_stopped) {
-               DEBUG(2, __FUNCTION__ "(), hw stopped!\n");
+       if (tty->hw_stopped)
                return;
-       }
+
+       /* Unlink transmit buffer */
+       save_flags(flags);
+       cli();
+       
+       skb = self->tx_skb;
+       self->tx_skb = NULL;
+
+       restore_flags(flags);
 
        /* Flush transmit buffer if any */
-       if (self->tx_skb) {
-               DEBUG(1, __FUNCTION__ "(), flushing!\n");
-               ircomm_tty_do_event(self, IRCOMM_TTY_DATA_REQUEST, 
-                                   self->tx_skb, NULL);
-               self->tx_skb = NULL;
-       }
+       if (skb)
+               ircomm_tty_do_event(self, IRCOMM_TTY_DATA_REQUEST, skb, NULL);
                
        /* Check if user (still) wants to be waken up */
        if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && 
@@ -625,9 +664,9 @@ static int ircomm_tty_write(struct tty_struct *tty, int from_user,
        ASSERT(self != NULL, return -1;);
        ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
-/*     save_flags(flags);
+       save_flags(flags);
        cli();
-*/
+
        /* Fetch current transmit buffer */
        skb = self->tx_skb;
 
@@ -637,20 +676,19 @@ static int ircomm_tty_write(struct tty_struct *tty, int from_user,
         * max data size. The normal case however is just the opposite, and
         * this function may be called multiple times, and will then actually
         * defragment the data and send it out as one packet as soon as 
-        * possible, but at a safer point in time 
+        * possible, but at a safer point in time
         */
-       while (count && !tty->hw_stopped) {
+       while (count) {
                size = count;
 
                /* Adjust data size to the max data size */
-               if (size > self->max_data_size) {
-                       DEBUG(1, __FUNCTION__ 
-                             "(), size %d to big, clipping to %d!\n",
-                             size, self->max_data_size);
+               if (size > self->max_data_size)
                        size = self->max_data_size;
-               }
                
-               /* Do we already have a buffer ready for transmit? */
+               /* 
+                * Do we already have a buffer ready for transmit, or do
+                * we need to allocate a new frame 
+                */
                if (skb) {                      
                        /* 
                         * Any room for more data at the end of the current 
@@ -663,25 +701,18 @@ static int ircomm_tty_write(struct tty_struct *tty, int from_user,
                                if (size > tailroom)
                                        size = tailroom;
                        } else {
-                               /* Current transmit frame is full */
-                               DEBUG(1, __FUNCTION__ "(), flushing!\n");
-                               ircomm_tty_do_event(self, 
-                                                   IRCOMM_TTY_DATA_REQUEST, 
-                                                   skb, NULL);
-                               skb = self->tx_skb = NULL;
+                               /* 
+                                * Current transmit frame is full, so break 
+                                * out, so we can send it as soon as possible
+                                */
+                               break;
                        }
-               }
-
-               /* Check if we need to allocate a new frame */
-               if (!skb) {
-                       DEBUG(3, __FUNCTION__ 
-                             "(), allocating new buffer of size %d!\n",
-                             self->max_data_size+self->max_header_size);
+               } else {
                        /* Prepare a full sized frame */
                        skb = dev_alloc_skb(self->max_data_size+
                                            self->max_header_size);
                        if (!skb) {
-                               /*restore_flags(flags);*/
+                               restore_flags(flags);
                                return -ENOBUFS;
                        }
                        skb_reserve(skb, self->max_header_size);
@@ -694,12 +725,12 @@ static int ircomm_tty_write(struct tty_struct *tty, int from_user,
                else
                        memcpy(skb_put(skb,size), buf+len, size);
                
-               DEBUG(1, __FUNCTION__ "(), size=%d\n", size);
-
                count -= size;
                len += size;
        }
 
+       restore_flags(flags);
+
        /*     
         * Schedule a new thread which will transmit the frame as soon
         * as possible, but at a safe point in time. We do this so the
@@ -710,8 +741,6 @@ static int ircomm_tty_write(struct tty_struct *tty, int from_user,
        queue_task(&self->tqueue, &tq_immediate);
        mark_bh(IMMEDIATE_BH);
        
-       /*restore_flags(flags);*/
-
        return len;
 }
 
@@ -725,6 +754,7 @@ static int ircomm_tty_write(struct tty_struct *tty, int from_user,
 static int ircomm_tty_write_room(struct tty_struct *tty)
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
+       unsigned long flags;
        int ret;
 
        ASSERT(self != NULL, return -1;);
@@ -734,10 +764,13 @@ static int ircomm_tty_write_room(struct tty_struct *tty)
        if (tty->hw_stopped)
                ret = 0;
        else {
+               save_flags(flags);
+               cli();
                if (self->tx_skb)
                        ret = self->max_data_size - self->tx_skb->len;
                else
                        ret = self->max_data_size;
+               restore_flags(flags);
        }
        DEBUG(2, __FUNCTION__ "(), ret=%d\n", ret);
 
@@ -753,8 +786,27 @@ static int ircomm_tty_write_room(struct tty_struct *tty)
 static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
+       unsigned long orig_jiffies, poll_time;
+       
+       DEBUG(0, __FUNCTION__ "()\n");
+
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
-       DEBUG(2, __FUNCTION__ "(), not impl\n");
+       orig_jiffies = jiffies;
+
+       /* Set poll time to 200 ms */
+       poll_time = MIN(timeout, MSECS_TO_JIFFIES(200));
+
+       while (self->tx_skb && self->tx_skb->len) {
+               current->state = TASK_INTERRUPTIBLE;
+               schedule_timeout(poll_time);
+               if (signal_pending(current))
+                       break;
+               if (timeout && time_after(jiffies, orig_jiffies + timeout))
+                       break;
+       }
+       current->state = TASK_RUNNING;
 }
 
 /*
@@ -785,7 +837,6 @@ static void ircomm_tty_throttle(struct tty_struct *tty)
                ircomm_param_request(self, IRCOMM_DTE, TRUE);
        }
 
-       DEBUG(1, __FUNCTION__"(), FLOW_STOP\n");
         ircomm_flow_request(self->ircomm, FLOW_STOP);
 }
 
@@ -829,10 +880,21 @@ static void ircomm_tty_unthrottle(struct tty_struct *tty)
 static int ircomm_tty_chars_in_buffer(struct tty_struct *tty)
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
+       unsigned long flags;
+       int len = 0;
 
-       DEBUG(4, __FUNCTION__ "()\n");
+       ASSERT(self != NULL, return -1;);
+       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
-       return 0; /* We don't have any "buffer" */
+       save_flags(flags);
+       cli();
+
+       if (self->tx_skb)
+               len = self->tx_skb->len;
+
+       restore_flags(flags);
+
+       return len;
 }
 
 /*
@@ -846,7 +908,10 @@ static void ircomm_tty_hangup(struct tty_struct *tty)
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 
-       DEBUG(0, __FUNCTION__"()\n");
+       DEBUG(2, __FUNCTION__"()\n");
+
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
        if (!tty)
                return;
@@ -889,8 +954,6 @@ void ircomm_tty_start(struct tty_struct *tty)
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 
-       DEBUG(2, __FUNCTION__"()\n");
-
        ircomm_flow_request(self->ircomm, FLOW_START);
 }
 
@@ -904,24 +967,12 @@ void ircomm_tty_stop(struct tty_struct *tty)
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 
-       DEBUG(2, __FUNCTION__"()\n");
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
        ircomm_flow_request(self->ircomm, FLOW_STOP);
 }
 
-/*
- * Function ircomm_tty_break (tty, break_state)
- *
- *    
- *
- */
-static void ircomm_tty_break(struct tty_struct *tty, int break_state)
-{
-       struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
-
-       DEBUG(0, __FUNCTION__"(), not impl\n");
-}
-
 /*
  * Function ircomm_check_modem_status (self)
  *
@@ -934,8 +985,6 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
        struct tty_struct *tty;
        int status;
 
-       DEBUG(4, __FUNCTION__ "()\n");
-       
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
@@ -967,13 +1016,9 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
                                DEBUG(2, __FUNCTION__ "(), CTS tx start...\n");
                                
                                tty->hw_stopped = 0;
-                               
-                               if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) 
-                                   && tty->ldisc.write_wakeup)
-                               {
-                                       (tty->ldisc.write_wakeup)(tty);
-                               }
-                               wake_up_interruptible(&tty->write_wait);
+
+                               queue_task(&self->tqueue, &tq_immediate);
+                               mark_bh(IMMEDIATE_BH);
                                return;
                        }
                } else {
@@ -1044,35 +1089,6 @@ static int ircomm_tty_control_indication(void *instance, void *sap,
        return 0;
 }
 
-/*
- * Function ircomm_tty_disconnect_indication (instance, sap, reason, skb)
- *
- *    Link disconnected
- *
- */
-static void ircomm_tty_disconnect_indication(void *instance, void *sap, 
-                                            LM_REASON reason,
-                                            struct sk_buff *skb)
-{
-       struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
-
-       DEBUG(2, __FUNCTION__ "()\n");
-
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
-
-       if (!self->tty)
-               return;
-
-       /* Drop carrier */
-       self->session.dce = IRCOMM_DELTA_CD;
-       ircomm_tty_check_modem_status(self);
-#if 0
-       /* Disconnect */
-       tty_hangup(self->tty);
-#endif
-}
-
 /*
  * Function ircomm_tty_flow_indication (instance, sap, cmd)
  *
@@ -1093,18 +1109,17 @@ static void ircomm_tty_flow_indication(void *instance, void *sap,
 
        switch (cmd) {
        case FLOW_START:
-               DEBUG(1, __FUNCTION__ "(), hw start!\n");
+               DEBUG(2, __FUNCTION__ "(), hw start!\n");
                tty->hw_stopped = 0;
-               
-               if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) 
-                   && tty->ldisc.write_wakeup)
-                       (tty->ldisc.write_wakeup)(tty);
-               wake_up_interruptible(&tty->write_wait);
+
+               /* ircomm_tty_do_softint will take care of the rest */
+               queue_task(&self->tqueue, &tq_immediate);
+               mark_bh(IMMEDIATE_BH);          
                break;
        default:
                /* If we get here, something is very wrong, better stop */
        case FLOW_STOP:
-               DEBUG(1, __FUNCTION__ "(), hw stopped!\n");
+               DEBUG(2, __FUNCTION__ "(), hw stopped!\n");
                tty->hw_stopped = 1;
                break;
        }
@@ -1114,6 +1129,8 @@ static int ircomm_tty_line_info(struct ircomm_tty_cb *self, char *buf)
 {
         int  ret=0;
 
+       ret += sprintf(buf+ret, "State: %s\n", ircomm_tty_state[self->state]);
+
        ret += sprintf(buf+ret, "Service type: ");
        if (self->service_type & IRCOMM_9_WIRE)
                ret += sprintf(buf+ret, "9_WIRE");
@@ -1125,12 +1142,15 @@ static int ircomm_tty_line_info(struct ircomm_tty_cb *self, char *buf)
                ret += sprintf(buf+ret, "No common service type!\n");
         ret += sprintf(buf+ret, "\n");
 
+       ret += sprintf(buf+ret, "Port name: %s\n", self->session.port_name);
+
        ret += sprintf(buf+ret, "DTE status: ");        
         if (self->session.dte & IRCOMM_RTS)
                 ret += sprintf(buf+ret, "RTS|");
         if (self->session.dte & IRCOMM_DTR)
                 ret += sprintf(buf+ret, "DTR|");
-       ret--; /* remove the last | */
+       if (self->session.dte)
+               ret--; /* remove the last | */
         ret += sprintf(buf+ret, "\n");
 
        ret += sprintf(buf+ret, "DCE status: ");
@@ -1142,7 +1162,8 @@ static int ircomm_tty_line_info(struct ircomm_tty_cb *self, char *buf)
                 ret += sprintf(buf+ret, "CD|");
         if (self->session.dce & IRCOMM_RI) 
                 ret += sprintf(buf+ret, "RI|");
-       ret--; /* remove the last | */
+       if (self->session.dce)
+               ret--; /* remove the last | */
         ret += sprintf(buf+ret, "\n");
 
        ret += sprintf(buf+ret, "Configuration: ");
@@ -1171,7 +1192,8 @@ static int ircomm_tty_line_info(struct ircomm_tty_cb *self, char *buf)
                ret += sprintf(buf+ret, "ENQ_ACK_IN|");
        if (self->session.flow_control & IRCOMM_ENQ_ACK_OUT)
                ret += sprintf(buf+ret, "ENQ_ACK_OUT|");
-       ret--; /* remove the last | */
+       if (self->session.flow_control)
+               ret--; /* remove the last | */
         ret += sprintf(buf+ret, "\n");
 
        ret += sprintf(buf+ret, "Flags: ");
@@ -1189,7 +1211,8 @@ static int ircomm_tty_line_info(struct ircomm_tty_cb *self, char *buf)
                ret += sprintf(buf+ret, "ASYNC_NORMAL_ACTIVE|");
        if (self->flags & ASYNC_CALLOUT_ACTIVE)
                ret += sprintf(buf+ret, "ASYNC_CALLOUT_ACTIVE|");
-       ret--; /* remove the last | */
+       if (self->flags)
+               ret--; /* remove the last | */
        ret += sprintf(buf+ret, "\n");
 
        ret += sprintf(buf+ret, "Open count: %d\n", self->open_count);
@@ -1197,7 +1220,6 @@ static int ircomm_tty_line_info(struct ircomm_tty_cb *self, char *buf)
                ret += sprintf(buf+ret, "Hardware: %s\n", 
                               self->tty->hw_stopped ? "Stopped" : "Running");
 
- exit:
         ret += sprintf(buf+ret, "\n");
         return ret;
 }
@@ -1213,7 +1235,7 @@ static int ircomm_tty_read_proc(char *buf, char **start, off_t offset, int len,
                                int *eof, void *unused)
 {
        struct ircomm_tty_cb *self;
-        int i, count = 0, l;
+        int count = 0, l;
         off_t begin = 0;
 
        self = (struct ircomm_tty_cb *) hashbin_get_first(ircomm_tty);
index e9618d848b650f6fd160beb18a2876163f24b5e9..f2466d68c7f214c65835c9b25ce0c87836d034f5 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sat Jun  5 17:42:00 1999
- * Modified at:   Wed Aug 25 13:32:00 1999
+ * Modified at:   Wed Sep  8 11:54:27 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -96,6 +96,8 @@ char *ircomm_tty_event[] = {
        "IRCOMM_TTY_DISCOVERY_INDICATION",
        "IRCOMM_TTY_CONNECT_CONFIRM",
        "IRCOMM_TTY_CONNECT_INDICATION",
+       "IRCOMM_TTY_DISCONNECT_REQUEST",
+       "IRCOMM_TTY_DISCONNECT_INDICATION",
        "IRCOMM_TTY_WD_TIMER_EXPIRED",
        "IRCOMM_TTY_GOT_PARAMETERS",
        "IRCOMM_TTY_GOT_LSAPSEL",
@@ -167,8 +169,10 @@ void ircomm_tty_detach_cable(struct ircomm_tty_cb *self)
        irlmp_unregister_service(self->skey);
 
        /* Remove LM-IAS object */
-       if (self->obj)
+       if (self->obj) {
                irias_delete_object(self->obj);
+               self->obj = NULL;
+       }
 
        ircomm_tty_do_event(self, IRCOMM_TTY_DETACH_CABLE, NULL, NULL);
 
@@ -204,7 +208,8 @@ static void ircomm_tty_ias_register(struct ircomm_tty_cb *self)
                irias_insert_object(self->obj);
        } else {
                hints = irlmp_service_to_hint(S_COMM);
-               
+               hints |= irlmp_service_to_hint(S_TELEPHONY);
+
                /* Register IrCOMM with LM-IAS */
                self->obj = irias_new_object("IrDA:IrCOMM", IAS_IRCOMM_ID);
                irias_add_integer_attrib(self->obj, "IrDA:TinyTP:LsapSel", 
@@ -257,8 +262,8 @@ static int ircomm_tty_send_initial_parameters(struct ircomm_tty_cb *self)
        }
 
        /* Only 9-wire service types continue here */
-#if 0
        ircomm_param_request(self, IRCOMM_FLOW_CONTROL, FALSE);
+#if 0
        ircomm_param_request(self, IRCOMM_XON_XOFF, FALSE);
        ircomm_param_request(self, IRCOMM_ENQ_ACK, FALSE);
 #endif 
@@ -296,6 +301,30 @@ static void ircomm_tty_discovery_indication(discovery_t *discovery)
        }
 }
 
+/*
+ * Function ircomm_tty_disconnect_indication (instance, sap, reason, skb)
+ *
+ *    Link disconnected
+ *
+ */
+void ircomm_tty_disconnect_indication(void *instance, void *sap, 
+                                     LM_REASON reason,
+                                     struct sk_buff *skb)
+{
+       struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
+
+       DEBUG(2, __FUNCTION__ "()\n");
+
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+
+       if (!self->tty)
+               return;
+
+       ircomm_tty_do_event(self, IRCOMM_TTY_DISCONNECT_INDICATION, NULL, 
+                           NULL);
+}
+
 /*
  * Function ircomm_tty_getvalue_confirm (result, obj_id, value, priv)
  *
@@ -315,7 +344,7 @@ static void ircomm_tty_getvalue_confirm(int result, __u16 obj_id,
 
        /* Check if request succeeded */
        if (result != IAS_SUCCESS) {
-               DEBUG(0, __FUNCTION__ "(), got NULL value!\n");
+               DEBUG(4, __FUNCTION__ "(), got NULL value!\n");
                return;
        }
 
@@ -421,29 +450,35 @@ void ircomm_tty_link_established(struct ircomm_tty_cb *self)
 
        /*  
         * IrCOMM link is now up, and if we are not using hardware
-        * flow-control, then declare the hardware as running 
+        * flow-control, then declare the hardware as running. Otherwise
+        * the client will have to wait for the CD to be set.
         */
        if (!(self->flags & ASYNC_CTS_FLOW)) {
                DEBUG(2, __FUNCTION__ "(), starting hardware!\n");
                if (!self->tty)
                        return;
                self->tty->hw_stopped = 0;
-
-               /* Kick client */
-               ircomm_tty_do_softint(self);
        }
+       /* Wake up processes blocked on open */
+       wake_up_interruptible(&self->open_wait);
+
+       /* 
+        * Wake up processes blocked on write, or waiting for a write 
+        * wakeup notification
+        */
+       queue_task(&self->tqueue, &tq_immediate);
+       mark_bh(IMMEDIATE_BH);
 }
 
 /*
  * Function irlan_start_watchdog_timer (self, timeout)
  *
- *    
- *
+ *    Start the watchdog timer. This timer is used to make sure that any 
+ *    connection attempt is successful, and if not, we will retry after 
+ *    the timeout
  */
 void ircomm_tty_start_watchdog_timer(struct ircomm_tty_cb *self, int timeout)
 {
-       DEBUG(4, __FUNCTION__ "()\n");
-       
        irda_start_timer(&self->watchdog_timer, timeout, (void *) self,
                         ircomm_tty_watchdog_timer_expired);
 }
@@ -458,7 +493,7 @@ void ircomm_tty_watchdog_timer_expired(void *data)
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) data;
        
-       DEBUG(1, __FUNCTION__ "()\n");
+       DEBUG(4, __FUNCTION__ "()\n");
 
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -479,7 +514,7 @@ static int ircomm_tty_state_idle(struct ircomm_tty_cb *self,
 {
        int ret = 0;
 
-       DEBUG(1, __FUNCTION__": state=%s, event=%s\n",
+       DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
              ircomm_tty_state[self->state], ircomm_tty_event[event]);
 
        switch (event) {
@@ -507,9 +542,11 @@ static int ircomm_tty_state_idle(struct ircomm_tty_cb *self,
 
                /* Accept connection */
                ircomm_connect_response(self->ircomm, NULL);
-               
-               ircomm_tty_link_established(self);
                ircomm_tty_next_state(self, IRCOMM_TTY_READY);
+
+               /* Init connection */
+               ircomm_tty_send_initial_parameters(self);
+               ircomm_tty_link_established(self);
                break;
        case IRCOMM_TTY_WD_TIMER_EXPIRED:
                /* Just stay idle */
@@ -518,7 +555,7 @@ static int ircomm_tty_state_idle(struct ircomm_tty_cb *self,
                ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
                break;
        default:
-               DEBUG(0, __FUNCTION__"(), unknown event: %s\n",
+               DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
                      ircomm_tty_event[event]);
                return -EINVAL;
        }
@@ -538,7 +575,7 @@ static int ircomm_tty_state_search(struct ircomm_tty_cb *self,
 {
        int ret = 0;
 
-       DEBUG(1, __FUNCTION__": state=%s, event=%s\n",
+       DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
              ircomm_tty_state[self->state], ircomm_tty_event[event]);
 
        switch (event) {
@@ -568,8 +605,11 @@ static int ircomm_tty_state_search(struct ircomm_tty_cb *self,
 
                /* Accept connection */
                ircomm_connect_response(self->ircomm, NULL);
-               ircomm_tty_link_established(self);
                ircomm_tty_next_state(self, IRCOMM_TTY_READY);
+
+               /* Init connection */
+               ircomm_tty_send_initial_parameters(self);
+               ircomm_tty_link_established(self);
                break;
        case IRCOMM_TTY_WD_TIMER_EXPIRED:
                /* Try to discover any remote devices */                
@@ -580,7 +620,7 @@ static int ircomm_tty_state_search(struct ircomm_tty_cb *self,
                ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
                break;
        default:
-               DEBUG(0, __FUNCTION__"(), unknown event: %s\n",
+               DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
                      ircomm_tty_event[event]);
                return -EINVAL;
        }
@@ -600,7 +640,7 @@ static int ircomm_tty_state_query_parameters(struct ircomm_tty_cb *self,
 {
        int ret = 0;
 
-       DEBUG(1, __FUNCTION__": state=%s, event=%s\n",
+       DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
              ircomm_tty_state[self->state], ircomm_tty_event[event]);
 
        switch (event) {
@@ -624,14 +664,17 @@ static int ircomm_tty_state_query_parameters(struct ircomm_tty_cb *self,
 
                /* Accept connection */
                ircomm_connect_response(self->ircomm, NULL);
-               ircomm_tty_link_established(self);
                ircomm_tty_next_state(self, IRCOMM_TTY_READY);
+
+               /* Init connection */
+               ircomm_tty_send_initial_parameters(self);
+               ircomm_tty_link_established(self);
                break;
        case IRCOMM_TTY_DETACH_CABLE:
                ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
                break;
        default:
-               DEBUG(0, __FUNCTION__"(), unknown event: %s\n",
+               DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
                      ircomm_tty_event[event]);
                return -EINVAL;
        }
@@ -651,7 +694,7 @@ static int ircomm_tty_state_query_lsap_sel(struct ircomm_tty_cb *self,
 {
        int ret = 0;
 
-       DEBUG(1, __FUNCTION__": state=%s, event=%s\n",
+       DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
              ircomm_tty_state[self->state], ircomm_tty_event[event]);
 
        switch (event) {
@@ -673,14 +716,17 @@ static int ircomm_tty_state_query_lsap_sel(struct ircomm_tty_cb *self,
 
                /* Accept connection */
                ircomm_connect_response(self->ircomm, NULL);
-               ircomm_tty_link_established(self);
                ircomm_tty_next_state(self, IRCOMM_TTY_READY);
+
+               /* Init connection */
+               ircomm_tty_send_initial_parameters(self);
+               ircomm_tty_link_established(self);
                break;
        case IRCOMM_TTY_DETACH_CABLE:
                ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
                break;
        default:
-               DEBUG(0, __FUNCTION__"(), unknown event: %s\n",
+               DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
                      ircomm_tty_event[event]);
                return -EINVAL;
        }
@@ -700,38 +746,20 @@ static int ircomm_tty_state_setup(struct ircomm_tty_cb *self,
 {
        int ret = 0;
 
-       DEBUG(1, __FUNCTION__": state=%s, event=%s\n",
+       DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
              ircomm_tty_state[self->state], ircomm_tty_event[event]);
 
        switch (event) {
        case IRCOMM_TTY_CONNECT_CONFIRM:
-               ircomm_tty_link_established(self);
+               del_timer(&self->watchdog_timer);
                ircomm_tty_next_state(self, IRCOMM_TTY_READY);
-
+               
                /* 
                 * Send initial parameters. This will also send out queued
                 * parameters waiting for the connection to come up 
                 */
                ircomm_tty_send_initial_parameters(self);
-
-               ASSERT(self->tty != NULL, return -1;);
-
-               /* Send queued frames */
-               while ((skb = skb_dequeue(&self->tx_queue))) {
-                       ret = ircomm_data_request(self->ircomm, skb);
-                       if (ret < 0)
-                               break;
-               }
-               
-               /* Wake up processes blocked on open */
-               wake_up_interruptible(&self->open_wait);
-
-               /* 
-                * Wake up processes blocked on write, or waiting for a write 
-                * wakeup notification
-                */
-               queue_task(&self->tqueue, &tq_immediate);
-               mark_bh(IMMEDIATE_BH);
+               ircomm_tty_link_established(self);
                break;
        case IRCOMM_TTY_CONNECT_INDICATION:
                del_timer(&self->watchdog_timer);
@@ -739,6 +767,10 @@ static int ircomm_tty_state_setup(struct ircomm_tty_cb *self,
                /* Accept connection */
                ircomm_connect_response(self->ircomm, NULL);
                ircomm_tty_next_state(self, IRCOMM_TTY_READY);
+
+               /* Init connection */
+               ircomm_tty_send_initial_parameters(self);
+               ircomm_tty_link_established(self);
                break;
        case IRCOMM_TTY_WD_TIMER_EXPIRED:
                /* Go back to search mode */
@@ -750,7 +782,7 @@ static int ircomm_tty_state_setup(struct ircomm_tty_cb *self,
                ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
                break;
        default:
-               DEBUG(0, __FUNCTION__"(), unknown event: %s\n",
+               DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
                      ircomm_tty_event[event]);
                return -EINVAL;
        }
@@ -774,14 +806,20 @@ static int ircomm_tty_state_ready(struct ircomm_tty_cb *self,
        case IRCOMM_TTY_DATA_REQUEST:
                ret = ircomm_data_request(self->ircomm, skb);
                break;          
-       case IRCOMM_TTY_DATA_INDICATION:
-               break;
        case IRCOMM_TTY_DETACH_CABLE:
                ircomm_disconnect_request(self->ircomm, NULL);
                ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
                break;
+       case IRCOMM_TTY_DISCONNECT_INDICATION:
+               ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);
+               ircomm_tty_start_watchdog_timer(self, 3*HZ);
+
+               /* Drop carrier */
+               self->session.dce = IRCOMM_DELTA_CD;
+               ircomm_tty_check_modem_status(self);
+               break;
        default:
-               DEBUG(0, __FUNCTION__"(), unknown event: %s\n",
+               DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
                      ircomm_tty_event[event]);
                return -EINVAL;
        }
@@ -813,7 +851,7 @@ void ircomm_tty_next_state(struct ircomm_tty_cb *self, IRCOMM_TTY_STATE state)
 {
        self->state = state;
        
-       DEBUG(1, __FUNCTION__": next state=%s, service type=%d\n", 
+       DEBUG(2, __FUNCTION__": next state=%s, service type=%d\n", 
              ircomm_tty_state[self->state], self->service_type);
 }
 
index e5981ecb239e6cc1f3c058555f67ec0234e109a8..fdbe2b1f24fe55104c63c9ab05df8c4d9d41b48d 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Thu Jun 10 14:39:09 1999
- * Modified at:   Wed Aug 25 14:11:02 1999
+ * Modified at:   Tue Aug 31 10:29:36 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -196,12 +196,12 @@ static int ircomm_tty_get_modem_info(struct ircomm_tty_cb *self,
 
        DEBUG(1, __FUNCTION__ "()\n");
 
-       result =  ((self->session.dte & IRCOMM_RTS)       ? TIOCM_RTS : 0)
-               | ((self->session.dte & IRCOMM_DTR)       ? TIOCM_DTR : 0)
-               | ((self->session.dce & IRCOMM_DELTA_CD)  ? TIOCM_CAR : 0)
-               | ((self->session.dce & IRCOMM_DELTA_RI)  ? TIOCM_RNG : 0)
-               | ((self->session.dce & IRCOMM_DELTA_DSR) ? TIOCM_DSR : 0)
-               | ((self->session.dce & IRCOMM_DELTA_CTS) ? TIOCM_CTS : 0);
+       result =  ((self->session.dte & IRCOMM_RTS) ? TIOCM_RTS : 0)
+               | ((self->session.dte & IRCOMM_DTR) ? TIOCM_DTR : 0)
+               | ((self->session.dce & IRCOMM_CD)  ? TIOCM_CAR : 0)
+               | ((self->session.dce & IRCOMM_RI)  ? TIOCM_RNG : 0)
+               | ((self->session.dce & IRCOMM_DSR) ? TIOCM_DSR : 0)
+               | ((self->session.dce & IRCOMM_CTS) ? TIOCM_CTS : 0);
 
        return put_user(result, value);
 }
@@ -286,21 +286,19 @@ static int ircomm_tty_get_serial_info(struct ircomm_tty_cb *self,
 
        memset(&info, 0, sizeof(info));
        info.line = self->line;
-       /* info.flags = self->flags; */
+       info.flags = self->flags;
        info.baud_base = self->session.data_rate;
-#if 0
-       info.close_delay = driver->close_delay;
-       info.closing_wait = driver->closing_wait;
-#endif
+       info.close_delay = self->close_delay;
+       info.closing_wait = self->closing_wait;
+
        /* For compatibility  */
        info.type = PORT_16550A;
        info.port = 0;
        info.irq = 0;
        info.xmit_fifo_size = 0;
        info.hub6 = 0;   
-#if 0
-       info.custom_divisor = driver->custom_divisor;
-#endif
+       info.custom_divisor = 0;
+
        if (copy_to_user(retinfo, &info, sizeof(*retinfo)))
                return -EFAULT;
 
index 1f4571a5d4ba6c342adeab1f11b8bbea8adc9c4e..6937d62f31e8c1e927d28d7128c922a76027935f 100644 (file)
@@ -1,12 +1,12 @@
 /*********************************************************************
  *                
  * Filename:      irda_device.c
- * Version:       0.5
+ * Version:       0.6
  * Description:   Abstract device driver layer and helper functions
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Wed Sep  2 20:22:08 1998
- * Modified at:   Tue Aug 24 14:31:13 1999
+ * Modified at:   Tue Sep 28 08:40:31 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Modified at:   Fri May 28  3:11 CST 1999
  * Modified by:   Horst von Brand <vonbrand@sleipnir.valparaiso.cl>
@@ -155,16 +155,16 @@ int irda_device_open(struct irda_device *self, char *name, void *priv)
 
        /* Allocate memory if needed */
        if (self->rx_buff.truesize > 0) {
-               self->rx_buff.head = ( __u8 *) kmalloc(self->rx_buff.truesize,
-                                                      self->rx_buff.flags);
+               self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
+                                                     self->rx_buff.flags);
                if (self->rx_buff.head == NULL)
                        return -ENOMEM;
 
                memset(self->rx_buff.head, 0, self->rx_buff.truesize);
        }
        if (self->tx_buff.truesize > 0) {
-               self->tx_buff.head = ( __u8 *) kmalloc(self->tx_buff.truesize, 
-                                                      self->tx_buff.flags);
+               self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
+                                                     self->tx_buff.flags);
                if (self->tx_buff.head == NULL) {
                        kfree(self->rx_buff.head);
                        return -ENOMEM;
@@ -191,14 +191,15 @@ int irda_device_open(struct irda_device *self, char *name, void *priv)
        /* Initialize IrDA net device */
        do {
                sprintf(self->name, "%s%d", "irda", i++);
-       } while (dev_get(self->name) != NULL);
+       } while (dev_get(self->name));
        
        self->netdev.name = self->name;
        self->netdev.priv = (void *) self;
        self->netdev.next = NULL;
-
-       if ((result = register_netdev(&self->netdev)) != 0) {
-               DEBUG(0, __FUNCTION__ "(), register_netdev() failed!\n");
+       
+       result = register_netdev(&self->netdev);
+       if (result) {
+               ERROR(__FUNCTION__ "(), register_netdev() failed!\n");
                return -1;
        }
        
@@ -213,12 +214,9 @@ int irda_device_open(struct irda_device *self, char *name, void *priv)
        
        hashbin_insert(irda_device, (QUEUE *) self, (int) self, NULL);
        
-       /* Open network device */
-       dev_open(&self->netdev);
-
        MESSAGE("IrDA: Registered device %s\n", self->name);
 
-       irda_device_set_media_busy(self, FALSE);
+       irda_device_set_media_busy(&self->netdev, FALSE);
 
        return 0;
 }
@@ -238,8 +236,6 @@ void __irda_device_close(struct irda_device *self)
 
        /* We do this test to know if the device has been registered at all */
        if (self->netdev.type == ARPHRD_IRDA) {
-               dev_close(&self->netdev);
-               
                /* Remove netdevice */
                unregister_netdev(&self->netdev);
        }
@@ -284,10 +280,14 @@ void irda_device_close(struct irda_device *self)
  *    Called when we have detected that another station is transmiting
  *    in contention mode.
  */
-void irda_device_set_media_busy(struct irda_device *self, int status) 
+void irda_device_set_media_busy(struct net_device *dev, int status) 
 {
+       struct irda_device *self;
+
        DEBUG(4, __FUNCTION__ "(%s)\n", status ? "TRUE" : "FALSE");
 
+       self = dev->priv;
+
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == IRDA_DEVICE_MAGIC, return;);
 
@@ -359,7 +359,7 @@ static void __irda_device_change_speed(struct irda_device *self, int speed)
  *    Change the speed of the currently used irda_device
  *
  */
-inline void irda_device_change_speed(struct irda_device *self, int speed)
+void irda_device_change_speed(struct irda_device *self, int speed)
 {
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == IRDA_DEVICE_MAGIC, return;);
@@ -369,16 +369,24 @@ inline void irda_device_change_speed(struct irda_device *self, int speed)
                                speed);
 }
 
-inline int irda_device_is_media_busy( struct irda_device *self)
+int irda_device_is_media_busy(struct net_device *dev)
 {
+       struct irda_device *self;
+       
+       self = dev->priv;
+
        ASSERT(self != NULL, return FALSE;);
        ASSERT(self->magic == IRDA_DEVICE_MAGIC, return FALSE;);
        
        return self->media_busy;
 }
 
-inline int irda_device_is_receiving( struct irda_device *self)
+int irda_device_is_receiving(struct net_device *dev)
 {
+       struct irda_device *self;
+       
+       self = dev->priv;
+       
        ASSERT(self != NULL, return FALSE;);
        ASSERT(self->magic == IRDA_DEVICE_MAGIC, return FALSE;);
 
@@ -388,15 +396,21 @@ inline int irda_device_is_receiving( struct irda_device *self)
                return FALSE;
 }
 
-inline struct qos_info *irda_device_get_qos(struct irda_device *self)
+struct qos_info *irda_device_get_qos(struct net_device *dev)
 {
+       struct irda_device *self;
+
+       ASSERT(dev != NULL, return NULL;);
+
+       self = dev->priv;
+
        ASSERT(self != NULL, return NULL;);
        ASSERT(self->magic == IRDA_DEVICE_MAGIC, return NULL;);
 
        return &self->qos;
 }
 
-static struct enet_statistics *irda_device_get_stats( struct net_device *dev)
+static struct enet_statistics *irda_device_get_stats(struct net_device *dev)
 {
        struct irda_device *priv = (struct irda_device *) dev->priv;
 
@@ -464,7 +478,7 @@ int irda_device_net_open(struct net_device *dev)
         * Open new IrLAP layer instance, now that everything should be
         * initialized properly 
         */
-       self->irlap = irlap_open(self);
+       self->irlap = irlap_open(dev);
         
        /* It's now safe to initilize the saddr */
        memcpy(self->netdev.dev_addr, &self->irlap->saddr, 4);
@@ -508,7 +522,8 @@ static int irda_device_net_rebuild_header( struct sk_buff *skb)
        return 0;
 }
 
-static int irda_device_net_hard_header(struct sk_buff *skb, struct net_device *dev,
+static int irda_device_net_hard_header(struct sk_buff *skb, 
+                                      struct net_device *dev,
                                       unsigned short type, void *daddr, 
                                       void *saddr, unsigned len)
 {
@@ -521,22 +536,21 @@ static int irda_device_net_hard_header(struct sk_buff *skb, struct net_device *d
        return 0;
 }
 
-static int irda_device_net_set_config( struct net_device *dev, struct ifmap *map)
+static int irda_device_net_set_config(struct net_device *dev, 
+                                     struct ifmap *map)
 {
        DEBUG( 0, __FUNCTION__ "()\n");
 
        return 0;
 }
 
-static int irda_device_net_change_mtu( struct net_device *dev, int new_mtu)
+static int irda_device_net_change_mtu(struct net_device *dev, int new_mtu)
 {
      DEBUG( 0, __FUNCTION__ "()\n");
      
      return 0;  
 }
 
-
-#define SIOCSDONGLE     SIOCDEVPRIVATE
 static int irda_device_net_ioctl(struct net_device *dev, /* ioctl device */
                                 struct ifreq *rq,   /* Data passed */
                                 int    cmd)         /* Ioctl number */
@@ -548,16 +562,14 @@ static int irda_device_net_ioctl(struct net_device *dev, /* ioctl device */
 #endif
        struct irda_device *self;
 
-       DEBUG(4, __FUNCTION__ "()\n");
-
        ASSERT(dev != NULL, return -1;);
 
-       self = (struct irda_device *) dev->priv;
+       self = dev->priv;
 
        ASSERT(self != NULL, return -1;);
        ASSERT(self->magic == IRDA_DEVICE_MAGIC, return -1;);
 
-       DEBUG(0, "%s: ->irda_device_net_ioctl(cmd=0x%X)\n", dev->name, cmd);
+       DEBUG(0, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);
        
        /* Disable interrupts & save flags */
        save_flags(flags);
@@ -647,10 +659,16 @@ static int irda_device_net_ioctl(struct net_device *dev, /* ioctl device */
 #endif 
                break;
 #endif
+       case SIOCSBANDWIDTH: /* Set bandwidth */
+               irda_device_change_speed(self, rq->ifr_bandwidth);
+               break;
        case SIOCSDONGLE: /* Set dongle */
                /* Initialize dongle */
                irda_device_init_dongle(self, (int) rq->ifr_data);
                break;
+       case SIOCSMEDIABUSY: /* Set media busy */
+               irda_device_set_media_busy(&self->netdev, TRUE);
+               break;
        default:
                ret = -EOPNOTSUPP;
        }
index 7951d90abc911ae3d98c090ca291a0c99f4395c3..6b6061675a543093ede51ea9d89a81d4c78daa3c 100644 (file)
@@ -1 +1 @@
-dep_tristate 'IrLAN protocol' CONFIG_IRLAN $CONFIG_IRDA
+dep_tristate '  IrLAN protocol' CONFIG_IRLAN $CONFIG_IRDA
index cccbbb412aa1eac5f5b7604b5436327ebfc1c5ec..8940343536d6cc9e100b643dcb044f0758215160 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Tue Aug 17 15:30:40 1999
+ * Modified at:   Thu Sep  9 11:39:43 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -237,7 +237,7 @@ int irlan_register_netdev(struct irlan_cb *self)
                /* Get the first free irlan<x> name */
                do {
                        sprintf(self->ifname, "%s%d", "irlan", i++);
-               } while (dev_get(self->ifname) != NULL);
+               } while (dev_get(self->ifname));
        }
        self->dev.name = self->ifname;
        
@@ -615,7 +615,7 @@ void irlan_ias_register(struct irlan_cb *self, __u8 tsap_sel)
                irias_add_string_attrib(obj, "DeviceID", "HWP19F0");
                irias_add_integer_attrib(obj, "CompCnt", 1);
                if (self->provider.access_type == ACCESS_PEER)
-                       irias_add_string_attrib(obj, "Comp#02", "PNP8389");
+                       irias_add_string_attrib(obj, "Comp#01", "PNP8389");
                else
                        irias_add_string_attrib(obj, "Comp#01", "PNP8294");
 
index 68981d87cf330c609c8ea29200d77f54bb906034..2b59a1efce1e9f0ecbf7ff493713e199e30de2f7 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Stable
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Mon Aug 23 12:05:26 1999
+ * Modified at:   Mon Sep 20 11:04:32 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
@@ -106,15 +106,12 @@ void irlap_cleanup(void)
  *    Initialize IrLAP layer
  *
  */
-struct irlap_cb *irlap_open(struct irda_device *irdev)
+struct irlap_cb *irlap_open(struct net_device *dev)
 {
        struct irlap_cb *self;
 
        DEBUG(4, __FUNCTION__ "()\n");
        
-       ASSERT(irdev != NULL, return NULL;);
-       ASSERT(irdev->magic == IRDA_DEVICE_MAGIC, return NULL;);
-
        /* Initialize the irlap structure. */
        self = kmalloc(sizeof(struct irlap_cb), GFP_KERNEL);
        if (self == NULL)
@@ -124,8 +121,7 @@ struct irlap_cb *irlap_open(struct irda_device *irdev)
        self->magic = LAP_MAGIC;
 
        /* Make a binding between the layers */
-       self->irdev = irdev;
-       self->netdev = &irdev->netdev;
+       self->netdev = dev;
 
        irlap_next_state(self, LAP_OFFLINE);
 
@@ -186,7 +182,6 @@ static void __irlap_close(struct irlap_cb *self)
 
        irlap_flush_all_queues(self);
        
-       self->irdev = NULL;
        self->magic = 0;
        
        kfree(self);
@@ -277,7 +272,7 @@ void irlap_connect_request(struct irlap_cb *self, __u32 daddr,
        irlap_init_qos_capabilities(self, qos_user);
        
        if ((self->state == LAP_NDM) && 
-           !irda_device_is_media_busy(self->irdev))
+           !irda_device_is_media_busy(self->netdev))
                irlap_do_event(self, CONNECT_REQUEST, NULL, NULL);
        else
                self->connect_pending = TRUE;
@@ -565,7 +560,7 @@ void irlap_discovery_confirm(struct irlap_cb *self, hashbin_t *discovery_log)
         * connection attempts much easier.
         */
        if (discovery_log && hashbin_get_size(discovery_log) > 0)
-               irda_device_set_media_busy(self->irdev, FALSE);
+               irda_device_set_media_busy(self->netdev, FALSE);
        
        /* Inform IrLMP */
        irlmp_link_discovery_confirm(self->notify.instance, discovery_log);
@@ -849,17 +844,24 @@ void irlap_flush_all_queues(struct irlap_cb *self)
  */
 void irlap_change_speed(struct irlap_cb *self, __u32 speed)
 {
+       struct ifreq req;
+
        DEBUG(4, __FUNCTION__ "(), setting speed to %d\n", speed);
 
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == LAP_MAGIC, return;);
 
-       if (!self->irdev) {
+       if (!self->netdev) {
                DEBUG(1, __FUNCTION__ "(), driver missing!\n");
                return;
        }
 
-       irda_device_change_speed(self->irdev, speed);
+       /* 
+        * Warning, ifr_bandwidth is only 16 bits on architectures where ints
+         * are 16 bits wide.
+        */
+       req.ifr_bandwidth = speed;
+       self->netdev->do_ioctl(self->netdev, &req, SIOCSBANDWIDTH);
 
        self->qos_rx.baud_rate.value = speed;
        self->qos_tx.baud_rate.value = speed;
@@ -922,7 +924,7 @@ void irlap_init_qos_capabilities(struct irlap_cb *self,
 {
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == LAP_MAGIC, return;);
-       ASSERT(self->irdev != NULL, return;);
+       ASSERT(self->netdev != NULL, return;);
 
        /* Start out with the maximum QoS support possible */
        irda_init_max_qos_capabilies(&self->qos_rx);
@@ -933,7 +935,7 @@ void irlap_init_qos_capabilities(struct irlap_cb *self,
 
        /* Apply drivers QoS capabilities */
        irda_qos_compute_intersection(&self->qos_rx, 
-                                     irda_device_get_qos(self->irdev));
+                                     irda_device_get_qos(self->netdev));
 
        /*
         *  Check for user supplied QoS parameters. The service user is only 
@@ -1112,8 +1114,7 @@ int irlap_proc_read(char *buf, char **start, off_t offset, int len,
                ASSERT(self != NULL, return -ENODEV;);
                ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
 
-               len += sprintf(buf+len, "irlap%d <-> %s ",
-                               i++, self->irdev->name);
+               len += sprintf(buf+len, "irlap%d ", i++);
                len += sprintf(buf+len, "state: %s\n", 
                                irlap_state[ self->state]);
                
index c845ac8526f27dc372f6bd37b5818032612eebdf..203b7360fc298a0e52c83f39bc07d60f37f934bd 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sat Aug 16 00:59:29 1997
- * Modified at:   Wed Aug 25 14:49:47 1999
+ * Modified at:   Mon Sep 20 12:30:31 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
@@ -127,9 +127,9 @@ const char *irlap_state[] = {
        "LAP_RESET_CHECK",
 };
 
-static int (*state[])( struct irlap_cb *self, IRLAP_EVENT event, 
-                      struct sk_buff *skb, struct irlap_info *info) = 
-{ 
+static int (*state[])(struct irlap_cb *self, IRLAP_EVENT event, 
+                     struct sk_buff *skb, struct irlap_info *info) = 
+{
        irlap_state_ndm,
        irlap_state_query,
        irlap_state_reply,
@@ -257,7 +257,7 @@ void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event,
        case LAP_NDM:
                /* Check if we should try to connect */
                if ((self->connect_pending) && 
-                   !irda_device_is_media_busy(self->irdev)) 
+                   !irda_device_is_media_busy(self->netdev)) 
                {
                        self->connect_pending = FALSE;
                        
@@ -310,16 +310,14 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event,
        discovery_t *discovery_rsp;
        int ret = 0;
        
-       DEBUG(4, __FUNCTION__ "()\n");
-       
        ASSERT(self != NULL, return -1;);
        ASSERT(self->magic == LAP_MAGIC, return -1;);
 
        switch (event) {
        case CONNECT_REQUEST:
-               ASSERT(self->irdev != NULL, return -1;);
+               ASSERT(self->netdev != NULL, return -1;);
 
-               if (irda_device_is_media_busy(self->irdev)) {
+               if (irda_device_is_media_busy(self->netdev)) {
                        DEBUG(0, __FUNCTION__
                              "(), CONNECT_REQUEST: media busy!\n");
                        
@@ -337,20 +335,25 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event,
                        irlap_next_state(self, LAP_SETUP);
                }
                break;
-
        case RECV_SNRM_CMD:
-               self->daddr = info->daddr;
-               self->caddr = info->caddr;
-               
-               irlap_next_state(self, LAP_CONN);
-
-               irlap_connect_indication(self, skb);
+               /* Check if the frame contains and I field */
+               if (info) {                    
+                       self->daddr = info->daddr;
+                       self->caddr = info->caddr;
+                       
+                       irlap_next_state(self, LAP_CONN);
+                       
+                       irlap_connect_indication(self, skb);
+               } else {
+                       DEBUG(0, __FUNCTION__ "(), SNRM frame does not contain"
+                             " and I field!\n");
+                       dev_kfree_skb(skb);
+               }
                break;
-
        case DISCOVERY_REQUEST:         
                ASSERT(info != NULL, return -1;);
 
-               if (irda_device_is_media_busy(self->irdev)) {
+               if (irda_device_is_media_busy(self->netdev)) {
                        DEBUG(0, __FUNCTION__ "(), media busy!\n"); 
                        /* irlap->log.condition = MEDIA_BUSY; */
                        
@@ -371,9 +374,8 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event,
                irlap_start_slot_timer(self, self->slot_timeout);
                irlap_next_state(self, LAP_QUERY);
                break;
-
        case RECV_DISCOVERY_XID_CMD:
-               ASSERT( info != NULL, return -1;);
+               ASSERT(info != NULL, return -1;);
 
                /* Assert that this is not the final slot */
                if (info->s <= info->S) {
@@ -422,6 +424,10 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event,
        default:
                DEBUG(2, __FUNCTION__ "(), Unknown event %s\n", 
                      irlap_event[event]);
+
+               if (skb)
+                       dev_kfree_skb(skb);
+
                ret = -1;
                break;
        }       
@@ -499,7 +505,7 @@ static int irlap_state_query(struct irlap_cb *self, IRLAP_EVENT event,
                      irlap_event[event]);
 
                if (skb)
-                       dev_kfree_skb( skb);
+                       dev_kfree_skb(skb);
 
                ret = -1;
                break;
@@ -525,7 +531,7 @@ static int irlap_state_reply(struct irlap_cb *self, IRLAP_EVENT event,
        ASSERT(self != NULL, return -1;);
        ASSERT(self->magic == LAP_MAGIC, return -1;);
 
-       switch(event) {
+       switch (event) {
        case QUERY_TIMER_EXPIRED:
                DEBUG(2, __FUNCTION__ "(), QUERY_TIMER_EXPIRED <%ld>\n",
                      jiffies);
@@ -593,7 +599,7 @@ static int irlap_state_conn(struct irlap_cb *self, IRLAP_EVENT event,
                /* skb_pull(skb, 11); */
                skb_pull(skb, sizeof(struct snrm_frame));
 
-               ASSERT(self->irdev != NULL, return -1;);
+               ASSERT(self->netdev != NULL, return -1;);
 
                irlap_qos_negotiate(self, skb);
 
@@ -615,27 +621,21 @@ static int irlap_state_conn(struct irlap_cb *self, IRLAP_EVENT event,
                irlap_start_wd_timer(self, self->wd_timeout);
                irlap_next_state( self, LAP_NRM_S);
                break;
-
-       case RECV_SNRM_CMD:
-               DEBUG( 3, __FUNCTION__ "(), event RECV_SNRM_CMD!\n");
-#if 0
-               irlap_next_state( self, LAP_NDM);
-#endif
-               break;
-               
        case RECV_DISCOVERY_XID_CMD:
                DEBUG( 3, __FUNCTION__ "(), event RECV_DISCOVER_XID_CMD!\n");
                irlap_next_state( self, LAP_NDM);
-               break;
-               
+               break;          
        case DISCONNECT_REQUEST:
                irlap_send_dm_frame( self);
                irlap_next_state( self, LAP_CONN);
                break;
-
        default:
                DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event, 
                      irlap_event[event]);
+
+               if (skb)
+                       dev_kfree_skb(skb);
+
                ret = -1;
                break;
        }
@@ -694,11 +694,11 @@ static int irlap_state_setup(struct irlap_cb *self, IRLAP_EVENT event,
                 *  The device with the largest device address wins the battle
                 *  (both have sent a SNRM command!)
                 */
-               if (info->daddr > self->saddr) {
+               if (info &&(info->daddr > self->saddr)) {
                        del_timer(&self->final_timer);
                        irlap_initiate_connection_state(self);
 
-                       ASSERT(self->irdev != NULL, return -1;);
+                       ASSERT(self->netdev != NULL, return -1;);
 
                        skb_pull(skb, sizeof(struct snrm_frame));
 
@@ -718,6 +718,7 @@ static int irlap_state_setup(struct irlap_cb *self, IRLAP_EVENT event,
                        irlap_next_state(self, LAP_NRM_S);
                } else {
                        /* We just ignore the other device! */
+                       dev_kfree_skb(skb);
                        irlap_next_state(self, LAP_SETUP);
                }
                break;
@@ -733,7 +734,7 @@ static int irlap_state_setup(struct irlap_cb *self, IRLAP_EVENT event,
 
                skb_pull(skb, sizeof(struct ua_frame));
 
-               ASSERT(self->irdev != NULL, return -1;);
+               ASSERT(self->netdev != NULL, return -1;);
 
                irlap_qos_negotiate(self, skb);
 
@@ -756,10 +757,14 @@ static int irlap_state_setup(struct irlap_cb *self, IRLAP_EVENT event,
                irlap_disconnect_indication(self, LAP_DISC_INDICATION);
                break;
 
-       /* DM handled in irlap_frame.c, irlap_input() */
-               
+       /* DM handled in irlap_frame.c, irlap_driver_rcv() */           
        default:
-               DEBUG( 4, "irlap_state_setup: Unknown event");
+               DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event, 
+                     irlap_event[event]);
+               
+               if (skb)
+                       dev_kfree_skb(skb);
+
                ret = -1;
                break;
        }       
@@ -931,6 +936,10 @@ static int irlap_state_pclose(struct irlap_cb *self, IRLAP_EVENT event,
                break;
        default:
                DEBUG(1, __FUNCTION__ "(), Unknown event %d\n", event);
+
+               if (skb)
+                       dev_kfree_skb(skb);
+
                ret = -1;
                break;  
        }
@@ -1254,7 +1263,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
                 *  of receiving a frame (page 45, IrLAP). Check that
                 *  we only do this once for each frame.
                 */
-               if (irda_device_is_receiving(self->irdev) && !self->add_wait) {
+               if (irda_device_is_receiving(self->netdev) && !self->add_wait) {
                        DEBUG(4, "FINAL_TIMER_EXPIRED when receiving a "
                              "frame! Waiting a little bit more!\n");
                        irlap_start_final_timer(self, MSECS_TO_JIFFIES(300));
@@ -1373,6 +1382,9 @@ static int irlap_state_reset_wait(struct irlap_cb *self, IRLAP_EVENT event,
        default:
                DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", 
                      irlap_event[event]);
+               if (skb)
+                       dev_kfree_skb(skb);
+
                ret = -1;
                break;  
        }
@@ -1425,9 +1437,8 @@ static int irlap_state_reset(struct irlap_cb *self, IRLAP_EVENT event,
                if (self->retry_count < 3) {
                        irlap_wait_min_turn_around(self, &self->qos_tx);
 
-                       ASSERT(self->irdev != NULL, return -1;);
-                       irlap_send_snrm_frame(self, 
-                                             irda_device_get_qos(self->irdev));
+                       ASSERT(self->netdev != NULL, return -1;);
+                       irlap_send_snrm_frame(self, irda_device_get_qos(self->netdev));
 
                        self->retry_count++; /* Experimental!! */
 
@@ -1443,17 +1454,31 @@ static int irlap_state_reset(struct irlap_cb *self, IRLAP_EVENT event,
                }
                break;
        case RECV_SNRM_CMD:
-               DEBUG(3, __FUNCTION__ "(), RECV_SNRM_CMD\n");
-               irlap_initiate_connection_state(self);
-               irlap_wait_min_turn_around(self, &self->qos_tx);
-               irlap_send_ua_response_frame(self, &self->qos_rx);
-               irlap_reset_confirm();
-               irlap_start_wd_timer(self, self->wd_timeout);
-               irlap_next_state(self, LAP_NDM);
+               /* 
+                * SNRM frame is not allowed to contain an I-field in this 
+                * state
+                */
+               if (!info) {
+                       DEBUG(3, __FUNCTION__ "(), RECV_SNRM_CMD\n");
+                       irlap_initiate_connection_state(self);
+                       irlap_wait_min_turn_around(self, &self->qos_tx);
+                       irlap_send_ua_response_frame(self, &self->qos_rx);
+                       irlap_reset_confirm();
+                       irlap_start_wd_timer(self, self->wd_timeout);
+                       irlap_next_state(self, LAP_NDM);
+               } else {
+                       DEBUG(0, __FUNCTION__ "(), SNRM frame contained an I "
+                             "field!\n");
+                       dev_kfree_skb(skb);
+               }
                break;
        default:
                DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", 
                      irlap_event[event]);
+
+               if (skb)
+                       dev_kfree_skb(skb);
+
                ret = -1;
                break;  
        }
@@ -1482,14 +1507,13 @@ static int irlap_state_xmit_s(struct irlap_cb *self, IRLAP_EVENT event,
                /*
                 *  Send frame only if send window > 1
                 */ 
-               if ((self->window > 0) && ( !self->remote_busy)) {
+               if ((self->window > 0) && (!self->remote_busy)) {
                        /*
                         *  Test if we have transmitted more bytes over the 
                         *  link than its possible to do with the current 
                         *  speed and turn-around-time.
                         */
                        if ((skb->len+self->bofs_count) > self->bytes_left) {
-                               DEBUG( 4, "IrDA: Not allowed to transmit more bytes!\n");
                                skb_queue_head(&self->tx_list, skb);
                                /*
                                 *  Switch to NRM_S, this is only possible
@@ -1531,6 +1555,9 @@ static int irlap_state_xmit_s(struct irlap_cb *self, IRLAP_EVENT event,
        default:
                DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", 
                      irlap_event[event]);
+               if (skb)
+                       dev_kfree_skb(skb);
+
                ret = -EINVAL;
                break;
        }
@@ -1586,7 +1613,7 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event,
                                 *  Starting WD-timer here is optional, but
                                 *  not recommended. Note 6 IrLAP p. 83
                                 */
-                               /* irda_start_timer( WD_TIMER, self->wd_timeout); */
+                               /* irda_start_timer(WD_TIMER, self->wd_timeout); */
 
                                /* Keep state, do not move this line */
                                irlap_next_state(self, LAP_NRM_S);
@@ -1785,15 +1812,20 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event,
 
                break;
        case RECV_SNRM_CMD:
-               del_timer(&self->wd_timer);
-               DEBUG(1, __FUNCTION__ "(), received SNRM cmd\n");
-               irlap_next_state(self, LAP_RESET_CHECK);
-
-               irlap_reset_indication(self);
+               /* SNRM frame is not allowed to contain an I-field */
+               if (!info) {
+                       del_timer(&self->wd_timer);
+                       DEBUG(1, __FUNCTION__ "(), received SNRM cmd\n");
+                       irlap_next_state(self, LAP_RESET_CHECK);
+                       
+                       irlap_reset_indication(self);
+               } else {
+                       DEBUG(0, __FUNCTION__ "(), SNRM frame contained an "
+                             "I-field!\n");
+                       dev_kfree_skb(skb);            
+               }
                break;
        case WD_TIMER_EXPIRED:
-               DEBUG( 4, "WD_TIMER_EXPIRED: %ld\n", jiffies);
-       
                /*
                 *  Wait until retry_count * n matches negotiated threshold/
                 *  disconnect time (note 2 in IrLAP p. 82)
index 6e7b1e35eea591df0a4a8168332d8a54a49adf6c..303bc3b125993d3afe58d7730462024aa846549f 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Aug 19 10:27:26 1997
- * Modified at:   Wed Aug 25 13:15:53 1999
+ * Modified at:   Tue Sep 28 08:49:58 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -161,27 +161,34 @@ static void irlap_recv_snrm_cmd(struct irlap_cb *self, struct sk_buff *skb,
 {
        struct snrm_frame *frame;
 
-       DEBUG(3, __FUNCTION__ "()\n");
-
-       ASSERT(skb != NULL, return;);
-       ASSERT(info != NULL, return;);
-
        frame = (struct snrm_frame *) skb->data;
-
-       /* Copy peer device address */
-       info->daddr = le32_to_cpu(frame->saddr);
-
-       /* Copy connection address */
-       info->caddr = frame->ncaddr;
-
-       /* Check if connection address has got a valid value */
-       if ((info->caddr == 0x00) || (info->caddr == 0xfe)) {
-               DEBUG(3, __FUNCTION__ "(), invalid connection address!\n");
-               dev_kfree_skb(skb);
-               return;
-       }
-
-       irlap_do_event(self, RECV_SNRM_CMD, skb, info);
+       
+       if (skb->len >= sizeof(struct snrm_frame)) {
+               /* Copy the new connection address */
+               info->caddr = frame->ncaddr;
+
+               /* Check if the new connection address is valid */
+               if ((info->caddr == 0x00) || (info->caddr == 0xfe)) {
+                       DEBUG(3, __FUNCTION__ 
+                             "(), invalid connection address!\n");
+                       dev_kfree_skb(skb);
+                       return;
+               }
+               
+               /* Copy peer device address */
+               info->daddr = le32_to_cpu(frame->saddr);
+               info->saddr = le32_to_cpu(frame->daddr);
+               
+               /* Only accept if addressed directly to us */
+               if (info->saddr != self->saddr) {
+                       DEBUG(2, __FUNCTION__ "(), not addressed to us!\n");
+                       dev_kfree_skb(skb);
+                       return;
+               }
+               irlap_do_event(self, RECV_SNRM_CMD, skb, info);
+       } else
+               /* Signal that this SNRM frame does not contain and I-field */
+               irlap_do_event(self, RECV_SNRM_CMD, skb, NULL);
 }
 
 /*
@@ -318,7 +325,7 @@ void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s,
        skb_put(skb, 14);
        frame = (struct xid_frame *) skb->data;
 
-       if ( command) {
+       if (command) {
                frame->caddr = CBROADCAST | CMD_FRAME;
                frame->control =  XID_CMD | PF_BIT;
        } else {
@@ -334,7 +341,7 @@ void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s,
        else
                frame->daddr = cpu_to_le32(discovery->daddr);
        
-       switch(S) {
+       switch (S) {
        case 1:
                frame->flags = 0x00;
                break;
@@ -402,18 +409,24 @@ static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self,
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == LAP_MAGIC, return;);
 
+       xid = (struct xid_frame *) skb->data;
+
+       info->daddr = le32_to_cpu(xid->saddr);
+       info->saddr = le32_to_cpu(xid->daddr);
+
+       /* Make sure frame is addressed to us */
+       if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
+               dev_kfree_skb(skb);
+               DEBUG(0, __FUNCTION__ "(), frame is not addressed to us!\n");
+               return;
+       }
+
        if ((discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC)) == NULL) {
-               DEBUG(0, __FUNCTION__ "(), kmalloc failed!\n");
+               WARNING(__FUNCTION__ "(), kmalloc failed!\n");
                return;
        }
        memset(discovery, 0, sizeof(discovery_t));
 
-       xid = (struct xid_frame *) skb->data;
-
-       /* 
-        *  Copy peer device address and set the source address
-        */
-       info->daddr = le32_to_cpu(xid->saddr);
        discovery->daddr = info->daddr;
        discovery->saddr = self->saddr;
        discovery->timestamp = jiffies;
@@ -462,17 +475,17 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self,
        __u8 *discovery_info;
        char *text;
 
-       DEBUG(4, __FUNCTION__ "()\n");
-
-       ASSERT(self != NULL, return;);
-       ASSERT(self->magic == LAP_MAGIC, return;);
-       ASSERT(skb != NULL, return;);
-       ASSERT(info != NULL, return;);
-
        xid = (struct xid_frame *) skb->data;
-       
-       /* Copy peer device address */
+
        info->daddr = le32_to_cpu(xid->saddr);
+       info->saddr = le32_to_cpu(xid->daddr);
+
+       /* Make sure frame is addressed to us */
+       if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
+               DEBUG(0, __FUNCTION__ "(), frame is not addressed to us!\n");
+               dev_kfree_skb(skb);
+               return;
+       }
 
        switch (xid->flags & 0x03) {
        case 0x00:
@@ -567,7 +580,7 @@ void irlap_send_rr_frame(struct irlap_cb *self, int command)
  *
  *    Received RR (Receive Ready) frame from peer station, no harm in
  *    making it inline since its called only from one single place
- *    (irlap_input).
+ *    (irlap_driver_rcv).
  */
 static inline void irlap_recv_rr_frame(struct irlap_cb *self, 
                                       struct sk_buff *skb, 
@@ -642,21 +655,16 @@ static void irlap_recv_rnr_frame( struct irlap_cb *self, struct sk_buff *skb,
 static void irlap_recv_ua_frame(struct irlap_cb *self, struct sk_buff *skb, 
                                struct irlap_info *info) 
 {
-       DEBUG(4, __FUNCTION__ "(), <%ld>\n", jiffies); 
-
-       ASSERT(skb != NULL, return;);
-       ASSERT(info != NULL, return;);
-
        irlap_do_event(self, RECV_UA_RSP, skb, info);
 }
 
 /*
  * Function irlap_send_data_primary(self, skb)
  *
- *    
+ *    Send I-frames as the primary station but without the poll bit set
  *
  */
-void irlap_send_data_primary( struct irlap_cb *self, struct sk_buff *skb)
+void irlap_send_data_primary(struct irlap_cb *self, struct sk_buff *skb)
 {
        struct sk_buff *tx_skb;
 
@@ -698,11 +706,11 @@ void irlap_send_data_primary( struct irlap_cb *self, struct sk_buff *skb)
        }
 }
 /*
- * Function irlap_send_data_primary_poll ( self, skb)
+ * Function irlap_send_data_primary_poll (self, skb)
  *
  *    Send I(nformation) frame as primary with poll bit set
  */
-void irlap_send_data_primary_poll( struct irlap_cb *self, struct sk_buff *skb) 
+void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb) 
 {
        struct sk_buff *tx_skb;
 
@@ -779,12 +787,12 @@ void irlap_send_data_secondary_final(struct irlap_cb *self,
 {
        struct sk_buff *tx_skb = NULL;
 
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == LAP_MAGIC, return;);
-       ASSERT( skb != NULL, return;);
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == LAP_MAGIC, return;);
+       ASSERT(skb != NULL, return;);
 
        /* Is this reliable or unreliable data? */
-       if ( skb->data[1] == I_FRAME) {
+       if (skb->data[1] == I_FRAME) {
 
                /*  
                 *  Insert frame sequence number (Vs) in control field before
@@ -792,17 +800,17 @@ void irlap_send_data_secondary_final(struct irlap_cb *self,
                 */
                skb->data[1] = I_FRAME | (self->vs << 1);
                
-               tx_skb = skb_clone( skb, GFP_ATOMIC);
-               if ( tx_skb == NULL) {
-                       dev_kfree_skb( skb);
+               tx_skb = skb_clone(skb, GFP_ATOMIC);
+               if (tx_skb == NULL) {
+                       dev_kfree_skb(skb);
                        return;
                }               
 
                if (skb->sk != NULL)
-                       skb_set_owner_w( tx_skb, skb->sk);
+                       skb_set_owner_w(tx_skb, skb->sk);
                
                /* Insert frame in store */
-               skb_queue_tail( &self->wx_list, skb);
+               skb_queue_tail(&self->wx_list, skb);
                
                tx_skb->data[1] |= PF_BIT;
                
@@ -810,21 +818,21 @@ void irlap_send_data_secondary_final(struct irlap_cb *self,
                self->window = self->window_size;
                self->ack_required = FALSE;
                
-               irlap_start_wd_timer( self, self->wd_timeout);
+               irlap_start_wd_timer(self, self->wd_timeout);
 
-               irlap_send_i_frame( self, tx_skb, RSP_FRAME); 
+               irlap_send_i_frame(self, tx_skb, RSP_FRAME); 
        } else {
-               if ( self->ack_required) {
-                       irlap_send_ui_frame( self, skb, RSP_FRAME);
-                       irlap_send_rr_frame( self, RSP_FRAME);
+               if (self->ack_required) {
+                       irlap_send_ui_frame(self, skb, RSP_FRAME);
+                       irlap_send_rr_frame(self, RSP_FRAME);
                        self->ack_required = FALSE;
                } else {
                        skb->data[1] |= PF_BIT;
-                       irlap_send_ui_frame( self, skb, RSP_FRAME);
+                       irlap_send_ui_frame(self, skb, RSP_FRAME);
                }
                self->window = self->window_size;
 
-               irlap_start_wd_timer( self, self->wd_timeout);
+               irlap_start_wd_timer(self, self->wd_timeout);
        }
 }
 
@@ -834,16 +842,12 @@ void irlap_send_data_secondary_final(struct irlap_cb *self,
  *    Send I(nformation) frame as secondary without final bit set
  *
  */
-void irlap_send_data_secondary( struct irlap_cb *self, struct sk_buff *skb) 
+void irlap_send_data_secondary(struct irlap_cb *self, struct sk_buff *skb) 
 {
        struct sk_buff *tx_skb = NULL;
 
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == LAP_MAGIC, return;);
-       ASSERT( skb != NULL, return;);
-
        /* Is this reliable or unreliable data? */
-       if ( skb->data[1] == I_FRAME) {
+       if (skb->data[1] == I_FRAME) {
                
                /*  
                 *  Insert frame sequence number (Vs) in control field before
@@ -851,25 +855,25 @@ void irlap_send_data_secondary( struct irlap_cb *self, struct sk_buff *skb)
                 */
                skb->data[1] = I_FRAME | (self->vs << 1);
                
-               tx_skb = skb_clone( skb, GFP_ATOMIC);
-               if ( tx_skb == NULL) {
-                       dev_kfree_skb( skb);
+               tx_skb = skb_clone(skb, GFP_ATOMIC);
+               if (tx_skb == NULL) {
+                       dev_kfree_skb(skb);
                        return;
                }               
                
                if (skb->sk != NULL)
-                       skb_set_owner_w( tx_skb, skb->sk);
+                       skb_set_owner_w(tx_skb, skb->sk);
                
                /* Insert frame in store */
-               skb_queue_tail( &self->wx_list, skb);
+               skb_queue_tail(&self->wx_list, skb);
                
                self->vs = (self->vs + 1) % 8;
                self->ack_required = FALSE;             
                self->window -= 1;
 
-               irlap_send_i_frame( self, tx_skb, RSP_FRAME); 
+               irlap_send_i_frame(self, tx_skb, RSP_FRAME); 
        } else {
-               irlap_send_ui_frame( self, skb, RSP_FRAME);
+               irlap_send_ui_frame(self, skb, RSP_FRAME);
                self->window -= 1;
        }
 }
@@ -883,16 +887,14 @@ void irlap_send_data_secondary( struct irlap_cb *self, struct sk_buff *skb)
  * 
  *    FIXME: It is not safe to traverse a this list without locking it!
  */
-void irlap_resend_rejected_frames( struct irlap_cb *self, int command) 
+void irlap_resend_rejected_frames(struct irlap_cb *self, int command) 
 {
        struct sk_buff *tx_skb;
        struct sk_buff *skb;
        int count;
 
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == LAP_MAGIC, return;);
-
-       DEBUG(2, __FUNCTION__ "(), retry_count=%d\n", self->retry_count);
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == LAP_MAGIC, return;);
 
        /* Initialize variables */
        skb = tx_skb = NULL;
@@ -900,22 +902,22 @@ void irlap_resend_rejected_frames( struct irlap_cb *self, int command)
        /* 
         *  Resend all unacknowledged frames 
         */
-       count = skb_queue_len( &self->wx_list);
-       skb = skb_peek( &self->wx_list);
-       while ( skb != NULL) {
-               irlap_wait_min_turn_around( self, &self->qos_tx);
+       count = skb_queue_len(&self->wx_list);
+       skb = skb_peek(&self->wx_list);
+       while (skb != NULL) {
+               irlap_wait_min_turn_around(self, &self->qos_tx);
 
                /* We copy the skb to be retransmitted since we will have to 
                 * modify it. Cloning will confuse packet sniffers 
                 */
                /* tx_skb = skb_clone( skb, GFP_ATOMIC); */
                tx_skb = skb_copy(skb, GFP_ATOMIC);
-               if ( tx_skb == NULL) {
+               if (tx_skb == NULL) {
                        /* Unlink tx_skb from list */
                        tx_skb->next = tx_skb->prev = NULL;
                        tx_skb->list = NULL;
                
-                       dev_kfree_skb( skb);
+                       dev_kfree_skb(skb);
                        return; 
                }
                /* Unlink tx_skb from list */
@@ -925,8 +927,8 @@ void irlap_resend_rejected_frames( struct irlap_cb *self, int command)
                /*
                 *  make sure the skb->sk accounting of memory usage is sane
                 */
-               if ( skb->sk != NULL)
-                       skb_set_owner_w( tx_skb, skb->sk);
+               if (skb->sk != NULL)
+                       skb_set_owner_w(tx_skb, skb->sk);
 
                /* Clear old Nr field + poll bit */
                tx_skb->data[1] &= 0x0f;
@@ -934,18 +936,18 @@ void irlap_resend_rejected_frames( struct irlap_cb *self, int command)
                /* 
                 *  Set poll bit on the last frame retransmitted
                 */
-               if ( count-- == 1) 
+               if (count-- == 1)
                        tx_skb->data[1] |= PF_BIT; /* Set p/f bit */
                else
                        tx_skb->data[1] &= ~PF_BIT; /* Clear p/f bit */
                
-               irlap_send_i_frame( self, tx_skb, command);
+               irlap_send_i_frame(self, tx_skb, command);
 
                /* 
                 *  If our skb is the last buffer in the list, then
                 *  we are finished, if not, move to the next sk-buffer
                 */
-               if ( skb == skb_peek_tail( &self->wx_list))
+               if (skb == skb_peek_tail( &self->wx_list))
                        skb = NULL;
                else
                        skb = skb->next;
@@ -955,13 +957,13 @@ void irlap_resend_rejected_frames( struct irlap_cb *self, int command)
         */
        return; /* Skip this for now, DB */
 
-       while ( skb_queue_len( &self->tx_list) > 0) {
+       while (skb_queue_len( &self->tx_list) > 0) {
                
-               DEBUG( 0, __FUNCTION__ "(), sending additional frames!\n");
-               if (( skb_queue_len( &self->tx_list) > 0) && 
-                   ( self->window > 0)) {
+               DEBUG(0, __FUNCTION__ "(), sending additional frames!\n");
+               if ((skb_queue_len( &self->tx_list) > 0) && 
+                   (self->window > 0)) {
                        skb = skb_dequeue( &self->tx_list); 
-                       ASSERT( skb != NULL, return;);
+                       ASSERT(skb != NULL, return;);
 
                        /*
                         *  If send window > 1 then send frame with pf 
@@ -989,11 +991,11 @@ void irlap_send_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
 {
        __u8  *frame;
 
-       DEBUG( 4, __FUNCTION__ "()\n");
+       DEBUG(4, __FUNCTION__ "()\n");
        
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == LAP_MAGIC, return;);
-       ASSERT( skb != NULL, return;);
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == LAP_MAGIC, return;);
+       ASSERT(skb != NULL, return;);
        
        frame = skb->data;
        
@@ -1012,16 +1014,12 @@ void irlap_send_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
 void irlap_send_i_frame(struct irlap_cb *self, struct sk_buff *skb, 
                        int command) 
 {
-       __u8  *frame;
-       
-       frame = skb->data;
-       
        /* Insert connection address */
-       frame[0] = self->caddr;
-       frame[0] |= (command) ? CMD_FRAME : 0;
+       skb->data[0] = self->caddr;
+       skb->data[0] |= (command) ? CMD_FRAME : 0;
        
        /* Insert next to receive (Vr) */
-       frame[1] |= (self->vr << 5);  /* insert nr */
+       skb->data[1] |= (self->vr << 5);  /* insert nr */
 
        irlap_queue_xmit(self, skb);
 }
@@ -1030,7 +1028,7 @@ void irlap_send_i_frame(struct irlap_cb *self, struct sk_buff *skb,
  * Function irlap_recv_i_frame (skb, frame)
  *
  *    Receive and parse an I (Information) frame, no harm in making it inline
- *    since it's called only from one single place (irlap_input).
+ *    since it's called only from one single place (irlap_driver_rcv).
  */
 static inline void irlap_recv_i_frame(struct irlap_cb *self, 
                                      struct sk_buff *skb, 
@@ -1073,18 +1071,18 @@ static void irlap_recv_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
  *    Received Frame Reject response.
  *
  */
-static void irlap_recv_frmr_frame( struct irlap_cb *self, struct sk_buff *skb, 
-                                  struct irlap_info *info) 
+static void irlap_recv_frmr_frame(struct irlap_cb *self, struct sk_buff *skb, 
+                                 struct irlap_info *info) 
 {
        __u8 *frame;
        int w, x, y, z;
 
-       DEBUG( 0, __FUNCTION__ "()\n");
+       DEBUG(0, __FUNCTION__ "()\n");
        
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == LAP_MAGIC, return;);
-       ASSERT( skb != NULL, return;);
-       ASSERT( info != NULL, return;);
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == LAP_MAGIC, return;);
+       ASSERT(skb != NULL, return;);
+       ASSERT(info != NULL, return;);
        
        frame = skb->data;
 
@@ -1097,24 +1095,24 @@ static void irlap_recv_frmr_frame( struct irlap_cb *self, struct sk_buff *skb,
        y = frame[3] & 0x04;
        z = frame[3] & 0x08;
        
-       if ( w) {
-               DEBUG( 0, "Rejected control field is undefined or not "
-                      "implemented.\n");
+       if (w) {
+               DEBUG(0, "Rejected control field is undefined or not "
+                     "implemented.\n");
        } 
-       if ( x) {
-               DEBUG( 0, "Rejected control field was invalid because it "
-                      "contained a non permitted I field.\n");
+       if (x) {
+               DEBUG(0, "Rejected control field was invalid because it "
+                     "contained a non permitted I field.\n");
        }
-       if ( y) {
-               DEBUG( 0, "Received I field exceeded the maximum negotiated "
-                      "for the existing connection or exceeded the maximum "
-                      "this station supports if no connection exists.\n");
+       if (y) {
+               DEBUG(0, "Received I field exceeded the maximum negotiated "
+                     "for the existing connection or exceeded the maximum "
+                     "this station supports if no connection exists.\n");
        }
-       if ( z) {
-               DEBUG( 0, "Rejected control field control field contained an "
-                      "invalid Nr count.\n");
+       if (z) {
+               DEBUG(0, "Rejected control field control field contained an "
+                     "invalid Nr count.\n");
        }
-       irlap_do_event( self, RECV_FRMR_RSP, skb, info);
+       irlap_do_event(self, RECV_FRMR_RSP, skb, info);
 }
 
 /*
@@ -1170,7 +1168,7 @@ void irlap_recv_test_frame(struct irlap_cb *self, struct sk_buff *skb,
 {
        struct test_frame *frame;
 
-       DEBUG(0, __FUNCTION__ "()\n");
+       DEBUG(2, __FUNCTION__ "()\n");
        
        if (skb->len < sizeof(struct test_frame)) {
                DEBUG(0, __FUNCTION__ "() test frame to short!\n");
@@ -1183,6 +1181,12 @@ void irlap_recv_test_frame(struct irlap_cb *self, struct sk_buff *skb,
        info->daddr = le32_to_cpu(frame->saddr);
        info->saddr = le32_to_cpu(frame->daddr);
 
+       /* Make sure frame is addressed to us */
+       if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
+               dev_kfree_skb(skb);
+               return;
+       }
+
        if (command)
                irlap_do_event(self, RECV_TEST_CMD, skb, info);
        else
@@ -1208,7 +1212,18 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev,
        idev = (struct irda_device *) dev->priv;
        self = idev->irlap;
 
-       ASSERT(skb->len > 1, return -1;);
+       /* If the net device is down, then IrLAP is gone! */
+       if (!self || self->magic != LAP_MAGIC) {
+               dev_kfree_skb(skb);
+               return -1;
+       }
+
+       /* Check if frame is large enough for parsing */
+       if (skb->len < 2) {
+               ERROR(__FUNCTION__ "(), frame to short!\n");
+               dev_kfree_skb(skb);
+               return -1;
+       }
        
        command    = skb->data[0] & CMD_FRAME;
        info.caddr = skb->data[0] & CBROADCAST;
@@ -1218,10 +1233,9 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev,
 
        control = info.control;
 
-       /*  First check if this frame addressed to us */
+       /*  First we check if this frame has a valid connection address */
        if ((info.caddr != self->caddr) && (info.caddr != CBROADCAST)) {
-               DEBUG(2, __FUNCTION__ "(), Received frame is not for us!\n");
-
+               DEBUG(0, __FUNCTION__ "(), wrong connection address!\n");
                dev_kfree_skb(skb);
                return 0;
        }
@@ -1259,7 +1273,8 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev,
                        DEBUG( 0, "*** SREJ frame received! ***\n");
                        break;
                default:
-                       WARNING(__FUNCTION__ "() Unknown S frame %02x received!\n",
+                       WARNING(__FUNCTION__ 
+                               "() Unknown S-frame %02x received!\n",
                                info.control);
                        break;
                }
index d958d048c8231f459460a9c751572037455f844b..8b63351ed026a5d73843991e719a65989e46adf4 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Stable.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 17 20:54:32 1997
- * Modified at:   Mon Aug 23 09:30:56 1999
+ * Modified at:   Mon Sep 27 11:15:20 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -503,24 +503,21 @@ int irlmp_connect_response(struct lsap_cb *self, struct sk_buff *userdata)
  */
 void irlmp_connect_confirm(struct lsap_cb *self, struct sk_buff *skb) 
 {
-       int max_seg_size;
        int max_header_size;
        int lap_header_size;
+       int max_seg_size;
 
        DEBUG(3, __FUNCTION__ "()\n");
        
        ASSERT(skb != NULL, return;);
        ASSERT(self != NULL, return;);
-       ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
-       
+       ASSERT(self->magic == LMP_LSAP_MAGIC, return;); 
        ASSERT(self->lap != NULL, return;);
-       self->qos = *self->lap->qos;
 
-       max_seg_size = self->lap->qos->data_size.value-LMP_HEADER;
-       DEBUG(2, __FUNCTION__ "(), max_seg_size=%d\n", max_seg_size);
+       self->qos = *self->lap->qos;
 
-       lap_header_size = irlap_get_header_size(self->lap->irlap);
-       
+       max_seg_size    = self->lap->qos->data_size.value-LMP_HEADER;
+       lap_header_size = irlap_get_header_size(self->lap->irlap);      
        max_header_size = LMP_HEADER + lap_header_size;
 
        DEBUG(2, __FUNCTION__ "(), max_header_size=%d\n", max_header_size);
@@ -530,7 +527,7 @@ void irlmp_connect_confirm(struct lsap_cb *self, struct sk_buff *skb)
 
        if (self->notify.connect_confirm) {
                self->notify.connect_confirm(self->notify.instance, self,
-                                            &self->qos, max_seg_size, 
+                                            &self->qos, max_seg_size,
                                             max_header_size, skb);
        }
 }
@@ -1118,6 +1115,10 @@ __u16 irlmp_service_to_hint(int service)
                hint.byte[0] |= HINT_EXTENSION;
                hint.byte[1] |= HINT_OBEX;
                break;
+       case S_TELEPHONY:
+               hint.byte[0] |= HINT_EXTENSION;
+               hint.byte[1] |= HINT_TELEPHONY;
+               break;
        case S_ANY:
                hint.word = 0xffff;
                break;
index d2408730ebd730935eaf26d7aab97f8721d5626c..ee41e54f4f34bc34e5c0984e830aacbc4913daf5 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Wed Aug 25 14:38:49 1999
+ * Modified at:   Tue Sep 21 13:04:33 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -195,10 +195,10 @@ void irlmp_idle_timer_expired(void *data)
 static void irlmp_state_standby(struct lap_cb *self, IRLMP_EVENT event, 
                                struct sk_buff *skb)
 {      
-       DEBUG( 4, __FUNCTION__ "()\n"); 
-       ASSERT( self->irlap != NULL, return;);
+       DEBUG(4, __FUNCTION__ "()\n"); 
+       ASSERT(self->irlap != NULL, return;);
        
-       switchevent) {
+       switch (event) {
        case LM_LAP_DISCOVERY_REQUEST:
                /* irlmp_next_station_state( LMP_DISCOVER); */
                
@@ -213,10 +213,10 @@ static void irlmp_state_standby(struct lap_cb *self, IRLMP_EVENT event,
                 *  think that the link is free since IrLMP may then start
                 *  discovery before the connection is properly set up. DB.
                 */
-               irlmp_next_lap_state( self, LAP_ACTIVE);
+               irlmp_next_lap_state(self, LAP_ACTIVE);
 
                /* Just accept connection TODO, this should be fixed */
-               irlap_connect_response( self->irlap, skb);
+               irlap_connect_response(self->irlap, skb);
                break;
        case LM_LAP_CONNECT_REQUEST:
                DEBUG(4, __FUNCTION__ "() LS_CONNECT_REQUEST\n");
@@ -224,11 +224,11 @@ static void irlmp_state_standby(struct lap_cb *self, IRLMP_EVENT event,
                /* FIXME: need to set users requested QoS */
                irlap_connect_request(self->irlap, self->daddr, NULL, 0);
 
-               irlmp_next_lap_state( self, LAP_U_CONNECT);
+               irlmp_next_lap_state(self, LAP_U_CONNECT);
                break;
        case LM_LAP_DISCONNECT_INDICATION:
-               DEBUG( 4, __FUNCTION__ 
-                      "(), Error LM_LAP_DISCONNECT_INDICATION\n");
+               DEBUG(4, __FUNCTION__ 
+                     "(), Error LM_LAP_DISCONNECT_INDICATION\n");
                
                irlmp_next_lap_state( self, LAP_STANDBY);
                break;
@@ -251,15 +251,15 @@ static void irlmp_state_u_connect( struct lap_cb *self, IRLMP_EVENT event,
        struct lsap_cb *lsap;
        struct lsap_cb *lsap_current;
        
-       DEBUG(2, __FUNCTION__ "(), event=%s\n", irlmp_event[ event]);
+       DEBUG(2, __FUNCTION__ "(), event=%s\n", irlmp_event[event]);
 
-       switchevent) {
+       switch (event) {
        case LM_LAP_CONNECT_CONFIRM:
                /* For all lsap_ce E Associated do LS_Connect_confirm */
-               irlmp_next_lap_state( self, LAP_ACTIVE);
+               irlmp_next_lap_state(self, LAP_ACTIVE);
 
-               lsap = ( struct lsap_cb *) hashbin_get_first( self->lsaps);
-               while ( lsap != NULL) {
+               lsap = (struct lsap_cb *) hashbin_get_first(self->lsaps);
+               while (lsap != NULL) {
                        irlmp_do_lsap_event(lsap, LM_LAP_CONNECT_CONFIRM, skb);
                        lsap = (struct lsap_cb*) hashbin_get_next(self->lsaps);
                }               
@@ -267,33 +267,33 @@ static void irlmp_state_u_connect( struct lap_cb *self, IRLMP_EVENT event,
        case LM_LAP_DISCONNECT_INDICATION:
                DEBUG(2, __FUNCTION__ "(), IRLAP_DISCONNECT_INDICATION\n");
        
-               irlmp_next_lap_state( self, LAP_STANDBY);
+               irlmp_next_lap_state(self, LAP_STANDBY);
 
                /* Send disconnect event to all LSAPs using this link */
                
-               lsap = ( struct lsap_cb *) hashbin_get_first( self->lsaps);
-               while ( lsap != NULL ) {
-                       ASSERT( lsap->magic == LMP_LSAP_MAGIC, return;);
+               lsap = (struct lsap_cb *) hashbin_get_first( self->lsaps);
+               while (lsap != NULL ) {
+                       ASSERT(lsap->magic == LMP_LSAP_MAGIC, return;);
                        
                        lsap_current = lsap;
 
                        /* Be sure to stay one item ahead */
-                       lsap = ( struct lsap_cb *) hashbin_get_next( self->lsaps);
-                       irlmp_do_lsap_event( lsap_current, 
-                                            LM_LAP_DISCONNECT_INDICATION,
-                                            NULL);
+                       lsap = (struct lsap_cb *) hashbin_get_next( self->lsaps);
+                       irlmp_do_lsap_event(lsap_current, 
+                                           LM_LAP_DISCONNECT_INDICATION,
+                                           NULL);
                }
                break;
        case LM_LAP_DISCONNECT_REQUEST:
-               DEBUG( 4, __FUNCTION__ "(), LM_LAP_DISCONNECT_REQUEST\n");
+               DEBUG(4, __FUNCTION__ "(), LM_LAP_DISCONNECT_REQUEST\n");
 
-               irlmp_next_lap_state( self, LAP_STANDBY);
+               irlmp_next_lap_state(self, LAP_STANDBY);
 
                /* FIXME */
 /*             irlap_disconnect_request( self->irlap); */
                break;
        default:
-               DEBUG( 4, __FUNCTION__ "(), Unknown event\n");
+               DEBUG(4, __FUNCTION__ "(), Unknown event\n");
                break;
        }       
 }
@@ -359,9 +359,7 @@ static void irlmp_state_active(struct lap_cb *self, IRLMP_EVENT event,
                if (hashbin_get_size(self->lsaps) == 0) {
                        irlmp_next_lap_state(self, LAP_STANDBY);
                        irlap_disconnect_request(self->irlap);
-               } else
-                       /* Still not ready, so wait a little bit more */
-                       irlmp_start_idle_timer(self, LM_IDLE_TIMEOUT);
+               }
                break;
        case LM_LAP_DISCONNECT_INDICATION:
                irlmp_next_lap_state(self, LAP_STANDBY);                
@@ -638,7 +636,20 @@ static int irlmp_state_setup(struct lsap_cb *self, IRLMP_EVENT event,
                irlmp_connect_confirm(self, skb);
                break;
        case LM_DISCONNECT_INDICATION:
-               DEBUG(0, __FUNCTION__ "(), this should never happen!!\n");
+               irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
+                       
+               ASSERT(self->lap != NULL, return -1;);
+               ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
+       
+               ASSERT(skb != NULL, return -1;);
+               ASSERT(skb->len > 3, return -1;);
+               reason = skb->data[3];
+
+                /* Try to close the LAP connection */
+               DEBUG(4, __FUNCTION__ "(), trying to close IrLAP\n");
+               irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
+
+               irlmp_disconnect_indication(self, reason, skb);
                break;
        case LM_LAP_DISCONNECT_INDICATION:
                irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
index 0feec822647d86dd4df03fb9529c8ca92238edbd..e5c5d72ef97c7cc64eeb54cbba1e5af204ab76b6 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Dec 15 13:55:39 1997
- * Modified at:   Wed Aug 11 08:53:56 1999
+ * Modified at:   Mon Sep 20 09:27:25 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1997, 1999 Dag Brattli, All Rights Reserved.
@@ -120,7 +120,9 @@ EXPORT_SYMBOL(irda_debug);
 EXPORT_SYMBOL(irda_notify_init);
 EXPORT_SYMBOL(irmanager_notify);
 EXPORT_SYMBOL(irda_lock);
+#ifdef CONFIG_PROC_FS
 EXPORT_SYMBOL(proc_irda);
+#endif
 EXPORT_SYMBOL(irda_param_insert);
 EXPORT_SYMBOL(irda_param_extract);
 EXPORT_SYMBOL(irda_param_extract_all);
@@ -204,10 +206,10 @@ EXPORT_SYMBOL(irtty_set_packet_mode);
 int __init irda_init(void)
 {
        printk(KERN_INFO "IrDA (tm) Protocols for Linux-2.3 (Dag Brattli)\n");
-
+       
        irlmp_init();
        irlap_init();
-
+       
 #ifdef MODULE
        irda_device_init();     /* Called by init/main.c when non-modular */
 #endif
@@ -360,10 +362,10 @@ void irmanager_notify( struct irmanager_event *event)
 {
        struct irda_event *new;
        
-       DEBUG( 4, __FUNCTION__ "()\n");
-
+       DEBUG(4, __FUNCTION__ "()\n");
+       
        /* Make sure irmanager is running */
-       if ( !irda.in_use) {
+       if (!irda.in_use) {
                printk( KERN_ERR "irmanager is not running!\n");
                return;
        }
@@ -374,14 +376,14 @@ void irmanager_notify( struct irmanager_event *event)
        if ( new == NULL) {
                return; 
        }
-       memset( new, 0, sizeof( struct irda_event));
+       memset(new, 0, sizeof( struct irda_event));
        new->event = *event;
        
        /* Queue event */
-       enqueue_last( &irda.event_queue, (QUEUE *) new);
+       enqueue_last(&irda.event_queue, (QUEUE *) new);
        
        /* Wake up irmanager sleeping on read */
-       wake_up_interruptible( &irda.wait_queue);
+       wake_up_interruptible(&irda.wait_queue);
 }
 
 static int irda_open( struct inode * inode, struct file *file)
@@ -395,7 +397,7 @@ static int irda_open( struct inode * inode, struct file *file)
        irda.in_use = TRUE;
                
        MOD_INC_USE_COUNT;
-
+       
        return 0;
 }
 
@@ -411,9 +413,9 @@ static int irda_ioctl( struct inode *inode, struct file *filp,
        struct irda_todo *todo;
        int err = 0;
        int size = _IOC_SIZE(cmd);
-
-       DEBUG( 4, __FUNCTION__ "()\n");
-
+       
+       DEBUG(4, __FUNCTION__ "()\n");
+       
        if ( _IOC_DIR(cmd) & _IOC_READ)
                err = verify_area( VERIFY_WRITE, (void *) arg, size);
        else if ( _IOC_DIR(cmd) & _IOC_WRITE)
@@ -424,43 +426,43 @@ static int irda_ioctl( struct inode *inode, struct file *filp,
        switch( cmd) {
        case IRMGR_IOCTNPC:
                /* Got process context! */
-               DEBUG( 4, __FUNCTION__ "(), got process context!\n");
-
-               while (( todo = (struct irda_todo *) dequeue_first( 
+               DEBUG(4, __FUNCTION__ "(), got process context!\n");
+               
+               while ((todo = (struct irda_todo *) dequeue_first( 
                        &irda.todo_queue)) != NULL)
                {
-                       todo->callback( todo->self, todo->param);
+                       todo->callback(todo->self, todo->param);
 
-                       kfree( todo);
+                       kfree(todo);
                }
                break;
 
        default:
                return -ENOIOCTLCMD;
        }
-
+       
        return 0;
 }
 
-static int irda_close( struct inode *inode, struct file *file)
+static int irda_close(struct inode *inode, struct file *file)
 {
-       DEBUG( 4, __FUNCTION__ "()\n");
+       DEBUG(4, __FUNCTION__ "()\n");
        
        MOD_DEC_USE_COUNT;
-
+       
        irda.in_use = FALSE;
 
        return 0;
 }
 
-static ssize_t irda_read( struct file *file, char *buffer, size_t count, 
-                         loff_t *noidea)
+static ssize_t irda_read(struct file *file, char *buffer, size_t count, 
+                        loff_t *noidea)
 {
        struct irda_event *event;
        unsigned long flags;
        int len;
 
-       DEBUG( 4, __FUNCTION__ "()\n");
+       DEBUG(4, __FUNCTION__ "()\n");
 
        /* * Go to sleep and wait for event if there is no event to be read! */
        save_flags( flags);
@@ -473,7 +475,7 @@ static ssize_t irda_read( struct file *file, char *buffer, size_t count,
         *  Ensure proper reaction to signals, and screen out 
         *  blocked signals (page 112. linux device drivers)
         */
-       if ( signal_pending( current))
+       if (signal_pending( current))
                return -ERESTARTSYS;
 
        event = (struct irda_event *) dequeue_first( &irda.event_queue);
@@ -481,25 +483,25 @@ static ssize_t irda_read( struct file *file, char *buffer, size_t count,
                return 0;
 
        len = sizeof(struct irmanager_event);
-       copy_to_user( buffer, &event->event, len);
+       copy_to_user(buffer, &event->event, len);
 
        /* Finished with event */
-       kfree( event);
+       kfree(event);
 
        return len;
 }
 
-static ssize_t irda_write( struct file *file, const char *buffer,
-                          size_t count, loff_t *noidea)
+static ssize_t irda_write(struct file *file, const char *buffer,
+                         size_t count, loff_t *noidea)
 {
-       DEBUG( 0, __FUNCTION__ "()\n");
+       DEBUG(0, __FUNCTION__ "()\n");
        
        return 0;
 }
 
-static u_int irda_poll( struct file *file, poll_table *wait)
+static u_int irda_poll(struct file *file, poll_table *wait)
 {
-       DEBUG( 0, __FUNCTION__ "(), Sorry not implemented yet!\n");
+       DEBUG(0, __FUNCTION__ "(), Sorry not implemented yet!\n");
 
        return 0;
 }
index 9d1288779f8d379d3c3277376d7d8ff7b0779eef..43fb65380bdd01ea1aed6f6df5da5f223ef37b75 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:31 1997
- * Modified at:   Thu Jul  8 21:25:31 1999
+ * Modified at:   Mon Sep 27 12:02:52 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -729,9 +729,8 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel,
  *
  */
 static void irttp_connect_confirm(void *instance, void *sap, 
-                                 struct qos_info *qos,
-                                 __u32 max_seg_size, __u8 max_header_size,
-                                 struct sk_buff *skb) 
+                                 struct qos_info *qos, __u32 max_seg_size,
+                                 __u8 max_header_size, struct sk_buff *skb) 
 {
        struct tsap_cb *self;
        int parameters;
@@ -747,7 +746,7 @@ static void irttp_connect_confirm(void *instance, void *sap,
        ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
        ASSERT(skb != NULL, return;);
 
-       self->max_seg_size = max_seg_size;
+       self->max_seg_size = max_seg_size - TTP_HEADER;
        self->max_header_size = max_header_size + TTP_HEADER;
 
        /*
@@ -797,11 +796,11 @@ static void irttp_connect_confirm(void *instance, void *sap,
        DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n", 
              self->send_credit, self->avail_credit, self->remote_credit);
 
-       DEBUG(0, __FUNCTION__ "(), MaxSduSize=%d\n", self->tx_max_sdu_size);
+       DEBUG(2, __FUNCTION__ "(), MaxSduSize=%d\n", self->tx_max_sdu_size);
 
        if (self->notify.connect_confirm) {
                self->notify.connect_confirm(self->notify.instance, self, qos,
-                                            self->tx_max_sdu_size, 
+                                            self->tx_max_sdu_size,
                                             self->max_header_size, skb);
        }
 }
@@ -870,8 +869,6 @@ void irttp_connect_indication(void *instance, void *sap, struct qos_info *qos,
                skb_pull(skb, MIN(skb->len, plen+1));
        }
 
-       DEBUG(4, __FUNCTION__ "(), initial send_credit=%d\n", n);
-
        if (self->notify.connect_indication) {
                self->notify.connect_indication(self->notify.instance, self, 
                                                qos, self->tx_max_sdu_size, 
index 8d645740f6864872d6e8609316db5c2c008b4066..6af865bacd46ab12a7edba87f9fb47ddb2345351 100644 (file)
@@ -7,7 +7,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Sep  9 00:00:26 1997
- * Modified at:   Tue Aug 17 10:25:21 1999
+ * Modified at:   Wed Sep  1 09:14:55 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -278,7 +278,7 @@ static int irlap_param_baud_rate(void *instance, param_t *param, int get)
 
        if (get) {
                param->pv.i = self->qos_rx.baud_rate.bits;
-               DEBUG(0, __FUNCTION__ "(), baud rate = 0x%02x\n", param->pv.i);         
+               DEBUG(2, __FUNCTION__ "(), baud rate = 0x%02x\n", param->pv.i);         
        } else {
                /* 
                 *  Stations must agree on baud rate, so calculate
index 57e3d25106c874f6fe2c3cb7e1006950c12d9def..fab26fd37b8b7d33d99d7bd6c9890210c793a782 100644 (file)
@@ -6,10 +6,11 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sat Aug 16 00:59:29 1997
- * Modified at:   Sat Jun 26 17:03:22 1999
+ * Modified at:   Mon Sep 20 11:32:37 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
+ *     Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, 
+ *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -124,16 +125,14 @@ inline void irlmp_start_idle_timer(struct lap_cb *self, int timeout)
  *    IrLAP slot timer has expired
  *
  */
-static void irlap_slot_timer_expired( void* data)
+static void irlap_slot_timer_expired(void *data)
 {
        struct irlap_cb *self = (struct irlap_cb *) data;
 
-       DEBUG( 4, "Slot timer expired!\n");
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == LAP_MAGIC, return;);
 
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == LAP_MAGIC, return;);
-
-       irlap_do_event( self, SLOT_TIMER_EXPIRED, NULL, NULL);
+       irlap_do_event(self, SLOT_TIMER_EXPIRED, NULL, NULL);
 } 
 
 /*
@@ -142,16 +141,14 @@ static void irlap_slot_timer_expired( void* data)
  *    IrLAP query timer has expired
  *
  */
-static void irlap_query_timer_expired( void* data)
+static void irlap_query_timer_expired(void *data)
 {
        struct irlap_cb *self = (struct irlap_cb *) data;
 
-       DEBUG( 4, "Query timer expired!\n");
-
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == LAP_MAGIC, return;);
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == LAP_MAGIC, return;);
 
-       irlap_do_event( self, QUERY_TIMER_EXPIRED, NULL, NULL);
+       irlap_do_event(self, QUERY_TIMER_EXPIRED, NULL, NULL);
 } 
 
 /*
@@ -160,16 +157,14 @@ static void irlap_query_timer_expired( void* data)
  *    
  *
  */
-static void irlap_final_timer_expired( void* data)
+static void irlap_final_timer_expired(void *data)
 {
        struct irlap_cb *self = (struct irlap_cb *) data;
 
-       DEBUG( 4, "Final timer expired!\n");
-
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == LAP_MAGIC, return;);
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == LAP_MAGIC, return;);
 
-       irlap_do_event( self, FINAL_TIMER_EXPIRED, NULL, NULL);
+       irlap_do_event(self, FINAL_TIMER_EXPIRED, NULL, NULL);
 }
 
 /*
@@ -178,16 +173,14 @@ static void irlap_final_timer_expired( void* data)
  *    
  *
  */
-static void irlap_wd_timer_expired( void* data)
+static void irlap_wd_timer_expired(void *data)
 {
        struct irlap_cb *self = (struct irlap_cb *) data;
        
-       DEBUG( 4, "WD timer expired!\n");
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == LAP_MAGIC, return;);
        
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == LAP_MAGIC, return;);
-       
-       irlap_do_event( self, WD_TIMER_EXPIRED, NULL, NULL);
+       irlap_do_event(self, WD_TIMER_EXPIRED, NULL, NULL);
 }
 
 /*
@@ -196,16 +189,14 @@ static void irlap_wd_timer_expired( void* data)
  *    
  *
  */
-static void irlap_backoff_timer_expired( void* data)
+static void irlap_backoff_timer_expired(void *data)
 {
        struct irlap_cb *self = (struct irlap_cb *) data;
        
-       DEBUG( 0, "Backoff timer expired!\n");
-       
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == LAP_MAGIC, return;);
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == LAP_MAGIC, return;);
        
-       irlap_do_event( self, BACKOFF_TIMER_EXPIRED, NULL, NULL);
+       irlap_do_event(self, BACKOFF_TIMER_EXPIRED, NULL, NULL);
 }
 
 
@@ -214,14 +205,12 @@ static void irlap_backoff_timer_expired( void* data)
  *
  *    
  */
-void irda_device_media_busy_expired( void* data)
+void irda_device_media_busy_expired(void* data)
 {
-       struct irda_device *self = ( struct irda_device *) data;
+       struct irda_device *self = (struct irda_device *) data;
 
-       DEBUG( 4, "Mediabusy timer expired!\n");
-       
-       ASSERT( self != NULL, return;);
-       ASSERT( self->magic == IRDA_DEVICE_MAGIC, return;);
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == IRDA_DEVICE_MAGIC, return;);
 
-       irda_device_set_media_busy( self, FALSE);
+       irda_device_set_media_busy(&self->netdev, FALSE);
 }
index 0d4e08e2d979ab92be36a3fe9e2258ebc768e84a..5f5ed14f3b025be529f3d67feb9502c3313c66ac 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Wed Aug 25 13:13:53 1999
+ * Modified at:   Mon Sep 20 11:18:44 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Modified at:   Fri May 28  3:11 CST 1999
  * Modified by:   Horst von Brand <vonbrand@sleipnir.valparaiso.cl>
@@ -203,7 +203,7 @@ static void state_outside_frame(struct irda_device *idev, __u8 byte)
                /* idev->xbofs++; */
                break;
        case EOF:
-               irda_device_set_media_busy( idev, TRUE);
+               irda_device_set_media_busy(&idev->netdev, TRUE);
                break;
        default:
                break;
@@ -261,7 +261,7 @@ static void state_link_escape(struct irda_device *idev, __u8 byte)
        switch (byte) {
        case BOF: /* New frame? */
                idev->rx_buff.state = BEGIN_FRAME;
-               irda_device_set_media_busy(idev, TRUE);
+               irda_device_set_media_busy(&idev->netdev, TRUE);
                break;
        case CE:
                DEBUG(4, "WARNING: State not defined\n");
@@ -299,7 +299,7 @@ static void state_inside_frame(struct irda_device *idev, __u8 byte)
        switch (byte) {
        case BOF: /* New frame? */
                idev->rx_buff.state = BEGIN_FRAME;
-               irda_device_set_media_busy(idev, TRUE);
+               irda_device_set_media_busy(&idev->netdev, TRUE);
                break;
        case CE: /* Stuffed char */
                idev->rx_buff.state = LINK_ESCAPE;
@@ -314,7 +314,7 @@ static void state_inside_frame(struct irda_device *idev, __u8 byte)
                                   idev->rx_buff.len);
                } else {
                        /* Wrong CRC, discard frame!  */
-                       irda_device_set_media_busy(idev, TRUE); 
+                       irda_device_set_media_busy(&idev->netdev, TRUE); 
                        
                        idev->stats.rx_errors++;
                        idev->stats.rx_crc_errors++;